@aligndottech/cli 0.67.0 → 0.68.0

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 (119) hide show
  1. package/README.md +29 -8
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +5 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/capture.d.ts.map +1 -1
  6. package/dist/commands/capture.js +4 -0
  7. package/dist/commands/capture.js.map +1 -1
  8. package/dist/commands/check.d.ts +1 -5
  9. package/dist/commands/check.d.ts.map +1 -1
  10. package/dist/commands/check.js +1 -33
  11. package/dist/commands/check.js.map +1 -1
  12. package/dist/commands/default-action.d.ts.map +1 -1
  13. package/dist/commands/default-action.js +18 -7
  14. package/dist/commands/default-action.js.map +1 -1
  15. package/dist/commands/mcp.d.ts.map +1 -1
  16. package/dist/commands/mcp.js +2 -0
  17. package/dist/commands/mcp.js.map +1 -1
  18. package/dist/commands/setup.d.ts.map +1 -1
  19. package/dist/commands/setup.js +22 -13
  20. package/dist/commands/setup.js.map +1 -1
  21. package/dist/lib/agent/edit-gate.d.ts +30 -0
  22. package/dist/lib/agent/edit-gate.d.ts.map +1 -0
  23. package/dist/lib/agent/edit-gate.js +67 -0
  24. package/dist/lib/agent/edit-gate.js.map +1 -0
  25. package/dist/lib/agent/edit-text.d.ts +14 -0
  26. package/dist/lib/agent/edit-text.d.ts.map +1 -0
  27. package/dist/lib/agent/edit-text.js +34 -0
  28. package/dist/lib/agent/edit-text.js.map +1 -0
  29. package/dist/lib/agent/engines/claude-code-protocol.d.ts +24 -0
  30. package/dist/lib/agent/engines/claude-code-protocol.d.ts.map +1 -0
  31. package/dist/lib/agent/engines/claude-code-protocol.js +123 -0
  32. package/dist/lib/agent/engines/claude-code-protocol.js.map +1 -0
  33. package/dist/lib/agent/engines/claude-code.d.ts +17 -0
  34. package/dist/lib/agent/engines/claude-code.d.ts.map +1 -0
  35. package/dist/lib/agent/engines/claude-code.js +122 -0
  36. package/dist/lib/agent/engines/claude-code.js.map +1 -0
  37. package/dist/lib/agent/engines/pi-models.d.ts +46 -0
  38. package/dist/lib/agent/engines/pi-models.d.ts.map +1 -0
  39. package/dist/lib/agent/engines/pi-models.js +91 -0
  40. package/dist/lib/agent/engines/pi-models.js.map +1 -0
  41. package/dist/lib/agent/engines/pi-sdk.d.ts +39 -0
  42. package/dist/lib/agent/engines/pi-sdk.d.ts.map +1 -0
  43. package/dist/lib/agent/engines/pi-sdk.js +105 -0
  44. package/dist/lib/agent/engines/pi-sdk.js.map +1 -0
  45. package/dist/lib/agent/engines/pi.d.ts +44 -0
  46. package/dist/lib/agent/engines/pi.d.ts.map +1 -0
  47. package/dist/lib/agent/engines/pi.js +185 -0
  48. package/dist/lib/agent/engines/pi.js.map +1 -0
  49. package/dist/lib/agent/graph-tools.d.ts +23 -0
  50. package/dist/lib/agent/graph-tools.d.ts.map +1 -0
  51. package/dist/lib/agent/graph-tools.js +33 -0
  52. package/dist/lib/agent/graph-tools.js.map +1 -0
  53. package/dist/lib/agent/permission-broker.d.ts +25 -0
  54. package/dist/lib/agent/permission-broker.d.ts.map +1 -0
  55. package/dist/lib/agent/permission-broker.js +47 -0
  56. package/dist/lib/agent/permission-broker.js.map +1 -0
  57. package/dist/lib/agent/run-agent-session.d.ts +44 -0
  58. package/dist/lib/agent/run-agent-session.d.ts.map +1 -0
  59. package/dist/lib/agent/run-agent-session.js +137 -0
  60. package/dist/lib/agent/run-agent-session.js.map +1 -0
  61. package/dist/lib/agent/select-engine.d.ts +28 -0
  62. package/dist/lib/agent/select-engine.d.ts.map +1 -0
  63. package/dist/lib/agent/select-engine.js +14 -0
  64. package/dist/lib/agent/select-engine.js.map +1 -0
  65. package/dist/lib/agent/tui/app.d.ts +11 -0
  66. package/dist/lib/agent/tui/app.d.ts.map +1 -0
  67. package/dist/lib/agent/tui/app.js +122 -0
  68. package/dist/lib/agent/tui/app.js.map +1 -0
  69. package/dist/lib/agent/tui/cards.d.ts +16 -0
  70. package/dist/lib/agent/tui/cards.d.ts.map +1 -0
  71. package/dist/lib/agent/tui/cards.js +46 -0
  72. package/dist/lib/agent/tui/cards.js.map +1 -0
  73. package/dist/lib/agent/tui/controller.d.ts +21 -0
  74. package/dist/lib/agent/tui/controller.d.ts.map +1 -0
  75. package/dist/lib/agent/tui/controller.js +29 -0
  76. package/dist/lib/agent/tui/controller.js.map +1 -0
  77. package/dist/lib/agent/tui/theme.d.ts +11 -0
  78. package/dist/lib/agent/tui/theme.d.ts.map +1 -0
  79. package/dist/lib/agent/tui/theme.js +13 -0
  80. package/dist/lib/agent/tui/theme.js.map +1 -0
  81. package/dist/lib/agent/types.d.ts +81 -0
  82. package/dist/lib/agent/types.d.ts.map +1 -0
  83. package/dist/lib/agent/types.js +2 -0
  84. package/dist/lib/agent/types.js.map +1 -0
  85. package/dist/lib/commit-shape.d.ts +3 -1
  86. package/dist/lib/commit-shape.d.ts.map +1 -1
  87. package/dist/lib/commit-shape.js +8 -2
  88. package/dist/lib/commit-shape.js.map +1 -1
  89. package/dist/lib/config.d.ts +4 -0
  90. package/dist/lib/config.d.ts.map +1 -1
  91. package/dist/lib/config.js +17 -0
  92. package/dist/lib/config.js.map +1 -1
  93. package/dist/lib/doctor.d.ts +1 -1
  94. package/dist/lib/doctor.js +2 -2
  95. package/dist/lib/git.d.ts.map +1 -1
  96. package/dist/lib/git.js +4 -1
  97. package/dist/lib/git.js.map +1 -1
  98. package/dist/lib/launch/mcp-child-env.js +1 -1
  99. package/dist/lib/launch/mcp-child-env.js.map +1 -1
  100. package/dist/lib/launch/pi-state.d.ts.map +1 -1
  101. package/dist/lib/launch/pi-state.js +9 -3
  102. package/dist/lib/launch/pi-state.js.map +1 -1
  103. package/dist/lib/personal-import.d.ts +4 -0
  104. package/dist/lib/personal-import.d.ts.map +1 -1
  105. package/dist/lib/personal-import.js +4 -0
  106. package/dist/lib/personal-import.js.map +1 -1
  107. package/dist/lib/scope-real.d.ts +12 -0
  108. package/dist/lib/scope-real.d.ts.map +1 -1
  109. package/dist/lib/sync/real-env.d.ts +12 -0
  110. package/dist/lib/sync/real-env.d.ts.map +1 -1
  111. package/dist/lib/usage-telemetry.d.ts +1 -1
  112. package/dist/lib/usage-telemetry.d.ts.map +1 -1
  113. package/dist/lib/usage-telemetry.js +20 -2
  114. package/dist/lib/usage-telemetry.js.map +1 -1
  115. package/dist/lib/write-confirm.d.ts +13 -4
  116. package/dist/lib/write-confirm.d.ts.map +1 -1
  117. package/dist/lib/write-confirm.js +29 -10
  118. package/dist/lib/write-confirm.js.map +1 -1
  119. package/package.json +5 -2
