@prestyj/cli 5.32.0 → 5.32.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 (230) hide show
  1. package/README.md +3 -2
  2. package/assets/skills/task-list/SKILL.md +39 -0
  3. package/dist/app-sidecar/app-settings.js +11 -5
  4. package/dist/app-sidecar/app-settings.js.map +1 -1
  5. package/dist/app-sidecar/auth-routes.js +10 -3
  6. package/dist/app-sidecar/auth-routes.js.map +1 -1
  7. package/dist/app-sidecar/git-target.d.ts +15 -2
  8. package/dist/app-sidecar/git-target.js +24 -10
  9. package/dist/app-sidecar/git-target.js.map +1 -1
  10. package/dist/app-sidecar/goal-routes.js +8 -0
  11. package/dist/app-sidecar/goal-routes.js.map +1 -1
  12. package/dist/app-sidecar/history-routes.js +7 -0
  13. package/dist/app-sidecar/history-routes.js.map +1 -1
  14. package/dist/app-sidecar/history.d.ts +5 -0
  15. package/dist/app-sidecar/history.js.map +1 -1
  16. package/dist/app-sidecar/integration-routes.js +4 -0
  17. package/dist/app-sidecar/integration-routes.js.map +1 -1
  18. package/dist/app-sidecar/mcp-routes.js +1 -0
  19. package/dist/app-sidecar/mcp-routes.js.map +1 -1
  20. package/dist/app-sidecar/mcp-rows.d.ts +2 -0
  21. package/dist/app-sidecar/mcp-rows.js +4 -1
  22. package/dist/app-sidecar/mcp-rows.js.map +1 -1
  23. package/dist/app-sidecar/prompt-routes.js +67 -1
  24. package/dist/app-sidecar/prompt-routes.js.map +1 -1
  25. package/dist/app-sidecar/route-context.d.ts +2 -0
  26. package/dist/app-sidecar/run-control-routes.js +43 -3
  27. package/dist/app-sidecar/run-control-routes.js.map +1 -1
  28. package/dist/app-sidecar/session-routes.js +10 -0
  29. package/dist/app-sidecar/session-routes.js.map +1 -1
  30. package/dist/app-sidecar/task-routes.js +2 -0
  31. package/dist/app-sidecar/task-routes.js.map +1 -1
  32. package/dist/app-sidecar/trophy-manager.d.ts +15 -0
  33. package/dist/app-sidecar/trophy-manager.js +71 -0
  34. package/dist/app-sidecar/trophy-manager.js.map +1 -0
  35. package/dist/app-sidecar/workspace-routes.js +1 -0
  36. package/dist/app-sidecar/workspace-routes.js.map +1 -1
  37. package/dist/app-sidecar.js +157 -30
  38. package/dist/app-sidecar.js.map +1 -1
  39. package/dist/cli/auth.js +22 -1
  40. package/dist/cli/auth.js.map +1 -1
  41. package/dist/cli/mcp.js +6 -1
  42. package/dist/cli/mcp.js.map +1 -1
  43. package/dist/cli.js +13 -9
  44. package/dist/cli.js.map +1 -1
  45. package/dist/config.js +4 -2
  46. package/dist/config.js.map +1 -1
  47. package/dist/core/action-threats.d.ts +68 -0
  48. package/dist/core/action-threats.js +894 -0
  49. package/dist/core/action-threats.js.map +1 -0
  50. package/dist/core/agent-notifications.d.ts +18 -0
  51. package/dist/core/agent-notifications.js +35 -2
  52. package/dist/core/agent-notifications.js.map +1 -1
  53. package/dist/core/agent-session/verification-tracker.d.ts +21 -0
  54. package/dist/core/agent-session/verification-tracker.js +39 -1
  55. package/dist/core/agent-session/verification-tracker.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +168 -2
  57. package/dist/core/agent-session.js +486 -23
  58. package/dist/core/agent-session.js.map +1 -1
  59. package/dist/core/blocked-packages-file.d.ts +33 -0
  60. package/dist/core/blocked-packages-file.js +274 -0
  61. package/dist/core/blocked-packages-file.js.map +1 -0
  62. package/dist/core/compaction/policy.d.ts +2 -2
  63. package/dist/core/compaction/policy.js +86 -43
  64. package/dist/core/compaction/policy.js.map +1 -1
  65. package/dist/core/compaction/token-estimator.d.ts +4 -1
  66. package/dist/core/compaction/token-estimator.js +5 -2
  67. package/dist/core/compaction/token-estimator.js.map +1 -1
  68. package/dist/core/event-bus.d.ts +10 -0
  69. package/dist/core/event-bus.js +2 -0
  70. package/dist/core/event-bus.js.map +1 -1
  71. package/dist/core/idle-wake.d.ts +62 -0
  72. package/dist/core/idle-wake.js +103 -0
  73. package/dist/core/idle-wake.js.map +1 -0
  74. package/dist/core/injection-detect.d.ts +2 -1
  75. package/dist/core/injection-detect.js +13 -4
  76. package/dist/core/injection-detect.js.map +1 -1
  77. package/dist/core/installed-threats.d.ts +23 -0
  78. package/dist/core/installed-threats.js +71 -0
  79. package/dist/core/installed-threats.js.map +1 -0
  80. package/dist/core/mcp/catalog-cache.d.ts +2 -0
  81. package/dist/core/mcp/catalog-cache.js +4 -0
  82. package/dist/core/mcp/catalog-cache.js.map +1 -1
  83. package/dist/core/mcp/client.d.ts +8 -0
  84. package/dist/core/mcp/client.js +37 -3
  85. package/dist/core/mcp/client.js.map +1 -1
  86. package/dist/core/mcp/deferred-catalog.d.ts +12 -1
  87. package/dist/core/mcp/deferred-catalog.js +37 -10
  88. package/dist/core/mcp/deferred-catalog.js.map +1 -1
  89. package/dist/core/mcp/index.d.ts +2 -0
  90. package/dist/core/mcp/index.js +1 -0
  91. package/dist/core/mcp/index.js.map +1 -1
  92. package/dist/core/mcp/tool-guard.d.ts +58 -0
  93. package/dist/core/mcp/tool-guard.js +215 -0
  94. package/dist/core/mcp/tool-guard.js.map +1 -0
  95. package/dist/core/network-guard.d.ts +0 -20
  96. package/dist/core/network-guard.js +6 -0
  97. package/dist/core/network-guard.js.map +1 -1
  98. package/dist/core/package-cooldown.d.ts +71 -0
  99. package/dist/core/package-cooldown.js +301 -0
  100. package/dist/core/package-cooldown.js.map +1 -0
  101. package/dist/core/package-threats.d.ts +77 -3
  102. package/dist/core/package-threats.js +1250 -78
  103. package/dist/core/package-threats.js.map +1 -1
  104. package/dist/core/process-manager.d.ts +54 -12
  105. package/dist/core/process-manager.js +233 -56
  106. package/dist/core/process-manager.js.map +1 -1
  107. package/dist/core/project-files.d.ts +15 -0
  108. package/dist/core/project-files.js +37 -0
  109. package/dist/core/project-files.js.map +1 -0
  110. package/dist/core/prompt-commands.js +1 -0
  111. package/dist/core/prompt-commands.js.map +1 -1
  112. package/dist/core/session-manager.d.ts +3 -1
  113. package/dist/core/session-manager.js +2 -1
  114. package/dist/core/session-manager.js.map +1 -1
  115. package/dist/core/settings-manager.d.ts +1 -0
  116. package/dist/core/settings-manager.js +4 -0
  117. package/dist/core/settings-manager.js.map +1 -1
  118. package/dist/core/shell-threats.d.ts +14 -1
  119. package/dist/core/shell-threats.js +73 -24
  120. package/dist/core/shell-threats.js.map +1 -1
  121. package/dist/core/skill-scan.d.ts +112 -0
  122. package/dist/core/skill-scan.js +781 -0
  123. package/dist/core/skill-scan.js.map +1 -0
  124. package/dist/core/skills.d.ts +33 -0
  125. package/dist/core/skills.js +87 -16
  126. package/dist/core/skills.js.map +1 -1
  127. package/dist/core/slash-commands.d.ts +5 -1
  128. package/dist/core/slash-commands.js +24 -9
  129. package/dist/core/slash-commands.js.map +1 -1
  130. package/dist/core/steering.d.ts +7 -0
  131. package/dist/core/steering.js +13 -0
  132. package/dist/core/steering.js.map +1 -1
  133. package/dist/core/style-packs/index.js +1 -1
  134. package/dist/core/style-packs/index.js.map +1 -1
  135. package/dist/core/style-packs/packs.js +2 -2
  136. package/dist/core/subagent-manager.js +5 -4
  137. package/dist/core/subagent-manager.js.map +1 -1
  138. package/dist/core/threat-feed.d.ts +65 -0
  139. package/dist/core/threat-feed.js +335 -0
  140. package/dist/core/threat-feed.js.map +1 -0
  141. package/dist/core/trophies/catalog-more.d.ts +2 -0
  142. package/dist/core/trophies/catalog-more.js +857 -0
  143. package/dist/core/trophies/catalog-more.js.map +1 -0
  144. package/dist/core/trophies/catalog.d.ts +4 -0
  145. package/dist/core/trophies/catalog.js +649 -0
  146. package/dist/core/trophies/catalog.js.map +1 -0
  147. package/dist/core/trophies/engine.d.ts +70 -0
  148. package/dist/core/trophies/engine.js +351 -0
  149. package/dist/core/trophies/engine.js.map +1 -0
  150. package/dist/core/trophies/store.d.ts +17 -0
  151. package/dist/core/trophies/store.js +113 -0
  152. package/dist/core/trophies/store.js.map +1 -0
  153. package/dist/core/trophies/types.d.ts +119 -0
  154. package/dist/core/trophies/types.js +78 -0
  155. package/dist/core/trophies/types.js.map +1 -0
  156. package/dist/core/verification-evidence.d.ts +10 -6
  157. package/dist/core/verification-evidence.js +190 -11
  158. package/dist/core/verification-evidence.js.map +1 -1
  159. package/dist/goals-agent/goals-agent.js +3 -2
  160. package/dist/goals-agent/goals-agent.js.map +1 -1
  161. package/dist/interactive.js +16 -5
  162. package/dist/interactive.js.map +1 -1
  163. package/dist/modes/acp-mode.js +8 -1
  164. package/dist/modes/acp-mode.js.map +1 -1
  165. package/dist/modes/agent-home-mode.js +13 -1
  166. package/dist/modes/agent-home-mode.js.map +1 -1
  167. package/dist/modes/rpc-mode.d.ts +2 -1
  168. package/dist/modes/rpc-mode.js +15 -3
  169. package/dist/modes/rpc-mode.js.map +1 -1
  170. package/dist/modes/serve-mode.js +13 -1
  171. package/dist/modes/serve-mode.js.map +1 -1
  172. package/dist/system-prompt.d.ts +8 -0
  173. package/dist/system-prompt.js +34 -13
  174. package/dist/system-prompt.js.map +1 -1
  175. package/dist/test-support/slow-git.d.ts +1 -0
  176. package/dist/test-support/slow-git.js +21 -0
  177. package/dist/test-support/slow-git.js.map +1 -0
  178. package/dist/tools/background-watch-lint.d.ts +18 -0
  179. package/dist/tools/background-watch-lint.js +102 -0
  180. package/dist/tools/background-watch-lint.js.map +1 -0
  181. package/dist/tools/bash.d.ts +15 -4
  182. package/dist/tools/bash.js +75 -47
  183. package/dist/tools/bash.js.map +1 -1
  184. package/dist/tools/checklist.d.ts +3 -3
  185. package/dist/tools/compress.js +45 -0
  186. package/dist/tools/compress.js.map +1 -1
  187. package/dist/tools/edit.js +5 -0
  188. package/dist/tools/edit.js.map +1 -1
  189. package/dist/tools/generate-image.d.ts +29 -6
  190. package/dist/tools/generate-image.js +325 -151
  191. package/dist/tools/generate-image.js.map +1 -1
  192. package/dist/tools/grep.d.ts +14 -0
  193. package/dist/tools/grep.js +36 -2
  194. package/dist/tools/grep.js.map +1 -1
  195. package/dist/tools/index.d.ts +5 -1
  196. package/dist/tools/index.js +7 -4
  197. package/dist/tools/index.js.map +1 -1
  198. package/dist/tools/prompt-hints.d.ts +8 -1
  199. package/dist/tools/prompt-hints.js +22 -2
  200. package/dist/tools/prompt-hints.js.map +1 -1
  201. package/dist/tools/routine-output.d.ts +30 -0
  202. package/dist/tools/routine-output.js +203 -0
  203. package/dist/tools/routine-output.js.map +1 -0
  204. package/dist/tools/skill.d.ts +2 -2
  205. package/dist/tools/skill.js +8 -1
  206. package/dist/tools/skill.js.map +1 -1
  207. package/dist/tools/subagent-shared.js +4 -1
  208. package/dist/tools/subagent-shared.js.map +1 -1
  209. package/dist/tools/task-output.js +11 -1
  210. package/dist/tools/task-output.js.map +1 -1
  211. package/dist/tools/write.js +8 -0
  212. package/dist/tools/write.js.map +1 -1
  213. package/dist/ui/components/ModelSelector.d.ts +10 -0
  214. package/dist/ui/components/ModelSelector.js +51 -5
  215. package/dist/ui/components/ModelSelector.js.map +1 -1
  216. package/dist/ui/components/ToolExecution.js +2 -2
  217. package/dist/ui/components/ToolExecution.js.map +1 -1
  218. package/dist/ui/mcp.d.ts +2 -0
  219. package/dist/ui/mcp.js.map +1 -1
  220. package/dist/ui/terminal-history.js +2 -1
  221. package/dist/ui/terminal-history.js.map +1 -1
  222. package/dist/ui/tool-line-summary.js +3 -1
  223. package/dist/ui/tool-line-summary.js.map +1 -1
  224. package/dist/utils/git.d.ts +12 -3
  225. package/dist/utils/git.js +21 -8
  226. package/dist/utils/git.js.map +1 -1
  227. package/dist/utils/image.d.ts +14 -0
  228. package/dist/utils/image.js +23 -0
  229. package/dist/utils/image.js.map +1 -1
  230. package/package.json +5 -5
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Wake an idle session when its own background work needs attention.
3
+ *
4
+ * Background alerts — a build or CI watcher that failed, a task that exited
5
+ * non-zero, a child agent that finished — ride the steering path, which only
6
+ * exists while a run is live. Once the agent has ended its turn, an alert sat
7
+ * in the queue until the user happened to send another message (measured: 8 of
8
+ * 483 runs began with a status update that had been waiting for exactly that).
9
+ *
10
+ * This starts a run for the alert instead, inside hard limits:
11
+ *
12
+ * - Never while anything else could deliver it: a live run, a run being
13
+ * claimed, an autopilot cycle. The alert waits for that run's next steering
14
+ * boundary instead, and is retried here if the run ends without draining it.
15
+ * - Never while the user is deciding something (a plan awaiting review).
16
+ * - Never after the user pressed Stop, until they send another message. Stop
17
+ * means "stop acting on your own", and a background exit is not a reason to
18
+ * override it.
19
+ * - At most {@link DEFAULT_MAX_WAKES_PER_PROMPT} wakes per user message, so a
20
+ * flapping task cannot keep the agent (and the bill) running unattended.
21
+ *
22
+ * Pure policy over injected callbacks; the host owns the run itself.
23
+ */
24
+ /** Batch alerts that land together (a failure line, then the exit) into one run. */
25
+ export declare const DEFAULT_IDLE_WAKE_DEBOUNCE_MS = 2000;
26
+ /** Unattended wakes allowed per human prompt. */
27
+ export declare const DEFAULT_MAX_WAKES_PER_PROMPT = 2;
28
+ export type IdleWakeSkip = "stopped" | "budget" | "blocked" | "nothing-pending";
29
+ export interface IdleWakeDeps {
30
+ /** A run, a run claim, or an autopilot cycle is live and will deliver it. */
31
+ isBusy: () => boolean;
32
+ /** The user is deciding something (a plan awaiting review). */
33
+ isBlocked: () => boolean;
34
+ /** An urgent alert is still waiting to be delivered. */
35
+ hasPendingAlert: () => boolean;
36
+ /** Monotonic count of human prompts; budgets and Stop reset when it moves. */
37
+ humanPromptSeq: () => number;
38
+ /** Start the wake run; resolves when it has settled. */
39
+ start: () => Promise<void>;
40
+ /** Observability hook for skipped wakes. */
41
+ onSkip?: (reason: IdleWakeSkip) => void;
42
+ debounceMs?: number;
43
+ maxWakesPerPrompt?: number;
44
+ }
45
+ export declare class IdleWakeController {
46
+ private readonly deps;
47
+ private timer;
48
+ private budgetSeq;
49
+ private wakesUsed;
50
+ private stoppedAtSeq;
51
+ private starting;
52
+ private disposed;
53
+ constructor(deps: IdleWakeDeps);
54
+ /** An urgent alert was queued. Debounced; safe to call often. */
55
+ trigger(): void;
56
+ /** The user pressed Stop: no unattended wakes until their next message. */
57
+ noteStop(): void;
58
+ dispose(): void;
59
+ private cancelTimer;
60
+ private fire;
61
+ private skip;
62
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Wake an idle session when its own background work needs attention.
3
+ *
4
+ * Background alerts — a build or CI watcher that failed, a task that exited
5
+ * non-zero, a child agent that finished — ride the steering path, which only
6
+ * exists while a run is live. Once the agent has ended its turn, an alert sat
7
+ * in the queue until the user happened to send another message (measured: 8 of
8
+ * 483 runs began with a status update that had been waiting for exactly that).
9
+ *
10
+ * This starts a run for the alert instead, inside hard limits:
11
+ *
12
+ * - Never while anything else could deliver it: a live run, a run being
13
+ * claimed, an autopilot cycle. The alert waits for that run's next steering
14
+ * boundary instead, and is retried here if the run ends without draining it.
15
+ * - Never while the user is deciding something (a plan awaiting review).
16
+ * - Never after the user pressed Stop, until they send another message. Stop
17
+ * means "stop acting on your own", and a background exit is not a reason to
18
+ * override it.
19
+ * - At most {@link DEFAULT_MAX_WAKES_PER_PROMPT} wakes per user message, so a
20
+ * flapping task cannot keep the agent (and the bill) running unattended.
21
+ *
22
+ * Pure policy over injected callbacks; the host owns the run itself.
23
+ */
24
+ /** Batch alerts that land together (a failure line, then the exit) into one run. */
25
+ export const DEFAULT_IDLE_WAKE_DEBOUNCE_MS = 2_000;
26
+ /** Unattended wakes allowed per human prompt. */
27
+ export const DEFAULT_MAX_WAKES_PER_PROMPT = 2;
28
+ export class IdleWakeController {
29
+ deps;
30
+ timer = null;
31
+ budgetSeq = -1;
32
+ wakesUsed = 0;
33
+ stoppedAtSeq = null;
34
+ starting = false;
35
+ disposed = false;
36
+ constructor(deps) {
37
+ this.deps = deps;
38
+ }
39
+ /** An urgent alert was queued. Debounced; safe to call often. */
40
+ trigger() {
41
+ if (this.disposed || this.timer !== null)
42
+ return;
43
+ this.timer = setTimeout(() => {
44
+ this.timer = null;
45
+ void this.fire();
46
+ }, this.deps.debounceMs ?? DEFAULT_IDLE_WAKE_DEBOUNCE_MS);
47
+ this.timer.unref?.();
48
+ }
49
+ /** The user pressed Stop: no unattended wakes until their next message. */
50
+ noteStop() {
51
+ this.stoppedAtSeq = this.deps.humanPromptSeq();
52
+ this.cancelTimer();
53
+ }
54
+ dispose() {
55
+ this.disposed = true;
56
+ this.cancelTimer();
57
+ }
58
+ cancelTimer() {
59
+ if (this.timer !== null)
60
+ clearTimeout(this.timer);
61
+ this.timer = null;
62
+ }
63
+ async fire() {
64
+ if (this.disposed || this.starting)
65
+ return;
66
+ if (!this.deps.hasPendingAlert())
67
+ return this.skip("nothing-pending");
68
+ const seq = this.deps.humanPromptSeq();
69
+ if (this.stoppedAtSeq === seq)
70
+ return this.skip("stopped");
71
+ if (seq !== this.budgetSeq) {
72
+ this.budgetSeq = seq;
73
+ this.wakesUsed = 0;
74
+ }
75
+ if (this.wakesUsed >= (this.deps.maxWakesPerPrompt ?? DEFAULT_MAX_WAKES_PER_PROMPT)) {
76
+ return this.skip("budget");
77
+ }
78
+ if (this.deps.isBusy()) {
79
+ // The live run should drain it at its next steering boundary. If that
80
+ // run is already past its last boundary, the alert would strand — so
81
+ // look again shortly rather than trusting the run to have taken it.
82
+ this.trigger();
83
+ return;
84
+ }
85
+ if (this.deps.isBlocked())
86
+ return this.skip("blocked");
87
+ this.wakesUsed += 1;
88
+ this.starting = true;
89
+ try {
90
+ await this.deps.start();
91
+ }
92
+ finally {
93
+ this.starting = false;
94
+ }
95
+ // An alert that landed after the wake run's last steering boundary.
96
+ if (this.deps.hasPendingAlert())
97
+ this.trigger();
98
+ }
99
+ skip(reason) {
100
+ this.deps.onSkip?.(reason);
101
+ }
102
+ }
103
+ //# sourceMappingURL=idle-wake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle-wake.js","sourceRoot":"","sources":["../../src/core/idle-wake.ts"],"names":[],"mappings":"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"}
@@ -27,7 +27,7 @@ export declare function normalizeForDetection(text: string): string;
27
27
  /** Scan untrusted text; `null` when nothing instruction-like was found. */
28
28
  export declare function detectInjection(text: string): InjectionHit | null;
29
29
  /** Tools whose output is attacker-controllable content from outside the repo. */
30
- export declare function isUntrustedTool(name: string): boolean;
30
+ export declare function isUntrustedTool(name: string, args?: Record<string, unknown>): boolean;
31
31
  export declare function injectionWarning(kind: string): string;
32
32
  /**
33
33
  * `transformToolResult` hook body: for untrusted tools, append the warning
@@ -35,4 +35,5 @@ export declare function injectionWarning(kind: string): string;
35
35
  */
36
36
  export declare function flagUntrustedToolResult(call: {
37
37
  name: string;
38
+ args?: Record<string, unknown>;
38
39
  }, content: ToolResultContent): ToolResultContent;
@@ -15,7 +15,7 @@
15
15
  * attacker would use. Mere mentions of the topic ("prompt injection",
16
16
  * "system prompt") do not hit.
17
17
  */
18
- const SCAN_WINDOW = 200_000;
18
+ const SCAN_WINDOW = 100_000;
19
19
  const MAX_BLOBS = 64;
20
20
  const MAX_BLOB_CHARS = 16_384;
21
21
  /** Zero-width, joiners, bidi controls/isolates, soft hyphen, BOM, tag chars. */
@@ -146,7 +146,7 @@ const RULES = [
146
146
  kind: "fake role/tool marker",
147
147
  re: new RegExp(String.raw `<\|im_start\|>\s*(?:system|assistant)|<\|(?:start_header_id|eot_id|endoftext|system)\|>` +
148
148
  String.raw `|</?(?:tool_result|function_results|function_calls|system-reminder|system_prompt)>` +
149
- String.raw `|(?:^|\n)[ \t]*\[(?:system|/?inst)\][ \t]*(?:\n|$|[a-z])`),
149
+ String.raw `|(?:^|\n)[ \t]*\[(?:system|/?inst)\][ \t]*\r?(?:\n|$|[a-z])`),
150
150
  },
