aiwcli 0.10.3 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/run.js +1 -1
- package/dist/commands/clear.js +28 -131
- package/dist/commands/init/index.js +3 -3
- package/dist/lib/gitignore-manager.d.ts +32 -0
- package/dist/lib/gitignore-manager.js +141 -2
- package/dist/templates/CLAUDE.md +8 -8
- package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
- package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
- package/dist/templates/_shared/.claude/settings.json +7 -7
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
- package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
- package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
- package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
- package/dist/templates/_shared/hooks-ts/session_end.ts +107 -0
- package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
- package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
- package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +12 -12
- package/dist/templates/_shared/lib-ts/base/constants.ts +22 -15
- package/dist/templates/_shared/lib-ts/base/git-state.ts +1 -1
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +129 -50
- package/dist/templates/_shared/lib-ts/base/inference.ts +28 -21
- package/dist/templates/_shared/lib-ts/base/logger.ts +15 -2
- package/dist/templates/_shared/lib-ts/base/state-io.ts +9 -7
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +131 -131
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +142 -0
- package/dist/templates/_shared/lib-ts/base/utils.ts +69 -69
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +30 -24
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +50 -32
- package/dist/templates/_shared/lib-ts/context/context-store.ts +76 -48
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +43 -23
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +10 -6
- package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +11 -10
- package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +158 -0
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +6 -4
- package/dist/templates/_shared/lib-ts/types.ts +68 -55
- package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
- package/dist/templates/_shared/scripts/resume_handoff.ts +345 -0
- package/dist/templates/_shared/scripts/save_handoff.ts +3 -3
- package/dist/templates/_shared/scripts/status_line.ts +687 -0
- package/dist/templates/cc-native/.claude/settings.json +175 -185
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +0 -2
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +109 -135
- package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1027 -0
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +792 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +115 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +120 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +250 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +275 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +107 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +240 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +385 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
- package/dist/templates/cc-native/_cc-native/plan-review.config.json +14 -1
- package/oclif.manifest.json +1 -1
- package/package.json +2 -2
- package/dist/templates/_shared/hooks/__init__.py +0 -16
- package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/archive_plan.py +0 -177
- package/dist/templates/_shared/hooks/context_monitor.py +0 -270
- package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
- package/dist/templates/_shared/hooks/pre_compact.py +0 -104
- package/dist/templates/_shared/hooks/session_end.py +0 -173
- package/dist/templates/_shared/hooks/session_start.py +0 -206
- package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
- package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
- package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
- package/dist/templates/_shared/lib/__init__.py +0 -1
- package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__init__.py +0 -65
- package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/subprocess_utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
- package/dist/templates/_shared/lib/base/constants.py +0 -358
- package/dist/templates/_shared/lib/base/hook_utils.py +0 -339
- package/dist/templates/_shared/lib/base/inference.py +0 -307
- package/dist/templates/_shared/lib/base/logger.py +0 -305
- package/dist/templates/_shared/lib/base/stop_words.py +0 -221
- package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
- package/dist/templates/_shared/lib/base/utils.py +0 -263
- package/dist/templates/_shared/lib/context/__init__.py +0 -102
- package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
- package/dist/templates/_shared/lib/context/context_selector.py +0 -508
- package/dist/templates/_shared/lib/context/context_store.py +0 -653
- package/dist/templates/_shared/lib/context/plan_manager.py +0 -303
- package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
- package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
- package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
- package/dist/templates/_shared/lib/templates/README.md +0 -206
- package/dist/templates/_shared/lib/templates/__init__.py +0 -36
- package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/formatters.py +0 -146
- package/dist/templates/_shared/lib/templates/plan_context.py +0 -73
- package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/save_handoff.py +0 -357
- package/dist/templates/_shared/scripts/status_line.py +0 -716
- package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
- package/dist/templates/cc-native/MIGRATION.md +0 -86
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -954
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
- package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
- package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
- package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
- package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
- package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
- package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
- package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
- package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
- package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
- package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1071
- package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
- package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { execFileSync } from "node:child_process";
|
|
8
|
+
|
|
8
9
|
import { logDebug, logWarn } from "./logger.js";
|
|
9
10
|
import { STOP_WORDS } from "./stop-words.js";
|
|
10
11
|
import { cleanTextForSlug } from "./utils.js";
|
|
@@ -44,19 +45,25 @@ export function inference(
|
|
|
44
45
|
|
|
45
46
|
try {
|
|
46
47
|
const isWin = process.platform === "win32";
|
|
47
|
-
|
|
48
|
+
// On Windows with shell:true, Node.js sets windowsVerbatimArguments —
|
|
49
|
+
// args are joined with spaces, NOT individually quoted. We must manually
|
|
50
|
+
// wrap multi-word/special-char args in "..." for cmd.exe parsing.
|
|
51
|
+
// Inside double quotes: "" = literal ", and |&<> are safe.
|
|
52
|
+
const empty = isWin ? '""' : "";
|
|
53
|
+
let promptArg = fullPrompt;
|
|
54
|
+
if (isWin) {
|
|
55
|
+
promptArg = '"' + fullPrompt.replaceAll(/\r?\n/g, " ").replaceAll('"', '""') + '"';
|
|
56
|
+
}
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
// (no string interpolation — avoids command injection)
|
|
51
|
-
stdout = execFileSync(
|
|
58
|
+
const stdout = execFileSync(
|
|
52
59
|
"claude",
|
|
53
|
-
["--model", model, "--print", "--setting-sources",
|
|
60
|
+
["--model", model, "--print", "--setting-sources", empty, "-p", promptArg],
|
|
54
61
|
{
|
|
55
62
|
timeout: timeoutSec * 1000,
|
|
56
63
|
env,
|
|
57
64
|
encoding: "utf-8",
|
|
58
65
|
stdio: ["pipe", "pipe", "pipe"],
|
|
59
|
-
shell: isWin, // Windows needs shell for
|
|
66
|
+
shell: isWin, // Windows needs shell for .cmd resolution
|
|
60
67
|
},
|
|
61
68
|
);
|
|
62
69
|
|
|
@@ -66,10 +73,10 @@ export function inference(
|
|
|
66
73
|
output: stdout.trim(),
|
|
67
74
|
latency_ms: latencyMs,
|
|
68
75
|
};
|
|
69
|
-
} catch (
|
|
76
|
+
} catch (error: any) {
|
|
70
77
|
const latencyMs = Date.now() - startTime;
|
|
71
78
|
|
|
72
|
-
if (
|
|
79
|
+
if (error.code === "ETIMEDOUT" || error.killed) {
|
|
73
80
|
return {
|
|
74
81
|
success: false,
|
|
75
82
|
output: "",
|
|
@@ -78,7 +85,7 @@ export function inference(
|
|
|
78
85
|
};
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
if (
|
|
88
|
+
if (error.code === "ENOENT") {
|
|
82
89
|
return {
|
|
83
90
|
success: false,
|
|
84
91
|
output: "",
|
|
@@ -88,11 +95,11 @@ export function inference(
|
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
// Non-zero exit code
|
|
91
|
-
if (
|
|
98
|
+
if (error.status !== undefined && error.status !== 0) {
|
|
92
99
|
return {
|
|
93
100
|
success: false,
|
|
94
|
-
output: (
|
|
95
|
-
error: (
|
|
101
|
+
output: (error.stdout ?? "").toString().trim(),
|
|
102
|
+
error: (error.stderr ?? "").toString().trim() || `Exit code: ${error.status}`,
|
|
96
103
|
latency_ms: latencyMs,
|
|
97
104
|
};
|
|
98
105
|
}
|
|
@@ -100,7 +107,7 @@ export function inference(
|
|
|
100
107
|
return {
|
|
101
108
|
success: false,
|
|
102
109
|
output: "",
|
|
103
|
-
error: String(
|
|
110
|
+
error: String(error),
|
|
104
111
|
latency_ms: latencyMs,
|
|
105
112
|
};
|
|
106
113
|
}
|
|
@@ -126,13 +133,13 @@ Output ONLY the keywords separated by spaces, nothing else.`;
|
|
|
126
133
|
export function generateSemanticSummary(
|
|
127
134
|
prompt: string,
|
|
128
135
|
timeout = 15,
|
|
129
|
-
):
|
|
136
|
+
): null | string {
|
|
130
137
|
const result = inference(CONTEXT_ID_SYSTEM_PROMPT, prompt, "standard", timeout);
|
|
131
138
|
|
|
132
139
|
if (!result.success || !result.output) return null;
|
|
133
140
|
|
|
134
141
|
let summary = result.output.trim();
|
|
135
|
-
summary = summary.
|
|
142
|
+
summary = summary.replaceAll(/^["']+|["']+$/g, "");
|
|
136
143
|
summary = summary.replace(/[.!?]+$/, "");
|
|
137
144
|
|
|
138
145
|
// Filter stop words
|
|
@@ -187,7 +194,7 @@ Respond with ONLY a JSON object: {"slug": "your 8-12 word phrase here"}`;
|
|
|
187
194
|
export function generateContextIdSlug(
|
|
188
195
|
prompt: string,
|
|
189
196
|
timeout = 3,
|
|
190
|
-
):
|
|
197
|
+
): null | string {
|
|
191
198
|
const truncated = prompt.slice(0, 500);
|
|
192
199
|
|
|
193
200
|
const result = inference(CONTEXT_ID_SLUG_PROMPT, truncated, "fast", timeout);
|
|
@@ -200,7 +207,7 @@ export function generateContextIdSlug(
|
|
|
200
207
|
const raw = result.output.trim();
|
|
201
208
|
|
|
202
209
|
// Parse JSON response, fall back to raw text
|
|
203
|
-
let slug:
|
|
210
|
+
let slug: null | string = null;
|
|
204
211
|
try {
|
|
205
212
|
const parsed = JSON.parse(raw);
|
|
206
213
|
if (parsed && typeof parsed === "object" && "slug" in parsed) {
|
|
@@ -213,11 +220,11 @@ export function generateContextIdSlug(
|
|
|
213
220
|
if (!slug) slug = raw;
|
|
214
221
|
|
|
215
222
|
// Clean up
|
|
216
|
-
slug = slug.
|
|
223
|
+
slug = slug.replaceAll(/^["'`]+|["'`]+$/g, "");
|
|
217
224
|
slug = slug.replace(/[.!?]+$/, "");
|
|
218
|
-
slug = slug.
|
|
219
|
-
slug = slug.
|
|
220
|
-
slug = slug.
|
|
225
|
+
slug = slug.replaceAll('-', " ");
|
|
226
|
+
slug = slug.replaceAll(/[^a-zA-Z0-9 ]/g, "");
|
|
227
|
+
slug = slug.replaceAll(/\s+/g, " ").trim();
|
|
221
228
|
|
|
222
229
|
const words = slug.split(" ");
|
|
223
230
|
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* Log location: _output/hook-log.jsonl (global, all sessions)
|
|
6
6
|
* Filter by session using the "sid" field.
|
|
7
7
|
*
|
|
8
|
+
* stderr is OPT-IN: convenience functions (logDebug, logInfo, logWarn, logError)
|
|
9
|
+
* write to file only by default. To also write to stderr (visible to Claude Code
|
|
10
|
+
* as "hook error"), pass { stderr: true } or use logBlocking().
|
|
11
|
+
* logHookError() always writes to stderr (unhandled errors must be visible).
|
|
12
|
+
*
|
|
8
13
|
* Environment variables:
|
|
9
14
|
* - HOOK_LOG_DISABLE=1: Disable all file logging
|
|
10
15
|
* - HOOK_LOG_LEVEL=warn: Minimum level to log (default: debug)
|
|
@@ -94,7 +99,7 @@ export function hookLog(
|
|
|
94
99
|
const levelNum = LEVELS[levelLower] ?? 0;
|
|
95
100
|
const component = opts?.component ?? "";
|
|
96
101
|
const tracebackStr = opts?.traceback_str ?? "";
|
|
97
|
-
const stderrEnabled = opts?.stderr
|
|
102
|
+
const stderrEnabled = opts?.stderr === true;
|
|
98
103
|
|
|
99
104
|
// Write to stderr
|
|
100
105
|
if (stderrEnabled) {
|
|
@@ -147,7 +152,7 @@ export function hookLog(
|
|
|
147
152
|
try {
|
|
148
153
|
if (fs.existsSync(logPath)) {
|
|
149
154
|
const content = fs.readFileSync(logPath, "utf-8");
|
|
150
|
-
const lines = content.split(
|
|
155
|
+
const lines = content.split(/\r?\n/);
|
|
151
156
|
if (lines.length > MAX_LOG_LINES) {
|
|
152
157
|
fs.writeFileSync(
|
|
153
158
|
logPath,
|
|
@@ -182,6 +187,14 @@ export function logError(hookName: string, message: string, opts?: Record<string
|
|
|
182
187
|
hookLog("error", hookName, message, opts);
|
|
183
188
|
}
|
|
184
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Log an error that SHOULD be visible to user/model via stderr.
|
|
192
|
+
* Use for real problems needing attention, not routine diagnostics.
|
|
193
|
+
*/
|
|
194
|
+
export function logBlocking(hookName: string, message: string, opts?: Record<string, any>): void {
|
|
195
|
+
hookLog("error", hookName, message, { ...opts, stderr: true });
|
|
196
|
+
}
|
|
197
|
+
|
|
185
198
|
/**
|
|
186
199
|
* Log a structured diagnostic entry at a hook decision point.
|
|
187
200
|
* See SPEC.md §3.8
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
|
-
import * as path from "node:path";
|
|
9
|
-
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
|
|
10
10
|
import { atomicWrite } from "./atomic-write.js";
|
|
11
|
+
import { getContextDir } from "./constants.js";
|
|
11
12
|
import { logWarn } from "./logger.js";
|
|
12
13
|
import type { ContextState, Mode } from "../types.js";
|
|
13
14
|
|
|
@@ -29,7 +30,8 @@ export function toDict(state: ContextState): Record<string, unknown> {
|
|
|
29
30
|
if (value !== null && value !== undefined) {
|
|
30
31
|
result[key] = value;
|
|
31
32
|
}
|
|
32
|
-
}
|
|
33
|
+
}
|
|
34
|
+
|
|
33
35
|
return result;
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -52,11 +54,11 @@ export function readStateJson(
|
|
|
52
54
|
if (!fs.existsSync(sp)) return null;
|
|
53
55
|
|
|
54
56
|
try {
|
|
55
|
-
const raw = fs.readFileSync(sp, "
|
|
57
|
+
const raw = fs.readFileSync(sp, "utf8");
|
|
56
58
|
const data = JSON.parse(raw) as Record<string, any>;
|
|
57
59
|
return dictToState(data);
|
|
58
|
-
} catch (
|
|
59
|
-
logWarn("state_io", `Failed to read state.json for '${contextId}': ${
|
|
60
|
+
} catch (error: any) {
|
|
61
|
+
logWarn("state_io", `Failed to read state.json for '${contextId}': ${error}`);
|
|
60
62
|
return null;
|
|
61
63
|
}
|
|
62
64
|
}
|
|
@@ -69,7 +71,7 @@ export function writeStateJson(
|
|
|
69
71
|
contextId: string,
|
|
70
72
|
state: ContextState,
|
|
71
73
|
projectRoot?: string,
|
|
72
|
-
): [boolean,
|
|
74
|
+
): [boolean, null | string] {
|
|
73
75
|
const sp = statePath(contextId, projectRoot);
|
|
74
76
|
const dir = path.dirname(sp);
|
|
75
77
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -14,161 +14,161 @@
|
|
|
14
14
|
|
|
15
15
|
export const STOP_WORDS: ReadonlySet<string> = new Set([
|
|
16
16
|
// ARTICLES
|
|
17
|
-
"a", "
|
|
17
|
+
"a", "about", "above",
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"i", "you", "he", "she", "it", "we", "they",
|
|
29
|
-
"me", "him", "her", "us", "them",
|
|
30
|
-
"myself", "yourself", "himself", "herself", "itself", "ourselves", "themselves",
|
|
19
|
+
"absolutely", "accordingly", "across", "active", "actually", "after", "afterwards", "against", "ago", "ah",
|
|
20
|
+
"aiw", "all", "allow", "almost", "along", "already", "alright", "also",
|
|
21
|
+
"alternatively", "although", "always", // AUXILIARY/MODAL VERBS
|
|
22
|
+
"am", "among", "an", // CONJUNCTIONS
|
|
23
|
+
"and", "another",
|
|
24
|
+
"any", "anybody", "anyone", "anything", "anyway", "anyways", "apparently", "appear",
|
|
25
|
+
"are", "aren", "arent", "args", "around", "as", "ask",
|
|
26
|
+
"assert", "async", "at", // SINGLE LETTERS
|
|
27
|
+
"b",
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"
|
|
29
|
+
"based", "basic", "basically", "bat", "be", "because", "become",
|
|
30
|
+
"been", "before", "begin", "behind", "being",
|
|
31
|
+
"below", "below", "beside", "besides", "between", "beyond", "block",
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
"
|
|
33
|
+
"both", "but", "by", "c", "can", "cant", "case",
|
|
34
|
+
"cases", "cause", "cc", "certainly", "chunk",
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
"who", "whom", "whose", "which",
|
|
41
|
-
|
|
42
|
-
// PRONOUNS - Indefinite
|
|
43
|
-
"someone", "somebody", "something", "anyone", "anybody", "anything",
|
|
44
|
-
"everyone", "everybody", "everything", "no one", "nobody", "nothing",
|
|
45
|
-
"one", "ones",
|
|
46
|
-
|
|
47
|
-
// AUXILIARY/MODAL VERBS
|
|
48
|
-
"am", "is", "are", "was", "were", "be", "been", "being",
|
|
49
|
-
"have", "has", "had", "having",
|
|
50
|
-
"do", "does", "did", "doing", "done",
|
|
51
|
-
"can", "could", "will", "would", "shall", "should", "may", "might", "must",
|
|
52
|
-
|
|
53
|
-
// CONJUNCTIONS
|
|
54
|
-
"and", "or", "but", "nor", "so", "yet",
|
|
55
|
-
"if", "then", "else", "whether", "unless", "although", "though",
|
|
56
|
-
"because", "while", "whereas", "whenever", "wherever",
|
|
57
|
-
|
|
58
|
-
// QUESTION WORDS
|
|
59
|
-
"what", "when", "where", "why", "how",
|
|
60
|
-
|
|
61
|
-
// ADVERBS OF PLACE/TIME
|
|
62
|
-
"here", "there", "now", "always", "never", "often", "sometimes",
|
|
63
|
-
"already", "still", "soon", "later", "ago", "today", "tomorrow",
|
|
64
|
-
"yesterday", "currently", "previously", "recently", "immediately",
|
|
65
|
-
"finally", "eventually", "meanwhile", "afterwards",
|
|
66
|
-
|
|
67
|
-
// NEGATION
|
|
68
|
-
"no", "not", "none", "neither",
|
|
69
|
-
"don", "doesn", "didn", "won", "wouldn", "couldn", "shouldn",
|
|
70
|
-
"isn", "aren", "wasn", "weren", "hasn", "haven", "hadn",
|
|
71
|
-
|
|
72
|
-
// QUANTIFIERS
|
|
73
|
-
"some", "any", "all", "each", "every", "both", "few", "more", "most",
|
|
74
|
-
"many", "much", "several", "other", "another", "enough", "less", "least",
|
|
75
|
-
"either", "such",
|
|
36
|
+
"clarification", "class", "clearly", "come",
|
|
76
37
|
|
|
77
|
-
|
|
78
|
-
"just", "also", "only", "really", "actually", "basically", "simply",
|
|
79
|
-
"very", "quite", "rather", "pretty", "somewhat", "almost", "nearly",
|
|
80
|
-
"exactly", "completely", "entirely", "totally", "absolutely",
|
|
81
|
-
"probably", "possibly", "maybe", "perhaps", "definitely", "certainly",
|
|
82
|
-
"apparently", "obviously", "clearly", "literally", "essentially",
|
|
83
|
-
|
|
84
|
-
// SPEECH-TO-TEXT FILLERS (STT artifacts from voice input)
|
|
85
|
-
"um", "uh", "ah", "oh", "hmm", "hm", "er", "eh", "huh",
|
|
86
|
-
"hey", "hi", "hello", "yeah", "yep", "yup", "nah", "nope",
|
|
87
|
-
"gonna", "gotta", "wanna", "kinda", "sorta",
|
|
88
|
-
"stuff", "anyway", "anyways", "alright", "right", "well",
|
|
89
|
-
|
|
90
|
-
// COMMON REQUEST PHRASES
|
|
91
|
-
"want", "need", "help", "please", "like", "let", "get",
|
|
92
|
-
"think", "know", "see", "try", "make", "give", "take",
|
|
93
|
-
"look", "looking", "trying", "going", "getting", "making",
|
|
38
|
+
"complete", "completely", "consequently", "consider",
|
|
94
39
|
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"include", "provide", "require", "allow", "expect", "cause",
|
|
99
|
-
"follow", "consider", "continue", "start", "begin", "end",
|
|
100
|
-
"contain", "contains",
|
|
40
|
+
"const", "contain", "contains", "continue", "conversely", "correct",
|
|
41
|
+
"correctly", "could", "couldn", "couldnt", "critical", "current",
|
|
42
|
+
"currently", "d",
|
|
101
43
|
|
|
102
|
-
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
44
|
+
"def", "definitely", "dict", "did", "didn", "didnt", "different", "directory",
|
|
45
|
+
"do", "does", "doesn", "doesn",
|
|
46
|
+
"doesnt", "doing", "don", "done", "dont",
|
|
47
|
+
"down", "during", "e", "each", "eh", "eight", "either", "elif", "else",
|
|
106
48
|
|
|
107
|
-
|
|
108
|
-
"
|
|
49
|
+
"empty", "end", "enough", "entirely", "eprint", "er",
|
|
50
|
+
"essentially", // SHORT NOISE
|
|
51
|
+
"etc", "eventually", "every", "everybody", "everyone", "everything",
|
|
52
|
+
"exactly", "example", "examples", "except", "exe",
|
|
109
53
|
|
|
110
|
-
|
|
111
|
-
"using", "used", "uses",
|
|
112
|
-
"based", "following",
|
|
113
|
-
"same", "different", "specific", "existing", "new", "current", "first",
|
|
114
|
-
"full", "complete", "single", "multiple", "simple",
|
|
115
|
-
"needed", "required", "provided", "expected", "correctly",
|
|
116
|
-
"works", "working", "work",
|
|
54
|
+
"existing", "expect", "expected", "f", "false",
|
|
117
55
|
|
|
118
|
-
|
|
119
|
-
"
|
|
56
|
+
"feature", "features", "feel", "few", "finally", "find", "first",
|
|
57
|
+
"five", "folder", "follow", "following", "footer", "for", "format",
|
|
58
|
+
"four", "from", "full", "furthermore", "g",
|
|
59
|
+
"general", "get", "getting", "give",
|
|
120
60
|
|
|
121
|
-
//
|
|
122
|
-
"
|
|
61
|
+
// COMMON NON-ACTION VERBS
|
|
62
|
+
"go", "going", "gonna", "gotta",
|
|
63
|
+
"group", "h", "had", "hadn", "hadnt", "has", "hasn",
|
|
64
|
+
"hasnt", "have", "haven", "havent", "having", "he", "header",
|
|
123
65
|
|
|
124
|
-
//
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"set", "list", "group", "item", "items",
|
|
66
|
+
"hello", "help", "hence", "her", "her", // ADVERBS OF PLACE/TIME
|
|
67
|
+
"here", "heres", "hers", "herself",
|
|
68
|
+
"hes", "hey", "hi", // GENERIC ADJECTIVES
|
|
69
|
+
"high", "him", "himself", "his", "hm",
|
|
70
|
+
"hmm", "how",
|
|
130
71
|
|
|
131
|
-
//
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
72
|
+
// LINKING/TRANSITION WORDS
|
|
73
|
+
"however", "huh", // PRONOUNS - Personal
|
|
74
|
+
"i", "id", "if", "ill", // CONTRACTED FORMS
|
|
75
|
+
"im",
|
|
76
|
+
"immediately", "import", "important", "in", "include", "index", // GENERIC TECHNICAL NOUNS
|
|
77
|
+
"information",
|
|
78
|
+
"inside", "instead", "into", "is", "isn",
|
|
79
|
+
"isnt", "issue", "it", "item", "items", "its",
|
|
80
|
+
"itself", "ive", "j", "js", "json",
|
|
135
81
|
|
|
136
|
-
//
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
82
|
+
// FILLER/HEDGE WORDS
|
|
83
|
+
"just", "k", "keep", "kind", "kinda", "know", "l", "lambda", "last",
|
|
84
|
+
"later", "least", "len", "less", "let", "lets", "level", "like",
|
|
85
|
+
"likewise", "line", "lines", "list", "literally",
|
|
86
|
+
"ll", "look", "looking", "low", "m", "main",
|
|
140
87
|
|
|
141
|
-
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"process", "version", "mode", "state",
|
|
88
|
+
"make", "making", "manual", "many", "may", "maybe", "md",
|
|
89
|
+
"me", "mean", "meanwhile", "method", "might", "mine", "mode",
|
|
90
|
+
"more", "moreover", "most", "much", "multiple", "must",
|
|
145
91
|
|
|
146
|
-
//
|
|
147
|
-
"
|
|
148
|
-
"
|
|
92
|
+
// PRONOUNS - Possessive
|
|
93
|
+
"my", "myself", "n", "nah", "near", "nearly", "need", "needed",
|
|
94
|
+
"neither", "never", "nevertheless", "new", "next", "nine", // NEGATION
|
|
95
|
+
"no", "nobody",
|
|
96
|
+
"none", "none", "nonetheless", "no one", "nope", "nor",
|
|
97
|
+
"not", "nothing", "now", "o", "obviously", "of",
|
|
98
|
+
"off", "often",
|
|
99
|
+
|
|
100
|
+
"oh", "ok", "okay", "on", "one", "ones",
|
|
101
|
+
"only", "onto", "option", "optional", "options",
|
|
102
|
+
"or", "other", "otherwise", "our", "ours",
|
|
103
|
+
|
|
104
|
+
"ourselves", "out", "outside", "over", "overall", "p", "part", "parts", "pass",
|
|
105
|
+
|
|
106
|
+
"per", "perhaps", "phase",
|
|
107
|
+
"pl", "please",
|
|
108
|
+
"point", "points", "possibly", "pretty", "previously", "primary", "probably",
|
|
109
|
+
"process", "proper", "provide", "provided", "purpose",
|
|
110
|
+
"put", // FILE EXTENSIONS
|
|
111
|
+
"py", "q", "question", // QUERY LANGUAGE
|
|
112
|
+
"questions",
|
|
113
|
+
"quite", "r", "rather",
|
|
149
114
|
|
|
150
115
|
// FRAGMENT WORDS
|
|
151
|
-
"re", "
|
|
116
|
+
"re", "real", "really", "recently",
|
|
117
|
+
|
|
118
|
+
"region", "remain", "require",
|
|
152
119
|
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
|
|
157
|
-
"
|
|
158
|
-
"
|
|
120
|
+
"required", "result", "return", "right", "s", "same", "say",
|
|
121
|
+
"secondary", // DOCUMENT/CODE STRUCTURE
|
|
122
|
+
"section", "see", "seem",
|
|
123
|
+
// PROGRAMMING KEYWORDS
|
|
124
|
+
"self", "set", "seven", "several",
|
|
125
|
+
"shall", "she", "shes", "should",
|
|
126
|
+
"shouldn", "shouldnt", "show", "similarly", "simple",
|
|
127
|
+
|
|
128
|
+
"simply", "since", "single", "six", "so", // QUANTIFIERS
|
|
129
|
+
"some", "somebody", // PRONOUNS - Indefinite
|
|
130
|
+
"someone",
|
|
131
|
+
"something", "sometimes", "somewhat", "soon", "sorta", "source", "specific", "stable",
|
|
132
|
+
"start", "state", "status", "stay", // STRUCTURAL WORDS
|
|
133
|
+
"step", "steps",
|
|
134
|
+
|
|
135
|
+
"still", "str", "stuff", "such", "sys", "t",
|
|
136
|
+
"take", "tell", "ten", "that", "thats", "the",
|
|
137
|
+
"their", "theirs", "them", "themselves", "then", "there",
|
|
138
|
+
|
|
139
|
+
"therefore", "theres", "these", "they", "theyre", "theyve",
|
|
140
|
+
// OVERLY GENERIC TERMS
|
|
141
|
+
"thing", "things", "think", // PRONOUNS - Demonstrative
|
|
142
|
+
"this", "those", "though", "three",
|
|
143
|
+
"through", "thus", "time", "times",
|
|
159
144
|
|
|
160
|
-
//
|
|
161
|
-
"
|
|
145
|
+
// PREPOSITIONS
|
|
146
|
+
"to", "today", "toml", "tomorrow", // SHORT FILLER
|
|
147
|
+
"too", "totally",
|
|
148
|
+
"toward", "towards", "true", "try", "trying", "ts",
|
|
162
149
|
|
|
163
150
|
// NUMBER WORDS
|
|
164
|
-
"two", "
|
|
151
|
+
"two", "type", "types", "u", "uh", // SPEECH-TO-TEXT FILLERS (STT artifacts from voice input)
|
|
152
|
+
"um", "under", "unless",
|
|
153
|
+
|
|
154
|
+
"until", "up", "upon", "us", "used", "uses", // COMMON CODING TERMS
|
|
155
|
+
"using",
|
|
156
|
+
"v", "value", "ve", "version", "very", "via", "w",
|
|
157
|
+
"wanna", // COMMON REQUEST PHRASES
|
|
158
|
+
"want", "was", "wasn", "wasnt", "way", "ways",
|
|
159
|
+
"we", "well", "were", "weren", "werent", "weve", // QUESTION WORDS
|
|
160
|
+
"what",
|
|
161
|
+
"whats", "when", "whenever", "where", "whereas",
|
|
162
|
+
|
|
163
|
+
"wherever", "whether", "which", "while",
|
|
164
|
+
|
|
165
|
+
// PRONOUNS - Relative
|
|
166
|
+
"who", "whom", "whos", "whose", "why", "will", "with", "within", "without",
|
|
165
167
|
|
|
166
|
-
|
|
167
|
-
"
|
|
168
|
-
"q", "r", "u", "v", "w", "x", "y", "z",
|
|
168
|
+
"won", "wont", "work", "working", "works", "would", "wouldn", "wouldnt", "x", "y", "yaml", "yeah", "yep", "yes",
|
|
169
|
+
"yesterday", "yet", "yield", "you", "youll", "your", "youre", "yours",
|
|
169
170
|
|
|
170
|
-
|
|
171
|
-
"too", "yes", "ok", "okay",
|
|
171
|
+
"yourself", "youve", "yup", "z",
|
|
172
172
|
]);
|
|
173
173
|
|
|
174
174
|
/**
|