@@ -0,0 +1,137 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import { confirm, isCancel } from '@clack/prompts';
4
+ import { alignNudgeBody } from '../agent-rules.js';
5
+ import { createConfigStore, savedLlmConfig } from '../config.js';
6
+ import { createGatewayClient } from '../gateway-client.js';
7
+ import { findOnPath } from '../launch/detect.js';
8
+ import { isLocalDefault } from '../launch/launch.js';
9
+ import { readProjectState } from '../launch/project-state.js';
10
+ import { childEnv } from '../launch/run-agent.js';
11
+ import { createLocalDb } from '../local-db.js';
12
+ import { hasConfiguredProvider, probeOllama } from '../local-llm.js';
13
+ import { alignConfigDir } from '../private-files.js';
14
+ import { STARTUP_ENV } from '../startup-env.js';
15
+ import { launchAlignEntry } from '../trusted-align-bin.js';
16
+ import { gateEdit } from './edit-gate.js';
17
+ import { decisionsThatWroteTheseLines } from './edit-text.js';
18
+ import { createClaudeCodeEngine } from './engines/claude-code.js';
19
+ import { resolvePiModel } from './engines/pi-models.js';
20
+ import { createGraphTools } from './graph-tools.js';
21
+ import { selectEngine } from './select-engine.js';
22
+ import { runAgentUi } from './tui/app.js';
23
+ const NOTHING_TO_RUN = [
24
+ 'Align needs a model to run its own agent, or your own Claude Code.',
25
+ ' Add an API key: align ai',
26
+ ' Use a local model: ollama pull qwen2.5:7b',
27
+ ' Or install Claude Code (your subscription works): https://claude.com/claude-code',
28
+ ];
29
+ const CANNOT_RUN = {
30
+ align: 'Align\'s own engine has no model. Add a key with `align ai`, or start Ollama.',
31
+ claude: 'Claude Code is not installed (no `claude` on PATH).',
32
+ };
33
+ function claudeArgs(state) {
34
+ const args = [];
35
+ if (!state.projectHasBlock)
36
+ args.push('--append-system-prompt', alignNudgeBody());
37
+ // Last, because claude's --mcp-config is variadic. Named align-local so it never replaces a
38
+ // server the user configured as `align` (see adapters/claude-code.ts).
39
+ if (!state.projectHasMcp)
40
+ args.push('--mcp-config', JSON.stringify({ mcpServers: { 'align-local': launchAlignEntry('mcpServers') } }));
41
+ return args;
42
+ }
43
+ export async function runAgentSession(opts, deps = defaultSessionDeps()) {
44
+ const model = await deps.resolveModel();
45
+ const claudeBin = deps.findClaude();
46
+ const choice = selectEngine({ flag: opts.engine, remembered: deps.getRemembered(), hasModel: model !== undefined, claudeOnPath: claudeBin !== null });
47
+ if (choice.engine === 'none') {
48
+ (choice.unavailable ? [CANNOT_RUN[choice.unavailable]] : NOTHING_TO_RUN).forEach((l) => deps.out(l));
49
+ return 1;
50
+ }
51
+ if (opts.engine)
52
+ deps.remember(opts.engine);
53
+ const claude = () => deps.createClaudeCodeEngine({
54
+ cwd: deps.cwd,
55
+ bin: claudeBin ?? 'claude',
56
+ extraArgs: claudeArgs(deps.projectState()),
57
+ // The user's own environment, not Align's: a key Align saved stays out of `claude`, and
58
+ // ALIGN_WRAPPED stops an `align` run inside it from opening a second agent.
59
+ env: childEnv(deps.env, deps.startupEnv, { ALIGN_WRAPPED: '1' }),
60
+ });
61
+ let engine;
62
+ let agent = choice.engine === 'align' ? 'align' : 'claude-code';
63
+ if (choice.engine === 'align' && model) {
64
+ try {
65
+ const { createPiEngine } = await deps.loadPiEngine();
66
+ engine = await createPiEngine({ cwd: deps.cwd, stateDir: alignConfigDir(), model, tools: deps.graphTools() });
67
+ }
68
+ catch (err) {
69
+ if (!claudeBin || opts.engine === 'align') {
70
+ deps.out(`Align's own engine could not start: ${err.message}`);
71
+ return 1;
72
+ }
73
+ deps.out(`Align's own engine could not start (${err.message}). Using your Claude Code instead.`);
74
+ engine = claude();
75
+ agent = 'claude-code';
76
+ }
77
+ }
78
+ else {
79
+ engine = claude();
80
+ }
81
+ deps.record(agent);
82
+ return deps.runAgentUi({ engine, decisionCount: deps.countDecisions(), gate: deps.makeGate() });
83
+ }
84
+ export function defaultSessionDeps() {
85
+ const config = createConfigStore();
86
+ const localEnv = config.getEnvironment('local');
87
+ const client = createGatewayClient(localEnv);
88
+ const cwd = process.cwd();
89
+ return {
90
+ cwd,
91
+ env: process.env,
92
+ startupEnv: STARTUP_ENV,
93
+ out: (l) => process.stderr.write(`${l}\n`),
94
+ getRemembered: () => config.getAgentEngine(),
95
+ remember: (e) => config.setAgentEngine(e),
96
+ resolveModel: () => resolvePiModel({ saved: savedLlmConfig(config), probeOllama }),
97
+ findClaude: () => findOnPath('claude', process.env, process.platform),
98
+ projectState: () => readProjectState(cwd, os.homedir(), { localIsDefault: isLocalDefault() }),
99
+ makeGate: () => (ask) => gateEdit(ask, {
100
+ client,
101
+ cwd,
102
+ canAdjudicate: () => hasConfiguredProvider(),
103
+ blame: (input, at) => decisionsThatWroteTheseLines(client, input, at),
104
+ }),
105
+ graphTools: () => createGraphTools({ client, env: localEnv }),
106
+ countDecisions: () => {
107
+ if (!localEnv.localDbPath)
108
+ return 0;
109
+ const db = createLocalDb(localEnv.localDbPath);
110
+ try {
111
+ return db.getStats().decisions;
112
+ }
113
+ finally {
114
+ db.close();
115
+ }
116
+ },
117
+ // The engine is a one-time download on first use (pi-sdk.ts says why), asked for here, before
118
+ // the screen opens. A no or a failure falls back like any engine that cannot start.
119
+ loadPiEngine: async () => {
120
+ const { defaultPiSdkDeps, loadPiSdk, PI_ENGINE_VERSION } = await import('./engines/pi-sdk.js');
121
+ const sdk = await loadPiSdk(defaultPiSdkDeps({
122
+ engineDir: path.join(alignConfigDir(), 'engine', PI_ENGINE_VERSION),
123
+ confirm: async (message) => { const yes = await confirm({ message, initialValue: true }); return !isCancel(yes) && yes === true; },
124
+ }));
125
+ const { createPiEngine } = await import('./engines/pi.js');
126
+ return { createPiEngine: (o) => createPiEngine(o, { sdk }) };
127
+ },
128
+ createClaudeCodeEngine,
129
+ runAgentUi,
130
+ record: (agent) => {
131
+ void import('../usage-telemetry.js')
132
+ .then((m) => m.recordFunnelStage(localEnv, 'agent_launched', 'align', { agent }))
133
+ .catch(() => undefined);
134
+ },
135
+ };
136
+ }
137
+ //# sourceMappingURL=run-agent-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-agent-session.js","sourceRoot":"","sources":["../../../src/lib/agent/run-agent-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Which engine bare `align` runs behind Align's UI.
3
+ *
4
+ * An explicit `--engine` is obeyed or refused, never swapped for the other: a person who typed
5
+ * `--engine claude` and got a different model would not know which one answered. A remembered
6
+ * choice is softer, because the machine may have changed since it was saved (Claude Code
7
+ * uninstalled, a key removed), so it falls back to the default. The default prefers Align's own
8
+ * engine when a model is configured, then the user's own Claude Code, which keeps a subscription
9
+ * user on their subscription with no key to buy.
10
+ */
11
+ export type EngineName = 'align' | 'claude';
12
+ export interface EngineFacts {
13
+ flag?: EngineName;
14
+ remembered?: EngineName;
15
+ /** A model the Align engine can run on: a saved or exported key, or a reachable Ollama. */
16
+ hasModel: boolean;
17
+ claudeOnPath: boolean;
18
+ }
19
+ export type EngineChoice = {
20
+ engine: 'align';
21
+ } | {
22
+ engine: 'claude-code';
23
+ } | {
24
+ engine: 'none';
25
+ unavailable?: EngineName;
26
+ };
27
+ export declare function selectEngine(f: EngineFacts): EngineChoice;
28
+ //# sourceMappingURL=select-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-engine.d.ts","sourceRoot":"","sources":["../../../src/lib/agent/select-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAO1H,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,YAAY,CAKzD"}
@@ -0,0 +1,14 @@
1
+ function runnable(name, f) {
2
+ if (name === 'align')
3
+ return f.hasModel ? { engine: 'align' } : undefined;
4
+ return f.claudeOnPath ? { engine: 'claude-code' } : undefined;
5
+ }
6
+ export function selectEngine(f) {
7
+ if (f.flag)
8
+ return runnable(f.flag, f) ?? { engine: 'none', unavailable: f.flag };
9
+ const remembered = f.remembered && runnable(f.remembered, f);
10
+ if (remembered)
11
+ return remembered;
12
+ return runnable('align', f) ?? runnable('claude', f) ?? { engine: 'none' };
13
+ }
14
+ //# sourceMappingURL=select-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-engine.js","sourceRoot":"","sources":["../../../src/lib/agent/select-engine.ts"],"names":[],"mappings":"AAsBA,SAAS,QAAQ,CAAC,IAAgB,EAAE,CAAc;IAChD,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAc;IACzC,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClF,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC7D,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type Terminal } from '@earendil-works/pi-tui';
2
+ import type { AgentEngine, GateOutcome, ToolAsk } from '../types.js';
3
+ /** The only file that names pi-tui, so a breaking change there stays in one place. */
4
+ export interface AgentUiOptions {
5
+ engine: AgentEngine;
6
+ decisionCount: number;
7
+ gate: (ask: ToolAsk) => Promise<GateOutcome>;
8
+ terminal?: Terminal;
9
+ }
10
+ export declare function runAgentUi(opts: AgentUiOptions): Promise<number>;
11
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/tui/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0G,KAAK,QAAQ,EAAuB,MAAM,wBAAwB,CAAC;AAGpL,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAe,OAAO,EAAE,MAAM,aAAa,CAAC;AAKlF,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAaD,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgGtE"}
@@ -0,0 +1,122 @@
1
+ import { Container, Editor, Markdown, matchesKey, ProcessTerminal, Spacer, Text, TuiMainScreen } from '@earendil-works/pi-tui';
2
+ import chalk from 'chalk';
3
+ import { createBroker } from '../permission-broker.js';
4
+ import { commandCard, gateCard, gateNote, headerLine, toolLine } from './cards.js';
5
+ import { answerForKey, createController } from './controller.js';
6
+ import { theme } from './theme.js';
7
+ const markdownTheme = {
8
+ heading: theme.title, link: theme.link, linkUrl: theme.dim, code: theme.key, codeBlock: (s) => s,
9
+ codeBlockBorder: theme.dim, quote: theme.dim, quoteBorder: theme.dim, hr: theme.dim, listBullet: theme.key,
10
+ bold: chalk.bold, italic: chalk.italic, strikethrough: chalk.strikethrough, underline: chalk.underline,
11
+ };
12
+ const editorTheme = {
13
+ borderColor: theme.dim,
14
+ selectList: { selectedPrefix: theme.key, selectedText: theme.title, description: theme.dim, scrollInfo: theme.dim, noMatch: theme.dim },
15
+ };
16
+ export async function runAgentUi(opts) {
17
+ const { engine } = opts;
18
+ const tui = new TuiMainScreen(opts.terminal ?? new ProcessTerminal());
19
+ const transcript = new Container();
20
+ const editor = new Editor(tui, editorTheme);
21
+ const controller = createController();
22
+ let streaming;
23
+ let pending;
24
+ let finish = () => { };
25
+ const addLines = (lines) => {
26
+ streaming = undefined;
27
+ for (const l of lines)
28
+ transcript.addChild(new Text(l, 1, 0));
29
+ tui.requestRender();
30
+ };
31
+ const endTurn = () => { controller.turnEnded(); editor.disableSubmit = false; tui.requestRender(); };
32
+ const askHuman = (q) => {
33
+ addLines(['', ...(q.kind === 'gate' ? gateCard(q) : commandCard(q)), '']);
34
+ controller.beginAsk();
35
+ return new Promise((resolve) => { pending = { kind: q.kind, resolve }; });
36
+ };
37
+ const broker = createBroker({ gate: opts.gate, askHuman, onGate: (outcome) => addLines(gateNote(outcome)) });
38
+ const onKey = (data) => {
39
+ if (matchesKey(data, 'ctrl+c')) {
40
+ if (controller.ctrlC() === 'exit')
41
+ finish(0);
42
+ else
43
+ addLines([theme.dim('Press Ctrl+C again to leave.')]);
44
+ return { consume: true };
45
+ }
46
+ controller.otherKey();
47
+ if (matchesKey(data, 'ctrl+d') && controller.ctrlD(editor.getText() === '') === 'exit') {
48
+ finish(0);
49
+ return { consume: true };
50
+ }
51
+ if (pending) {
52
+ const answer = answerForKey(pending.kind, data);
53
+ if (answer) {
54
+ const { resolve } = pending;
55
+ pending = undefined;
56
+ controller.endAsk();
57
+ resolve(answer);
58
+ }
59
+ return { consume: true };
60
+ }
61
+ if (matchesKey(data, 'escape') && controller.escape() === 'abort') {
62
+ engine.abort();
63
+ return { consume: true };
64
+ }
65
+ return undefined;
66
+ };
67
+ editor.onSubmit = (text) => {
68
+ const line = controller.submit(text);
69
+ if (line === undefined)
70
+ return;
71
+ editor.setText('');
72
+ editor.disableSubmit = true;
73
+ addLines(['', `${theme.brand('>')} ${line}`]);
74
+ engine.prompt(line).catch((e) => addLines([theme.error(e instanceof Error ? e.message : String(e))])).finally(endTurn);
75
+ };
76
+ tui.addChild(new Text(headerLine({ label: engine.label, decisionCount: opts.decisionCount }), 1, 0));
77
+ tui.addChild(new Spacer(1));
78
+ tui.addChild(transcript);
79
+ tui.addChild(editor);
80
+ tui.setFocus(editor);
81
+ tui.addInputListener(onKey);
82
+ const closed = new Promise((resolve) => { finish = resolve; });
83
+ let failed;
84
+ try {
85
+ tui.start();
86
+ // An engine that cannot start (no `claude`, a bad key) ends the run with its reason, printed
87
+ // after the screen is restored, rather than throwing out of a cleared terminal.
88
+ await engine.start((e) => {
89
+ if (e.type === 'text') {
90
+ if (!streaming) {
91
+ streaming = { md: new Markdown('', 1, 0, markdownTheme), text: '' };
92
+ transcript.addChild(streaming.md);
93
+ }
94
+ streaming.text += e.delta;
95
+ streaming.md.setText(streaming.text);
96
+ }
97
+ else if (e.type === 'gate') {
98
+ addLines(gateNote(e.outcome));
99
+ }
100
+ else if (e.type === 'error') {
101
+ addLines([theme.error(e.message)]);
102
+ }
103
+ else {
104
+ addLines(toolLine(e));
105
+ if (e.type === 'turn-end')
106
+ endTurn();
107
+ }
108
+ tui.requestRender();
109
+ }, broker).catch((err) => { failed = err instanceof Error ? err.message : String(err); });
110
+ if (failed === undefined) {
111
+ const code = await closed;
112
+ await engine.close();
113
+ return code;
114
+ }
115
+ }
116
+ finally {
117
+ tui.stop();
118
+ }
119
+ process.stderr.write(`${failed}\n`);
120
+ return 1;
121
+ }
122
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../src/lib/agent/tui/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { HumanQuestion } from '../permission-broker.js';
2
+ import type { AgentUiEvent, GateOutcome } from '../types.js';
3
+ export declare function headerLine(o: {
4
+ label: string;
5
+ decisionCount: number;
6
+ }): string;
7
+ export declare function gateCard(q: Extract<HumanQuestion, {
8
+ kind: 'gate';
9
+ }>): string[];
10
+ export declare function commandCard(q: Extract<HumanQuestion, {
11
+ kind: 'command';
12
+ }>): string[];
13
+ /** What an allowed edit leaves in the transcript. Never silent when the gate could not check. */
14
+ export declare function gateNote(outcome: GateOutcome): string[];
15
+ export declare function toolLine(e: AgentUiEvent): string[];
16
+ //# sourceMappingURL=cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/tui/cards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAG3E,wBAAgB,UAAU,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAG9E;AAUD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,EAAE,CAY9E;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAAG,MAAM,EAAE,CAEpF;AAED,iGAAiG;AACjG,wBAAgB,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,CAKvD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAIlD"}
@@ -0,0 +1,46 @@
1
+ import { theme } from './theme.js';
2
+ export function headerLine(o) {
3
+ const n = `${o.decisionCount} ${o.decisionCount === 1 ? 'decision' : 'decisions'}`;
4
+ return [theme.brand('Align'), o.label, n].join(theme.dim(' · '));
5
+ }
6
+ function decisionLines(d) {
7
+ return [
8
+ ` ${theme.title(d.title)}`,
9
+ ...(d.why ? [` ${d.why}`] : []),
10
+ ...(d.url ? [` ${theme.link(d.url)}`] : []),
11
+ ];
12
+ }
13
+ export function gateCard(q) {
14
+ const lead = {
15
+ conflict: 'This edit conflicts with a decision',
16
+ 'rewrites-decided-lines': 'This edit changes lines written by a decision',
17
+ unchecked: 'Align could not read this edit, so it was not checked against your decisions',
18
+ }[q.outcome.reason];
19
+ return [
20
+ theme.warn(lead),
21
+ ...q.outcome.cards.flatMap((d) => ['', ...decisionLines(d)]),
22
+ '',
23
+ theme.key('[a] allow once [s] stop'),
24
+ ];
25
+ }
26
+ export function commandCard(q) {
27
+ return [theme.warn('Run this command?'), ` ${q.command}`, '', theme.key('[y] yes [s] yes for this session [n] no')];
28
+ }
29
+ /** What an allowed edit leaves in the transcript. Never silent when the gate could not check. */
30
+ export function gateNote(outcome) {
31
+ if (outcome.kind !== 'allow')
32
+ return [];
33
+ if (outcome.note === 'not-checked')
34
+ return [theme.dim('not checked against the decision graph')];
35
+ if (outcome.cards.length === 0)
36
+ return [];
37
+ return [theme.dim(`checked against: ${outcome.cards.map((d) => d.title).join(', ')}`)];
38
+ }
39
+ export function toolLine(e) {
40
+ if (e.type === 'tool-start')
41
+ return [`${theme.dim('•')} ${theme.title(e.tool)} ${theme.dim(e.summary)}`];
42
+ if (e.type === 'tool-end' && !e.ok)
43
+ return [theme.error(' that tool call failed')];
44
+ return [];
45
+ }
46
+ //# sourceMappingURL=cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.js","sourceRoot":"","sources":["../../../../src/lib/agent/tui/cards.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,UAAU,UAAU,CAAC,CAA2C;IACpE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACnF,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,aAAa,CAAC,CAAe;IACpC,OAAO;QACL,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;QAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAA2C;IAClE,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE,qCAAqC;QAC/C,wBAAwB,EAAE,+CAA+C;QACzE,SAAS,EAAE,8EAA8E;KAC1F,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAChB,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,EAAE;QACF,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAA8C;IACxE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;AAC3H,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,QAAQ,CAAC,OAAoB;IAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACjG,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAe;IACtC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzG,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACpF,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { HumanAnswer } from '../types.js';
2
+ /** The screen's state machine, with no terminal in it so it can be tested on its own. */
3
+ export type Phase = 'idle' | 'running' | 'awaiting-answer';
4
+ export interface Controller {
5
+ phase(): Phase;
6
+ /** Returns the text to send, or undefined when the line is empty or a turn is already running. */
7
+ submit(text: string): string | undefined;
8
+ turnEnded(): void;
9
+ beginAsk(): void;
10
+ endAsk(): void;
11
+ /** Esc: abort only while a turn runs (not while a question is open). */
12
+ escape(): 'abort' | 'none';
13
+ /** Two in a row exit. */
14
+ ctrlC(): 'hint' | 'exit';
15
+ /** Any key that is not Ctrl+C resets the exit count. */
16
+ otherKey(): void;
17
+ ctrlD(editorEmpty: boolean): 'exit' | 'none';
18
+ }
19
+ export declare function createController(): Controller;
20
+ export declare function answerForKey(kind: 'gate' | 'command', key: string): HumanAnswer | undefined;
21
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/tui/controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,yFAAyF;AACzF,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,KAAK,CAAC;IACf,kGAAkG;IAClG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,SAAS,IAAI,IAAI,CAAC;IAClB,QAAQ,IAAI,IAAI,CAAC;IACjB,MAAM,IAAI,IAAI,CAAC;IACf,wEAAwE;IACxE,MAAM,IAAI,OAAO,GAAG,MAAM,CAAC;IAC3B,yBAAyB;IACzB,KAAK,IAAI,MAAM,GAAG,MAAM,CAAC;IACzB,wDAAwD;IACxD,QAAQ,IAAI,IAAI,CAAC;IACjB,KAAK,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CAC9C;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAmB7C;AAOD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE3F"}
@@ -0,0 +1,29 @@
1
+ export function createController() {
2
+ let phase = 'idle';
3
+ let ctrlCs = 0;
4
+ return {
5
+ phase: () => phase,
6
+ submit(text) {
7
+ const t = text.trim();
8
+ if (phase !== 'idle' || t === '')
9
+ return undefined;
10
+ phase = 'running';
11
+ return t;
12
+ },
13
+ turnEnded() { phase = 'idle'; },
14
+ beginAsk() { phase = 'awaiting-answer'; },
15
+ endAsk() { phase = 'running'; },
16
+ escape: () => (phase === 'running' ? 'abort' : 'none'),
17
+ ctrlC() { ctrlCs += 1; return ctrlCs >= 2 ? 'exit' : 'hint'; },
18
+ otherKey() { ctrlCs = 0; },
19
+ ctrlD: (editorEmpty) => (editorEmpty ? 'exit' : 'none'),
20
+ };
21
+ }
22
+ const ANSWER_KEYS = {
23
+ gate: { a: 'allow', s: 'stop' },
24
+ command: { y: 'allow', s: 'allow-session', n: 'stop' },
25
+ };
26
+ export function answerForKey(kind, key) {
27
+ return ANSWER_KEYS[kind][key.toLowerCase()];
28
+ }
29
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../../src/lib/agent/tui/controller.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,gBAAgB;IAC9B,IAAI,KAAK,GAAU,MAAM,CAAC;IAC1B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK;QAClB,MAAM,CAAC,IAAI;YACT,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,SAAS,CAAC;YACnD,KAAK,GAAG,SAAS,CAAC;YAClB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,SAAS,KAAK,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;QAC/B,QAAQ,KAAK,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC;QACzC,MAAM,KAAK,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACtD,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,KAAK,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,WAAW,GAA4D;IAC3E,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE;IAC/B,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,MAAM,EAAE;CACvD,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAwB,EAAE,GAAW;IAChE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Align's colours for the agent screen. Pure string styling, so cards stay testable as text. */
2
+ export declare const theme: {
3
+ brand: (s: string) => string;
4
+ dim: (s: string) => string;
5
+ title: (s: string) => string;
6
+ warn: (s: string) => string;
7
+ link: (s: string) => string;
8
+ key: (s: string) => string;
9
+ error: (s: string) => string;
10
+ };
11
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/tui/theme.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,eAAO,MAAM,KAAK;eACL,MAAM,KAAG,MAAM;aACjB,MAAM,KAAG,MAAM;eACb,MAAM,KAAG,MAAM;cAChB,MAAM,KAAG,MAAM;cACf,MAAM,KAAG,MAAM;aAChB,MAAM,KAAG,MAAM;eACb,MAAM,KAAG,MAAM;CAC3B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import chalk from 'chalk';
2
+ import { BRAND } from '../../brand.js';
3
+ /** Align's colours for the agent screen. Pure string styling, so cards stay testable as text. */
4
+ export const theme = {
5
+ brand: (s) => chalk.hex(BRAND.teal).bold(s),
6
+ dim: (s) => chalk.dim(s),
7
+ title: (s) => chalk.bold(s),
8
+ warn: (s) => chalk.yellow(s),
9
+ link: (s) => chalk.hex(BRAND.teal).underline(s),
10
+ key: (s) => chalk.hex(BRAND.teal)(s),
11
+ error: (s) => chalk.red(s),
12
+ };
13
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../../src/lib/agent/tui/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,iGAAiG;AACjG,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,GAAG,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,KAAK,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/D,GAAG,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,KAAK,EAAE,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3C,CAAC"}
@@ -0,0 +1,81 @@
1
+ import type { HookToolInput } from '../hook-payload.js';
2
+ /**
3
+ * The Align agent's own vocabulary. Engines (Align's own on Pi, the user's own Claude Code)
4
+ * translate their wire formats into these types, so the gate, the broker and the UI never
5
+ * name an engine's types, and a breaking change in an engine stays inside its adapter.
6
+ */
7
+ /** What a tool call is, for the purpose of deciding who must approve it. */
8
+ export type ToolKind = 'edit' | 'command' | 'read' | 'other';
9
+ export interface ToolAsk {
10
+ /** The engine's id for this tool call. */
11
+ id: string;
12
+ /** The engine's tool name, as the engine spells it (Write, edit, Bash, bash). */
13
+ tool: string;
14
+ kind: ToolKind;
15
+ /** For kind 'edit': the change normalised to the shape the hook check already reads. */
16
+ edit?: HookToolInput;
17
+ /** For kind 'command': the command line. */
18
+ command?: string;
19
+ /** For kind 'other': the tool's input as JSON, so a person approves what will actually run. */
20
+ detail?: string;
21
+ }
22
+ /** A decision shown to the human on a gate card. */
23
+ export interface GateDecision {
24
+ id: string;
25
+ title: string;
26
+ why?: string;
27
+ url?: string;
28
+ /** How the gate found it: the edit rewrites lines it wrote, retrieval, or an adjudicated verdict. */
29
+ via: 'blame' | 'retrieval' | 'verdict';
30
+ }
31
+ export type GateOutcome = {
32
+ kind: 'allow';
33
+ cards: GateDecision[];
34
+ note?: 'not-checked';
35
+ }
36
+ /** unchecked: an edit whose shape the gate cannot read. It asks rather than passing unseen. */
37
+ | {
38
+ kind: 'ask';
39
+ reason: 'conflict' | 'rewrites-decided-lines' | 'unchecked';
40
+ cards: GateDecision[];
41
+ };
42
+ export type HumanAnswer = 'allow' | 'allow-session' | 'stop';
43
+ export type BrokerVerdict = {
44
+ allow: true;
45
+ } | {
46
+ allow: false;
47
+ message: string;
48
+ };
49
+ export type AgentUiEvent = {
50
+ type: 'text';
51
+ delta: string;
52
+ } | {
53
+ type: 'tool-start';
54
+ id: string;
55
+ tool: string;
56
+ summary: string;
57
+ } | {
58
+ type: 'tool-end';
59
+ id: string;
60
+ ok: boolean;
61
+ } | {
62
+ type: 'gate';
63
+ outcome: GateOutcome;
64
+ filePath?: string;
65
+ } | {
66
+ type: 'turn-end';
67
+ } | {
68
+ type: 'error';
69
+ message: string;
70
+ };
71
+ /** The port every engine implements. */
72
+ export interface AgentEngine {
73
+ /** Shown in the header, e.g. "Claude Code (your subscription)". */
74
+ readonly label: string;
75
+ start(onEvent: (e: AgentUiEvent) => void, broker: (ask: ToolAsk) => Promise<BrokerVerdict>): Promise<void>;
76
+ /** Sends one user turn; resolves when the turn ends. */
77
+ prompt(text: string): Promise<void>;
78
+ abort(): void;
79
+ close(): Promise<void>;
80
+ }
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/agent/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;GAIG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7D,MAAM,WAAW,OAAO;IACtB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qGAAqG;IACrG,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,aAAa,CAAA;CAAE;AAChE,+FAA+F;GAC7F;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,wBAAwB,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAExG,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,eAAe,GAAG,MAAM,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3G,wDAAwD;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/agent/types.ts"],"names":[],"mappings":""}
@@ -50,7 +50,9 @@ export declare function isNonBehaviouralType(title: string): boolean;
50
50
  * replace, drop, stop, move, change, make), `feat`, an `RFC:` prefix, and any title in a language
51
51
  * whose verbs this list does not know. A one-off lead is rescued by a stated purpose
52
52
  * (STATED_WHY: "so that", "to keep", "because" ...), a policy word or modal (adopt, require,
53
- * never, should not ...), or a sweeping quantifier (all, every).
53
+ * never, should not ...), a sweeping quantifier (all, every), or a numeric bound (between 400 and 599).
54
54
  */
55
+ /** Does the title state a numeric bound? Shared so a title-only rule is kept by every filter, not only this one. */
56
+ export declare function statesNumericBound(title: string): boolean;
55
57
  export declare function isOneOffChangeTitle(title: string): boolean;
56
58
  //# sourceMappingURL=commit-shape.d.ts.map