koneck 2.25.37 → 2.25.39

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.
@@ -43,6 +43,14 @@ export interface AllowRule {
43
43
  export declare function commandPrefixSuggestion(command: string): string;
44
44
  /** Whether a granted rule covers this call. */
45
45
  export declare function ruleMatches(rule: AllowRule, tool: string, argsJson: string): boolean;
46
+ /**
47
+ * Whether a command only reads.
48
+ *
49
+ * A chained command is never trusted, however it starts: `ls | rm -rf .` begins with `ls`. The
50
+ * same reasoning that keeps a granted prefix from covering a chain applies here, and for the same
51
+ * reason — the check looks at the front of the line and the danger is at the back.
52
+ */
53
+ export declare function isReadOnlyCommand(command: string): boolean;
46
54
  /**
47
55
  * What should happen to one tool call: run it, ask, or refuse.
48
56
  *
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,wFAAwF;AACxF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,4FAA4F;IAC5F,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,KAAK,EAAE,SAAS,QAAQ,EAkCpC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAcD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAM/C;AAED,2FAA2F;AAC3F,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED,+CAA+C;AAC/C,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAUpF;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC1B,QAAQ,CAIV;AAMD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAUjE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;AAED,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,CAIjF;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,wFAAwF;AACxF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,4FAA4F;IAC5F,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,KAAK,EAAE,SAAS,QAAQ,EAkCpC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAcD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAM/C;AAED,2FAA2F;AAC3F,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED,+CAA+C;AAC/C,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAUpF;AAiCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsB1D;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC1B,QAAQ,CAaV;AAMD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAUjE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;AAED,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,CAIjF;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEpD"}
@@ -40,7 +40,7 @@ export function modeSpec(name) {
40
40
  /** Tools that only observe. Never gated: an agent reads constantly, and prompting would be noise. */
41
41
  const READ_TOOLS = new Set([
42
42
  'read_files', 'list_dir', 'glob_search', 'grep_search', 'fetch_url', 'web_search',
43
- 'remember', 'git_status', 'git_diff', 'git_log',
43
+ 'remember', 'plan', 'git_status', 'git_diff', 'git_log',
44
44
  ]);
45
45
  /** Tools that change the working tree. */
46
46
  const WRITE_TOOLS = new Set([
@@ -103,6 +103,63 @@ export function ruleMatches(rule, tool, argsJson) {
103
103
  return false;
104
104
  return text.startsWith(rule.prefix);
105
105
  }
106
+ /**
107
+ * Commands that only look, and are run without asking in any mode that would otherwise ask.
108
+ *
109
+ * Without this, careful mode asks about `ls`. A prompt for something that cannot change anything
110
+ * is pure friction, and friction is what teaches people to approve without reading — at which
111
+ * point the prompt that matters gets waved through too. Codex draws the same line and calls the
112
+ * policy "untrusted": trusted commands run, everything else escalates.
113
+ *
114
+ * Membership is decided by what a command can do, not by how harmless it sounds. Anything that
115
+ * writes, installs, connects out, or evaluates code is absent on purpose.
116
+ */
117
+ const READ_ONLY_COMMANDS = new Set([
118
+ 'ls', 'dir', 'pwd', 'cd', 'echo', 'cat', 'head', 'tail', 'wc', 'file', 'stat',
119
+ 'find', 'grep', 'rg', 'ag', 'tree', 'which', 'type', 'whoami', 'id', 'hostname',
120
+ 'date', 'uptime', 'df', 'du', 'ps', 'env', 'printenv', 'uname', 'basename', 'dirname',
121
+ 'sort', 'uniq', 'cut', 'diff', 'md5sum', 'sha256sum', 'true', 'false',
122
+ ]);
123
+ /** Subcommands of tools that are safe only in part: `git log` yes, `git push` emphatically not. */
124
+ const READ_ONLY_SUBCOMMANDS = {
125
+ git: new Set(['status', 'log', 'diff', 'show', 'branch', 'remote', 'blame', 'describe',
126
+ 'rev-parse', 'ls-files', 'shortlog', 'tag', 'config']),
127
+ npm: new Set(['ls', 'list', 'view', 'outdated', 'why', 'root', 'prefix', 'config']),
128
+ yarn: new Set(['list', 'why', 'info']),
129
+ pnpm: new Set(['list', 'why', 'root']),
130
+ cargo: new Set(['tree', 'metadata']),
131
+ docker: new Set(['ps', 'images', 'version', 'info']),
132
+ kubectl: new Set(['get', 'describe', 'version']),
133
+ };
134
+ /**
135
+ * Whether a command only reads.
136
+ *
137
+ * A chained command is never trusted, however it starts: `ls | rm -rf .` begins with `ls`. The
138
+ * same reasoning that keeps a granted prefix from covering a chain applies here, and for the same
139
+ * reason — the check looks at the front of the line and the danger is at the back.
140
+ */
141
+ export function isReadOnlyCommand(command) {
142
+ const text = command.trim();
143
+ if (!text || SHELL_CHAINING.test(text))
144
+ return false;
145
+ const words = text.split(/\s+/).filter(Boolean);
146
+ const head = (words[0] ?? '').toLowerCase();
147
+ // Redirection writes files even when the command itself would not.
148
+ if (words.some(w => w === '>' || w === '>>'))
149
+ return false;
150
+ const subcommands = READ_ONLY_SUBCOMMANDS[head];
151
+ if (subcommands) {
152
+ const sub = (words[1] ?? '').toLowerCase();
153
+ return subcommands.has(sub);
154
+ }
155
+ if (!READ_ONLY_COMMANDS.has(head))
156
+ return false;
157
+ // `find … -delete` and `find … -exec` are not reads at all.
158
+ if (head === 'find' && words.some(w => w === '-delete' || w === '-exec' || w === '-execdir')) {
159
+ return false;
160
+ }
161
+ return true;
162
+ }
106
163
  /**
107
164
  * What should happen to one tool call: run it, ask, or refuse.
108
165
  *
@@ -113,6 +170,17 @@ export function decide(mode, tool, argsJson, rules) {
113
170
  const base = modeSpec(mode).policy[toolRisk(tool)];
114
171
  if (base !== 'ask')
115
172
  return base;
173
+ // A command that cannot change anything is not worth a question. Note this is reached only
174
+ // when the mode says "ask" — plan mode's "deny" is decided above and stays denied.
175
+ if (tool === 'execute_command') {
176
+ let command = '';
177
+ try {
178
+ command = String(JSON.parse(argsJson).command ?? '');
179
+ }
180
+ catch { /* ask */ }
181
+ if (command && isReadOnlyCommand(command))
182
+ return 'allow';
183
+ }
116
184
  return rules.some(r => ruleMatches(r, tool, argsJson)) ? 'allow' : 'ask';
117
185
  }
