@glbgpt/cli 0.2.3 → 0.2.4

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.
Files changed (47) hide show
  1. package/README.md +50 -4
  2. package/dist/src/coding/bashTool.js +27 -11
  3. package/dist/src/coding/bashTool.js.map +1 -1
  4. package/dist/src/coding/deliveryCheck.d.ts +7 -0
  5. package/dist/src/coding/deliveryCheck.js +143 -0
  6. package/dist/src/coding/deliveryCheck.js.map +1 -0
  7. package/dist/src/coding/permissionGate.d.ts +6 -0
  8. package/dist/src/coding/permissionGate.js +8 -2
  9. package/dist/src/coding/permissionGate.js.map +1 -1
  10. package/dist/src/coding/projectContext.js +11 -1
  11. package/dist/src/coding/projectContext.js.map +1 -1
  12. package/dist/src/commands/configCommand.js +9 -3
  13. package/dist/src/commands/configCommand.js.map +1 -1
  14. package/dist/src/commands/execCommand.js +18 -1
  15. package/dist/src/commands/execCommand.js.map +1 -1
  16. package/dist/src/config/configFile.d.ts +4 -0
  17. package/dist/src/config/configFile.js +4 -0
  18. package/dist/src/config/configFile.js.map +1 -1
  19. package/dist/src/core/compaction.d.ts +6 -1
  20. package/dist/src/core/compaction.js +23 -5
  21. package/dist/src/core/compaction.js.map +1 -1
  22. package/dist/src/core/httpChatBackend.js +72 -20
  23. package/dist/src/core/httpChatBackend.js.map +1 -1
  24. package/dist/src/core/progressGuard.d.ts +16 -0
  25. package/dist/src/core/progressGuard.js +197 -0
  26. package/dist/src/core/progressGuard.js.map +1 -0
  27. package/dist/src/core/runChat.d.ts +8 -0
  28. package/dist/src/core/runChat.js +23 -5
  29. package/dist/src/core/runChat.js.map +1 -1
  30. package/dist/src/core/tokenBudget.d.ts +45 -0
  31. package/dist/src/core/tokenBudget.js +111 -0
  32. package/dist/src/core/tokenBudget.js.map +1 -0
  33. package/dist/src/core/turnLoop.d.ts +7 -1
  34. package/dist/src/core/turnLoop.js +108 -44
  35. package/dist/src/core/turnLoop.js.map +1 -1
  36. package/dist/src/core/types.d.ts +21 -0
  37. package/dist/src/exec/output.d.ts +6 -0
  38. package/dist/src/exec/output.js +26 -11
  39. package/dist/src/exec/output.js.map +1 -1
  40. package/dist/src/tui/App.js +7 -3
  41. package/dist/src/tui/App.js.map +1 -1
  42. package/dist/src/tui/chatController.d.ts +11 -1
  43. package/dist/src/tui/chatController.js +91 -15
  44. package/dist/src/tui/chatController.js.map +1 -1
  45. package/dist/src/tui/run.js +1 -0
  46. package/dist/src/tui/run.js.map +1 -1
  47. package/package.json +1 -1
package/README.md CHANGED
@@ -48,13 +48,18 @@ few searches per message), and fetch public web pages by URL (free).
48
48
 
49
49
  On tool-capable models the assistant can also **run shell commands, create files, and edit
50
50
  files** in your workspace — every command and file change asks for your approval first
