@yagni-app/code 1.0.5 → 1.0.7

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 (111) hide show
  1. package/README.md +89 -27
  2. package/dist/claudeCompat.d.ts +59 -0
  3. package/dist/claudeCompat.js +109 -2
  4. package/dist/claudePlugins.d.ts +45 -3
  5. package/dist/claudePlugins.js +129 -19
  6. package/dist/cli.js +28 -4
  7. package/dist/doctor.d.ts +42 -4
  8. package/dist/doctor.js +150 -15
  9. package/dist/extension/condensedTools.d.ts +12 -1
  10. package/dist/extension/condensedTools.js +17 -9
  11. package/dist/extension/index.d.ts +18 -5
  12. package/dist/extension/index.js +319 -72
  13. package/dist/extension/mcp/approval.d.ts +45 -0
  14. package/dist/extension/mcp/approval.js +164 -0
  15. package/dist/extension/mcp/auth.d.ts +124 -0
  16. package/dist/extension/mcp/auth.js +560 -0
  17. package/dist/extension/mcp/authStore.d.ts +61 -0
  18. package/dist/extension/mcp/authStore.js +105 -0
  19. package/dist/extension/mcp/callbackPage.d.ts +31 -0
  20. package/dist/extension/mcp/callbackPage.js +222 -0
  21. package/dist/extension/mcp/cliConfig.d.ts +12 -0
  22. package/dist/extension/mcp/cliConfig.js +12 -0
  23. package/dist/extension/mcp/config.d.ts +153 -0
  24. package/dist/extension/mcp/config.js +381 -0
  25. package/dist/extension/mcp/log.d.ts +28 -0
  26. package/dist/extension/mcp/log.js +82 -0
  27. package/dist/extension/mcp/manager.d.ts +100 -0
  28. package/dist/extension/mcp/manager.js +273 -0
  29. package/dist/extension/mcp/names.d.ts +25 -0
  30. package/dist/extension/mcp/names.js +40 -0
  31. package/dist/extension/mcp/panel.d.ts +33 -0
  32. package/dist/extension/mcp/panel.js +268 -0
  33. package/dist/extension/mcp/prompts.d.ts +23 -0
  34. package/dist/extension/mcp/prompts.js +93 -0
  35. package/dist/extension/mcp/startup.d.ts +55 -0
  36. package/dist/extension/mcp/startup.js +152 -0
  37. package/dist/extension/mcp/tools.d.ts +31 -0
  38. package/dist/extension/mcp/tools.js +117 -0
  39. package/dist/extension/mcp/transports.d.ts +17 -0
  40. package/dist/extension/mcp/transports.js +44 -0
  41. package/dist/extension/permission/gate.d.ts +104 -2
  42. package/dist/extension/permission/gate.js +387 -31
  43. package/dist/extension/permission/guardian.d.ts +24 -5
  44. package/dist/extension/permission/guardian.js +162 -24
  45. package/dist/extension/permissionRules/bashFileArgs.d.ts +39 -0
  46. package/dist/extension/permissionRules/bashFileArgs.js +236 -0
  47. package/dist/extension/permissionRules/engine.d.ts +50 -0
  48. package/dist/extension/permissionRules/engine.js +238 -0
  49. package/dist/extension/permissionRules/loadConfig.d.ts +53 -0
  50. package/dist/extension/permissionRules/loadConfig.js +90 -0
  51. package/dist/extension/permissionRules/parser.d.ts +38 -0
  52. package/dist/extension/permissionRules/parser.js +136 -0
  53. package/dist/extension/permissionRules/pathRules.d.ts +58 -0
  54. package/dist/extension/permissionRules/pathRules.js +120 -0
  55. package/dist/extension/permissionRules/shellRules.d.ts +52 -0
  56. package/dist/extension/permissionRules/shellRules.js +221 -0
  57. package/dist/extension/pipeline/invocation.d.ts +3 -6
  58. package/dist/extension/pipeline/invocation.js +3 -6
  59. package/dist/extension/pipeline/personas.js +5 -0
  60. package/dist/extension/pipeline/runner.d.ts +0 -1
  61. package/dist/extension/pipeline/runner.js +6 -14
  62. package/dist/extension/plugins/inventory.d.ts +88 -0
  63. package/dist/extension/plugins/inventory.js +144 -0
  64. package/dist/extension/plugins/panel.d.ts +45 -0
  65. package/dist/extension/plugins/panel.js +293 -0
  66. package/dist/extension/sandbox/bash.d.ts +99 -0
  67. package/dist/extension/sandbox/bash.js +190 -0
  68. package/dist/extension/sandbox/config.d.ts +114 -0
  69. package/dist/extension/sandbox/config.js +366 -0
  70. package/dist/extension/sandbox/manager.d.ts +98 -0
  71. package/dist/extension/sandbox/manager.js +216 -0
  72. package/dist/extension/sandbox/panel.d.ts +111 -0
  73. package/dist/extension/sandbox/panel.js +342 -0
  74. package/dist/extension/sandbox/session.d.ts +85 -0
  75. package/dist/extension/sandbox/session.js +775 -0
  76. package/dist/extension/telemetry/attrs.d.ts +96 -0
  77. package/dist/extension/telemetry/attrs.js +149 -0
  78. package/dist/extension/telemetry/config.d.ts +99 -0
  79. package/dist/extension/telemetry/config.js +193 -0
  80. package/dist/extension/telemetry/index.d.ts +7 -0
  81. package/dist/extension/telemetry/index.js +7 -0
  82. package/dist/extension/telemetry/probe.d.ts +29 -0
  83. package/dist/extension/telemetry/probe.js +122 -0
  84. package/dist/extension/telemetry/register.d.ts +40 -0
  85. package/dist/extension/telemetry/register.js +192 -0
  86. package/dist/extension/telemetry/sdk.d.ts +63 -0
  87. package/dist/extension/telemetry/sdk.js +207 -0
  88. package/dist/extension/telemetry/tracker.d.ts +131 -0
  89. package/dist/extension/telemetry/tracker.js +551 -0
  90. package/dist/extension/vendor/IGNORE-LICENSE-MIT +21 -0
  91. package/dist/extension/vendor/ignore.d.ts +86 -0
  92. package/dist/extension/vendor/ignore.js +788 -0
  93. package/dist/goHeadless.d.ts +1 -1
  94. package/dist/goHeadless.js +2 -2
  95. package/dist/launch.d.ts +4 -3
  96. package/dist/launch.js +7 -4
  97. package/dist/mcpCommand.d.ts +122 -0
  98. package/dist/mcpCommand.js +787 -0
  99. package/dist/otel.d.ts +69 -63
  100. package/dist/otel.js +154 -119
  101. package/dist/paths.d.ts +13 -0
  102. package/dist/paths.js +18 -0
  103. package/dist/pluginCommand.d.ts +43 -0
  104. package/dist/pluginCommand.js +499 -0
  105. package/dist/pluginStore.d.ts +170 -0
  106. package/dist/pluginStore.js +554 -0
  107. package/dist/upgrade.d.ts +11 -2
  108. package/dist/upgrade.js +48 -8
  109. package/package.json +20 -3
  110. package/dist/extension/mcpTools.d.ts +0 -57
  111. package/dist/extension/mcpTools.js +0 -132