151
151
  ];
152
152
  /** Encoded blobs: long base64 or hex runs. */
@@ -205,8 +205,17 @@ export function detectInjection(text) {
205
205
  }
206
206
  return scanBlobs(window.replace(INVISIBLE, ""));
207
207
  }
208
+ /**
209
+ * Bash commands whose output is third-party text: issue/PR bodies and
210
+ * comments (`gh`, `glab`) and fetched web pages (`curl`/`wget`).
211
+ */
212
+ const UNTRUSTED_BASH = /(?:^|[\s;&|(])(?:gh\s+(?:issue\s+(?:view|list)|pr\s+(?:view|diff|list)|api|release\s+view|search)\b|glab\s|curl\s|wget\s)/;
208
213
  /** Tools whose output is attacker-controllable content from outside the repo. */
209
- export function isUntrustedTool(name) {
214
+ export function isUntrustedTool(name, args) {
215
+ if (name === "bash") {
216
+ const command = args?.command;
217
+ return typeof command === "string" && UNTRUSTED_BASH.test(command);
218
+ }
210
219
  return name === "web_fetch" || name === "web_search" || name.startsWith("mcp__");
211
220
  }
212
221
  export function injectionWarning(kind) {
@@ -217,7 +226,7 @@ export function injectionWarning(kind) {
217
226
  * line on a hit. Content is never altered otherwise.
218
227
  */
219
228
  export function flagUntrustedToolResult(call, content) {
220
- if (!isUntrustedTool(call.name))
229
+ if (!isUntrustedTool(call.name, call.args))
221
230
  return content;
222
231
  if (typeof content === "string") {
223
232
  const hit = detectInjection(content);
@@ -1 +1 @@
1
- {"version":3,"file":"injection-detect.js","sourceRoot":"","sources":["../../src/core/injection-detect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"injection-detect.js","sourceRoot":"","sources":["../../src/core/injection-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { BlockedPackage } from "./shell-threats.js";
2
+ import { type PackageCheckOptions } from "./package-threats.js";
3
+ export interface InstalledThreat {
4
+ /** Stable id: lockfile path + flagged items (a fix or new hit is a new key). */
5
+ key: string;
6
+ /** Absolute lockfile path. */
7
+ file: string;
8
+ /** Flagged `name@version (IDs)` items. */
9
+ packages: string[];
10
+ /** The same, structured, for the project's "don't install" list. */
11
+ blocked: BlockedPackage[];
12
+ /** One plain line for the user. */
13
+ message: string;
14
+ /** What the agent is told to do. */
15
+ agentText: string;
16
+ }
17
+ /** Lockfile path → mtime, for "did a run change a lockfile?" checks. */
18
+ export type LockfileStamp = Map<string, number>;
19
+ /** Which known lockfiles exist in `dir`, with their mtimes. Missing ones are skipped. */
20
+ export declare function stampProjectLockfiles(dir: string): Promise<LockfileStamp>;
21
+ export declare function sameStamp(a: LockfileStamp, b: LockfileStamp): boolean;
22
+ /** Check every known lockfile in `dir`. Clean or nothing to check → []. */
23
+ export declare function scanProjectLockfiles(dir: string, options?: PackageCheckOptions): Promise<InstalledThreat[]>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Already-installed packages: check a project's existing lockfiles against the
3
+ * malware data (local daily feed + one batched OSV lookup per lockfile), so a
4
+ * package flagged AFTER it was installed is still found. Runs in the
5
+ * background (session start, after each daily feed update, after a run that
6
+ * changed a lockfile); never on a command's critical path, never a prompt.
7
+ *
8
+ * Cost: one `stat` per known lockfile name; a lockfile is only read when it
9
+ * exists, and its verdict is cached by content hash and re-asked of OSV at most
10
+ * once a day (core/package-threats.ts).
11
+ */
12
+ import fsp from "node:fs/promises";
13
+ import path from "node:path";
14
+ import { checkLockfileMalware, PROJECT_LOCKFILES, } from "./package-threats.js";
15
+ /** Which known lockfiles exist in `dir`, with their mtimes. Missing ones are skipped. */
16
+ export async function stampProjectLockfiles(dir) {
17
+ const stamp = new Map();
18
+ await Promise.all(PROJECT_LOCKFILES.map(async (lock) => {
19
+ const file = path.join(dir, lock.file);
20
+ try {
21
+ const st = await fsp.stat(file);
22
+ if (st.isFile())
23
+ stamp.set(file, st.mtimeMs);
24
+ }
25
+ catch {
26
+ // Not there: nothing to check.
27
+ }
28
+ }));
29
+ return stamp;
30
+ }
31
+ export function sameStamp(a, b) {
32
+ if (a.size !== b.size)
33
+ return false;
34
+ for (const [file, mtime] of a)
35
+ if (b.get(file) !== mtime)
36
+ return false;
37
+ return true;
38
+ }
39
+ function describe(file, dir, packages, blocked) {
40
+ const rel = path.relative(dir, file) || path.basename(file);
41
+ const list = packages.slice(0, 5).join(", ") +
42
+ (packages.length > 5 ? ` and ${packages.length - 5} more` : "");
43
+ return {
44
+ key: `${file}\0${[...packages].sort().join("\0")}`,
45
+ file,
46
+ packages,
47
+ blocked,
48
+ message: `This project uses a package now known to be infected: ${list} (in ${rel}). ` +
49
+ `The agent has been told to replace it.`,
50
+ agentText: `Security notice: ${rel} in this project pins a package that is now known to be malware: ${list}. ` +
51
+ `Before running any of the project's code, replace it: update the dependency to a clean version ` +
52
+ `(the release before the flagged one, or a newer fixed one), regenerate the lockfile and reinstall. ` +
53
+ `Then tell the user in one plain sentence what you changed. Do not run the flagged version.`,
54
+ };
55
+ }
56
+ /** Check every known lockfile in `dir`. Clean or nothing to check → []. */
57
+ export async function scanProjectLockfiles(dir, options = {}) {
58
+ const stamp = await stampProjectLockfiles(dir);
59
+ if (stamp.size === 0)
60
+ return [];
61
+ const found = await Promise.all(PROJECT_LOCKFILES.filter((lock) => stamp.has(path.join(dir, lock.file))).map(async (lock) => {
62
+ const threats = await checkLockfileMalware(lock, dir, options);
63
+ const packages = threats.flatMap((t) => t.packages ?? []);
64
+ const blocked = threats.flatMap((t) => t.blocked ?? []);
65
+ return packages.length > 0
66
+ ? describe(path.join(dir, lock.file), dir, packages, blocked)
67
+ : null;
68
+ }));
69
+ return found.filter((t) => t !== null);
70
+ }
71
+ //# sourceMappingURL=installed-threats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-threats.js","sourceRoot":"","sources":["../../src/core/installed-threats.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,8 @@ export declare class McpCatalogCache {
45
45
  /** Serializes read-modify-write cycles within one process. */
46
46
  private writeQueue;
47
47
  constructor(filePath?: string);
48
+ /** Where this cache lives; sibling state (tool pins) is kept beside it. */
49
+ get path(): string;
48
50
  private readAll;
49
51
  private writeAll;
50
52
  /**
@@ -70,6 +70,10 @@ export class McpCatalogCache {
70
70
  constructor(filePath = getAppPaths().mcpCatalogFile) {
71
71
  this.filePath = filePath;
72
72
  }
73
+ /** Where this cache lives; sibling state (tool pins) is kept beside it. */
74
+ get path() {
75
+ return this.filePath;
76
+ }
73
77
  async readAll() {
74
78
  try {
75
79
  const raw = await fs.readFile(this.filePath, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-cache.js","sourceRoot":"","sources":["../../../src/core/mcp/catalog-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog-cache.js","sourceRoot":"","sources":["../../../src/core/mcp/catalog-cache.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { ElicitResult } from "@modelcontextprotocol/client";
2
2
  import type { AgentTool } from "@prestyj/agent";
3
3
  import type { MCPServerConfig } from "./types.js";
4
4
  import { McpCatalogCache } from "./catalog-cache.js";
5
+ import { McpToolGuard, type HiddenMcpTool } from "./tool-guard.js";
5
6
  import { type SharedMcpPool } from "./shared-pool.js";
6
7
  /**
7
8
  * How long a stdio server may sit with no call in flight before its process is
@@ -33,6 +34,8 @@ export interface MCPConnectResult {
33
34
  toolCount: number;
34
35
  tools: AgentTool[];
35
36
  error?: string;
37
+ /** Tools the ez-safe guard withheld from the model, with one-line reasons. */
38
+ hidden?: HiddenMcpTool[];
36
39
  /** True when the server returned 401/Unauthorized and an OAuth login is
37
40
  * required before it can connect. The UI surfaces this as "requires login". */
38
41
  requiresAuth?: boolean;
@@ -95,6 +98,10 @@ export declare class MCPClientManager {
95
98
  */
96
99
  private sharedHandles;
97
100
  private readonly catalogCache;
101
+ /** Scans + pins each server's tool descriptions before exposure (ez-safe S2). */
102
+ private readonly toolGuard;
103
+ /** Tools hidden by the guard on the latest connect, per server. */
104
+ private readonly hiddenTools;
98
105
  /**
99
106
  * Opt into the 2026-07-28 revision. Off by default: `mode: "auto"` probes with
100
107
  * `server/discover` before falling back to `initialize`, and a legacy stdio
@@ -132,6 +139,7 @@ export declare class MCPClientManager {
132
139
  private idleStopped;
133
140
  constructor(opts?: {
134
141
  catalogCache?: McpCatalogCache;
142
+ toolGuard?: McpToolGuard;
135
143
  modernProtocol?: boolean;
136
144
  onElicit?: MCPElicitHandler;
137
145
  sharedPool?: SharedMcpPool;
@@ -3,13 +3,17 @@ import { Client, OAuthError, OAuthErrorCode, ProtocolError, SdkError, SdkErrorCo
3
3
  import { z } from "zod";
4
4
  import http from "node:http";
5
5
  import os from "node:os";
6
+ import path from "node:path";
6
7
  import { log } from "../logger.js";
7
8
  import { McpOAuthProvider, MCP_OAUTH_CALLBACK_PORT, MCP_OAUTH_CALLBACK_PATH, } from "./oauth-provider.js";
8
9
  import { McpOAuthStore } from "./oauth-store.js";
9
10
  import { isLocalhost, alternateLoopback, isNetworkError } from "./loopback.js";
10
11
  import { toToolResult } from "./content.js";
11
12
  import { resolveStdioCommand } from "./resolve-stdio.js";
13
+ import { checkMcpLaunch } from "../package-threats.js";
14
+ import { launchCooldownEnv } from "../package-cooldown.js";
12
15
  import { McpCatalogCache } from "./catalog-cache.js";
16
+ import { McpToolGuard } from "./tool-guard.js";
13
17
  import { isShareableServer, sharedMcpPool, } from "./shared-pool.js";
14
18
  /**
15
19
  * How long a stdio server may sit with no call in flight before its process is
@@ -76,6 +80,10 @@ export class MCPClientManager {
76
80
  */
77
81
  sharedHandles = new Map();
78
82
  catalogCache;
83
+ /** Scans + pins each server's tool descriptions before exposure (ez-safe S2). */
84
+ toolGuard;
85
+ /** Tools hidden by the guard on the latest connect, per server. */
86
+ hiddenTools = new Map();
79
87
  /**
80
88
  * Opt into the 2026-07-28 revision. Off by default: `mode: "auto"` probes with
81
89
  * `server/discover` before falling back to `initialize`, and a legacy stdio
@@ -113,6 +121,11 @@ export class MCPClientManager {
113
121
  idleStopped = new WeakSet();
114
122
  constructor(opts = {}) {
115
123
  this.catalogCache = opts.catalogCache ?? new McpCatalogCache();
124
+ // Pins sit beside the catalog cache, so a test that isolates the cache
125
+ // isolates the pins too (and the real ~/.ezcoder is never touched).
126
+ this.toolGuard =
127
+ opts.toolGuard ??
128
+ new McpToolGuard(path.join(path.dirname(this.catalogCache.path), "mcp-tool-pins.json"));
116
129
  this.modernProtocol = opts.modernProtocol ?? false;
117
130
  this.onElicit = opts.onElicit;
118
131
  this.pool = opts.sharedPool ?? sharedMcpPool;
@@ -311,6 +324,7 @@ export class MCPClientManager {
311
324
  throw new Error(handle.result.error ?? "connection failed");
312
325
  }
313
326
  this.sharedHandles.set(config.name, handle);
327
+ this.hiddenTools.set(config.name, handle.result.hidden ?? []);
314
328
  // Wrap each pooled tool so a call from THIS session is attributable while
315
329
  // it runs. The pool needs that to answer "which window asked?" when the
316
330
  // server elicits mid-call; without it a shared server could only ever
@@ -394,7 +408,14 @@ export class MCPClientManager {
394
408
  const results = settled.map((result, i) => {
395
409
  const name = enabled[i].name;
396
410
  if (result.status === "fulfilled") {
397
- return { name, ok: true, toolCount: result.value.length, tools: result.value };
411
+ const hidden = this.hiddenTools.get(name) ?? [];
412
+ return {
413
+ name,
414
+ ok: true,
415
+ toolCount: result.value.length,
416
+ tools: result.value,
417
+ ...(hidden.length > 0 ? { hidden } : {}),
418
+ };
398
419
  }
399
420
  const requiresAuth = isUnauthorized(result.reason);
400
421
  const error = requiresAuth ? "Requires login." : formatConnectError(result.reason);
@@ -593,11 +614,19 @@ export class MCPClientManager {
593
614
  // wrapper whose only job is to resolve+launch the real server, doubling
594
615
  // memory per connection. Non-resolvable / non-npx commands pass through
595
616
  // unchanged. Mirrors the LSP `process.execPath`+bin pattern.
617
+ // Same package guard as bash installs: a flagged `npx`/`uvx` package is
618
+ // never started (P7). Throws like any other connect failure.
619
+ const packageBlocked = await checkMcpLaunch(config.command, config.args ?? []);
620
+ if (packageBlocked) {
621
+ log("WARN", "mcp", `not starting "${config.name}": ${packageBlocked}`);
622
+ throw new Error(`MCP server "${config.name}" not started. ${packageBlocked}`);
623
+ }
624
+ const cooldownEnv = await launchCooldownEnv(config.command, config.args ?? [], os.homedir());
596
625
  const resolved = resolveStdioCommand(config.command, config.args);
597
626
  transport = new StdioClientTransport({
598
627
  command: resolved.command,
599
628
  args: resolved.args,
600
- env: { ...process.env, ...config.env },
629
+ env: { ...process.env, ...cooldownEnv, ...config.env },
601
630
  cwd: os.homedir(),
602
631
  stderr: "pipe",
603
632
  });
@@ -664,7 +693,12 @@ export class MCPClientManager {
664
693
  log("WARN", "mcp", `MCP server "${config.name}" closed unexpectedly`);
665
694
  this.onServerClosed?.(config.name);
666
695
  };
667
- const { tools } = await client.listTools(undefined, { timeout });
696
+ const listed = await client.listTools(undefined, { timeout });
697
+ // ez-safe S2: hide poisoned / shadowing / rug-pulled tools before anything
698
+ // (catalog cache, deferred catalog, model) sees them.
699
+ const guarded = await this.toolGuard.filter(config.name, client.getServerVersion()?.version, listed.tools);
700
+ const tools = guarded.tools;
701
+ this.hiddenTools.set(config.name, guarded.hidden);
668
702
  // Start the idle countdown (a no-op for HTTP / keepAlive / a call in
669
703
  // flight). A probe connection is closed right away, so it never idles.
670
704
  if (!opts.probe)