@kenkaiiii/ggcoder 5.49.0 → 5.49.2

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 (50) hide show
  1. package/dist/core/agent-session-verification-flow.test.d.ts +2 -0
  2. package/dist/core/agent-session-verification-flow.test.d.ts.map +1 -0
  3. package/dist/core/agent-session-verification-flow.test.js +125 -0
  4. package/dist/core/agent-session-verification-flow.test.js.map +1 -0
  5. package/dist/core/agent-session-verification-gate.test.js +6 -4
  6. package/dist/core/agent-session-verification-gate.test.js.map +1 -1
  7. package/dist/core/agent-session.d.ts +9 -2
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +33 -5
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/event-bus.d.ts +6 -6
  12. package/dist/core/event-bus.d.ts.map +1 -1
  13. package/dist/core/event-bus.js.map +1 -1
  14. package/dist/core/process-manager-notifications.test.js +31 -13
  15. package/dist/core/process-manager-notifications.test.js.map +1 -1
  16. package/dist/core/process-manager.d.ts +11 -0
  17. package/dist/core/process-manager.d.ts.map +1 -1
  18. package/dist/core/process-manager.js +1 -1
  19. package/dist/core/process-manager.js.map +1 -1
  20. package/dist/core/sandbox.d.ts.map +1 -1
  21. package/dist/core/sandbox.js +66 -1
  22. package/dist/core/sandbox.js.map +1 -1
  23. package/dist/core/sandbox.test.js +64 -0
  24. package/dist/core/sandbox.test.js.map +1 -1
  25. package/dist/core/verification-gate.d.ts +22 -12
  26. package/dist/core/verification-gate.d.ts.map +1 -1
  27. package/dist/core/verification-gate.js +126 -27
  28. package/dist/core/verification-gate.js.map +1 -1
  29. package/dist/core/verification-gate.test.js +40 -4
  30. package/dist/core/verification-gate.test.js.map +1 -1
  31. package/dist/tools/path-utils.d.ts +28 -1
  32. package/dist/tools/path-utils.d.ts.map +1 -1
  33. package/dist/tools/path-utils.js +44 -2
  34. package/dist/tools/path-utils.js.map +1 -1
  35. package/dist/tools/path-utils.test.js +57 -1
  36. package/dist/tools/path-utils.test.js.map +1 -1
  37. package/dist/tools/web-fetch.d.ts +7 -0
  38. package/dist/tools/web-fetch.d.ts.map +1 -1
  39. package/dist/tools/web-fetch.js +284 -20
  40. package/dist/tools/web-fetch.js.map +1 -1
  41. package/dist/tools/web-fetch.test.js +137 -0
  42. package/dist/tools/web-fetch.test.js.map +1 -1
  43. package/dist/ui/App.d.ts.map +1 -1
  44. package/dist/ui/App.js +15 -4
  45. package/dist/ui/App.js.map +1 -1
  46. package/dist/ui/app-items.d.ts +3 -0
  47. package/dist/ui/app-items.d.ts.map +1 -1
  48. package/dist/ui/app-items.js +3 -0
  49. package/dist/ui/app-items.js.map +1 -1
  50. package/package.json +4 -4
@@ -1,4 +1,4 @@
1
- /** Follow-ups per run before the gate escalates to "state what went unverified". */
1
+ /** Follow-ups per run. After this the gate is silent for the rest of the run. */
2
2
  export const MAX_VERIFICATION_INJECTIONS = 1;
3
3
  /** Words that may precede the real command without changing its shape. */