118
186
  function rulesFile(cwd) {
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
package/dist/plan.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The list of steps a run is working through, kept where the model can see it every turn.
3
+ *
4
+ * The failure this exists for: asked to build a Stokvel platform, a run listed directories, read
5
+ * a file, narrated what it would do next, listed the same directories again, and eventually
6
+ * halted having built nothing. Nothing was holding the shape of the job. Each turn the model saw
7
+ * a transcript and had to reconstruct what it was doing from it, and by the time the transcript
8
+ * was long it reconstructed something different every time.
9
+ *
10
+ * A plan makes that state explicit rather than inferred. It is written by the model, restated to
11
+ * it on every turn, and shown to the person watching — who can then see the agent forget, which
12
+ * is the difference between "it is stuck" and "it says step 4 of 7 and is on step 4".
13
+ */
14
+ export type StepState = 'todo' | 'doing' | 'done' | 'blocked';
15
+ export interface PlanStep {
16
+ text: string;
17
+ state: StepState;
18
+ /** Why it is blocked, when it is. */
19
+ note?: string;
20
+ }
21
+ export interface Plan {
22
+ steps: PlanStep[];
23
+ /** When the plan was last written, for showing staleness in a long session. */
24
+ updatedAt: number;
25
+ }
26
+ export declare const EMPTY_PLAN: Plan;
27
+ /** At most this many steps. A plan nobody can hold in their head is a transcript with bullets. */
28
+ export declare const MAX_STEPS = 20;
29
+ /**
30
+ * A plan from whatever shape the model sent.
31
+ *
32
+ * Deliberately forgiving. A model that writes `{"steps": ["a", "b"]}` has expressed a perfectly
33
+ * good plan and should not be argued with about the schema; rejecting it teaches it to stop using
34
+ * the tool, and the tool only helps if it is used.
35
+ */
36
+ export declare function parsePlan(input: unknown, now: number): Plan | string;
37
+ /**
38
+ * The plan as the model is reminded of it, at the top of every turn.
39
+ *
40
+ * Written as instruction rather than decoration: the point is that the next action follows from
41
+ * the plan, and that a step which is finished gets marked so rather than silently redone.
42
+ */
43
+ export declare function planReminder(plan: Plan): string;
44
+ /** One line for a status bar: how far along, and what is being done now. */
45
+ export declare function planSummary(plan: Plan): string;
46
+ /** What the model is told after it writes a plan, so the next step is unambiguous. */
47
+ export declare function planAck(plan: Plan): string;
48
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,IAAkC,CAAC;AAE5D,kGAAkG;AAClG,eAAO,MAAM,SAAS,KAAK,CAAC;AAc5B;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CA0BpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAe/C;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO9C;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO1C"}
package/dist/plan.js ADDED
@@ -0,0 +1,108 @@
1
+ /**
2
+ * The list of steps a run is working through, kept where the model can see it every turn.
3
+ *
4
+ * The failure this exists for: asked to build a Stokvel platform, a run listed directories, read
5
+ * a file, narrated what it would do next, listed the same directories again, and eventually
6
+ * halted having built nothing. Nothing was holding the shape of the job. Each turn the model saw
7
+ * a transcript and had to reconstruct what it was doing from it, and by the time the transcript
8
+ * was long it reconstructed something different every time.
9
+ *
10
+ * A plan makes that state explicit rather than inferred. It is written by the model, restated to
11
+ * it on every turn, and shown to the person watching — who can then see the agent forget, which
12
+ * is the difference between "it is stuck" and "it says step 4 of 7 and is on step 4".
13
+ */
14
+ export const EMPTY_PLAN = { steps: [], updatedAt: 0 };
15
+ /** At most this many steps. A plan nobody can hold in their head is a transcript with bullets. */
16
+ export const MAX_STEPS = 20;
17
+ const STATES = ['todo', 'doing', 'done', 'blocked'];
18
+ function coerceState(value) {
19
+ const text = String(value ?? '').toLowerCase();
20
+ if (STATES.includes(text))
21
+ return text;
22
+ // in_progress, in-progress, active, wip — all mean the same thing to whoever wrote them.
23
+ if (/progress|active|current|wip|working/.test(text))
24
+ return 'doing';
25
+ if (/complete|finish|done/.test(text))
26
+ return 'done';
27
+ if (/block|stuck|wait/.test(text))
28
+ return 'blocked';
29
+ return 'todo';
30
+ }
31
+ /**
32
+ * A plan from whatever shape the model sent.
33
+ *
34
+ * Deliberately forgiving. A model that writes `{"steps": ["a", "b"]}` has expressed a perfectly
35
+ * good plan and should not be argued with about the schema; rejecting it teaches it to stop using
36
+ * the tool, and the tool only helps if it is used.
37
+ */
38
+ export function parsePlan(input, now) {
39
+ const raw = input?.steps ?? input;
40
+ if (!Array.isArray(raw)) {
41
+ return 'ERROR: plan needs a "steps" array, e.g. ' +
42
+ '{"steps":[{"text":"design the ledger schema","state":"doing"}]}.';
43
+ }
44
+ if (raw.length === 0)
45
+ return 'ERROR: a plan with no steps says nothing. Give at least one step.';
46
+ const steps = [];
47
+ for (const entry of raw.slice(0, MAX_STEPS)) {
48
+ if (typeof entry === 'string') {
49
+ if (entry.trim())
50
+ steps.push({ text: entry.trim(), state: 'todo' });
51
+ continue;
52
+ }
53
+ const obj = entry;
54
+ const text = String(obj.text ?? obj.step ?? obj.title ?? '').trim();
55
+ if (!text)
56
+ continue;
57
+ const note = obj.note === undefined ? undefined : String(obj.note).trim();
58
+ steps.push({
59
+ text: text.slice(0, 200),
60
+ state: coerceState(obj.state ?? obj.status),
61
+ ...(note ? { note: note.slice(0, 200) } : {}),
62
+ });
63
+ }
64
+ if (steps.length === 0)
65
+ return 'ERROR: none of those steps had any text in them.';
66
+ return { steps, updatedAt: now };
67
+ }
68
+ /**
69
+ * The plan as the model is reminded of it, at the top of every turn.
70
+ *
71
+ * Written as instruction rather than decoration: the point is that the next action follows from
72
+ * the plan, and that a step which is finished gets marked so rather than silently redone.
73
+ */
74
+ export function planReminder(plan) {
75
+ if (plan.steps.length === 0)
76
+ return '';
77
+ const done = plan.steps.filter(s => s.state === 'done').length;
78
+ const current = plan.steps.find(s => s.state === 'doing') ?? plan.steps.find(s => s.state === 'todo');
79
+ const lines = plan.steps.map((s, i) => {
80
+ const mark = s.state === 'done' ? 'x' : s.state === 'doing' ? '>' : s.state === 'blocked' ? '!' : ' ';
81
+ return ` [${mark}] ${i + 1}. ${s.text}${s.note ? ` — ${s.note}` : ''}`;
82
+ });
83
+ return `\n## Your plan (${done}/${plan.steps.length} done)\n` +
84
+ lines.join('\n') +
85
+ (current ? `\n\nCurrent step: ${current.text}` : '\n\nEvery step is done or blocked.') +
86
+ `\nWork the current step. Call \`plan\` again to mark it done and move on, or to change the ` +
87
+ `plan if what you have learned makes it wrong. Do not re-do a step already marked done.\n`;
88
+ }
89
+ /** One line for a status bar: how far along, and what is being done now. */
90
+ export function planSummary(plan) {
91
+ if (plan.steps.length === 0)
92
+ return '';
93
+ const done = plan.steps.filter(s => s.state === 'done').length;
94
+ const current = plan.steps.find(s => s.state === 'doing');
95
+ const blocked = plan.steps.filter(s => s.state === 'blocked').length;
96
+ const suffix = blocked > 0 ? ` ${blocked} blocked` : '';
97
+ return `${done}/${plan.steps.length}${current ? ` ${current.text.slice(0, 48)}` : ''}${suffix}`;
98
+ }
99
+ /** What the model is told after it writes a plan, so the next step is unambiguous. */
100
+ export function planAck(plan) {
101
+ const done = plan.steps.filter(s => s.state === 'done').length;
102
+ const current = plan.steps.find(s => s.state === 'doing') ?? plan.steps.find(s => s.state === 'todo');
103
+ return current
104
+ ? `Plan recorded: ${plan.steps.length} steps, ${done} done. Now do this step: ${current.text}`
105
+ : `Plan recorded: all ${plan.steps.length} steps are done or blocked. ` +
106
+ `If the task is finished, say so and stop.`;
107
+ }
108
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
package/dist/tools.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  import type { ToolDefinition, ReadFilesArgs, WriteFileArgs, ApplyDiffArgs, ExecuteCommandArgs, ListDirArgs, GlobSearchArgs, GrepSearchArgs, MoveFileArgs, DeleteFileArgs, SearchReplaceArgs, FetchUrlArgs, RememberArgs, WebSearchArgs } from './types.js';
2
2
  export declare const TOOL_DEFINITIONS: ToolDefinition[];
3
+ /**
4
+ * Lines returned for one file unless a window is asked for.
5
+ *
6
+ * There was no cap at all: a five thousand line file went whole into the context window and
7
+ * crowded out everything the run had learned before it. What follows is a model that has read a
8
+ * great deal and remembers almost none of it — which is most of what looks like an agent losing
9
+ * the thread.
10
+ */
11
+ export declare const MAX_READ_LINES = 800;
3
12
  export declare function readFiles(args: ReadFilesArgs, cwd: string): Promise<string>;
4
13
  export declare function writeFile(args: WriteFileArgs, cwd: string, requireApproval: boolean): Promise<string>;
5
14
  export declare function applyDiff(args: ApplyDiffArgs, cwd: string, requireApproval: boolean): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,gBAAgB,EAAE,cAAc,EA6Q5C,CAAC;AAIF,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBjF;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,QAAc,CAAC;AAS1C,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAO9F;AAED,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAGD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAyB,EACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAWpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,GAAE,MAAyB,EACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAIR;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,EACxB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,MAAM,CAAC,CAmFjB;AA+CD,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C7E;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBnF;AAgBD,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4CnF;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB/E;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAcD,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAmBD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BlE;AAwCD,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBpE;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcjE;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa/E;AAKD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBzD,CAAC;AAEF,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAG1F;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAoBnF;AA+BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBxE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -10,7 +10,9 @@ import { GIT_TOOL_DEFINITIONS, dispatchGitTool } from './git-tools.js';
10
10
  export const TOOL_DEFINITIONS = [
11
11
  {
12
12
  name: 'read_files',
13
- description: 'Read one or more files concurrently. Returns content with line numbers. Use for any file inspection.',
13
+ description: 'Read one or more files concurrently. Returns content with line numbers. ' +
14
+ 'Long files come back as the first 800 lines with the rest offered by offset — page only ' +
15
+ 'if you must; grep_search is usually the better way to find something in a large file.',
14
16
  parameters: {
15
17
  type: 'object',
16
18
  properties: {
@@ -19,6 +21,14 @@ export const TOOL_DEFINITIONS = [
19
21
  items: { type: 'string' },
20
22
  description: 'File paths to read (absolute or relative to cwd)',
21
23
  },
24
+ offset: {
25
+ type: 'number',
26
+ description: 'First line to return, zero-based. For paging through a long file.',
27
+ },
28
+ limit: {
29
+ type: 'number',
30
+ description: 'How many lines to return from offset. Defaults to 800.',
31
+ },
22
32
  },
23
33
  required: ['paths'],
24
34
  },
@@ -198,6 +208,36 @@ export const TOOL_DEFINITIONS = [
198
208
  required: ['url'],
199
209
  },
200
210
  },
211
+ {
212
+ name: 'plan',
213
+ description: 'Record or update the list of steps you are working through. Call it once at the start of ' +
214
+ 'any task with more than one step, and again whenever a step is finished, blocked, or the ' +
215
+ 'plan turns out to be wrong. The plan is restated to you every turn, so it is how you keep ' +
216
+ 'track of a long job instead of re-deriving it from the transcript.',
217
+ parameters: {
218
+ type: 'object',
219
+ properties: {
220
+ steps: {
221
+ type: 'array',
222
+ description: 'The full list of steps, in order. Send the whole list every time, not a delta.',
223
+ items: {
224
+ type: 'object',
225
+ properties: {
226
+ text: { type: 'string', description: 'What the step is' },
227
+ state: {
228
+ type: 'string',
229
+ enum: ['todo', 'doing', 'done', 'blocked'],
230
+ description: 'Exactly one step should be "doing" at a time',
231
+ },
232
+ note: { type: 'string', description: 'Why it is blocked, if it is' },
233
+ },
234
+ required: ['text'],
235
+ },
236
+ },
237
+ },
238
+ required: ['steps'],
239
+ },
240
+ },
201
241
  {
202
242
  name: 'remember',
203
243
  description: 'Persist a durable fact about this project to .koneck/MEMORY.md, where every future session ' +
@@ -266,20 +306,53 @@ export const TOOL_DEFINITIONS = [
266
306
  ...GIT_TOOL_DEFINITIONS,
267
307
  ];
268
308
  // ─── Tool handlers ────────────────────────────────────────────────────────────
309
+ /**
310
+ * Lines returned for one file unless a window is asked for.
311
+ *
312
+ * There was no cap at all: a five thousand line file went whole into the context window and
313
+ * crowded out everything the run had learned before it. What follows is a model that has read a
314
+ * great deal and remembers almost none of it — which is most of what looks like an agent losing
315
+ * the thread.
316
+ */
317
+ export const MAX_READ_LINES = 800;
318
+ /** One file's contents, as a window with its position said out loud. */
319
+ function renderWindow(filePath, content, offset, limit) {
320
+ const lines = content.split('\n');
321
+ const total = lines.length;
322
+ const from = Math.max(0, Math.min(offset, Math.max(0, total - 1)));
323
+ const to = Math.min(total, from + limit);
324
+ const body = lines
325
+ .slice(from, to)
326
+ .map((line, i) => `${String(from + i + 1).padStart(5)} │ ${line}`)
327
+ .join('\n');
328
+ const shownAll = from === 0 && to >= total;
329
+ const header = shownAll
330
+ ? `=== ${filePath} (${total} lines) ===`
331
+ : `=== ${filePath} (lines ${from + 1}-${to} of ${total}) ===`;
332
+ // Truncation is stated, never silent. A model that believes it has seen a whole file decides
333
+ // things about the part it never read.
334
+ const footer = shownAll
335
+ ? ''
336
+ : `\n… ${total - to} lines below. Read them with ` +
337
+ `{"paths":["${filePath}"],"offset":${to},"limit":${limit}} — or use grep_search to find ` +
338
+ `what you need instead of paging through it.`;
339
+ return header + '\n' + body + footer;
340
+ }
269
341
  export async function readFiles(args, cwd) {
270
342
  // Said plainly rather than thrown. A missing field used to surface as "Cannot read properties
271
343
  // of undefined (reading 'map')", which tells the model nothing it can act on.
272
344
  if (!Array.isArray(args.paths) || args.paths.length === 0) {
273
345
  return 'ERROR: read_files needs a "paths" array, e.g. {"paths": ["src/App.jsx"]}.';
274
346
  }
347
+ const offset = Math.max(0, Math.floor(Number(args.offset ?? 0)) || 0);
348
+ const requested = Math.floor(Number(args.limit ?? MAX_READ_LINES));
349
+ const limit = Number.isFinite(requested) && requested > 0
350
+ ? Math.min(requested, MAX_READ_LINES * 4) // an explicit ask can go further, not forever
351
+ : MAX_READ_LINES;
275
352
  const results = await Promise.allSettled(args.paths.map(async (filePath) => {
276
353
  const abs = path.resolve(cwd, filePath);
277
354
  const content = await fs.readFile(abs, 'utf-8');
278
- const numbered = content
279
- .split('\n')
280
- .map((line, i) => `${String(i + 1).padStart(5)} │ ${line}`)
281
- .join('\n');
282
- return `=== ${filePath} (${content.split('\n').length} lines) ===\n${numbered}`;
355
+ return renderWindow(filePath, content, offset, limit);
283
356
  }));
284
357
  return results
285
358
  .map((r, i) => r.status === 'fulfilled'