@@ -26,7 +26,7 @@
26
26
  * When the mode leaves plan, stale plan-context messages are filtered out of
27
27
  * the context so the model doesn't keep believing it is restricted.
28
28
  */
29
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
29
+ import type { ExtensionAPI, ExtensionContext, ToolCallEvent, ToolCallEventResult } from "@earendil-works/pi-coding-agent";
30
30
  import { type ApprovedPrefixGrant } from "./approvedPrefixes.js";
31
31
  import type { HookRunner } from "../hooks.js";
32
32
  import { type BlessStore } from "../bless.js";
@@ -53,6 +53,13 @@ export interface PermissionPolicy {
53
53
  reviewConfirmTools: string[];
54
54
  /** Consequential external writes that require fresh consent in every mode. */
55
55
  alwaysConfirmTools?: string[];
56
+ /**
57
+ * Optional predicate: this tool is a mutating action (an MCP server tool
58
+ * that writes, for instance) so it joins planBlock/reviewConfirm even
59
+ * though it was registered dynamically and never appears in the static
60
+ * lists above. Evaluated AFTER the static lists (a static entry wins).
61
+ */
62
+ isMutating?: (toolName: string) => boolean;
56
63
  /**
57
64
  * Optional: a recorded decision already blesses this action, so it auto-runs in
58
65
  * review mode instead of prompting. The hook for tying the gate to captured
@@ -87,6 +94,33 @@ export interface GateDecision {
87
94
  */
88
95
  classifyJustification?: string;
89
96
  }
