@yagni-app/code-staging 0.3.2-staging.1112.1 → 0.3.2-staging.1115.1

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 (43) hide show
  1. package/dist/cli.js +13 -0
  2. package/dist/extension/hooks.d.ts +111 -0
  3. package/dist/extension/hooks.js +666 -0
  4. package/dist/extension/index.d.ts +7 -0
  5. package/dist/extension/index.js +22 -0
  6. package/dist/extension/permission.d.ts +7 -0
  7. package/dist/extension/permission.js +100 -1
  8. package/dist/extension/pipeline/activityFeed.js +19 -5
  9. package/dist/extension/pipeline/checker.d.ts +99 -0
  10. package/dist/extension/pipeline/checker.js +238 -0
  11. package/dist/extension/pipeline/fanout.d.ts +116 -0
  12. package/dist/extension/pipeline/fanout.js +248 -0
  13. package/dist/extension/pipeline/fanoutBeats.d.ts +31 -0
  14. package/dist/extension/pipeline/fanoutBeats.js +86 -0
  15. package/dist/extension/pipeline/goCommand.d.ts +14 -0
  16. package/dist/extension/pipeline/goCommand.js +38 -1
  17. package/dist/extension/pipeline/headlessGo.d.ts +163 -0
  18. package/dist/extension/pipeline/headlessGo.js +333 -0
  19. package/dist/extension/pipeline/invocation.d.ts +7 -1
  20. package/dist/extension/pipeline/invocation.js +7 -1
  21. package/dist/extension/pipeline/mission.d.ts +55 -0
  22. package/dist/extension/pipeline/mission.js +70 -0
  23. package/dist/extension/pipeline/orchestrator.d.ts +48 -3
  24. package/dist/extension/pipeline/orchestrator.js +450 -9
  25. package/dist/extension/pipeline/personas.d.ts +16 -1
  26. package/dist/extension/pipeline/personas.js +117 -6
  27. package/dist/extension/pipeline/runSession.d.ts +45 -1
  28. package/dist/extension/pipeline/runState.d.ts +57 -12
  29. package/dist/extension/pipeline/runState.js +60 -18
  30. package/dist/extension/pipeline/runner.js +10 -1
  31. package/dist/extension/pipeline/stages.d.ts +84 -7
  32. package/dist/extension/pipeline/stages.js +166 -0
  33. package/dist/extension/pipeline/tierCap.d.ts +32 -0
  34. package/dist/extension/pipeline/tierCap.js +57 -0
  35. package/dist/extension/pipeline/types.d.ts +130 -1
  36. package/dist/extension/pipeline/types.js +17 -0
  37. package/dist/extension/pipeline/verify.d.ts +86 -3
  38. package/dist/extension/pipeline/verify.js +175 -6
  39. package/dist/goHeadless.d.ts +75 -0
  40. package/dist/goHeadless.js +132 -0
  41. package/dist/paths.d.ts +9 -0
  42. package/dist/paths.js +12 -0
  43. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -22,6 +22,7 @@ import { claudeCompatArgs } from "./claudeCompat.js";
22
22
  import { agentDir, credentialsDir, piPackageDir } from "./credentials.js";
23
23
  import { DISTRIBUTION } from "./distribution.js";
24
24
  import { connectCommand } from "./connectClaudeCode.js";
25
+ import { goCommand } from "./goHeadless.js";
25
26
  import { login } from "./login.js";
26
27
  import { logout } from "./logout.js";
27
28
  import { tokenCommand } from "./token.js";
