@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.
- package/README.md +89 -27
- package/dist/claudeCompat.d.ts +59 -0
- package/dist/claudeCompat.js +109 -2
- package/dist/claudePlugins.d.ts +45 -3
- package/dist/claudePlugins.js +129 -19
- package/dist/cli.js +28 -4
- package/dist/doctor.d.ts +42 -4
- package/dist/doctor.js +150 -15
- package/dist/extension/condensedTools.d.ts +12 -1
- package/dist/extension/condensedTools.js +17 -9
- package/dist/extension/index.d.ts +18 -5
- package/dist/extension/index.js +319 -72
- package/dist/extension/mcp/approval.d.ts +45 -0
- package/dist/extension/mcp/approval.js +164 -0
- package/dist/extension/mcp/auth.d.ts +124 -0
- package/dist/extension/mcp/auth.js +560 -0
- package/dist/extension/mcp/authStore.d.ts +61 -0
- package/dist/extension/mcp/authStore.js +105 -0
- package/dist/extension/mcp/callbackPage.d.ts +31 -0
- package/dist/extension/mcp/callbackPage.js +222 -0
- package/dist/extension/mcp/cliConfig.d.ts +12 -0
- package/dist/extension/mcp/cliConfig.js +12 -0
- package/dist/extension/mcp/config.d.ts +153 -0
- package/dist/extension/mcp/config.js +381 -0
- package/dist/extension/mcp/log.d.ts +28 -0
- package/dist/extension/mcp/log.js +82 -0
- package/dist/extension/mcp/manager.d.ts +100 -0
- package/dist/extension/mcp/manager.js +273 -0
- package/dist/extension/mcp/names.d.ts +25 -0
- package/dist/extension/mcp/names.js +40 -0
- package/dist/extension/mcp/panel.d.ts +33 -0
- package/dist/extension/mcp/panel.js +268 -0
- package/dist/extension/mcp/prompts.d.ts +23 -0
- package/dist/extension/mcp/prompts.js +93 -0
- package/dist/extension/mcp/startup.d.ts +55 -0
- package/dist/extension/mcp/startup.js +152 -0
- package/dist/extension/mcp/tools.d.ts +31 -0
- package/dist/extension/mcp/tools.js +117 -0
- package/dist/extension/mcp/transports.d.ts +17 -0
- package/dist/extension/mcp/transports.js +44 -0
- package/dist/extension/permission/gate.d.ts +104 -2
- package/dist/extension/permission/gate.js +387 -31
- package/dist/extension/permission/guardian.d.ts +24 -5
- package/dist/extension/permission/guardian.js +162 -24
- package/dist/extension/permissionRules/bashFileArgs.d.ts +39 -0
- package/dist/extension/permissionRules/bashFileArgs.js +236 -0
- package/dist/extension/permissionRules/engine.d.ts +50 -0
- package/dist/extension/permissionRules/engine.js +238 -0
- package/dist/extension/permissionRules/loadConfig.d.ts +53 -0
- package/dist/extension/permissionRules/loadConfig.js +90 -0
- package/dist/extension/permissionRules/parser.d.ts +38 -0
- package/dist/extension/permissionRules/parser.js +136 -0
- package/dist/extension/permissionRules/pathRules.d.ts +58 -0
- package/dist/extension/permissionRules/pathRules.js +120 -0
- package/dist/extension/permissionRules/shellRules.d.ts +52 -0
- package/dist/extension/permissionRules/shellRules.js +221 -0
- package/dist/extension/pipeline/invocation.d.ts +3 -6
- package/dist/extension/pipeline/invocation.js +3 -6
- package/dist/extension/pipeline/personas.js +5 -0
- package/dist/extension/pipeline/runner.d.ts +0 -1
- package/dist/extension/pipeline/runner.js +6 -14
- package/dist/extension/plugins/inventory.d.ts +88 -0
- package/dist/extension/plugins/inventory.js +144 -0
- package/dist/extension/plugins/panel.d.ts +45 -0
- package/dist/extension/plugins/panel.js +293 -0
- package/dist/extension/sandbox/bash.d.ts +99 -0
- package/dist/extension/sandbox/bash.js +190 -0
- package/dist/extension/sandbox/config.d.ts +114 -0
- package/dist/extension/sandbox/config.js +366 -0
- package/dist/extension/sandbox/manager.d.ts +98 -0
- package/dist/extension/sandbox/manager.js +216 -0
- package/dist/extension/sandbox/panel.d.ts +111 -0
- package/dist/extension/sandbox/panel.js +342 -0
- package/dist/extension/sandbox/session.d.ts +85 -0
- package/dist/extension/sandbox/session.js +775 -0
- package/dist/extension/telemetry/attrs.d.ts +96 -0
- package/dist/extension/telemetry/attrs.js +149 -0
- package/dist/extension/telemetry/config.d.ts +99 -0
- package/dist/extension/telemetry/config.js +193 -0
- package/dist/extension/telemetry/index.d.ts +7 -0
- package/dist/extension/telemetry/index.js +7 -0
- package/dist/extension/telemetry/probe.d.ts +29 -0
- package/dist/extension/telemetry/probe.js +122 -0
- package/dist/extension/telemetry/register.d.ts +40 -0
- package/dist/extension/telemetry/register.js +192 -0
- package/dist/extension/telemetry/sdk.d.ts +63 -0
- package/dist/extension/telemetry/sdk.js +207 -0
- package/dist/extension/telemetry/tracker.d.ts +131 -0
- package/dist/extension/telemetry/tracker.js +551 -0
- package/dist/extension/vendor/IGNORE-LICENSE-MIT +21 -0
- package/dist/extension/vendor/ignore.d.ts +86 -0
- package/dist/extension/vendor/ignore.js +788 -0
- package/dist/goHeadless.d.ts +1 -1
- package/dist/goHeadless.js +2 -2
- package/dist/launch.d.ts +4 -3
- package/dist/launch.js +7 -4
- package/dist/mcpCommand.d.ts +122 -0
- package/dist/mcpCommand.js +787 -0
- package/dist/otel.d.ts +69 -63
- package/dist/otel.js +154 -119
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +18 -0
- package/dist/pluginCommand.d.ts +43 -0
- package/dist/pluginCommand.js +499 -0
- package/dist/pluginStore.d.ts +170 -0
- package/dist/pluginStore.js +554 -0
- package/dist/upgrade.d.ts +11 -2
- package/dist/upgrade.js +48 -8
- package/package.json +20 -3
- package/dist/extension/mcpTools.d.ts +0 -57
- 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
|