97
+ /**
98
+ * What the hard floors say about an ALLOW-rule verdict — the three invariants
99
+ * that outrank any user/project permission rule. Extracted from the inline
100
+ * allow path so the gate reads linearly and the floors are directly testable.
101
+ * PURE — no I/O, no session state:
102
+ *
103
+ * "allow" no floor applies — the rule's allow short-circuits everything
104
+ * "block" the exec-policy forbidden band holds despite the allow rule
105
+ * "confirm" alwaysConfirmTools keeps its fresh-consent contract
106
+ * "hold" plan mode's no-mutation contract outranks the allow rule —
107
+ * fall through to the normal plan-mode gate
108
+ *
109
+ * Order is deliberate: plan-mode first (its outcome routes to the EXISTING
110
+ * plan-mode machinery, not a bespoke block); then the terminal forbidden-band
111
+ * block; then the confirm deferral.
112
+ */
113
+ export type AllowRuleFloorOutcome = {
114
+ kind: "allow";
115
+ } | {
116
+ kind: "block";
117
+ reason: string;
118
+ } | {
119
+ kind: "confirm";
120
+ } | {
121
+ kind: "hold";
122
+ };
123
+ export declare function allowRuleFloorVerdict(toolName: string, params: Record<string, unknown>, mode: PermissionMode, policy: PermissionPolicy): AllowRuleFloorOutcome;
90
124
  /**
91
125
  * Pure permission decision for one tool call under a mode + policy. Auto allows
92
126
  * ordinary tools; plan blocks the write/exec set; review marks writes for confirmation
@@ -98,7 +132,7 @@ export declare function decideGate(toolName: string, params: Record<string, unkn
98
132
  * is emitted per terminal outcome; `consulted` says whether a Guardian LLM
99
133
  * call actually happened (grants/cache hits skip it).
100
134
  */
101
- export type GuardianGateOutcome = "prefix_allow" | "cached_allow" | "allow" | "deny" | "ask_approved" | "ask_approved_remembered" | "ask_denied" | "ask_headless_blocked" | "breaker_ask_approved" | "breaker_blocked" | GuardianError;
135
+ export type GuardianGateOutcome = "prefix_allow" | "cached_allow" | "sandbox_auto_allow" | "allow" | "deny" | "ask_approved" | "ask_approved_remembered" | "ask_denied" | "ask_headless_blocked" | "breaker_ask_approved" | "breaker_blocked" | GuardianError;
102
136
  /**
103
137
  * Rich per-decision event for opt-in storage (YAG-510). Carries the RAW
104
138
  * command — the wiring layer (index.ts) hashes/redacts per the workspace's
@@ -122,6 +156,17 @@ export interface GuardianGateEvent {
122
156
  * error-fallback ask that the user then approved). */
123
157
  guardianError?: GuardianError;
124
158
  }
159
+ /** Claude Code's decision sources for a tool permission outcome. */
160
+ export type ToolDecisionSource = "config" | "hook" | "user_permanent" | "user_temporary" | "user_abort" | "user_reject";
161
+ /** One terminal tool_call outcome, in Claude Code's telemetry shape. */
162
+ export interface ToolDecisionEvent {
163
+ toolName: string;
164
+ toolCallId?: string;
165
+ decision: "accept" | "reject";
166
+ source: ToolDecisionSource;
167
+ /** For edit/write tools: the target path (language attribution). */
168
+ filePath?: string;
169
+ }
125
170
  /** What was blessed with "don't ask again", handed to the capture hook. */
