@pentoshi/clai 3.0.0 → 3.6.0
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/README.md +1 -1
- package/dist/agent/classic-renderer.js +9 -1
- package/dist/agent/classic-renderer.js.map +1 -1
- package/dist/agent/context-manager.js +8 -2
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/events.d.ts +5 -0
- package/dist/agent/loop-guard.d.ts +2 -0
- package/dist/agent/loop-guard.js +39 -2
- package/dist/agent/loop-guard.js.map +1 -1
- package/dist/agent/plan-tool.d.ts +22 -0
- package/dist/agent/plan-tool.js +434 -49
- package/dist/agent/plan-tool.js.map +1 -1
- package/dist/agent/project-root.d.ts +33 -0
- package/dist/agent/project-root.js +158 -0
- package/dist/agent/project-root.js.map +1 -0
- package/dist/agent/runner.js +1204 -253
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/task-evidence.d.ts +103 -0
- package/dist/agent/task-evidence.js +413 -0
- package/dist/agent/task-evidence.js.map +1 -0
- package/dist/agent/tool-call-parser.d.ts +21 -0
- package/dist/agent/tool-call-parser.js +101 -28
- package/dist/agent/tool-call-parser.js.map +1 -1
- package/dist/agent/tool-history.d.ts +27 -0
- package/dist/agent/tool-history.js +150 -0
- package/dist/agent/tool-history.js.map +1 -0
- package/dist/agent/workspace-orient.d.ts +64 -0
- package/dist/agent/workspace-orient.js +418 -0
- package/dist/agent/workspace-orient.js.map +1 -0
- package/dist/app/adapters/agent-event-adapter.js +5 -0
- package/dist/app/adapters/agent-event-adapter.js.map +1 -1
- package/dist/app/controllers/session-controller.js +4 -0
- package/dist/app/controllers/session-controller.js.map +1 -1
- package/dist/app/events/app-event.d.ts +4 -0
- package/dist/app/events/app-event.js.map +1 -1
- package/dist/commands/doctor.js +14 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/index.js +40 -8
- package/dist/index.js.map +1 -1
- package/dist/llm/adapters/anthropic-tools.d.ts +99 -0
- package/dist/llm/adapters/anthropic-tools.js +225 -0
- package/dist/llm/adapters/anthropic-tools.js.map +1 -0
- package/dist/llm/adapters/gemini-tools.d.ts +54 -0
- package/dist/llm/adapters/gemini-tools.js +139 -0
- package/dist/llm/adapters/gemini-tools.js.map +1 -0
- package/dist/llm/adapters/ollama-tools.d.ts +22 -0
- package/dist/llm/adapters/ollama-tools.js +62 -0
- package/dist/llm/adapters/ollama-tools.js.map +1 -0
- package/dist/llm/adapters/openai-tools.d.ts +39 -0
- package/dist/llm/adapters/openai-tools.js +71 -0
- package/dist/llm/adapters/openai-tools.js.map +1 -0
- package/dist/llm/agentrouter.js +23 -4
- package/dist/llm/agentrouter.js.map +1 -1
- package/dist/llm/anthropic.js +93 -92
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/aws-mantle.js +93 -56
- package/dist/llm/aws-mantle.js.map +1 -1
- package/dist/llm/bynara.js +23 -4
- package/dist/llm/bynara.js.map +1 -1
- package/dist/llm/capabilities.d.ts +7 -0
- package/dist/llm/capabilities.js +74 -0
- package/dist/llm/capabilities.js.map +1 -1
- package/dist/llm/gemini.js +63 -48
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/groq.js +23 -4
- package/dist/llm/groq.js.map +1 -1
- package/dist/llm/http.d.ts +22 -17
- package/dist/llm/http.js +99 -26
- package/dist/llm/http.js.map +1 -1
- package/dist/llm/kimchi.js +23 -4
- package/dist/llm/kimchi.js.map +1 -1
- package/dist/llm/nvidia.js +23 -4
- package/dist/llm/nvidia.js.map +1 -1
- package/dist/llm/ollama.js +49 -31
- package/dist/llm/ollama.js.map +1 -1
- package/dist/llm/openai.js +23 -4
- package/dist/llm/openai.js.map +1 -1
- package/dist/llm/openrouter.js +23 -4
- package/dist/llm/openrouter.js.map +1 -1
- package/dist/llm/qwen-cloud.js +23 -4
- package/dist/llm/qwen-cloud.js.map +1 -1
- package/dist/llm/router.js +48 -6
- package/dist/llm/router.js.map +1 -1
- package/dist/llm/tool-protocol.d.ts +73 -0
- package/dist/llm/tool-protocol.js +282 -0
- package/dist/llm/tool-protocol.js.map +1 -0
- package/dist/modes/ask.js +74 -20
- package/dist/modes/ask.js.map +1 -1
- package/dist/prompts/index.d.ts +13 -5
- package/dist/prompts/index.js +122 -23
- package/dist/prompts/index.js.map +1 -1
- package/dist/repl.js +7 -0
- package/dist/repl.js.map +1 -1
- package/dist/store/config.d.ts +7 -0
- package/dist/store/config.js +1 -0
- package/dist/store/config.js.map +1 -1
- package/dist/store/plan.d.ts +2 -0
- package/dist/store/plan.js.map +1 -1
- package/dist/tools/capabilities.d.ts +2 -0
- package/dist/tools/capabilities.js +101 -6
- package/dist/tools/capabilities.js.map +1 -1
- package/dist/tools/command-intent.d.ts +1 -0
- package/dist/tools/command-intent.js +31 -0
- package/dist/tools/command-intent.js.map +1 -1
- package/dist/tools/definitions.d.ts +20 -0
- package/dist/tools/definitions.js +509 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/fs.d.ts +6 -0
- package/dist/tools/fs.js +68 -9
- package/dist/tools/fs.js.map +1 -1
- package/dist/tools/net-ping-sweep.js +69 -16
- package/dist/tools/net-ping-sweep.js.map +1 -1
- package/dist/tools/nmap-runner.d.ts +8 -7
- package/dist/tools/nmap-runner.js +126 -65
- package/dist/tools/nmap-runner.js.map +1 -1
- package/dist/tools/registry.js +122 -33
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/validate.d.ts +11 -0
- package/dist/tools/validate.js +53 -0
- package/dist/tools/validate.js.map +1 -1
- package/dist/tools/web/search.js +48 -4
- package/dist/tools/web/search.js.map +1 -1
- package/dist/tui/runtime.d.ts +19 -0
- package/dist/tui/runtime.js +92 -0
- package/dist/tui/runtime.js.map +1 -0
- package/dist/tui/state.js +2 -0
- package/dist/tui/state.js.map +1 -1
- package/dist/tui-v2/app/App.d.ts +3 -3
- package/dist/tui-v2/app/App.js +22 -10
- package/dist/tui-v2/app/App.js.map +1 -1
- package/dist/tui-v2/app/plan-lifecycle.d.ts +6 -0
- package/dist/tui-v2/app/plan-lifecycle.js +43 -7
- package/dist/tui-v2/app/plan-lifecycle.js.map +1 -1
- package/dist/tui-v2/components/modal/confirm-modal.d.ts +5 -6
- package/dist/tui-v2/components/modal/confirm-modal.js +60 -21
- package/dist/tui-v2/components/modal/confirm-modal.js.map +1 -1
- package/dist/tui-v2/components/modal/secret-modal.d.ts +3 -9
- package/dist/tui-v2/components/modal/secret-modal.js +17 -17
- package/dist/tui-v2/components/modal/secret-modal.js.map +1 -1
- package/dist/tui-v2/components/overlay/overlay-host.d.ts +12 -3
- package/dist/tui-v2/components/overlay/overlay-host.js +19 -4
- package/dist/tui-v2/components/overlay/overlay-host.js.map +1 -1
- package/dist/tui-v2/components/plan/plan-view.d.ts +1 -1
- package/dist/tui-v2/components/plan/plan-view.js +8 -4
- package/dist/tui-v2/components/plan/plan-view.js.map +1 -1
- package/dist/tui-v2/components/status/status-line.js +10 -1
- package/dist/tui-v2/components/status/status-line.js.map +1 -1
- package/dist/tui-v2/components/transcript/assistant-message.js +6 -0
- package/dist/tui-v2/components/transcript/assistant-message.js.map +1 -1
- package/dist/tui-v2/components/transcript/compacted-row.d.ts +5 -5
- package/dist/tui-v2/components/transcript/compacted-row.js +15 -40
- package/dist/tui-v2/components/transcript/compacted-row.js.map +1 -1
- package/dist/tui-v2/components/transcript/tool-card.js +43 -13
- package/dist/tui-v2/components/transcript/tool-card.js.map +1 -1
- package/dist/tui-v2/components/transcript/transcript-row.js +8 -1
- package/dist/tui-v2/components/transcript/transcript-row.js.map +1 -1
- package/dist/tui-v2/rendering/batch-sections.d.ts +12 -0
- package/dist/tui-v2/rendering/batch-sections.js +68 -0
- package/dist/tui-v2/rendering/batch-sections.js.map +1 -1
- package/dist/tui-v2/rendering/strip-tool-surfaces.d.ts +10 -0
- package/dist/tui-v2/rendering/strip-tool-surfaces.js +32 -0
- package/dist/tui-v2/rendering/strip-tool-surfaces.js.map +1 -0
- package/dist/tui-v2/rendering/tool-presenter.d.ts +6 -1
- package/dist/tui-v2/rendering/tool-presenter.js +68 -2
- package/dist/tui-v2/rendering/tool-presenter.js.map +1 -1
- package/dist/tui-v2/state/transcript-hydrate.js +6 -2
- package/dist/tui-v2/state/transcript-hydrate.js.map +1 -1
- package/dist/tui-v2/state/transcript-reducer.js +74 -16
- package/dist/tui-v2/state/transcript-reducer.js.map +1 -1
- package/dist/tui-v2/state/transcript-types.d.ts +1 -1
- package/dist/types.d.ts +58 -0
- package/dist/ui/ansi-box.d.ts +2 -0
- package/dist/ui/ansi-box.js +8 -1
- package/dist/ui/ansi-box.js.map +1 -1
- package/package.json +13 -4
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getActiveProjectRoot } from "./project-root.js";
|
|
4
|
+
export function isMetaPlanTool(name) {
|
|
5
|
+
return name === "plan.create" || name === "task.update" || name === "agent.handoff";
|
|
6
|
+
}
|
|
7
|
+
/** Tools that count as real work/verify evidence for the open task. */
|
|
8
|
+
export function isEvidenceWorkTool(name) {
|
|
9
|
+
return !isMetaPlanTool(name);
|
|
10
|
+
}
|
|
11
|
+
export function recordTaskWorkSuccess(ledger, taskId, toolName) {
|
|
12
|
+
if (!taskId || !isEvidenceWorkTool(toolName))
|
|
13
|
+
return ledger;
|
|
14
|
+
if (!ledger || ledger.taskId !== taskId) {
|
|
15
|
+
return { taskId, successWorkCount: 1, lastOkTool: toolName };
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
taskId,
|
|
19
|
+
successWorkCount: ledger.successWorkCount + 1,
|
|
20
|
+
lastOkTool: toolName,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function openTaskLedger(taskId) {
|
|
24
|
+
return { taskId, successWorkCount: 0 };
|
|
25
|
+
}
|
|
26
|
+
export function canMarkTaskDone(ledger, taskId) {
|
|
27
|
+
if (!ledger || ledger.taskId !== taskId) {
|
|
28
|
+
return {
|
|
29
|
+
ok: false,
|
|
30
|
+
reason: `Cannot mark [${taskId}] done: no work ledger for this task. ` +
|
|
31
|
+
`Call task.update {taskId:"${taskId}", state:"in_progress"}, do the real work, ` +
|
|
32
|
+
`inspect the tool result, and only then mark done if you are satisfied.`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (ledger.successWorkCount < 1) {
|
|
36
|
+
return {
|
|
37
|
+
ok: false,
|
|
38
|
+
reason: `Cannot mark [${taskId}] done: no successful tool result observed since it went in_progress. ` +
|
|
39
|
+
`Do the work, wait for the tool output, verify it succeeded, and only mark done when satisfied. ` +
|
|
40
|
+
(ledger.lastOkTool
|
|
41
|
+
? ""
|
|
42
|
+
: "Example: fs.write / shell.exec / shell.start must return ok first."),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return { ok: true };
|
|
46
|
+
}
|
|
47
|
+
function commandOf(call) {
|
|
48
|
+
return typeof call.args.command === "string" ? call.args.command : "";
|
|
49
|
+
}
|
|
50
|
+
/** One-shot scaffolders — must NEVER be treated as "start the dev server". Stack-agnostic. */
|
|
51
|
+
export function isScaffoldCreateCommand(cmd) {
|
|
52
|
+
return /\b(?:npm\s+create|npm\s+init|yarn\s+create|pnpm\s+create|bun\s+create|npx\s+(?:--yes\s+)?create-[\w-]+|create-vite|create-next-app|create-react-app|cargo\s+new|cargo\s+init|go\s+mod\s+init|poetry\s+new|django-admin\s+startproject|rails\s+new|composer\s+create-project|mix\s+new|flutter\s+create|dotnet\s+new)\b/i.test(cmd);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* True only for actually running a long-lived dev server — not create-vite /
|
|
56
|
+
* npm create which merely contain the word "vite".
|
|
57
|
+
*/
|
|
58
|
+
export function isDevServerCall(call) {
|
|
59
|
+
const cmd = commandOf(call);
|
|
60
|
+
if (isScaffoldCreateCommand(cmd))
|
|
61
|
+
return false;
|
|
62
|
+
if (call.name === "shell.start") {
|
|
63
|
+
// Explicit background job is usually a server; still exclude create-*.
|
|
64
|
+
if (!cmd)
|
|
65
|
+
return true;
|
|
66
|
+
return (/\bnpm\s+run\s+dev\b|\byarn\s+dev\b|\bpnpm\s+(run\s+)?dev\b|\bbun\s+(run\s+)?dev\b|\bnext\s+dev\b|\bnuxt\s+dev\b|\bcargo\s+watch\b|\bflask\s+run\b|\buvicorn\b|\bgunicorn\b|\brails\s+s(?:erver)?\b|\bdjango(-admin)?\s+runserver\b|\bdotnet\s+run\b|\bgo\s+run\b/i.test(cmd) ||
|
|
67
|
+
// bare `vite` / `vite --host` as the process — not `create vite`
|
|
68
|
+
/(?:^|[;&|]\s*)vite(?:\s|$)/i.test(cmd) ||
|
|
69
|
+
/\b(python3?\s+-m\s+http\.server|php\s+-S)\b/i.test(cmd));
|
|
70
|
+
}
|
|
71
|
+
return (/\bnpm\s+run\s+dev\b|\byarn\s+dev\b|\bpnpm\s+(run\s+)?dev\b|\bbun\s+(run\s+)?dev\b|\bnext\s+dev\b|\bnuxt\s+dev\b|\brails\s+s(?:erver)?\b|\bdjango(-admin)?\s+runserver\b/i.test(cmd) || /(?:^|[;&|]\s*)vite(?:\s|$)/i.test(cmd));
|
|
72
|
+
}
|
|
73
|
+
/** Preflight / inspect tools allowed before the model opens a task. */
|
|
74
|
+
export function isPlanPreflightTool(name) {
|
|
75
|
+
return (name === "tool.check" ||
|
|
76
|
+
name === "sysinfo" ||
|
|
77
|
+
name === "fs.list" ||
|
|
78
|
+
name === "fs.read" ||
|
|
79
|
+
name === "fs.search" ||
|
|
80
|
+
name === "net.context");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Tools allowed on a coding BUILD turn before plan.create exists.
|
|
84
|
+
* Explore + optional web research + plan — no scaffold/write/install freestyle.
|
|
85
|
+
*/
|
|
86
|
+
export function isBuildPrePlanAllowedTool(name) {
|
|
87
|
+
return (name === "plan.create" ||
|
|
88
|
+
isPlanPreflightTool(name) ||
|
|
89
|
+
name === "tool.batch" ||
|
|
90
|
+
name === "fs.search" ||
|
|
91
|
+
// Research before planning (docs/examples) is fine; it does not mutate the project
|
|
92
|
+
name === "web.search" ||
|
|
93
|
+
name === "web.fetch");
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Commands that legitimately sit quiet for minutes (npm install, create-next-app).
|
|
97
|
+
* Must not be killed by the short "no output" stall watchdog.
|
|
98
|
+
*/
|
|
99
|
+
export function isLongQuietInstallOrScaffoldCommand(cmd) {
|
|
100
|
+
if (!cmd.trim())
|
|
101
|
+
return false;
|
|
102
|
+
if (isScaffoldCreateCommand(cmd))
|
|
103
|
+
return true;
|
|
104
|
+
return (/\b(?:npm|pnpm|yarn|bun)\s+i(?:nstall)?\b/i.test(cmd) ||
|
|
105
|
+
/\b(?:npm|pnpm|yarn|bun)\s+(?:ci|update)\b/i.test(cmd) ||
|
|
106
|
+
/\bpip(?:3)?\s+install\b/i.test(cmd) ||
|
|
107
|
+
/\bpoetry\s+install\b/i.test(cmd) ||
|
|
108
|
+
/\bcomposer\s+install\b/i.test(cmd) ||
|
|
109
|
+
/\bbundle\s+install\b/i.test(cmd) ||
|
|
110
|
+
/\bcargo\s+(?:build|fetch|install)\b/i.test(cmd) ||
|
|
111
|
+
/\bgo\s+mod\s+(?:download|tidy)\b/i.test(cmd) ||
|
|
112
|
+
/\bdotnet\s+restore\b/i.test(cmd));
|
|
113
|
+
}
|
|
114
|
+
/** Stall watchdog budget: scaffold/install can be silent for a long time. */
|
|
115
|
+
export function toolStallBudgetMs(call) {
|
|
116
|
+
const cmd = typeof call.args.command === "string" ? call.args.command : "";
|
|
117
|
+
if (call.name === "pkg.install")
|
|
118
|
+
return 10 * 60_000;
|
|
119
|
+
if ((call.name === "shell.exec" || call.name === "shell.start") &&
|
|
120
|
+
isLongQuietInstallOrScaffoldCommand(cmd)) {
|
|
121
|
+
return 15 * 60_000; // create-next-app + npm install often 2–10+ min with quiet stretches
|
|
122
|
+
}
|
|
123
|
+
return 60_000;
|
|
124
|
+
}
|
|
125
|
+
/** Harmless version/which probes models use instead of tool.check before planning. */
|
|
126
|
+
export function isReadOnlyVersionProbeCommand(cmd) {
|
|
127
|
+
const c = cmd.trim();
|
|
128
|
+
if (!c || /[;&|`]/.test(c))
|
|
129
|
+
return false; // no chains
|
|
130
|
+
return (/^(?:node|nodejs|npm|npx|pnpm|yarn|bun|deno|python3?|pip3?|go|rustc|cargo|ruby|php|java|dotnet|flutter|swift)\s+(?:-v|--version|version)\s*$/i.test(c) || /^(?:which|command\s+-v|type)\s+[A-Za-z0-9._-]+\s*$/i.test(c));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Multi-step coding builds must plan before mutate (scaffold/write/install).
|
|
134
|
+
* Trivial one-liners and non-build prompts skip this.
|
|
135
|
+
*/
|
|
136
|
+
export function codingBuildRequiresPlan(prompt, opts) {
|
|
137
|
+
if (opts?.informational || opts?.idle || opts?.pentest)
|
|
138
|
+
return false;
|
|
139
|
+
const p = prompt.trim();
|
|
140
|
+
if (!p)
|
|
141
|
+
return false;
|
|
142
|
+
// Explicit single-file micro edits can skip the plan
|
|
143
|
+
if (p.length < 100 &&
|
|
144
|
+
/\b(fix|typo|rename|bump|tweak)\b/i.test(p) &&
|
|
145
|
+
!/\b(app|project|scaffold|create|build|todo|blog)\b/i.test(p)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
return true; // caller already checked looksLikeBuildTask
|
|
149
|
+
}
|
|
150
|
+
function isLocalHttpProbe(call) {
|
|
151
|
+
const blob = `${call.name} ${commandOf(call)} ${JSON.stringify(call.args)}`;
|
|
152
|
+
return (/\b(localhost|127\.0\.0\.1)\b/i.test(blob) &&
|
|
153
|
+
(call.name === "shell.exec" ||
|
|
154
|
+
call.name === "http.fetch" ||
|
|
155
|
+
call.name === "web.fetch" ||
|
|
156
|
+
/\bcurl\b/i.test(blob)));
|
|
157
|
+
}
|
|
158
|
+
export function looksLikeInstallTaskTitle(title) {
|
|
159
|
+
const t = title.toLowerCase();
|
|
160
|
+
return (/\b(install|dependencies|deps|packages)\b/.test(t) &&
|
|
161
|
+
!/\b(dev\s*server|localhost|probe|run\s+dev)\b/.test(t));
|
|
162
|
+
}
|
|
163
|
+
export function looksLikeScaffoldTaskTitle(title) {
|
|
164
|
+
const t = title.toLowerCase();
|
|
165
|
+
return (/\b(scaffold|create-vite|create vite|create-next|init project|bootstrap|cargo\s+new|rails\s+new|poetry\s+new)\b/.test(t) ||
|
|
166
|
+
(/\b(create|init|generate)\b/.test(t) &&
|
|
167
|
+
/\b(project|app|package|crate|module|vite)\b/.test(t) &&
|
|
168
|
+
!/\b(feature|component|endpoint|todo|style|persist)\b/.test(t)));
|
|
169
|
+
}
|
|
170
|
+
export function isPackageInstallCommand(cmd) {
|
|
171
|
+
return /\bnpm\s+i(nstall)?\b|\byarn\s+install\b|\bpnpm\s+i(nstall)?\b|\bbun\s+install\b|\bpip\s+install\b|\bpoetry\s+install\b|\bcargo\s+build\b|\bcomposer\s+install\b|\bbundle\s+install\b|\bgo\s+mod\s+tidy\b/.test(cmd);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Soft scope check: refuse run/verify tools while the open task is only
|
|
175
|
+
* scaffold / implement / install.
|
|
176
|
+
* When `planTaskTitles` is provided, install is only blocked on implement
|
|
177
|
+
* tasks if the plan actually has a dedicated install task (otherwise allow).
|
|
178
|
+
*/
|
|
179
|
+
export function workOutOfScopeForTask(taskTitle, call, opts) {
|
|
180
|
+
if (isMetaPlanTool(call.name))
|
|
181
|
+
return undefined;
|
|
182
|
+
const t = taskTitle.toLowerCase();
|
|
183
|
+
const isRunVerifyTask = /\b(dev\s*server|run\s+dev|start\s+.*server|localhost|shell\.start|leave\s+.*running|probe|verify\s+in\s+browser)\b/.test(t) ||
|
|
184
|
+
(/\b(start|run)\b/.test(t) && /\b(server|dev|app|verify)\b/.test(t));
|
|
185
|
+
if (isRunVerifyTask)
|
|
186
|
+
return undefined;
|
|
187
|
+
const isInstallOnly = looksLikeInstallTaskTitle(taskTitle);
|
|
188
|
+
const isScaffoldOnly = looksLikeScaffoldTaskTitle(taskTitle);
|
|
189
|
+
const isImplementOnly = !isInstallOnly &&
|
|
190
|
+
!isScaffoldOnly &&
|
|
191
|
+
(/\b(implement|integrate|feature|rewrite|write\s+src|add\s+\w+\s+(component|module|handler|endpoint|page|route|model)|persist|localstorage|styling|styles?)\b/.test(t) ||
|
|
192
|
+
(/\b(component|module|handler|endpoint|ui|page|todo)\b/.test(t) &&
|
|
193
|
+
!/\b(install|scaffold|dev\s*server|create\s+project)\b/.test(t)));
|
|
194
|
+
// Install always OK under scaffold or install tasks
|
|
195
|
+
if ((isScaffoldOnly || isInstallOnly) &&
|
|
196
|
+
call.name === "shell.exec" &&
|
|
197
|
+
isPackageInstallCommand(commandOf(call))) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
if ((isInstallOnly || isScaffoldOnly || isImplementOnly) &&
|
|
201
|
+
(isDevServerCall(call) || isLocalHttpProbe(call))) {
|
|
202
|
+
return (`Out of scope for current task "${taskTitle}": do not start the dev server or probe localhost yet. ` +
|
|
203
|
+
`Finish and VERIFY this task's own work, mark it done only when satisfied, then open the run/verify task with task.update in_progress.`);
|
|
204
|
+
}
|
|
205
|
+
if (isImplementOnly &&
|
|
206
|
+
call.name === "shell.exec" &&
|
|
207
|
+
isPackageInstallCommand(commandOf(call))) {
|
|
208
|
+
const planTitles = opts?.planTaskTitles;
|
|
209
|
+
const planHasInstallTask = !planTitles ||
|
|
210
|
+
planTitles.length === 0 ||
|
|
211
|
+
planTitles.some((title) => looksLikeInstallTaskTitle(title));
|
|
212
|
+
if (planHasInstallTask) {
|
|
213
|
+
return (`Out of scope for current task "${taskTitle}": run package install under the install task, not while implementing files.`);
|
|
214
|
+
}
|
|
215
|
+
// No install task in the plan — allow install so work is not stuck.
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Choose which pending plan task should own this tool call (auto-start).
|
|
222
|
+
* Prevents npm install from being attributed to "localStorage" / style tasks.
|
|
223
|
+
*/
|
|
224
|
+
export function pickPendingTaskForToolCall(pending, call, allTitles) {
|
|
225
|
+
if (pending.length === 0)
|
|
226
|
+
return undefined;
|
|
227
|
+
const titles = allTitles ?? pending.map((p) => p.title);
|
|
228
|
+
const cmd = commandOf(call);
|
|
229
|
+
const score = (title) => {
|
|
230
|
+
if (workOutOfScopeForTask(title, call, { planTaskTitles: titles })) {
|
|
231
|
+
return -100;
|
|
232
|
+
}
|
|
233
|
+
let s = 1; // any in-scope pending task is viable
|
|
234
|
+
if (isPackageInstallCommand(cmd)) {
|
|
235
|
+
if (looksLikeInstallTaskTitle(title))
|
|
236
|
+
s += 20;
|
|
237
|
+
else if (looksLikeScaffoldTaskTitle(title))
|
|
238
|
+
s += 10;
|
|
239
|
+
else
|
|
240
|
+
s -= 5; // prefer not to attach install to feature tasks
|
|
241
|
+
}
|
|
242
|
+
if (isDevServerCall(call) || isLocalHttpProbe(call)) {
|
|
243
|
+
if (/\b(dev\s*server|run\s+dev|localhost|shell\.start|probe|verify)\b/i.test(title)) {
|
|
244
|
+
s += 20;
|
|
245
|
+
}
|
|
246
|
+
else
|
|
247
|
+
s -= 10;
|
|
248
|
+
}
|
|
249
|
+
if (call.name === "fs.write" ||
|
|
250
|
+
call.name === "fs.writeMany" ||
|
|
251
|
+
call.name === "fs.edit") {
|
|
252
|
+
if (looksLikeInstallTaskTitle(title))
|
|
253
|
+
s -= 15;
|
|
254
|
+
if (/\b(component|feature|todo|implement|style|persist|localstorage|ui|page)\b/i.test(title)) {
|
|
255
|
+
s += 12;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return s;
|
|
259
|
+
};
|
|
260
|
+
let best;
|
|
261
|
+
let bestScore = -Infinity;
|
|
262
|
+
for (const p of pending) {
|
|
263
|
+
const sc = score(p.title);
|
|
264
|
+
if (sc > bestScore) {
|
|
265
|
+
best = p;
|
|
266
|
+
bestScore = sc;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!best || bestScore < 0)
|
|
270
|
+
return undefined;
|
|
271
|
+
return best;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* User asked for a product feature app (todo, blog, …), not "just scaffold framework X".
|
|
275
|
+
* Stack-agnostic: detects intent, not a particular framework.
|
|
276
|
+
*/
|
|
277
|
+
export function userAskedForFeatureApp(prompt) {
|
|
278
|
+
const p = prompt.trim().toLowerCase();
|
|
279
|
+
if (!p)
|
|
280
|
+
return false;
|
|
281
|
+
if (/\b(just|only)\s+(scaffold|init|initialize|boilerplate|starter|template)\b/.test(p)) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
// Named product feature + app/project shape
|
|
285
|
+
if (/\b(todo|to-?do|blog|dashboard|chat|kanban|notes?|crm|shop|store|cart|auth|login|signup|crud|calendar|inbox|quiz|portfolio|gallery|tracker|inventory|booking|counter|timer|weather)\b/.test(p) &&
|
|
286
|
+
/\b(app|application|project|site|page|ui|list|board|service|api)\b/.test(p)) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
// "build a full … with X feature"
|
|
290
|
+
if (/\b(?:with|including|that\s+has|that\s+supports)\b[\s\S]{0,40}\b(todo|auth|crud|login|dashboard|blog)\b/.test(p)) {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
/** Paths that look like application source (not lockfiles / build output). */
|
|
296
|
+
export function isAppSourcePath(path) {
|
|
297
|
+
const p = path.replace(/\\/g, "/");
|
|
298
|
+
if (/(?:^|\/)(?:node_modules|\.next|dist|build|coverage|\.git|vendor|target)(?:\/|$)/i.test(p)) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
if (/(?:^|\/)(?:package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb?)$/i.test(p)) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
return /\.(jsx?|tsx?|vue|svelte|py|go|rs|java|kt|rb|php|swift|cs|css|scss|sass|less|html|mdx)$/i.test(p);
|
|
305
|
+
}
|
|
306
|
+
export function extractWritePathsFromCall(call) {
|
|
307
|
+
const paths = [];
|
|
308
|
+
if (call.name === "fs.write" ||
|
|
309
|
+
call.name === "fs.edit" ||
|
|
310
|
+
call.name === "fs.replaceLines" ||
|
|
311
|
+
call.name === "fs.append") {
|
|
312
|
+
if (typeof call.args.path === "string")
|
|
313
|
+
paths.push(call.args.path);
|
|
314
|
+
}
|
|
315
|
+
if (call.name === "fs.writeMany" && Array.isArray(call.args.files)) {
|
|
316
|
+
for (const f of call.args.files) {
|
|
317
|
+
if (f && typeof f === "object" && typeof f.path === "string") {
|
|
318
|
+
paths.push(f.path);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return paths;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* True when a successful tool call implements product feature code (not only scaffold).
|
|
326
|
+
*/
|
|
327
|
+
export function isFeatureImplementationCall(call) {
|
|
328
|
+
const paths = extractWritePathsFromCall(call);
|
|
329
|
+
if (paths.some(isAppSourcePath))
|
|
330
|
+
return true;
|
|
331
|
+
// Hand-written multi-file setup without official scaffolder
|
|
332
|
+
if (call.name === "fs.writeMany" && paths.length >= 2)
|
|
333
|
+
return true;
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Soft block: don't start the local server until the product feature exists.
|
|
338
|
+
* Returns a message when the open work is still scaffold-only for a feature ask.
|
|
339
|
+
*/
|
|
340
|
+
export function incompleteFeatureBeforeServerMessage(userPrompt, sawFeatureImpl, call) {
|
|
341
|
+
if (!userAskedForFeatureApp(userPrompt))
|
|
342
|
+
return undefined;
|
|
343
|
+
if (sawFeatureImpl)
|
|
344
|
+
return undefined;
|
|
345
|
+
if (!isDevServerCall(call) && !(call.name === "shell.start"))
|
|
346
|
+
return undefined;
|
|
347
|
+
return (`Feature incomplete: the user asked for a product app (not just a blank scaffold). ` +
|
|
348
|
+
`Implement the requested feature first (real UI/state or API — replace starter boilerplate), ` +
|
|
349
|
+
`THEN start the server. Do not shell.start / npm run dev until the feature is written.`);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* User said work belongs on the Desktop (or similar). Returns absolute path.
|
|
353
|
+
*/
|
|
354
|
+
export function resolveUserDestinationHint(prompt, home = homedir()) {
|
|
355
|
+
const p = prompt.trim();
|
|
356
|
+
if (!p)
|
|
357
|
+
return undefined;
|
|
358
|
+
// Explicit absolute /Users/.../Desktop/... already in the prompt — prefer that root
|
|
359
|
+
const absDesktop = p.match(/((?:\/Users\/[^/\s]+|~)\/Desktop(?:\/[\w.-]+)?)/i);
|
|
360
|
+
if (absDesktop?.[1]) {
|
|
361
|
+
const raw = absDesktop[1].replace(/^~(?=\/|$)/, home);
|
|
362
|
+
// If they named a subfolder in the path, use parent Desktop for cwd default
|
|
363
|
+
if (/\/Desktop$/i.test(raw) || /\/Desktop\//i.test(raw)) {
|
|
364
|
+
const desk = raw.match(/^(.*?\/Desktop)/i);
|
|
365
|
+
return desk?.[1] ?? raw;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (/\b(?:in|on|into|under|to)\s+(?:the\s+)?desktop(?:\s+directory|\s+folder)?\b/i.test(p) ||
|
|
369
|
+
/\bdesktop\s+(?:directory|folder)\b/i.test(p) ||
|
|
370
|
+
/\bcreate\b.+\b(?:on|in)\s+desktop\b/i.test(p)) {
|
|
371
|
+
return join(home, "Desktop");
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Default shell cwd when the model omitted it but a project root / Desktop hint exists.
|
|
377
|
+
*/
|
|
378
|
+
export function applyDestinationCwd(call, destinationHint) {
|
|
379
|
+
if (call.name !== "shell.exec" && call.name !== "shell.start")
|
|
380
|
+
return call;
|
|
381
|
+
if (typeof call.args.cwd === "string" && call.args.cwd.trim())
|
|
382
|
+
return call;
|
|
383
|
+
const cmd = commandOf(call);
|
|
384
|
+
// Prefer sticky project root (todo-app) over bare Desktop for install/dev.
|
|
385
|
+
const cwd = getActiveProjectRoot() ?? destinationHint;
|
|
386
|
+
if (!cwd)
|
|
387
|
+
return call;
|
|
388
|
+
const looksCreate = isScaffoldCreateCommand(cmd);
|
|
389
|
+
// create into named subfolder: cwd should be parent of project if sticky root is the project
|
|
390
|
+
if (looksCreate) {
|
|
391
|
+
const nameMatch = cmd.match(/(?:create-vite(?:@\S+)?|create-next-app(?:@\S+)?|cargo\s+new|rails\s+new|poetry\s+new|flutter\s+create|mix\s+new|django-admin\s+startproject)\s+([A-Za-z0-9._-]+)/i);
|
|
392
|
+
if (nameMatch?.[1] && !nameMatch[1].startsWith("-")) {
|
|
393
|
+
const parent = cwd.replace(/[/\\][^/\\]+$/, "");
|
|
394
|
+
const useParent = cwd.endsWith(nameMatch[1]) ||
|
|
395
|
+
cwd.endsWith("/" + nameMatch[1]) ||
|
|
396
|
+
cwd.endsWith("\\" + nameMatch[1]);
|
|
397
|
+
return {
|
|
398
|
+
...call,
|
|
399
|
+
args: { ...call.args, cwd: useParent && parent ? parent : cwd },
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
// Prefer destination parent (Desktop) for create when sticky root is already a project
|
|
403
|
+
return { ...call, args: { ...call.args, cwd: destinationHint ?? cwd } };
|
|
404
|
+
}
|
|
405
|
+
const looksProjectLocal = /\b(npm\s+i(nstall)?|npm\s+run|yarn\s|pnpm\s|bun\s|pip\s+install|poetry\s+|cargo\s+|go\s+run|go\s+build|composer\s+|bundle\s+|dotnet\s+|flutter\s+|mix\s+|rails\s+|django)/i.test(cmd) || call.name === "shell.start";
|
|
406
|
+
if (!looksProjectLocal)
|
|
407
|
+
return call;
|
|
408
|
+
return {
|
|
409
|
+
...call,
|
|
410
|
+
args: { ...call.args, cwd },
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=task-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-evidence.js","sourceRoot":"","sources":["../../src/agent/task-evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,6 +78,12 @@ export declare function salvageTruncatedWrite(text: string): {
|
|
|
78
78
|
content: string;
|
|
79
79
|
lastLine: string;
|
|
80
80
|
} | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Salvage partial file content from a native tool call's raw argument JSON
|
|
83
|
+
* (streaming cut off / finish_reason length / _parseError). Reuses the
|
|
84
|
+
* text-path salvage by reconstructing a minimal {"name","args"} shape.
|
|
85
|
+
*/
|
|
86
|
+
export declare function salvageTruncatedWriteFromNative(name: string, rawArguments: string | undefined): ReturnType<typeof salvageTruncatedWrite>;
|
|
81
87
|
/**
|
|
82
88
|
* Count the number of ```tool fenced blocks in a message. Models sometimes
|
|
83
89
|
* emit MULTIPLE tool calls in one response (e.g. fs.writeMany + npm install +
|
|
@@ -152,6 +158,15 @@ export declare function looksLikeBuildTask(prompt: string, history?: ChatMessage
|
|
|
152
158
|
* "should I add auth" → those still want work).
|
|
153
159
|
*/
|
|
154
160
|
export declare function looksLikeInformationalQuery(prompt: string): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Model diagnosed a concrete failure (build/runtime/HTTP) and implies a fix
|
|
163
|
+
* but emitted no tool call — must not end the turn.
|
|
164
|
+
*/
|
|
165
|
+
export declare function looksLikeErrorDiagnosisWithFixIntent(text: string): boolean;
|
|
166
|
+
/** True when tool output is a local HTTP probe that did not return 2xx. */
|
|
167
|
+
export declare function localHttpProbeIsFailure(output: string): boolean;
|
|
168
|
+
/** True when tool output shows a successful 2xx local probe. */
|
|
169
|
+
export declare function localHttpProbeIsSuccess(output: string): boolean;
|
|
155
170
|
/**
|
|
156
171
|
* Detect a pure social / idle user prompt (greetings, thanks, short acks).
|
|
157
172
|
* These must never force tool use, plan workflows, or freshness retries.
|
|
@@ -195,6 +210,7 @@ export declare function freshnessGuardMessage(now?: Date): string;
|
|
|
195
210
|
* Directive injected for build/scaffold turns. Forces the careful
|
|
196
211
|
* explore → understand → plan → implement loop instead of a one-shot dump,
|
|
197
212
|
* and forbids stopping before the goal is reached.
|
|
213
|
+
* Language/stack-agnostic: principles only; pick tools that match the project.
|
|
198
214
|
*/
|
|
199
215
|
export declare function buildWorkflowDirective(): string;
|
|
200
216
|
/**
|
|
@@ -208,6 +224,11 @@ export declare function buildWorkflowDirective(): string;
|
|
|
208
224
|
* be flagged to the user rather than acted on.
|
|
209
225
|
*/
|
|
210
226
|
export declare function pentestWorkflowDirective(): string;
|
|
227
|
+
/**
|
|
228
|
+
* Always-on reminder when the session is already a remote/security engagement
|
|
229
|
+
* (plan kind=pentest or pentest-like turn), including after tasks complete.
|
|
230
|
+
*/
|
|
231
|
+
export declare function pentestNoLocalServerDirective(): string;
|
|
211
232
|
export declare function shouldDimToolChatter(call: ToolCall): boolean;
|
|
212
233
|
/**
|
|
213
234
|
* Returns true when the model's output looks like it is repeating the system
|