51
- (`[y]` allow once, `[a]` allow similar actions for this session, `[p]` always allow for this
51
+ (`[y]` allow once, `[a]` remember for this session, `[p]` remember for this
52
52
  project, `[n]` deny). Diffs are shown before an edit runs. Project instructions in
53
53
  `AGENTS.md` or `CLAUDE.md` (from the repository root down to the current directory) are
54
54
  picked up automatically (`--no-project-context` to skip). Long-running commands (dev
55
55
  servers, watchers) can run in the background — the assistant starts them detached, polls
56
56
  their output, and they are stopped when the CLI exits.
57
57
 
58
+ The approval prompt shows the scope remembered by `a`/`p`: a command prefix, the exact
59
+ command, or a directory for file writes/edits. Python interpreters and compound commands
60
+ usually require an **exact-command** approval: changing an inline script asks again.
61
+ Approving file writes does not approve shell commands.
62
+
58
63
  Long conversations compact automatically: when the history approaches the model's context
59
64
  limit the older part is summarized (one model call) and the conversation continues
60
65
  seamlessly — `/compact` triggers it manually. The full history always stays on disk.
@@ -236,10 +241,10 @@ re-points the link and leaves nothing to lose.
236
241
  | `glbgpt config get <key>` · `set <key> <value>` · `unset <key>` | Manage settings. |
237
242
 
238
243
  Keys: `lang`, `max-credits` (unattended media budget), `max-tool-calls` (tool calls per
239
- chat turn, default 40), `context-pruning` (set `false` to
244
+ chat turn, default 40), `max-turn-tokens` (cumulative request tokens per turn, default 200000), `context-pruning` (set `false` to
240
245
  keep old tool results in long chats), `update-check` (set `false` to disable the startup
241
246
  update prompt and notices about newer versions). One-shot overrides via env vars (`GLBGPT_LANG`,
242
- `GLBGPT_TOKEN`, `GLBGPT_MAX_CREDITS`, `GLBGPT_MAX_TOOL_CALLS`, `GLBGPT_CONTEXT_PRUNING`, `GLBGPT_UPDATE_CHECK`)
247
+ `GLBGPT_TOKEN`, `GLBGPT_MAX_CREDITS`, `GLBGPT_MAX_TOOL_CALLS`, `GLBGPT_MAX_TURN_TOKENS`, `GLBGPT_CONTEXT_PRUNING`, `GLBGPT_UPDATE_CHECK`)
243
248
  always win.
244
249
 
245
250
  For longer coding tasks, use `glbgpt config set max-tool-calls 100` or set
@@ -248,7 +253,48 @@ For longer coding tasks, use `glbgpt config set max-tool-calls 100` or set
248
253
  **not a token or credit limit**: raising it can increase model usage and cost.
249
254
  When the budget is reached, the CLI preserves completed work in the conversation
250
255
  and requests a final answer with no further tool execution, including any remaining
251
- work. Send a follow-up message to continue with a new turn's budget.
256
+ work, if the token budget permits. The turn is marked paused. Send a follow-up message to continue with a new turn's budget.
257
+
258
+ Conversation spending protection is separate from the media credit budget. Set
259
+ `glbgpt config set max-turn-tokens 100000` or `GLBGPT_MAX_TURN_TOKENS=100000` for a smaller
260
+ allowance (integers from 1000 to 10000000). All model requests in one turn count, including
261
+ tool rounds, safe structured-output retries, and automatic context compaction. At 80% the
262
+ CLI warns; before each request it compares the estimated input with the remaining budget.
263
+ It pauses without another summary request when the budget is exhausted or the next input
264
+ would exceed it. Provider usage is used when available; missing values are estimated and
265
+ marked `~` in the turn counter. Image attachments use a per-image reserve (4096 tokens
266
+ for explicit low detail, otherwise 16384), independent of URL/base64 transport size;
267
+ actual image token usage varies by model. An in-flight response, hidden reasoning, server prompts,
268
+ and different tokenizers can exceed the estimate: **this is not a hard billing cap or an
269
+ exact credit estimate**. The footer labels session totals separately from the current
270
+ turn budget. `glbgpt account transactions` remains the billing source.
271
+
272
+ Repeated unchanged tool results warn on the third occurrence and pause on the fifth.
273
+ Repeated Python failures can also be detected when the inline script changes but the
274
+ same command target returns the same error. Changed output or a new successful file
275
+ mutation resets the corresponding evidence; running background-task polling is exempt.
276
+ These are conservative local observations, not proof that a model is in an infinite loop
277
+ or that a task is too complex. On pause, the CLI preserves work and history, shows the
278
+ reason, and waits for a new message; queued messages do not automatically restart it.
279
+ On resume, older queued text appears before your newest instruction in the model history.
280
+ Starting a new session clears held messages and pending attachments.
281
+
282
+ A normal answer ends a conversational turn; it does not certify a finished coding task.
283
+ For clearly named file creation requests, the CLI checks that the requested files exist
284
+ and are nonempty, without executing them. Missing/empty files are marked **incomplete**;
285
+ existing files remain **unverified** for correctness. Ambiguous output descriptions are
286
+ not inferred. Reference files and appended stdin context are excluded from this check.
287
+ If a later message steers the active turn, the original inferred check is skipped because
288
+ its targets may no longer apply. The model is instructed to implement action requests, verify when possible,
289
+ and explain tests performed and unfinished work. There is no automatic paid follow-up
290
+ just because a model stopped with a plan. Request errors remain errors, with the upstream
291
+ message when available, rather than being labeled a loop.
292
+
293
+ `exec --jsonl` emits additive `notice`, `task_status`, and `turn_paused` events. A paused
294
+ turn exits nonzero; JSON errors include a `reason` (`repeated_no_progress`, `token_budget`,
295
+ `tool_budget`, or `tools_unavailable`) and `status: "paused"`. Partial text and known usage
296
+ are retained. A missing deliverable also exits nonzero and has `task.status: "incomplete"`;
297
+ a normal response without a file check keeps the existing result format.
252
298
 