126
171
  export interface BlessRememberInfo {
127
172
  tool: string;
@@ -180,12 +225,55 @@ export interface RegisterPermissionDeps {
180
225
  /** Persist a new grant (fire-and-forget; the in-memory list is updated
181
226
  * either way). index.ts wires approvedPrefixes.appendGrant. */
182
227
  persistGrant?: (grant: ApprovedPrefixGrant) => void;
228
+ /**
229
+ * persist a user-level permission rule string (e.g.
230
+ * `Bash(git push:*)`) into ~/.yagni-code/config.json permissions.allow.
231
+ * Wired by index.ts; offered as a third option on Guardian ask dialogs.
232
+ * Fail-soft: the in-session approval applies even if the write fails.
233
+ */
234
+ persistUserRule?: (ruleString: string) => void;
183
235
  /**
184
236
  * Called (fire-and-forget) at every terminal prompt-band outcome with the
185
237
  * rich storage event (raw command — the wiring layer redacts/hashes).
186
238
  * Fail-soft; never blocks.
187
239
  */
188
240
  onGuardianEvent?: (event: GuardianGateEvent) => void;
241
+ /**
242
+ * Called (fire-and-forget) at EVERY terminal tool_call outcome, for every
243
+ * tool, with the Claude Code-shaped decision (accept/reject + source).
244
+ * Feeds the telemetry `tool_decision` event and the
245
+ * `code_edit_tool.decision` counter. Fail-soft; never blocks.
246
+ */
247
+ onToolDecision?: (event: ToolDecisionEvent) => void;
248
+ /**
249
+ * settings-based permission rules (user + project config.json).
250
+ * When present, evaluated at the TOP of the tool_call handler, before
251
+ * hooks: deny → ask → allow, first match wins. Deny/ask are final; allow
252
+ * short-circuits the Guardian but can never lift the exec-policy forbidden
253
+ * band or the alwaysConfirmTools contract (both re-checked below).
254
+ */
255
+ permissionRules?: readonly import("../permissionRules/loadConfig.js").PermissionRule[];
256
+ /** ~/.yagni-code — the user `/`-anchor base for path rules. */
257
+ rulesUserStateHome?: string;
258
+ /** Project root for project-source `/`-anchored path rules; null outside a repo. */
259
+ rulesProjectRoot?: string | null;
260
+ /** Overrides ~ expansion for path rules (tests). */
261
+ rulesHomeDir?: string;
262
+ /** Called (fire-and-soft) after every rule verdict for debug logging. */
263
+ onRuleVerdict?: (event: import("../permissionRules/engine.js").RuleEvaluation & {
264
+ toolName: string;
265
+ cwd: string;
266
+ }) => void;
267
+ /**
268
+ * Sandbox auto-allow (YAGNI Code sandbox): when present and true for this bash call,
269
+ * a prompt-band command runs sandboxed WITHOUT a Guardian consult or user
270
+ * prompt (Claude's autoAllowBashIfSandboxed). Consulted AFTER deny/ask
271
+ * rules, the exec-policy forbidden band, grants, and the session cache —
272
+ * never in plan mode (plan's no-mutation contract outranks it). The
273
+ * caller (session.ts) owns the decision: sandbox initialized + this
274
+ * command will be wrapped + autoAllow enabled.
275
+ */
276
+ sandboxAutoAllow?: (toolName: string, params: Record<string, unknown>) => boolean;
189
277
  /**
190
278
  * User-configurable lifecycle hooks (YAG-506). When present, PreToolUse
191
279
  * hooks run before decideGate and can short-circuit (allow/deny/ask),
@@ -210,9 +298,23 @@ export declare function buildModeContextMessage(mode: PermissionMode): string;
210
298
  export declare function filterStaleModeContext<T>(messages: T[], currentMode?: PermissionMode): T[];
211
299
  /** Legacy alias — the original plan-mode filter name. */
212
300
  export declare const filterStalePlanContext: typeof filterStaleModeContext;
301
+ /** The decision source of ONE tool_call (telemetry), carried per invocation
302
+ * because tool calls run concurrently: refined by the user dialog, hooks,
303
+ * and Guardian outcomes as the call moves through the gate. */
304
+ interface DecisionSlot {
305
+ source: ToolDecisionSource;
306
+ }
307
+ /**
308
+ * The pi tool_call handler wiring (crash-honest attribution). Extracted so
309
+ * the telemetry contract is testable against the production path: a thrown
310
+ * gate records reject — never accept — logs a gate_crashed line (metadata
311
+ * only), and rethrows so pi's handling of a crashed handler is unchanged.
312
+ */
313
+ export declare function wireToolCallGate(pi: Pick<ExtensionAPI, "on">, run: (event: ToolCallEvent, ctx: ExtensionContext, slot: DecisionSlot) => Promise<ToolCallEventResult | undefined>, onToolDecision?: (ev: ToolDecisionEvent) => void): void;
213
314
  /**
214
315
  * Wire the tool_call gate + the /mode command onto a shared mode holder. Default
215
316
  * auto, so absent any /mode this is a no-op over today's behavior.
216
317
  */
217
318
  export declare function registerPermissionGate(pi: ExtensionAPI, deps?: RegisterPermissionDeps): void;
319
+ export {};
218
320
  //# sourceMappingURL=gate.d.ts.map