공개 문서
learn/canonical/knot/run-knot.sh.md
아래는 learn/canonical/knot/run-knot.sh.md 와 동일한 원문입니다. Markdown과 HTML 변환 결과를 각각 복사할 수 있습니다.
공개 문서 원문 (Markdown)
# tools/knot/run-knot.sh
> Hub reference copy — MAS 정본: `tools/knot/run-knot.sh`
```bash
#!/usr/bin/env bash
# Run knot workflows (ingest | query | lint | drain | validate) with harness-safe defaults.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
# shellcheck source=/dev/null
[[ -f "$ROOT/tools/knot/env.example" ]] && source "$ROOT/tools/knot/env.example"
WIKI_DIR="${KNOT_WIKI:-$ROOT/knot-wiki}"
# claude default: codex exec may block on stdin in non-TTY shells
RUNNER="${KNOT_RUNNER:-claude}"
usage() {
cat <<'EOF'
Usage: run-knot.sh <command> [args]
Commands:
ingest Process oldest inbox item (1 commit per source)
query <text> Answer from wiki; optional note save
lint Health check + fix mechanical errors
drain Batch ingest via ops/scripts/drain.sh
validate python3 ops/scripts/lint.py only (no LLM)
Env:
KNOT_WIKI wiki path (default: $ROOT/knot-wiki)
KNOT_RUNNER codex | claude | agy | gemini (default claude)
Harness note: knot is separate from tasks/ — see docs/KNOT-HARNESS-INTEGRATION.md
EOF
}
knot_schema_ref() {
if [[ -f "$WIKI_DIR/schema/schema.md" ]]; then echo "schema/schema.md"
else echo "schema.md"; fi
}
knot_prompts_dir() {
if [[ -d "$WIKI_DIR/ops/prompts" ]]; then echo "ops/prompts"
else echo "prompts"; fi
}
knot_scripts_dir() {
if [[ -d "$WIKI_DIR/ops/scripts" ]]; then echo "ops/scripts"
else echo "scripts"; fi
}
knot_lint_py() {
echo "$WIKI_DIR/$(knot_scripts_dir)/lint.py"
}
knot_drain_sh() {
echo "$WIKI_DIR/$(knot_scripts_dir)/drain.sh"
}
run_prompt() {
local prompt_file="$1"
local extra="${2:-}"
local schema_ref prompts_dir
schema_ref="$(knot_schema_ref)"
prompts_dir="$(knot_prompts_dir)"
local prompt="${schema_ref}와 ${prompts_dir}/${prompt_file}를 정독하고 그대로 실행하라"
[[ -n "$extra" ]] && prompt="$prompt $extra"
cd "$WIKI_DIR"
case "$RUNNER" in
codex) codex exec "$prompt" < /dev/null ;;
claude) claude -p "$prompt" --dangerously-skip-permissions < /dev/null ;;
agy)
if [[ -n "${KNOT_MODEL:-}" ]]; then
agy --model "$KNOT_MODEL" --dangerously-skip-permissions --print-timeout 9m -p "$prompt"
else
agy --dangerously-skip-permissions --print-timeout 9m -p "$prompt"
fi
;;
gemini) gemini -p "$prompt" ;;
*) "$RUNNER" -p "$prompt" ;;
esac
}
[[ $# -ge 1 ]] || { usage; exit 1; }
if [[ ! -d "$WIKI_DIR" ]]; then
echo "[FAIL] KNOT_WIKI not found: $WIKI_DIR" >&2
echo " run: bash tools/knot/install-knot-wiki.sh" >&2
exit 1
fi
cmd="$1"
shift
case "$cmd" in
ingest)
run_prompt "ingest.md"
;;
query)
[[ $# -ge 1 ]] || { echo "usage: run-knot.sh query \"질문\"" >&2; exit 1; }
run_prompt "query.md" "$*"
;;
lint)
run_prompt "lint.md"
;;
drain)
export KNOT_WIKI="$WIKI_DIR"
export KNOT_RUNNER="$RUNNER"
exec bash "$(knot_drain_sh)" "$@"
;;
validate)
python3 "$(knot_lint_py)" "$WIKI_DIR"
;;
-h|--help|help)
usage
;;
*)
echo "Unknown command: $cmd" >&2
usage
exit 1
;;
esac
```
공개 문서 변환 코드 (HTML)
<h1>tools/knot/run-knot.sh</h1>
<blockquote>
<p>Hub reference copy — MAS 정본: <code>tools/knot/run-knot.sh</code></p>
</blockquote>
<pre><code class="language-bash">#!/usr/bin/env bash
# Run knot workflows (ingest | query | lint | drain | validate) with harness-safe defaults.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
# shellcheck source=/dev/null
[[ -f "$ROOT/tools/knot/env.example" ]] && source "$ROOT/tools/knot/env.example"
WIKI_DIR="${KNOT_WIKI:-$ROOT/knot-wiki}"
# claude default: codex exec may block on stdin in non-TTY shells
RUNNER="${KNOT_RUNNER:-claude}"
usage() {
cat <<'EOF'
Usage: run-knot.sh <command> [args]
Commands:
ingest Process oldest inbox item (1 commit per source)
query <text> Answer from wiki; optional note save
lint Health check + fix mechanical errors
drain Batch ingest via ops/scripts/drain.sh
validate python3 ops/scripts/lint.py only (no LLM)
Env:
KNOT_WIKI wiki path (default: $ROOT/knot-wiki)
KNOT_RUNNER codex | claude | agy | gemini (default claude)
Harness note: knot is separate from tasks/ — see docs/KNOT-HARNESS-INTEGRATION.md
EOF
}
knot_schema_ref() {
if [[ -f "$WIKI_DIR/schema/schema.md" ]]; then echo "schema/schema.md"
else echo "schema.md"; fi
}
knot_prompts_dir() {
if [[ -d "$WIKI_DIR/ops/prompts" ]]; then echo "ops/prompts"
else echo "prompts"; fi
}
knot_scripts_dir() {
if [[ -d "$WIKI_DIR/ops/scripts" ]]; then echo "ops/scripts"
else echo "scripts"; fi
}
knot_lint_py() {
echo "$WIKI_DIR/$(knot_scripts_dir)/lint.py"
}
knot_drain_sh() {
echo "$WIKI_DIR/$(knot_scripts_dir)/drain.sh"
}
run_prompt() {
local prompt_file="$1"
local extra="${2:-}"
local schema_ref prompts_dir
schema_ref="$(knot_schema_ref)"
prompts_dir="$(knot_prompts_dir)"
local prompt="${schema_ref}와 ${prompts_dir}/${prompt_file}를 정독하고 그대로 실행하라"
[[ -n "$extra" ]] && prompt="$prompt $extra"
cd "$WIKI_DIR"
case "$RUNNER" in
codex) codex exec "$prompt" < /dev/null ;;
claude) claude -p "$prompt" --dangerously-skip-permissions < /dev/null ;;
agy)
if [[ -n "${KNOT_MODEL:-}" ]]; then
agy --model "$KNOT_MODEL" --dangerously-skip-permissions --print-timeout 9m -p "$prompt"
else
agy --dangerously-skip-permissions --print-timeout 9m -p "$prompt"
fi
;;
gemini) gemini -p "$prompt" ;;
*) "$RUNNER" -p "$prompt" ;;
esac
}
[[ $# -ge 1 ]] || { usage; exit 1; }
if [[ ! -d "$WIKI_DIR" ]]; then
echo "[FAIL] KNOT_WIKI not found: $WIKI_DIR" >&2
echo " run: bash tools/knot/install-knot-wiki.sh" >&2
exit 1
fi
cmd="$1"
shift
case "$cmd" in
ingest)
run_prompt "ingest.md"
;;
query)
[[ $# -ge 1 ]] || { echo "usage: run-knot.sh query \"질문\"" >&2; exit 1; }
run_prompt "query.md" "$*"
;;
lint)
run_prompt "lint.md"
;;
drain)
export KNOT_WIKI="$WIKI_DIR"
export KNOT_RUNNER="$RUNNER"
exec bash "$(knot_drain_sh)" "$@"
;;
validate)
python3 "$(knot_lint_py)" "$WIKI_DIR"
;;
-h|--help|help)
usage
;;
*)
echo "Unknown command: $cmd" >&2
usage
exit 1
;;
esac
</code></pre>