253
299
  Context pruning also runs between tool rounds, preserving the raw history on disk.
254
300
  `exec` and MCP usage totals include every model request in the turn; these token
@@ -89,13 +89,19 @@ async function runBash(command, cwd, timeoutS, spillDir) {
89
89
  }
90
90
  const shell = pickShell();
91
91
  const detached = process.platform !== 'win32';
92
- const child = spawn(shell, ['-c', command], {
93
- cwd,
94
- detached,
95
- env: process.env,
96
- stdio: ['ignore', 'pipe', 'pipe'],
97
- windowsHide: true,
98
- });
92
+ let child;
93
+ try {
94
+ child = spawn(shell, ['-c', command], {
95
+ cwd,
96
+ detached,
97
+ env: process.env,
98
+ stdio: ['ignore', 'pipe', 'pipe'],
99
+ windowsHide: true,
100
+ });
101
+ }
102
+ catch (err) {
103
+ return { error: `Could not start command: ${err instanceof Error ? err.message : String(err)}` };
104
+ }
99
105
  const acc = new OutputAccumulator(undefined, undefined, spillDir);
100
106
  child.stdout?.on('data', (b) => acc.append(b));
101
107
  child.stderr?.on('data', (b) => acc.append(b));
@@ -104,10 +110,11 @@ async function runBash(command, cwd, timeoutS, spillDir) {
104
110
  timedOut = true;
105
111
  killTree(child.pid);
106
112
  }, timeoutS * 1000);