@@ -288,6 +289,10 @@ export const HELP_TEXT = [
288
289
  " yagni login Authorize the active environment (device-code flow).",
289
290
  " yagni logout Revoke and clear the active environment's token.",
290
291
  " yagni doctor Check that everything is ready (green/red checklist).",
292
+ " yagni go --headless Run the /go pipeline without a session, for scripts",
293
+ " and CI: --ticket-file <path> [--plan-file <path>]",
294
+ " [--memo-file <path>] [--run-id <id>] [--json].",
295
+ " Exits 0 only on a reviewed, verified candidate.",
291
296
  " yagni connect claude-code Route Claude Code through the YAGNI model proxy",
292
297
  " (--project scopes to this repo; --off disconnects).",
293
298
  " yagni connect codex Route Codex CLI through the YAGNI model proxy.",
@@ -313,6 +318,8 @@ export const HELP_TEXT = [
313
318
  "The active environment is sticky; `use` switches it (prod is the default).",
314
319
  "Set YAGNI_BASE_URL to override the base URL for a single run.",
315
320
  "Set YAGNI_DISABLE_UPDATE_CHECK=1 to silence the new-version notice.",
321
+ "Set YAGNI_GO_TIER_CAP=<tier> to cap every pipeline stage at that tier",
322
+ " (peak, advanced, standard, efficient). For eval and smoke lanes only.",
316
323
  "Set YAGNI_DISABLE_CLAUDE_COMPAT=1 to skip loading .claude assets.",
317
324
  "Set YAGNI_DISABLE_BRANDING=1 to pass the system prompt through unmodified.",
318
325
  "Set YAGNI_DISABLE_CRASH_REPORTS=1 to turn off sanitized crash reports.",
@@ -424,6 +431,12 @@ export async function main(argv) {
424
431
  if (command === "connect") {
425
432
  return connectCommand(rest);
426
433
  }
434
+ // The headless pipeline entry. `go` is a real subcommand, not passthrough:
435
+ // the interactive run stays `/go` inside a session, and a `yagni go` without
436
+ // --headless is refused with usage rather than launched as an agent prompt.
437
+ if (command === "go") {
438
+ return goCommand(rest, {}, cliVersion());
439
+ }
427
440
  if (command === "token") {
428
441
  return tokenCommand();
429
442
  }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Lifecycle hooks system — user-configurable event hooks (YAG-506).
3
+ *
4
+ * Reads hook config from `~/.yagni-code/config.json` (user) and
5
+ * `.yagni-code/config.json` (project), and fires user-defined shell commands
6
+ * at lifecycle events. The config format mirrors Claude Code's `settings.json`
7
+ * hooks shape so a user can copy-paste between them.
8
+ *
9
+ * Supported events (8): SessionStart, UserPromptSubmit, PreToolUse,
10
+ * PostToolUse, PermissionRequest, PreCompact, PostCompact, SessionEnd.
11
+ *
12
+ * Exit code semantics (matching Claude Code / Codex):
13
+ * 0 = success; stdout parsed as JSON for structured decisions
14
+ * 2 = explicit block/deny (control events only); stderr = reason
15
+ * other = hook failure; decision ignored, warning surfaced, normal flow
16
+ *
17
+ * Fail-soft: a broken hook degrades to "no hook," never to "broken session."
18
+ */
19
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
20
+ /** A single hook command entry, matching Claude Code's wire format. */
21
+ export interface HookEntry {
22
+ type: "command";
23
+ command: string;
24
+ }
25
+ /** A configured hook group with an optional matcher and source tag. */
26
+ export interface HookGroup {
27
+ matcher?: string;
28
+ hooks: HookEntry[];
29
+ /** Where this group was loaded from. Project-level groups are gated on workspace trust. */
30
+ _source?: "user" | "project";
31
+ }
32
+ /** The hooks section of config.json. */
33
+ export type HooksConfig = Record<string, HookGroup[]>;
34
+ /** Supported Claude Code event names. */
35
+ export type HookEventName = "SessionStart" | "UserPromptSubmit" | "PreToolUse" | "PostToolUse" | "PermissionRequest" | "PreCompact" | "PostCompact" | "SessionEnd";
36
+ declare const SUPPORTED_EVENTS: readonly HookEventName[];
37
+ /** Result of a PreToolUse hook evaluation. */
38
+ export type PreToolUseHookResult = {
39
+ decision: "allow";
40
+ } | {
41
+ decision: "deny";
42
+ reason: string;
43
+ } | {
44
+ decision: "ask";
45
+ } | null;
46
+ /** Result of a PermissionRequest hook evaluation. */
47
+ export type PermissionRequestHookResult = {
48
+ decision: "allow";
49
+ } | {
50
+ decision: "deny";
51
+ reason: string;
52
+ } | null;
53
+ /** Interface injected into the permission gate. */
54
+ export interface HookRunner {
55
+ preToolUse(toolName: string, input: Record<string, unknown>, cwd: string, trusted?: boolean): Promise<PreToolUseHookResult>;
56
+ permissionRequest(toolName: string, input: Record<string, unknown>, cwd: string, trusted?: boolean): Promise<PermissionRequestHookResult>;
57
+ }
58
+ /** Read and merge hooks config from user and project files. Pure I/O, fail-soft. */
59
+ export declare function loadHooksConfig(userHome?: string, cwd?: string, env?: NodeJS.ProcessEnv): HooksConfig;
60
+ /**
61
+ * Check if a matcher matches a tool name. Matches Claude Code / Codex:
62
+ * - No matcher → matches everything
63
+ * - "*" → matches everything
64
+ * - Exact string or pipe-separated alternatives ("Edit|Write") → exact match
65
+ * - Contains regex chars → regex match
66
+ */
67
+ export declare function matchesMatcher(matcher: string | undefined, input: string | undefined): boolean;
68
+ interface ExecResult {
69
+ exitCode: number | null;
70
+ stdout: string;
71
+ stderr: string;
72
+ error: string | null;
73
+ durationMs: number;
74
+ }
75
+ /** Execute a hook command with stdin JSON, timeout, and fail-soft. */
76
+ declare function execHook(command: string, inputJson: string, cwd: string, timeoutMs?: number, env?: NodeJS.ProcessEnv): Promise<ExecResult>;
77
+ /** Extract permissionDecision from PreToolUse stdout JSON. */
78
+ export declare function parsePreToolUseOutput(stdout: string): PreToolUseHookResult;
79
+ /** Extract decision from PermissionRequest stdout JSON. */
80
+ export declare function parsePermissionRequestOutput(stdout: string): PermissionRequestHookResult;
81
+ /** Extract additionalContext from stdout JSON (for SessionStart, UserPromptSubmit, PostToolUse). */
82
+ export declare function parseAdditionalContext(stdout: string): string | null;
83
+ /** Check if stdout JSON has continue: false (for PreCompact cancellation). */
84
+ export declare function parseCompactCancel(stdout: string): boolean;
85
+ interface HookExecutorOptions {
86
+ config: HooksConfig;
87
+ env?: NodeJS.ProcessEnv;
88
+ execImpl?: typeof execHook;
89
+ /** Returns true when the workspace is trusted (pi's project trust model). */
90
+ isTrusted?: () => boolean;
91
+ }
92
+ /**
93
+ * Create a HookRunner for injection into the permission gate. The `isTrusted`
94
+ * function is called per hook invocation to gate project-level hooks on
95
+ * workspace trust (pi's project trust model). Defaults to always-trusted.
96
+ */
97
+ export declare function makeHookRunner(opts: HookExecutorOptions): HookRunner | null;
98
+ export interface RegisterHooksDeps {
99
+ config?: HooksConfig;
100
+ env?: NodeJS.ProcessEnv;
101
+ execImpl?: typeof execHook;
102
+ /** Returns true when the workspace is trusted (pi's project trust model). */
103
+ isTrusted?: () => boolean;
104
+ }
105
+ /**
106
+ * Register pi event handlers for all configured lifecycle hooks.
107
+ * No-op if no hooks are configured or in eval mode.
108
+ */
109
+ export declare function registerHooks(pi: ExtensionAPI, deps?: RegisterHooksDeps): void;
110
+ export { SUPPORTED_EVENTS as HOOK_SUPPORTED_EVENTS };
111
+ //# sourceMappingURL=hooks.d.ts.map