4
4
  const SHELL_WRAPPERS = new Set([
@@ -47,6 +47,10 @@ const RUNNERS = new Set([
47
47
  "mypy",
48
48
  "pylint",
49
49
  ]);
50
+ /** Shells whose `-c <script>` operand is itself a command to classify. */
51
+ const SHELL_INTERPRETERS = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
52
+ /** Nested `sh -c` unwraps allowed before the classifier gives up. */
53
+ const MAX_SHELL_DEPTH = 3;
50
54
  /** A non-flag word after the runner that makes the command a verification. */
51
55
  const VERIFY_KEYWORDS = [
52
56
  "test",
@@ -76,14 +80,105 @@ function isVerifyWord(word) {
76
80
  // Exact keyword, or a script name built on one (npm run test:unit).
77
81
  return VERIFY_KEYWORDS.some((keyword) => word === keyword || word.startsWith(`${keyword}:`));
78
82
  }
83
+ /**
84
+ * Split a command on shell control operators (`&&`, `||`, `;`, `|`, newline),
85
+ * ignoring operators inside quotes, and strip subshell/group punctuation from
86
+ * each piece. `cd pkg && npm test` must classify on its `npm test` half — the
87
+ * whole-string read saw `cd` as the runner and left the gate owed forever.
88
+ */
89
+ function splitCommandSegments(command) {
90
+ const segments = [];
91
+ let current = "";
92
+ let quote = null;
93
+ for (let i = 0; i < command.length; i++) {
94
+ const char = command[i];
95
+ if (quote) {
96
+ current += char;
97
+ if (char === "\\" && quote === '"')
98
+ current += command[++i] ?? "";
99
+ else if (char === quote)
100
+ quote = null;
101
+ continue;
102
+ }
103
+ if (char === "'" || char === '"') {
104
+ quote = char;
105
+ current += char;
106
+ continue;
107
+ }
108
+ if (char === "\\") {
109
+ current += char + (command[++i] ?? "");
110
+ continue;
111
+ }
112
+ // Bare `&` is deliberately not an operator: it would split `2>&1`.
113
+ const operator = ["&&", "||", ";", "|", "\n"].find((op) => command.startsWith(op, i));
114
+ if (operator) {
115
+ segments.push(current);
116
+ current = "";
117
+ i += operator.length - 1;
118
+ continue;
119
+ }
120
+ current += char;
121
+ }
122
+ segments.push(current);
123
+ return segments
124
+ .map((segment) => segment
125
+ .trim()
126
+ .replace(/^[({!\s]+/, "")
127
+ .replace(/[)}\s]+$/, ""))
128
+ .filter((segment) => segment.length > 0);
129
+ }
130
+ /** Split a segment into words, honouring quotes and dropping the quote marks. */
131
+ function tokenize(segment) {
132
+ const words = [];
133
+ let current = "";
134
+ let quote = null;
135
+ let started = false;
136
+ for (let i = 0; i < segment.length; i++) {
137
+ const char = segment[i];
138
+ if (quote) {
139
+ if (char === "\\" && quote === '"')
140
+ current += segment[++i] ?? "";
141
+ else if (char === quote)
142
+ quote = null;
143
+ else
144
+ current += char;
145
+ continue;
146
+ }
147
+ if (char === "'" || char === '"') {
148
+ quote = char;
149
+ started = true;
150
+ continue;
151
+ }
152
+ if (/\s/.test(char)) {
153
+ if (started || current.length > 0)
154
+ words.push(current);
155
+ current = "";
156
+ started = false;
157
+ continue;
158
+ }
159
+ if (char === "\\") {
160
+ current += segment[++i] ?? "";
161
+ continue;
162
+ }
163
+ current += char;
164
+ }
165
+ if (started || current.length > 0)
166
+ words.push(current);
167
+ return words;
168
+ }
79
169
  /**
80
170
  * True when the command looks like a test/typecheck/lint/build invocation:
81
- * wrappers stripped, a known runner leading, and a verification keyword among
82
- * its operands. Deliberately strict — `grep test x`, `git commit -m test` and
83
- * `./run_tests.sh` all read as NOT verification.
171
+ * compound segments considered independently, wrappers stripped, a known runner
172
+ * leading, and a verification keyword among its operands. Deliberately strict —
173
+ * `grep test x`, `git commit -m test` and `./run_tests.sh` all read as NOT
174
+ * verification.
84
175
  */
85
176
  export function isVerificationCommand(command) {
86
- const words = command.trim().split(/\s+/);
177
+ return splitCommandSegments(command).some((segment) => isVerificationSegment(segment, 0));
178
+ }
179
+ /** Classify one operator-free segment. `depth` bounds `sh -c` unwrapping. */
180
+ function isVerificationSegment(segment, depth) {
181
+ const words = tokenize(segment);
87
182
  let i = 0;
88
183
  while (i < words.length) {
89
184
  const word = words[i];
@@ -99,6 +194,16 @@ export function isVerificationCommand(command) {
99
194
  break;
100
195
  }
101
196
  const runner = words[i] ?? "";
197
+ // `sh -c "cd pkg && npm test"` — classify the script the shell will run.
198
+ if (SHELL_INTERPRETERS.has(runner)) {
199
+ if (depth >= MAX_SHELL_DEPTH)
200
+ return false;
201
+ const flagIndex = words.indexOf("-c", i + 1);
202
+ const script = flagIndex === -1 ? undefined : words[flagIndex + 1];
203
+ if (!script)
204
+ return false;
205
+ return splitCommandSegments(script).some((inner) => isVerificationSegment(inner, depth + 1));
206
+ }
102
207
  if (!RUNNERS.has(runner))
103
208
  return false;
104
209
  if (isVerifyWord(runner))
@@ -122,17 +227,9 @@ export function buildVerificationFollowUpMessage(files) {
122
227
  "command has completed since the last edit:\n" +
123
228
  files.map((filePath) => `- ${filePath}`).join("\n") +
124
229
  "\nRun the project's verification now (its test command, or the closest equivalent) and " +
125
- "address any failures. Do not describe the change as tested or working without having run it.",
126
- };
127
- }
128
- export function buildVerificationEscalationMessage(files) {
129
- return {
130
- role: "user",
131
- provenance: { source: "runtime", kind: "completion_gate", visibility: "hidden" },
132
- content: `Verification is still outstanding after ${MAX_VERIFICATION_INJECTIONS} attempt(s); ` +
133
- "the gate will not prompt again. Give your final response now and state plainly which of " +
134
- "these changes went unverified and why, so the user can check them:\n" +
135
- files.map((filePath) => `- ${filePath}`).join("\n"),
230
+ "address any failures. Do not describe the change as tested or working without having run it. " +
231
+ "This is the only time you will be asked: if you cannot run it, say plainly in your final " +
232
+ "response which of these changes went unverified and why, so the user can check them.",
136
233
  };
137
234
  }
138
235
  /**
@@ -159,23 +256,25 @@ export class VerificationGate {
159
256
  isOwed() {
160
257
  return this.lastMutationSeq > this.lastVerificationSeq;
161
258
  }
259
+ /**
260
+ * Would a stop right now inject? Lets the session arm clients BEFORE the
261
+ * candidate final answer streams, so the draft the injection replaces is held
262
+ * rather than painted and then superseded.
263
+ */
264
+ willInject() {
265
+ return this.isOwed() && this.injections < MAX_VERIFICATION_INJECTIONS;
266
+ }
162
267
  /**
163
268
  * The blocking message for the pre-stop hook, or null when nothing is owed
164
- * or the injection budget is spent. First the demand (budget 1), then one
165
- * terminal escalation requiring an honest unverified statement, then silent.
269
+ * or the single injection is spent. Still-owed on a later stop is deliberately
270
+ * silent: the demand already told the model to disclose what went unverified,
271
+ * and one more injection only costs the user another restated final answer.
166
272
  */
167
273
  followUp() {
168
- if (!this.isOwed())
169
- return null;
170
- if (this.injections >= MAX_VERIFICATION_INJECTIONS + 1)
274
+ if (!this.willInject())
171
275
  return null;
172
276
  this.injections += 1;
173
- const files = [...this.mutatedFiles].sort();
174
- return [
175
- this.injections > MAX_VERIFICATION_INJECTIONS
176
- ? buildVerificationEscalationMessage(files)
177
- : buildVerificationFollowUpMessage(files),
178
- ];
277
+ return [buildVerificationFollowUpMessage([...this.mutatedFiles].sort())];
179
278
  }
180
279
  reset() {
181
280
  this.seq = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"verification-gate.js","sourceRoot":"","sources":["../../src/core/verification-gate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verification-gate.js","sourceRoot":"","sources":["../../src/core/verification-gate.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,20 @@ describe("isVerificationCommand", () => {
24
24
  ["gradle test", "gradle test"],
25
25
  ["dotnet test", "dotnet test"],
26
26
  ["deno task test", "deno task test"],
27
+ // Compound / chained shells: the classifier must look past the first word.
28
+ ["cd packages/app && npm test", "cd into a package then test"],
29
+ ["cd /tmp/proj && pnpm --filter web test", "cd then filtered workspace test"],
30
+ ["npm run typecheck && npm run lint && npm run test", "chained checks"],
31
+ ["npm run build; npm test", "semicolon-separated"],
32
+ ["npm run test 2>&1 | tee /tmp/out.log", "piped into tee"],
33
+ ["npm test 2>&1 | tail -50", "piped into tail"],
34
+ ["npm run lint || npm test", "or-chained"],
35
+ ["(cd api && cargo test)", "subshell"],
36
+ ["git add -A && npm test", "non-verification first, verification second"],
37
+ ['sh -c "npm test"', "sh -c wrapper"],
38
+ ['bash -c "cd pkg && npm test"', "bash -c wrapping a chain"],
39
+ ["sh -c 'pytest tests/'", "sh -c with single quotes"],
40
+ ["cd pkg\nnpm test", "newline-separated"],
27
41
  ];
28
42
  const no = [
29
43
  ["git commit -m fix test", "commit message mentioning test"],
@@ -36,6 +50,14 @@ describe("isVerificationCommand", () => {
36
50
  ["go run main.go", "go run"],
37
51
  ["python train.py", "python script"],
38
52
  ["echo running tests soon", "echo mentioning tests"],
53
+ // Compound negatives: splitting must not invent verification.
54
+ ["cd packages/app && npm install", "cd then install"],
55
+ ["git add -A && git commit -m 'add test'", "chained git with test in the message"],
56
+ ["cd src && ./run_tests.sh", "cd then direct script"],
57
+ ['echo "npm test" > notes.txt', "verification text inside a quoted argument"],
58
+ ['sh -c "npm run dev"', "sh -c wrapping a dev server"],
59
+ ["bash scripts/test.sh", "bash running a script file, not -c"],
60
+ ["cat out.log | grep test", "piped grep"],
39
61
  ];
40
62
  it.each(yes)("classifies %s as verification (%s)", (command) => {
41
63
  expect(isVerificationCommand(command)).toBe(true);
@@ -78,17 +100,31 @@ describe("VerificationGate", () => {
78
100
  expect(gate.isOwed()).toBe(false);
79
101
  expect(gate.followUp()).toBeNull();
80
102
  });
81
- it("demands once, escalates once, then goes silent", () => {
103
+ it("demands once, then goes silent on every later stop while still owed", () => {
82
104
  const gate = new VerificationGate();
83
105
  gate.recordMutation("a.ts");
84
106
  const demand = gate.followUp();
85
107
  expect(String(demand[0].content)).toContain("Run the project's verification");
86
- // Model stopped again without verifying.
87
- const escalation = gate.followUp();
88
- expect(String(escalation[0].content)).toContain("unverified");
108
+ // Model stopped again without verifying: still owed, but no second turn is
109
+ // spent on it — each extra injection costs the user another final answer.
110
+ expect(gate.isOwed()).toBe(true);
111
+ expect(gate.followUp()).toBeNull();
89
112
  expect(gate.followUp()).toBeNull();
90
113
  expect(MAX_VERIFICATION_INJECTIONS).toBe(1);
91
114
  });
115
+ it("carries the unverified-disclosure fallback in its single demand", () => {
116
+ const gate = new VerificationGate();
117
+ gate.recordMutation("a.ts");
118
+ // The dropped escalation turn existed only to ask for this; the demand now
119
+ // asks for it up front, so the honesty requirement survives without a turn.
120
+ expect(String(gate.followUp()[0].content)).toContain("unverified");
121
+ });
122
+ it("spends no injection when nothing is owed, so a later mutation still gets its demand", () => {
123
+ const gate = new VerificationGate();
124
+ expect(gate.followUp()).toBeNull();
125
+ gate.recordMutation("a.ts");
126
+ expect(String(gate.followUp()[0].content)).toContain("Run the project's verification");
127
+ });
92
128
  it("a later mutation re-arms an already-satisfied gate after a fresh budget reset", () => {
93
129
  const gate = new VerificationGate();
94
130
  gate.recordMutation("a.ts");
@@ -1 +1 @@
1
- {"version":3,"file":"verification-gate.test.js","sourceRoot":"","sources":["../../src/core/verification-gate.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verification-gate.test.js","sourceRoot":"","sources":["../../src/core/verification-gate.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,31 @@
1
- export declare function resolvePath(cwd: string, filePath: string): string;
1
+ export interface ResolvePathOpts {
2
+ /** Injected for testability; defaults to process.platform. */
3
+ platform?: NodeJS.Platform;
4
+ }
5
+ /**
6
+ * MSYS drive path → native Windows path, e.g. `/c/Users/x` → `C:\Users\x`.
7
+ *
8
+ * On Windows our bash tool runs Git Bash (see core/shell.ts), an MSYS2
9
+ * environment, so command output is full of `/c/...`, `//c/...` and
10
+ * `/cygdrive/c/...` paths. The model reads those out of bash output and hands
11
+ * them straight back to the file tools; `path.resolve` then turns `/c/Users/x`
12
+ * into `C:\c\Users\x`, which never exists, so every such call fails and the
13
+ * agent burns turns guessing.
14
+ *
15
+ * Deliberate non-goals:
16
+ * - Non-Windows platforms are left completely alone: `/c/foo` is a perfectly
17
+ * legitimate POSIX path on macOS/Linux and rewriting it would be a
18
+ * data-corrupting regression. Hence the strict platform gate.
19
+ * - MSYS virtual mounts (`/tmp`, `/usr`, `/home`, `/bin`) are NOT translated.
20
+ * They live under the Git-Bash install root, which we cannot determine
21
+ * cheaply or deterministically here, and a wrong guess silently reads or
22
+ * writes the wrong file — far worse than a clear ENOENT.
23
+ * - We do NOT shell out to `cygpath`: this sits on the hot path of every
24
+ * single file tool call, so it would cost a process spawn per call, and
25
+ * `cygpath` is not always on PATH anyway. Pure string manipulation only.
26
+ */
27
+ export declare function msysToWindowsPath(filePath: string, opts?: ResolvePathOpts): string;
28
+ export declare function resolvePath(cwd: string, filePath: string, opts?: ResolvePathOpts): string;
2
29
  /**
3
30
  * Check if a path is a symlink. Used by file tools to prevent symlink-based
4
31
  * attacks that could read/write sensitive files outside the working directory.
@@ -1 +1 @@
1
- {"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../../src/tools/path-utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../../src/tools/path-utils.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,MAAM,CAiBtF;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,MAAM,CAK7F;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -1,11 +1,53 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import os from "node:os";
4
- export function resolvePath(cwd, filePath) {
4
+ /**
5
+ * MSYS drive path → native Windows path, e.g. `/c/Users/x` → `C:\Users\x`.
6
+ *
7
+ * On Windows our bash tool runs Git Bash (see core/shell.ts), an MSYS2
8
+ * environment, so command output is full of `/c/...`, `//c/...` and
9
+ * `/cygdrive/c/...` paths. The model reads those out of bash output and hands
10
+ * them straight back to the file tools; `path.resolve` then turns `/c/Users/x`
11
+ * into `C:\c\Users\x`, which never exists, so every such call fails and the
12
+ * agent burns turns guessing.
13
+ *
14
+ * Deliberate non-goals:
15
+ * - Non-Windows platforms are left completely alone: `/c/foo` is a perfectly
16
+ * legitimate POSIX path on macOS/Linux and rewriting it would be a
17
+ * data-corrupting regression. Hence the strict platform gate.
18
+ * - MSYS virtual mounts (`/tmp`, `/usr`, `/home`, `/bin`) are NOT translated.
19
+ * They live under the Git-Bash install root, which we cannot determine
20
+ * cheaply or deterministically here, and a wrong guess silently reads or
21
+ * writes the wrong file — far worse than a clear ENOENT.
22
+ * - We do NOT shell out to `cygpath`: this sits on the hot path of every
23
+ * single file tool call, so it would cost a process spawn per call, and
24
+ * `cygpath` is not always on PATH anyway. Pure string manipulation only.
25
+ */
26
+ export function msysToWindowsPath(filePath, opts = {}) {
27
+ const platform = opts.platform ?? process.platform;
28
+ if (platform !== "win32")
29
+ return filePath;
30
+ // `//c/x` (MSYS's own drive spelling) and `/cygdrive/c/x` mean exactly the
31
+ // same as `/c/x`. The drive must be a single letter and must be followed by a
32
+ // separator or end-of-string, so `/config` and `/cygdrive` stay untouched.
33
+ //
34
+ // `//c/x` is formally ambiguous with a UNC path whose HOST is one character.
35
+ // Single-letter hostnames don't exist in practice and Git Bash really does
36
+ // emit this form for drives, so translating is the right bet.
37
+ const match = /^(?:\/\/|\/cygdrive\/|\/)([A-Za-z])(?:\/(.*))?$/.exec(filePath);
38
+ if (!match)
39
+ return filePath;
40
+ const drive = match[1].toUpperCase();
41
+ const rest = match[2] ?? "";
42
+ // Always keep the trailing separator: bare `C:` is drive-RELATIVE on Windows
43
+ // (the cwd of that drive), which is not what `/c` means.
44
+ return `${drive}:\\${rest.replaceAll("/", "\\")}`;
45
+ }
46
+ export function resolvePath(cwd, filePath, opts = {}) {
5
47
  if (filePath.startsWith("~")) {
6
48
  filePath = path.join(os.homedir(), filePath.slice(1));
7
49
  }
8
- return path.resolve(cwd, filePath);
50
+ return path.resolve(cwd, msysToWindowsPath(filePath, opts));
9
51
  }
10
52
  /**
11
53
  * Check if a path is a symlink. Used by file tools to prevent symlink-based
@@ -1 +1 @@
1
- {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/tools/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,QAAgB;IACvD,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB;IAClD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uFAAuF;QACvF,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAAE,MAAM,GAAG,CAAC;IACtF,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB;IAC9C,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/tools/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAOzB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,OAAwB,EAAE;IAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC1C,2EAA2E;IAC3E,8EAA8E;IAC9E,2EAA2E;IAC3E,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,KAAK,GAAG,iDAAiD,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/E,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,yDAAyD;IACzD,OAAO,GAAG,KAAK,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,QAAgB,EAAE,OAAwB,EAAE;IACnF,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB;IAClD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uFAAuF;QACvF,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAAE,MAAM,GAAG,CAAC;IACtF,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB;IAC9C,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC"}
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import os from "node:os";
5
- import { resolvePath, rejectSymlink } from "./path-utils.js";
5
+ import { resolvePath, rejectSymlink, msysToWindowsPath } from "./path-utils.js";
6
6
  describe("resolvePath", () => {
7
7
  it("resolves relative path from cwd", () => {
8
8
  const result = resolvePath("/home/user/project", "src/index.ts");
@@ -26,6 +26,62 @@ describe("resolvePath", () => {
26
26
  expect(result).toBe(path.join(os.homedir(), "documents/file.txt"));
27
27
  });
28
28
  });
29
+ describe("msysToWindowsPath", () => {
30
+ const win = { platform: "win32" };
31
+ it("translates /c/... to a native drive path", () => {
32
+ expect(msysToWindowsPath("/c/Users/ken/proj/src/a.ts", win)).toBe("C:\\Users\\ken\\proj\\src\\a.ts");
33
+ expect(msysToWindowsPath("/d/repo", win)).toBe("D:\\repo");
34
+ });
35
+ it("uppercases the drive letter regardless of input case", () => {
36
+ expect(msysToWindowsPath("/C/Users/ken", win)).toBe("C:\\Users\\ken");
37
+ });
38
+ it("translates the //c/ and /cygdrive/c/ spellings identically", () => {
39
+ expect(msysToWindowsPath("//c/Users/x", win)).toBe("C:\\Users\\x");
40
+ expect(msysToWindowsPath("/cygdrive/c/Users/x", win)).toBe("C:\\Users\\x");
41
+ });
42
+ it("maps a drive-only path to the drive ROOT, not the drive-relative cwd", () => {
43
+ expect(msysToWindowsPath("/c", win)).toBe("C:\\");
44
+ expect(msysToWindowsPath("/c/", win)).toBe("C:\\");
45
+ expect(msysToWindowsPath("/cygdrive/d", win)).toBe("D:\\");
46
+ });
47
+ it("leaves MSYS virtual mounts alone rather than guessing", () => {
48
+ expect(msysToWindowsPath("/tmp/x", win)).toBe("/tmp/x");
49
+ expect(msysToWindowsPath("/usr/bin/git", win)).toBe("/usr/bin/git");
50
+ expect(msysToWindowsPath("/home/ken", win)).toBe("/home/ken");
51
+ });
52
+ it("requires a single-letter segment terminated by / or end-of-string", () => {
53
+ expect(msysToWindowsPath("/config/app.json", win)).toBe("/config/app.json");
54
+ expect(msysToWindowsPath("/cygdrive", win)).toBe("/cygdrive");
55
+ });
56
+ it("leaves an already-native Windows path unchanged", () => {
57
+ expect(msysToWindowsPath("C:\\x", win)).toBe("C:\\x");
58
+ expect(msysToWindowsPath("C:/x", win)).toBe("C:/x");
59
+ });
60
+ it("leaves relative paths unchanged", () => {
61
+ expect(msysToWindowsPath("src/index.ts", win)).toBe("src/index.ts");
62
+ expect(msysToWindowsPath("./a.ts", win)).toBe("./a.ts");
63
+ expect(msysToWindowsPath("", win)).toBe("");
64
+ });
65
+ it("never translates on non-Windows platforms (/c/foo is a real POSIX path)", () => {
66
+ for (const platform of ["darwin", "linux"]) {
67
+ expect(msysToWindowsPath("/c/foo", { platform })).toBe("/c/foo");
68
+ expect(msysToWindowsPath("/cygdrive/c/foo", { platform })).toBe("/cygdrive/c/foo");
69
+ expect(msysToWindowsPath("//c/foo", { platform })).toBe("//c/foo");
70
+ }
71
+ });
72
+ });
73
+ describe("resolvePath with MSYS input", () => {
74
+ it("translates before resolving", () => {
75
+ // path.resolve is host-dependent, so compare against resolving the already
76
+ // translated form: without the MSYS step this would resolve `/c/Users/...`
77
+ // verbatim, which is a different string on every platform.
78
+ const result = resolvePath("D:\\proj", "/c/Users/ken/a.ts", { platform: "win32" });
79
+ expect(result).toBe(path.resolve("D:\\proj", "C:\\Users\\ken\\a.ts"));
80
+ });
81
+ it("leaves /c/foo as a POSIX path when not on Windows", () => {
82
+ expect(resolvePath("/home/user/project", "/c/foo", { platform: "linux" })).toBe(path.resolve("/c/foo"));
83
+ });
84
+ });
29
85
  describe("rejectSymlink", () => {
30
86
  let tmpDir;
31
87
  beforeEach(async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"path-utils.test.js","sourceRoot":"","sources":["../../src/tools/path-utils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,2EAA2E;QAC3E,2EAA2E;QAC3E,mEAAmE;QACnE,0CAA0C;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,MAAc,CAAC;IAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAClD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QACxD,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"path-utils.test.js","sourceRoot":"","sources":["../../src/tools/path-utils.test.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,11 @@ import { type GetNetworkPolicy } from "../core/network-guard.js";
7
7
  */
8
8
  export declare function isBlockedUrl(urlString: string): boolean;
9
9
  export declare function htmlToCleanText(html: string): string;
10
+ /** A hyperlink shown in an outline render as `anchor text [number]`. */
11
+ export interface OutlineLink {
12
+ number: number;
13
+ url: string;
14
+ }
10
15
  type LlmsCandidateKind = "llms" | "llms-full" | "llms-ctx" | "page-md";
11
16
  interface LlmsCandidate {
12
17
  url: string;
@@ -20,11 +25,13 @@ export declare function createWebFetchTool(getNetworkPolicy?: GetNetworkPolicy):
20
25
  declare const parameters: z.ZodObject<{
21
26
  url: z.ZodOptional<z.ZodString>;
22
27
  urls: z.ZodOptional<z.ZodArray<z.ZodString>>;
28
+ follow: z.ZodOptional<z.ZodNumber>;
23
29
  max_length: z.ZodOptional<z.ZodNumber>;
24
30
  format: z.ZodOptional<z.ZodEnum<{
25
31
  text: "text";
26
32
  html: "html";
27
33
  markdown: "markdown";
34
+ outline: "outline";
28
35
  }>>;
29
36
  prefer_llms_txt: z.ZodOptional<z.ZodBoolean>;
30
37
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAIlE,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA0CvD;AAmGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYpD;AAwBD,KAAK,iBAAiB,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvE,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8HD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,SAAqB,GAC5B,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAqLD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAuCnF;AA2ED,wBAAgB,kBAAkB,CAChC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,SAAS,CAAC,OAAO,UAAU,CAAC,CAuC9B;AA0BD,QAAA,MAAM,UAAU;;;;;;;;;;iBAoBZ,CAAC"}
1
+ {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAIlE,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA0CvD;AAmGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYpD;AAcD,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AA6MD,KAAK,iBAAiB,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvE,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkID,wBAAsB,eAAe,CACnC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,SAAqB,GAC5B,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAwLD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAuCnF;AA2HD,wBAAgB,kBAAkB,CAChC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,SAAS,CAAC,OAAO,UAAU,CAAC,CA8E9B;AA0BD,QAAA,MAAM,UAAU;;;;;;;;;;;;iBAyCb,CAAC"}