107
- const exitCode = await new Promise((resolve) => {
108
- child.on('error', () => resolve(null));
113
+ let processError;
114
+ const { exitCode, exitSignal } = await new Promise((resolve) => {
115
+ child.once('error', (err) => { processError = err; });
109
116
  // 'close' (not 'exit') so stdio has fully flushed before we snapshot the output.
110
- child.on('close', (code) => resolve(code));
117
+ child.once('close', (code, signal) => resolve({ exitCode: code, exitSignal: signal }));
111
118
  });
112
119
  clearTimeout(timer);
113
120
  const { text } = await acc.finalize();
@@ -115,7 +122,16 @@ async function runBash(command, cwd, timeoutS, spillDir) {
115
122
  if (timedOut) {
116
123
  return { error: `${output}\n\nCommand timed out after ${timeoutS} seconds` };
117
124
  }
118
- if (exitCode !== 0 && exitCode !== null) {
125
+ if (processError) {
126
+ return { error: `${output}\n\nCould not start or complete command: ${processError.message}` };
127
+ }
128
+ if (exitSignal) {
129
+ return { error: `${output}\n\nCommand terminated by signal ${exitSignal}` };
130
+ }
131
+ if (exitCode === null) {
132
+ return { error: `${output}\n\nCommand ended without an exit status` };
133
+ }
134
+ if (exitCode !== 0) {
119
135
  return { error: `${output}\n\nCommand exited with code ${exitCode}` };
120
136
  }
121
137
  return { output };
@@ -1 +1 @@
1
- {"version":3,"file":"bashTool.js","sourceRoot":"","sources":["../../../src/coding/bashTool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bashTool.js","sourceRoot":"","sources":["../../../src/coding/bashTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ContentPart, TaskAssessment } from '../core/types.js';
2
+ /**
3
+ * A local existence/size check for explicitly requested file outputs. It never runs
4
+ * the deliverable, reads its contents, contacts a model, or declares task success.
5
+ * Ambiguous requests have no check rather than guessing which files should exist.
6
+ */
7
+ export declare function createDeliveryCheck(root: string, userContent: string | ContentPart[]): (() => Promise<TaskAssessment | undefined>) | undefined;
@@ -0,0 +1,143 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { GuardError, resolveInWorkspace } from '../fs/workspaceGuard.js';
4
+ // Deliberately recognize only explicit create/write/save targets. A filename in a
5
+ // command example, an input list, or a reference description is not a deliverable.
6
+ const ACTION = /\b(create|write|save|generate)\b|创建|新建|编写|写入|保存|生成/gi;
7
+ const ENGLISH_INTRO = /^(?:(?:a|an|the|new|this|that|my|our|your|simple|working|python|javascript|typescript|node|shell|bash|script|file|document|report|output|content|code|named|called|as|to|at|path)(?:\s+|:\s*)){0,12}/i;
8
+ const CHINESE_INTRO = /^(?:(?:一个|一份|这个|该|新的|名为|叫做|脚本|文件|文档|输出|内容|代码|到|为|python|javascript|typescript|shell|bash)\s*){0,12}/i;
9
+ const FILE_TOKEN = /^(?:`([^`\r\n]+)`|"([^"\r\n]+)"|'([^'\r\n]+)'|([^\s`"'<>;,!?(),。;!?:]+))/;
10
+ function fileToken(text) {
11
+ const match = FILE_TOKEN.exec(text.trimStart());
12
+ if (!match)
13
+ return undefined;
14
+ const quoted = match[1] ?? match[2] ?? match[3];
15
+ const file = (quoted ?? match[4].replace(/[.:]+$/, '')).trim();
16
+ // No URL, glob, expansion, or executable syntax. Known extensionless build files
17
+ // are accepted; arbitrary prose is not inferred to be a filesystem path.
18
+ if (!file || /[\u0000\r\n$*?<>|]/.test(file) || file.includes('://'))
19
+ return undefined;
20
+ const basename = path.basename(file);
21
+ if (!/\.[\p{L}\p{N}]{1,16}$/u.test(basename) && !/^(?:Makefile|Dockerfile|README|LICENSE)$/i.test(basename)) {
22
+ return undefined;
23
+ }
24
+ return { file, rest: text.trimStart().slice(match[0].length) };
25
+ }
26
+ function describesRuntimeOutput(clause) {
27
+ // Match only an immediately preceding program/file subject and its infinitive
28
+ // or modal clause. A separate imperative ("and create output.pdf") still counts.
29
+ const english = /(?:^|\s)(`[^`\r\n]+`|"[^"\r\n]+"|'[^'\r\n]+'|[^\s]+)\s+(?:(?:that|which)\s+)?(?:to|should|will|can|must|could|would|may|needs? to)\s+(?:be able to\s+)?$/i.exec(clause);
30
+ if (english) {
31
+ const subject = english[1];
32
+ if (/^(?:program|script|function|tool|application|it)$/i.test(subject))
33
+ return true;
34
+ const file = fileToken(subject);
35
+ if (file && file.rest.length === 0)
36
+ return true;
37
+ }
38
+ return /(?:程序|脚本|函数|工具)(?:应该|应|将|会|可以|能够|能|需要)\s*$/.test(clause);
39
+ }
40
+ function requestedFiles(content) {
41
+ const text = (typeof content === 'string'
42
+ ? content
43
+ : content.filter((part) => part.type === 'text').map((part) => part.text).join('\n'))
44
+ .replace(/```[\s\S]*?```/g, '');
45
+ const files = new Set();
46
+ for (const match of text.matchAll(ACTION)) {
47
+ const before = text.slice(0, match.index);
48
+ const boundaries = [...before.matchAll(/[\n;,。;,]|[.!?](?=\s|$)/g)];
49
+ const clause = before.slice((boundaries.at(-1)?.index ?? -1) + 1);
50
+ // Advice, examples, historical statements, and negative instructions must not
51
+ // turn a mention of a file into a requested deliverable.
52
+ if (/\b(?:explain|describe|example|how|don't|do not|never|avoid|already|previously|used to)\b|解释|如何|怎么|示例|不要|无需|不需要|已经|曾经/i.test(clause))
53
+ continue;
54
+ // A requested script's future outputs are not necessarily files the user asked
55
+ // us to produce during this turn (e.g. "the script should create output.pdf").
56
+ if (describesRuntimeOutput(clause))
57
+ continue;
58
+ const tail = text.slice(match.index + match[0].length).trimStart();
59
+ const intro = (match[1] ? ENGLISH_INTRO : CHINESE_INTRO).exec(tail)[0];
60
+ let target = fileToken(tail.slice(intro.length));
61
+ if (!target)
62
+ continue;
63
+ // In "save input.html as output.html", only the destination is requested.
64
+ if (/^save$/i.test(match[0])) {
65
+ const destination = /^\s+(?:as|to)\s+/i.exec(target.rest);
66
+ if (destination)
67
+ target = fileToken(target.rest.slice(destination[0].length));
68
+ if (!target)
69
+ continue;
70
+ }
71
+ files.add(target.file);
72
+ // Explicit conjunctions allow several outputs; following prose such as "and
73
+ // use reference.pdf" cannot match another filename here.
74
+ for (;;) {
75
+ const conjunction = /^\s*(?:and\s+|和\s*|以及\s*|、\s*)/i.exec(target.rest);
76
+ if (!conjunction)
77
+ break;
78
+ const next = fileToken(target.rest.slice(conjunction[0].length));
79
+ if (!next)
80
+ break;
81
+ files.add(next.file);
82
+ target = next;
83
+ }
84
+ }
85
+ return [...files];
86
+ }
87
+ /**
88
+ * A local existence/size check for explicitly requested file outputs. It never runs
89
+ * the deliverable, reads its contents, contacts a model, or declares task success.
90
+ * Ambiguous requests have no check rather than guessing which files should exist.
91
+ */
92
+ export function createDeliveryCheck(root, userContent) {
93
+ const files = requestedFiles(userContent);
94
+ if (files.length === 0)
95
+ return undefined;
96
+ return async () => {
97
+ let canonicalRoot;
98
+ try {
99
+ canonicalRoot = await fs.realpath(root);
100
+ }
101
+ catch {
102
+ return { status: 'unverified', message: 'Requested files could not be checked because the workspace is unavailable.' };
103
+ }
104
+ const incomplete = [];
105
+ const inaccessible = [];
106
+ for (const file of files) {
107
+ try {
108
+ const resolved = await resolveInWorkspace(canonicalRoot, file);
109
+ const stat = await fs.stat(resolved);
110
+ if (!stat.isFile())
111
+ incomplete.push(`${JSON.stringify(file)} is not a regular file`);
112
+ else if (stat.size === 0)
113
+ incomplete.push(`${JSON.stringify(file)} is empty`);
114
+ }
115
+ catch (err) {
116
+ if ((err instanceof GuardError && err.message.startsWith('Not found:')) ||
117
+ err.code === 'ENOENT') {
118
+ incomplete.push(`${JSON.stringify(file)} is missing`);
119
+ }
120
+ else {
121
+ // Do not echo Node errors or resolved symlink targets outside the workspace.
122
+ inaccessible.push(JSON.stringify(file));
123
+ }
124
+ }
125
+ }
126
+ if (incomplete.length > 0) {
127
+ return {
128
+ status: 'incomplete',
129
+ message: `Requested deliverables are incomplete: ${incomplete.join('; ')}.` +
130
+ (inaccessible.length > 0 ? ` Could not safely inspect: ${inaccessible.join(', ')}.` : ''),
131
+ };
132
+ }
133
+ if (inaccessible.length > 0) {
134
+ return { status: 'unverified', message: `Could not safely inspect requested files within the workspace: ${inaccessible.join(', ')}. Their existence and correctness remain unverified.` };
135
+ }
136
+ return {
137
+ status: 'unverified',
138
+ message: `Requested files exist and are nonempty: ${files.map((file) => JSON.stringify(file)).join(', ')}. ` +
139
+ 'Existence alone does not verify correctness, passing tests, or a visual match. This check did not execute the files.',
140
+ };
141
+ };
142
+ }
143
+ //# sourceMappingURL=deliveryCheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliveryCheck.js","sourceRoot":"","sources":["../../../src/coding/deliveryCheck.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,12 @@ export interface ApprovalRequest {
18
18
  preview?: string;
19
19
  /** Whether "Allow for session"/"Always allow (project)" may be offered (never for dangerous commands). */
20
20
  allowSession: boolean;
21
+ /** Exact rule remembered by a=session / p=project; absent when remembering is disallowed. */
22
+ rememberedScope?: {
23
+ kind: 'command-prefix' | 'exact-command' | 'directory';
24
+ /** Shell prefix, full command, or absolute directory subtree for file writes/edits only. */
25
+ value: string;
26
+ };
21
27
  }
22
28
  /** Interactive approver (TUI bridge). Absent approver = headless surface (exec). */
23
29
  export interface Approver {
@@ -60,16 +60,21 @@ export class CodingPermissionGate {
60
60
  message: 'Shell commands are disabled here. The user must re-run with --allow-bash (or --yolo) to enable them.',
61
61
  };
62
62
  }
63
+ const prefix = dangerous ? null : allowlistPrefixFor(command);
63
64
  const decision = await this.approver.approve({
64
65
  action: { kind: 'bash', command },
65
66
  title: dangerous ? 'Run command (DANGEROUS)' : 'Run command',
66
67
  detail: command,
67
68
  allowSession: !dangerous,
69
+ ...(!dangerous ? {
70
+ rememberedScope: prefix
71
+ ? { kind: 'command-prefix', value: prefix }
72
+ : { kind: 'exact-command', value: command },
73
+ } : {}),
68
74
  });
69
75
  if (decision === 'deny')
70
76
  return { ok: false, message: DENIED_BY_USER };
71
77
  if ((decision === 'allow-session' || decision === 'allow-project') && !dangerous) {
72
- const prefix = allowlistPrefixFor(command);
73
78
  if (prefix)
74
79
  this.bashAllowlist.add(prefix);
75
80
  else
@@ -110,17 +115,18 @@ export class CodingPermissionGate {
110
115
  : 'File writes are disabled here. The user must re-run with --allow-write (or --yolo) to enable them.',
111
116
  };
112
117
  }
118
+ const dir = path.dirname(action.path);
113
119
  const decision = await this.approver.approve({
114
120
  action,
115
121
  title: action.kind === 'edit' ? 'Edit file' : 'Write file',
116
122
  detail: rel || action.path,
117
123
  preview: action.preview,
118
124
  allowSession: !touchesGit,
125
+ ...(!touchesGit ? { rememberedScope: { kind: 'directory', value: dir } } : {}),
119
126
  });
120
127
  if (decision === 'deny')
121
128
  return { ok: false, message: DENIED_BY_USER };
122
129
  if ((decision === 'allow-session' || decision === 'allow-project') && !touchesGit) {
123
- const dir = path.dirname(action.path);
124
130
  this.writeDirAllowlist.add(dir);
125
131
  if (decision === 'allow-project')
126
132
  this.onPersist?.({ type: 'write-dir', value: dir });
@@ -1 +1 @@
1
- {"version":3,"file":"permissionGate.js","sourceRoot":"","sources":["../../../src/coding/permissionGate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissionGate.js","sourceRoot":"","sources":["../../../src/coding/permissionGate.ts"],"names":[],"mappings":"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"}
@@ -81,6 +81,9 @@ export async function loadProjectContext(workspaceRoot, maxBytes = PROJECT_CONTE
81
81
  export function buildCodingSystemMessage(opts) {
82
82
  const lines = [
83
83
  'When file and shell tools are available, follow these guidelines:',
84
+ '- Treat requests to create, change, or fix something as requests to perform that work. ' +
85
+ 'Inspect the project and carry out the authorized changes; a plan or a promise to act is not a completed deliverable. ' +
86
+ 'If the user explicitly asks only for advice or a plan, respect that scope.',
84
87
  '- Prefer the dedicated tools over bash equivalents: read_file over cat/head/tail/sed, ' +
85
88
  'grep over grep/rg, glob over find, list_dir over ls, edit_file over sed/awk, ' +
86
89
  'write_file over echo/heredoc redirection. They are safer and their output is easier to review.',
@@ -92,10 +95,17 @@ export function buildCodingSystemMessage(opts) {
92
95
  'absolute paths or `cd` within a single command.',
93
96
  '- For long-running commands (dev servers, watchers) use bash with run_in_background: true, ' +
94
97
  'then poll bash_output and stop with bash_kill when done.',
95
- '- After making changes, verify them when possible (run the tests or build the project).',
98
+ '- Before reporting completion, verify that the requested deliverable exists and inspect the resulting ' +
99
+ 'files or tool results. Run relevant tests or builds when feasible. A successful write alone does not ' +
100
+ 'prove the change works; a failed, interrupted, or unstarted command is not a passed check.',
101
+ '- In the final response, state what was actually completed, any unfinished work or blockers, and the ' +
102
+ 'verification performed with its results and limitations. Do not claim success without supporting evidence ' +
103
+ 'or end an action request with only a promise to implement or test later.',
96
104
  '- Independent read-only tool calls can be issued together in one round; mutations run one at a time.',
97
105
  '- Some actions require user approval. If one is denied, do not retry it verbatim — adjust ' +
98
106
  'your approach or ask the user.',
107
+ '- Approval to write or edit files does not approve shell commands. Remembered approvals apply only ' +
108
+ 'to the exact command, command prefix, or directory shown in the permission request.',
99
109
  '- Match the style of the surrounding code; keep changes minimal and scoped to the request.',
100
110
  `Workspace root: ${opts.workspaceRoot}`,
101
111
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"projectContext.js","sourceRoot":"","sources":["../../../src/coding/projectContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projectContext.js","sourceRoot":"","sources":["../../../src/coding/projectContext.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { CONFIG_KEYS, isConfigKey, readConfigSync, writeConfigValue } from '../c
2
2
  import { apiBaseUrl, webBaseUrl, lang } from '../config/env.js';
3
3
  import { DEFAULT_SESSION_MAX_CREDITS } from '../fs/limits.js';
4
4
  import { parseMaxToolCalls, resolveMaxToolCalls } from '../core/turnLimits.js';
5
+ import { parseMaxTurnTokens, resolveMaxTurnTokens } from '../core/tokenBudget.js';
5
6
  /**
6
7
  * `glbgpt config list|get|set|unset` — persistent CLI settings.
7
8
  *
@@ -26,7 +27,9 @@ export function effective(key) {
26
27
  ? lang()
27
28
  : key === 'max-tool-calls'
28
29
  ? String(resolveMaxToolCalls())
29
- : (fromEnv ?? stored ?? KEY_DEFAULTS[key] ?? '');
30
+ : key === 'max-turn-tokens'
31
+ ? String(resolveMaxTurnTokens())
32
+ : (fromEnv ?? stored ?? KEY_DEFAULTS[key] ?? '');
30
33
  return { value, source: fromEnv ? 'env' : stored ? 'config' : 'default' };
31
34
  }
32
35
  function badKey(key) {
@@ -53,9 +56,12 @@ export async function runConfigSet(key, value) {
53
56
  process.exitCode = 1;
54
57
  return;
55
58
  }
56
- if (key === 'max-tool-calls') {
59
+ if (key === 'max-tool-calls' || key === 'max-turn-tokens') {
57
60
  try {
58
- parseMaxToolCalls(value);
61
+ if (key === 'max-tool-calls')
62
+ parseMaxToolCalls(value);
63
+ else
64
+ parseMaxTurnTokens(value);
59
65
  }
60
66
  catch (err) {
61
67
  console.error(err instanceof Error ? err.message : String(err));
@@ -1 +1 @@
1
- {"version":3,"file":"configCommand.js","sourceRoot":"","sources":["../../../src/commands/configCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configCommand.js","sourceRoot":"","sources":["../../../src/commands/configCommand.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { createDeliveryCheck } from '../coding/deliveryCheck.js';
1
2
  import { promises as fs } from 'node:fs';
2
3
  import path from 'node:path';
3
4
  import { HttpChatBackend } from '../core/httpChatBackend.js';
@@ -90,6 +91,7 @@ export async function runExec(positional, opts, deps = {}) {
90
91
  }
91
92
  // 1. Assemble input. Any UsageError here is a caller/input error → exit 1, always on stderr.
92
93
  let promptText;
94
+ let deliveryPrompt;
93
95
  let promptContent;
94
96
  let outputSchema;
95
97
  try {
@@ -98,6 +100,9 @@ export async function runExec(positional, opts, deps = {}) {
98
100
  stdinIsTty: deps.stdinIsTty ?? process.stdin.isTTY === true,
99
101
  readStdin: deps.readStdin ?? readStdinAll,
100
102
  });
103
+ // With an explicit prompt, piped stdin and --file are reference material.
104
+ // Assess only the user's request, while retaining all context for the model.
105
+ deliveryPrompt = positional?.trim() && positional !== '-' ? positional : promptText;
101
106
  promptText = await injectFiles(promptText, opts.file ?? [], deps.readFile);
102
107
  promptContent = promptText;
103
108
  if (opts.image && opts.image.length > 0) {
@@ -139,9 +144,11 @@ export async function runExec(positional, opts, deps = {}) {
139
144
  const registry = new ToolRegistry();
140
145
  let media;
141
146
  let codingSystem;
147
+ let assessTask;
142
148
  let backgroundTasks;
143
149
  if (modelSupportsTools(model)) {
144
150
  const root = await workspaceRoot(deps.workspaceRootDir);
151
+ assessTask = createDeliveryCheck(root, deliveryPrompt);
145
152
  // Coding tools: headless is fail-closed — writes/bash are denied with a message
146
153
  // naming the enable flag unless the user opted in (--allow-write/--allow-bash/--yolo).
147
154
  const readState = new ReadFileState();
@@ -182,6 +189,7 @@ export async function runExec(positional, opts, deps = {}) {
182
189
  system: [codingSystem, opts.system].filter(Boolean).join('\n\n'),
183
190
  outputSchema,
184
191
  registry,
192
+ assessTask,
185
193
  }, (event) => {
186
194
  switch (event.type) {
187
195
  case 'assistant_delta':
@@ -189,6 +197,15 @@ export async function runExec(positional, opts, deps = {}) {
189
197
  case 'usage':
190
198
  output.usageEvent(event.promptTokens, event.completionTokens);
191
199
  break;
200
+ case 'notice':
201
+ output.notice(event.message);
202
+ break;
203
+ case 'task_status':
204
+ output.taskStatus(event.assessment);
205
+ break;
206
+ case 'turn_paused':
207
+ output.pause(event.reason, event.message);
208
+ break;
192
209
  case 'tool_call_begin':
193
210
  output.toolBegin(event.name, event.args);
194
211
  break;
@@ -225,7 +242,7 @@ export async function runExec(positional, opts, deps = {}) {
225
242
  killBackgroundTasks(backgroundTasks, sinks);
226
243
  output.finishResult(result.structured);
227
244
  await flushTelemetry();
228
- return 0;
245
+ return result.task?.status === 'incomplete' ? 1 : 0;
229
246
  }
230
247
  /** exec is one turn: any background bash task still running dies with the process. */
231
248
  function killBackgroundTasks(tasks, sinks) {