specrails-core 5.2.2 → 5.3.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 (102) hide show
  1. package/README.md +3 -0
  2. package/bin/specrails-core.mjs +5 -0
  3. package/dist/agent-runtime/cli-executor.d.ts +34 -0
  4. package/dist/agent-runtime/cli-executor.js +335 -0
  5. package/dist/agent-runtime/cli-executor.js.map +1 -0
  6. package/dist/agent-runtime/cli-process.d.ts +32 -0
  7. package/dist/agent-runtime/cli-process.js +159 -0
  8. package/dist/agent-runtime/cli-process.js.map +1 -0
  9. package/dist/agent-runtime/cli.d.ts +38 -0
  10. package/dist/agent-runtime/cli.js +168 -0
  11. package/dist/agent-runtime/cli.js.map +1 -0
  12. package/dist/agent-runtime/config.d.ts +7 -0
  13. package/dist/agent-runtime/config.js +162 -0
  14. package/dist/agent-runtime/config.js.map +1 -0
  15. package/dist/agent-runtime/core-host.d.ts +33 -0
  16. package/dist/agent-runtime/core-host.js +97 -0
  17. package/dist/agent-runtime/core-host.js.map +1 -0
  18. package/dist/agent-runtime/durable-store.d.ts +22 -0
  19. package/dist/agent-runtime/durable-store.js +205 -0
  20. package/dist/agent-runtime/durable-store.js.map +1 -0
  21. package/dist/agent-runtime/executor-types.d.ts +92 -0
  22. package/dist/agent-runtime/executor-types.js +29 -0
  23. package/dist/agent-runtime/executor-types.js.map +1 -0
  24. package/dist/agent-runtime/executors.d.ts +22 -0
  25. package/dist/agent-runtime/executors.js +44 -0
  26. package/dist/agent-runtime/executors.js.map +1 -0
  27. package/dist/agent-runtime/gemini-policy.d.ts +8 -0
  28. package/dist/agent-runtime/gemini-policy.js +36 -0
  29. package/dist/agent-runtime/gemini-policy.js.map +1 -0
  30. package/dist/agent-runtime/graph/artifacts.d.ts +40 -0
  31. package/dist/agent-runtime/graph/artifacts.js +179 -0
  32. package/dist/agent-runtime/graph/artifacts.js.map +1 -0
  33. package/dist/agent-runtime/graph/nodes.d.ts +36 -0
  34. package/dist/agent-runtime/graph/nodes.js +274 -0
  35. package/dist/agent-runtime/graph/nodes.js.map +1 -0
  36. package/dist/agent-runtime/graph/review-policy.d.ts +18 -0
  37. package/dist/agent-runtime/graph/review-policy.js +32 -0
  38. package/dist/agent-runtime/graph/review-policy.js.map +1 -0
  39. package/dist/agent-runtime/graph/roles.d.ts +44 -0
  40. package/dist/agent-runtime/graph/roles.js +126 -0
  41. package/dist/agent-runtime/graph/roles.js.map +1 -0
  42. package/dist/agent-runtime/graph/state.d.ts +75 -0
  43. package/dist/agent-runtime/graph/state.js +23 -0
  44. package/dist/agent-runtime/graph/state.js.map +1 -0
  45. package/dist/agent-runtime/graph-checkpointer.d.ts +61 -0
  46. package/dist/agent-runtime/graph-checkpointer.js +137 -0
  47. package/dist/agent-runtime/graph-checkpointer.js.map +1 -0
  48. package/dist/agent-runtime/index.d.ts +14 -0
  49. package/dist/agent-runtime/index.js +15 -0
  50. package/dist/agent-runtime/index.js.map +1 -0
  51. package/dist/agent-runtime/kimi-acp.d.ts +7 -0
  52. package/dist/agent-runtime/kimi-acp.js +179 -0
  53. package/dist/agent-runtime/kimi-acp.js.map +1 -0
  54. package/dist/agent-runtime/openai-executor.d.ts +18 -0
  55. package/dist/agent-runtime/openai-executor.js +174 -0
  56. package/dist/agent-runtime/openai-executor.js.map +1 -0
  57. package/dist/agent-runtime/prompts.d.ts +40 -0
  58. package/dist/agent-runtime/prompts.js +291 -0
  59. package/dist/agent-runtime/prompts.js.map +1 -0
  60. package/dist/agent-runtime/workflow-types.d.ts +210 -0
  61. package/dist/agent-runtime/workflow-types.js +2 -0
  62. package/dist/agent-runtime/workflow-types.js.map +1 -0
  63. package/dist/agent-runtime/workflow.d.ts +17 -0
  64. package/dist/agent-runtime/workflow.js +609 -0
  65. package/dist/agent-runtime/workflow.js.map +1 -0
  66. package/dist/agent-runtime/workspace-tools.d.ts +25 -0
  67. package/dist/agent-runtime/workspace-tools.js +120 -0
  68. package/dist/agent-runtime/workspace-tools.js.map +1 -0
  69. package/dist/installer/cli.d.ts +35 -0
  70. package/dist/installer/cli.js +3 -0
  71. package/dist/installer/cli.js.map +1 -1
  72. package/dist/installer/commands/doctor.d.ts +27 -0
  73. package/dist/installer/commands/framework.d.ts +85 -0
  74. package/dist/installer/commands/init.d.ts +147 -0
  75. package/dist/installer/commands/update.d.ts +56 -0
  76. package/dist/installer/commands/v5-migration.d.ts +32 -0
  77. package/dist/installer/phases/framework-lifecycle.d.ts +53 -0
  78. package/dist/installer/phases/install-config.d.ts +64 -0
  79. package/dist/installer/phases/manifest.d.ts +45 -0
  80. package/dist/installer/phases/prereqs.d.ts +51 -0
  81. package/dist/installer/phases/provider-detect.d.ts +89 -0
  82. package/dist/installer/phases/scaffold.d.ts +211 -0
  83. package/dist/installer/runtime/kimi.d.ts +84 -0
  84. package/dist/installer/runtime/pipeline-state.d.ts +210 -0
  85. package/dist/installer/runtime/pipeline-state.js +107 -38
  86. package/dist/installer/runtime/pipeline-state.js.map +1 -1
  87. package/dist/installer/util/errors.d.ts +46 -0
  88. package/dist/installer/util/exec.d.ts +41 -0
  89. package/dist/installer/util/fs.d.ts +153 -0
  90. package/dist/installer/util/git.d.ts +44 -0
  91. package/dist/installer/util/install-transaction.d.ts +29 -0
  92. package/dist/installer/util/logger.d.ts +31 -0
  93. package/dist/installer/util/paths.d.ts +34 -0
  94. package/dist/installer/util/prompts.d.ts +23 -0
  95. package/dist/installer/util/registry.d.ts +174 -0
  96. package/dist/installer/util/template.d.ts +23 -0
  97. package/docs/README.md +1 -0
  98. package/docs/agent-runtime.md +268 -0
  99. package/integration-contract.json +79 -7
  100. package/package.json +16 -1
  101. package/schemas/agent-runtime.schema.json +55 -0
  102. package/templates/runtime/provider-pipeline.md +16 -0
@@ -0,0 +1,205 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, open, readFile, rename, rm } from 'node:fs/promises';
3
+ import { hostname } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ export class WorkflowStoreError extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = 'WorkflowStoreError';
11
+ }
12
+ }
13
+ export const ENVELOPE_FORMAT = 2;
14
+ function errorCode(error) {
15
+ return typeof error === 'object' && error !== null && 'code' in error ? String(error.code) : undefined;
16
+ }
17
+ /** Reject non-JSON data instead of silently changing the fingerprint on serialization. */
18
+ export function fingerprint(value) {
19
+ const seen = new Set();
20
+ const canonical = (item) => {
21
+ if (item === null || typeof item === 'string' || typeof item === 'boolean')
22
+ return item;
23
+ if (typeof item === 'number' && Number.isFinite(item))
24
+ return item;
25
+ if (typeof item !== 'object' || item === null || seen.has(item))
26
+ throw new TypeError('Checkpoint values must be finite, acyclic JSON data');
27
+ if (!Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype && Object.getPrototypeOf(item) !== null) {
28
+ throw new TypeError('Checkpoint values must be plain JSON objects');
29
+ }
30
+ seen.add(item);
31
+ const result = Array.isArray(item)
32
+ ? item.map(canonical)
33
+ : Object.fromEntries(Object.keys(item).sort().map(key => [key, canonical(item[key])]));
34
+ seen.delete(item);
35
+ return result;
36
+ };
37
+ return createHash('sha256').update(JSON.stringify(canonical(value))).digest('hex');
38
+ }
39
+ function runDirectory(directory, runId) {
40
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(runId) || runId.endsWith('.') || /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(runId)) {
41
+ throw new WorkflowStoreError('INVALID_ID', 'Run ID must contain 1–128 letters, numbers, dots, underscores or dashes, start with a letter or number, and be a portable filename');
42
+ }
43
+ return join(resolve(directory), runId);
44
+ }
45
+ export async function readWorkflowEnvelope(directory, runId) {
46
+ let raw;
47
+ try {
48
+ raw = await readFile(join(runDirectory(directory, runId), 'checkpoint.json'), 'utf8');
49
+ }
50
+ catch (error) {
51
+ if (errorCode(error) === 'ENOENT')
52
+ return null;
53
+ throw error;
54
+ }
55
+ try {
56
+ const envelope = JSON.parse(raw);
57
+ const state = envelope.state;
58
+ if (envelope.format !== ENVELOPE_FORMAT || !state || state.schemaVersion !== 2 || state.runId !== runId || typeof state.traceId !== 'string' ||
59
+ !Array.isArray(state.events) || !Array.isArray(state.history) || !state.steps ||
60
+ envelope.checksum !== fingerprint({ state, graph: envelope.graph ?? null }))
61
+ throw new Error('Invalid envelope or checksum');
62
+ return { state, ...(envelope.graph ? { graph: envelope.graph } : {}) };
63
+ }
64
+ catch (error) {
65
+ throw new WorkflowStoreError('CORRUPT_STATE', `Cannot read checkpoint for ${runId}: ${error instanceof Error ? error.message : String(error)}`);
66
+ }
67
+ }
68
+ /** Read-only view of the host ledger. */
69
+ export async function readWorkflowState(directory, runId) {
70
+ return (await readWorkflowEnvelope(directory, runId))?.state ?? null;
71
+ }
72
+ /** Publish a complete checkpoint, receipt, usage, event ledger and graph history in one atomic rename. */
73
+ export async function writeWorkflowEnvelope(directory, envelope) {
74
+ const root = runDirectory(directory, envelope.state.runId);
75
+ await mkdir(root, { recursive: true, mode: 0o700 });
76
+ // JSON removes absent optional fields; validate the actual stored representation.
77
+ const normalized = JSON.parse(JSON.stringify({ state: envelope.state, graph: envelope.graph ?? null }));
78
+ const payload = JSON.stringify({ format: ENVELOPE_FORMAT, checksum: fingerprint(normalized), state: normalized.state, ...(normalized.graph ? { graph: normalized.graph } : {}) });
79
+ const temporary = join(root, `.checkpoint-${randomUUID()}.tmp`);
80
+ const handle = await open(temporary, 'wx', 0o600);
81
+ try {
82
+ await handle.writeFile(payload, 'utf8');
83
+ await handle.sync();
84
+ }
85
+ finally {
86
+ await handle.close();
87
+ }
88
+ try {
89
+ // Node's rename replaces an existing file on supported macOS and Windows filesystems.
90
+ await renameReplacing(temporary, join(root, 'checkpoint.json'));
91
+ // POSIX directory sync makes the rename durable; Windows cannot open directories this way.
92
+ if (process.platform !== 'win32') {
93
+ const directoryHandle = await open(root, 'r');
94
+ try {
95
+ await directoryHandle.sync();
96
+ }
97
+ finally {
98
+ await directoryHandle.close();
99
+ }
100
+ }
101
+ }
102
+ finally {
103
+ await rm(temporary, { force: true });
104
+ }
105
+ }
106
+ // Windows reports EPERM/EBUSY when a scanner or reader briefly holds the target;
107
+ // the rename is retried before it is reported as a persistence failure.
108
+ async function renameReplacing(from, to) {
109
+ for (let attempt = 0;; attempt++) {
110
+ try {
111
+ await rename(from, to);
112
+ return;
113
+ }
114
+ catch (error) {
115
+ const code = errorCode(error);
116
+ if (process.platform !== 'win32' || attempt >= 10 || (code !== 'EPERM' && code !== 'EBUSY' && code !== 'EACCES'))
117
+ throw error;
118
+ await new Promise(resolve => setTimeout(resolve, 10 * (attempt + 1)));
119
+ }
120
+ }
121
+ }
122
+ export async function writeWorkflowState(directory, state, graph) {
123
+ await writeWorkflowEnvelope(directory, { state, ...(graph ? { graph } : {}) });
124
+ }
125
+ async function ownerAt(path) {
126
+ try {
127
+ const owner = JSON.parse(await readFile(join(path, 'owner.json'), 'utf8'));
128
+ return Number.isInteger(owner.pid) && owner.pid > 0 && typeof owner.hostname === 'string' && typeof owner.token === 'string' ? owner : null;
129
+ }
130
+ catch (error) {
131
+ if (error instanceof SyntaxError || errorCode(error) === 'ENOENT')
132
+ return null;
133
+ throw error;
134
+ }
135
+ }
136
+ function alive(owner) {
137
+ if (owner.hostname !== hostname())
138
+ return true; // Never steal leases from another machine.
139
+ try {
140
+ process.kill(owner.pid, 0);
141
+ return true;
142
+ }
143
+ catch (error) {
144
+ return errorCode(error) !== 'ESRCH';
145
+ }
146
+ }
147
+ /** Atomic directory leases avoid platform-specific flock and native dependencies. */
148
+ export async function acquireWorkflowLease(directory, runId) {
149
+ const root = runDirectory(directory, runId);
150
+ const lease = join(root, '.lease');
151
+ const recovery = join(root, '.lease-recovery');
152
+ await mkdir(root, { recursive: true, mode: 0o700 });
153
+ const locked = () => new WorkflowStoreError('LOCKED', `Workflow ${runId} has an active or unverifiable lease`);
154
+ let created = false;
155
+ try {
156
+ await mkdir(lease);
157
+ created = true;
158
+ }
159
+ catch (error) {
160
+ if (errorCode(error) !== 'EEXIST')
161
+ throw error;
162
+ }
163
+ if (!created) {
164
+ // A separate election prevents two contenders from deleting each other's new lease.
165
+ try {
166
+ await mkdir(recovery);
167
+ }
168
+ catch (error) {
169
+ if (errorCode(error) === 'EEXIST')
170
+ throw locked();
171
+ throw error;
172
+ }
173
+ try {
174
+ const oldOwner = await ownerAt(lease);
175
+ if (!oldOwner || alive(oldOwner))
176
+ throw locked();
177
+ await rm(lease, { recursive: true, force: true });
178
+ await mkdir(lease);
179
+ }
180
+ finally {
181
+ await rm(recovery, { recursive: true, force: true });
182
+ }
183
+ }
184
+ const owner = { pid: process.pid, hostname: hostname(), token: randomUUID() };
185
+ try {
186
+ const handle = await open(join(lease, 'owner.json'), 'wx', 0o600);
187
+ try {
188
+ await handle.writeFile(JSON.stringify(owner));
189
+ await handle.sync();
190
+ }
191
+ finally {
192
+ await handle.close();
193
+ }
194
+ }
195
+ catch (error) {
196
+ await rm(lease, { recursive: true, force: true });
197
+ throw error;
198
+ }
199
+ return async () => {
200
+ const current = await ownerAt(lease);
201
+ if (current?.token === owner.token)
202
+ await rm(lease, { recursive: true, force: true });
203
+ };
204
+ }
205
+ //# sourceMappingURL=durable-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-store.js","sourceRoot":"","sources":["../../src/agent-runtime/durable-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { VerificationCommand } from '../installer/runtime/pipeline-state.js';
2
+ export type AgentRole = 'architect' | 'developer' | 'reviewer';
3
+ export type CliProvider = 'claude' | 'codex' | 'gemini' | 'kimi';
4
+ export type RuntimeProviderConfig = {
5
+ id: string;
6
+ kind: 'cli';
7
+ cli: CliProvider;
8
+ } | {
9
+ id: string;
10
+ kind: 'openai-compatible';
11
+ baseUrl: string;
12
+ apiKeyEnv?: string;
13
+ };
14
+ export interface RuntimeAgentConfig {
15
+ provider: string;
16
+ model?: string;
17
+ maxTurns?: number;
18
+ }
19
+ export type ReviewAspectName = 'type_correctness' | 'pattern_adherence' | 'test_coverage' | 'security' | 'architectural_alignment';
20
+ export interface RuntimeConfig {
21
+ schemaVersion: 1;
22
+ enabled: boolean;
23
+ providers: RuntimeProviderConfig[];
24
+ agents: Record<AgentRole, RuntimeAgentConfig>;
25
+ limits?: {
26
+ maxAttempts?: number;
27
+ maxTokens?: number;
28
+ maxCostUsd?: number;
29
+ timeoutMs?: number;
30
+ };
31
+ verification: VerificationCommand[];
32
+ approvalBeforeArchive?: boolean;
33
+ /** Review gate thresholds (0–100); unset fields keep Core's defaults. */
34
+ review?: {
35
+ minScore?: number;
36
+ aspects?: Partial<Record<ReviewAspectName, number>>;
37
+ };
38
+ /** What to do when the architect still reports low confidence after investigating: ask the requester (default) or proceed on stated assumptions. */
39
+ architect?: {
40
+ onLowConfidence?: 'ask' | 'proceed';
41
+ };
42
+ }
43
+ /** Null means unavailable, including when a CLI never reports billing. */
44
+ export interface AgentUsage {
45
+ inputTokens: number | null;
46
+ outputTokens: number | null;
47
+ costUsd: number | null;
48
+ }
49
+ export interface AgentEvent {
50
+ kind: 'text' | 'tool-start' | 'tool-end' | 'usage';
51
+ text?: string;
52
+ tool?: string;
53
+ /** Short human-readable tool target, such as a file path or command. Never a complete transcript. */
54
+ detail?: string;
55
+ usage?: AgentUsage;
56
+ }
57
+ export interface AgentRequest {
58
+ role: AgentRole;
59
+ prompt: string;
60
+ cwd: string;
61
+ allowedRoots: string[];
62
+ model?: string;
63
+ maxTurns?: number;
64
+ timeoutMs?: number;
65
+ maxTokens?: number;
66
+ maxCostUsd?: number;
67
+ /** Continue an earlier provider session when the executor supports it. Executors without sessions ignore it. */
68
+ resumeSessionId?: string;
69
+ /** JSON Schema for the final structured reply. Executors with native structured output enforce it; the prompt remains authoritative elsewhere. */
70
+ outputSchema?: Record<string, unknown>;
71
+ signal?: AbortSignal;
72
+ onEvent?: (event: AgentEvent) => void;
73
+ }
74
+ export interface AgentResult {
75
+ text: string;
76
+ usage: AgentUsage;
77
+ sessionId?: string;
78
+ structured?: Record<string, unknown>;
79
+ }
80
+ export type AgentLimits = Pick<AgentRequest, 'maxTokens' | 'maxCostUsd'>;
81
+ export interface AgentExecutor {
82
+ /** Side-effect-free preflight. Custom executors own their limit capabilities. */
83
+ validateLimits?(limits: AgentLimits): void;
84
+ execute(request: AgentRequest): Promise<AgentResult>;
85
+ }
86
+ export declare class AgentExecutionError extends Error {
87
+ readonly code: string;
88
+ readonly usage: AgentUsage;
89
+ constructor(message: string, code: string, usage?: AgentUsage);
90
+ }
91
+ export declare function unknownUsage(): AgentUsage;
92
+ export declare function validateAgentRequest(request: AgentRequest): void;
@@ -0,0 +1,29 @@
1
+ export class AgentExecutionError extends Error {
2
+ code;
3
+ usage;
4
+ constructor(message, code, usage = unknownUsage()) {
5
+ super(message);
6
+ this.code = code;
7
+ this.usage = usage;
8
+ this.name = 'AgentExecutionError';
9
+ }
10
+ }
11
+ export function unknownUsage() { return { inputTokens: null, outputTokens: null, costUsd: null }; }
12
+ export function validateAgentRequest(request) {
13
+ if (!['architect', 'developer', 'reviewer'].includes(request.role) || typeof request.prompt !== 'string' || !request.prompt.trim() || request.prompt.includes('\0'))
14
+ throw new AgentExecutionError('Invalid role request', 'invalid_request');
15
+ if (request.model !== undefined && (typeof request.model !== 'string' || !request.model.trim() || request.model.length > 256 || /^-/.test(request.model) || /[\0\r\n]/.test(request.model)))
16
+ throw new AgentExecutionError('Invalid model identifier', 'invalid_model');
17
+ for (const key of ['maxTurns', 'timeoutMs', 'maxTokens', 'maxCostUsd']) {
18
+ const value = request[key];
19
+ if (value !== undefined && (!Number.isFinite(value) || value <= 0 || (key !== 'maxCostUsd' && !Number.isSafeInteger(value))))
20
+ throw new AgentExecutionError(`Invalid ${key}`, 'invalid_limit');
21
+ }
22
+ if (request.resumeSessionId !== undefined && (typeof request.resumeSessionId !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/.test(request.resumeSessionId)))
23
+ throw new AgentExecutionError('Invalid session identifier', 'invalid_request');
24
+ if (request.outputSchema !== undefined && (!request.outputSchema || typeof request.outputSchema !== 'object' || Array.isArray(request.outputSchema)))
25
+ throw new AgentExecutionError('Invalid output schema', 'invalid_request');
26
+ if (request.signal?.aborted)
27
+ throw new AgentExecutionError('Agent cancelled', 'aborted');
28
+ }
29
+ //# sourceMappingURL=executor-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor-types.js","sourceRoot":"","sources":["../../src/agent-runtime/executor-types.ts"],"names":[],"mappings":"AA8DA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACC;IAA8B;IAA3E,YAAY,OAAe,EAAkB,IAAY,EAAkB,QAAoB,YAAY,EAAE;QAC3G,KAAK,CAAC,OAAO,CAAC,CAAA;QAD6B,SAAI,GAAJ,IAAI,CAAQ;QAAkB,UAAK,GAAL,KAAK,CAA6B;QAE3G,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AACD,MAAM,UAAU,YAAY,KAAiB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA,CAAC,CAAC;AAC9G,MAAM,UAAU,oBAAoB,CAAC,OAAqB;IACxD,IAAI,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAA;IAC7O,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,EAAE,eAAe,CAAC,CAAA;IACvQ,KAAK,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAU,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC1B,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,mBAAmB,CAAC,WAAW,GAAG,EAAE,EAAE,eAAe,CAAC,CAAA;IAChM,CAAC;IACD,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,OAAO,OAAO,CAAC,eAAe,KAAK,QAAQ,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,EAAE,iBAAiB,CAAC,CAAA;IAClP,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,OAAO,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAA;IAC/N,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;AAC1F,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { AgentExecutor, AgentLimits, AgentRequest, AgentResult, RuntimeConfig } from './executor-types.js';
2
+ import { type CliExecutorOptions } from './cli-executor.js';
3
+ import { type OpenAICompatibleOptions } from './openai-executor.js';
4
+ export { CliExecutor, buildCliInvocation, parseCliOutput } from './cli-executor.js';
5
+ export { OpenAICompatibleExecutor } from './openai-executor.js';
6
+ export { AgentExecutionError } from './executor-types.js';
7
+ export type * from './executor-types.js';
8
+ export declare class ExecutorRegistry {
9
+ private readonly executors;
10
+ register(id: string, executor: AgentExecutor): this;
11
+ get(id: string): AgentExecutor;
12
+ ids(): string[];
13
+ validateLimits(id: string, limits: AgentLimits): void;
14
+ execute(id: string, request: AgentRequest): Promise<AgentResult>;
15
+ }
16
+ export interface ExecutorRegistryOptions {
17
+ cli?: CliExecutorOptions;
18
+ openai?: OpenAICompatibleOptions;
19
+ /** Programmatic registrations replace configured executors or add new provider aliases. */
20
+ executors?: Record<string, AgentExecutor>;
21
+ }
22
+ export declare function createExecutorRegistry(input: RuntimeConfig, options?: ExecutorRegistryOptions): ExecutorRegistry;
@@ -0,0 +1,44 @@
1
+ import { AgentExecutionError, validateAgentRequest } from './executor-types.js';
2
+ import { validateRuntimeConfig } from './config.js';
3
+ import { CliExecutor } from './cli-executor.js';
4
+ import { OpenAICompatibleExecutor } from './openai-executor.js';
5
+ export { CliExecutor, buildCliInvocation, parseCliOutput } from './cli-executor.js';
6
+ export { OpenAICompatibleExecutor } from './openai-executor.js';
7
+ export { AgentExecutionError } from './executor-types.js';
8
+ export class ExecutorRegistry {
9
+ executors = new Map();
10
+ register(id, executor) {
11
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(id) || typeof executor?.execute !== 'function')
12
+ throw new Error('Invalid executor registration');
13
+ this.executors.set(id, executor);
14
+ return this;
15
+ }
16
+ get(id) {
17
+ const executor = this.executors.get(id);
18
+ if (!executor)
19
+ throw new AgentExecutionError(`No executor registered for provider '${id}'`, 'provider_not_found');
20
+ return executor;
21
+ }
22
+ ids() { return [...this.executors.keys()]; }
23
+ validateLimits(id, limits) { this.get(id).validateLimits?.(limits); }
24
+ async execute(id, request) {
25
+ validateAgentRequest(request);
26
+ const result = await this.get(id).execute(request);
27
+ if (!result || typeof result.text !== 'string' || !result.text.trim() || !result.usage || ['inputTokens', 'outputTokens', 'costUsd'].some(key => {
28
+ const value = result.usage[key];
29
+ return value !== null && (typeof value !== 'number' || !Number.isFinite(value) || value < 0);
30
+ }))
31
+ throw new AgentExecutionError('Executor returned an invalid result', 'invalid_executor_result');
32
+ return result;
33
+ }
34
+ }
35
+ export function createExecutorRegistry(input, options = {}) {
36
+ const config = validateRuntimeConfig(input, { registeredProviderIds: Object.keys(options.executors ?? {}) });
37
+ const registry = new ExecutorRegistry();
38
+ for (const provider of config.providers)
39
+ registry.register(provider.id, provider.kind === 'cli' ? new CliExecutor(provider.cli, options.cli) : new OpenAICompatibleExecutor(provider, options.openai));
40
+ for (const [id, executor] of Object.entries(options.executors ?? {}))
41
+ registry.register(id, executor);
42
+ return registry;
43
+ }
44
+ //# sourceMappingURL=executors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executors.js","sourceRoot":"","sources":["../../src/agent-runtime/executors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,wBAAwB,EAAgC,MAAM,sBAAsB,CAAA;AAE7F,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,OAAO,gBAAgB;IACV,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC7D,QAAQ,CAAC,EAAU,EAAE,QAAuB;QAC1C,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,OAAO,QAAQ,EAAE,OAAO,KAAK,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC/I,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,GAAG,CAAC,EAAU;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,mBAAmB,CAAC,wCAAwC,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAA;QACjH,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,GAAG,KAAe,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA,CAAC,CAAC;IACrD,cAAc,CAAC,EAAU,EAAE,MAAmB,IAAU,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC;IAC/F,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,OAAqB;QAC7C,oBAAoB,CAAC,OAAO,CAAC,CAAA;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAClD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC9I,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAgC,CAAC,CAAA;YAC5D,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;QAC9F,CAAC,CAAC;YAAE,MAAM,IAAI,mBAAmB,CAAC,qCAAqC,EAAE,yBAAyB,CAAC,CAAA;QACnG,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAOD,MAAM,UAAU,sBAAsB,CAAC,KAAoB,EAAE,UAAmC,EAAE;IAChG,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,EAAE,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IAC5G,MAAM,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAA;IACvC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS;QAAE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IACtM,KAAK,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;IACrG,OAAO,QAAQ,CAAA;AACjB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /** Admin rules outrank Gemini's persisted user approvals. No mode filter: the
2
+ * policy still applies when user settings disable plan and Gemini falls back
3
+ * to default mode. All tools outside this read-only set remain denied. */
4
+ export declare const GEMINI_READONLY_POLICY = "[[rule]]\ntoolName = [\"read_file\", \"read_many_files\", \"list_directory\", \"glob\", \"grep_search\"]\ndecision = \"allow\"\npriority = 999\n\n[[rule]]\ntoolName = \"*\"\ndecision = \"deny\"\npriority = 998\n";
5
+ export declare function assertGeminiAdminPolicyAvailable(options?: {
6
+ platform?: NodeJS.Platform;
7
+ readDirectory?: (directory: string) => string[];
8
+ }): void;
@@ -0,0 +1,36 @@
1
+ import { readdirSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { AgentExecutionError } from './executor-types.js';
4
+ /** Admin rules outrank Gemini's persisted user approvals. No mode filter: the
5
+ * policy still applies when user settings disable plan and Gemini falls back
6
+ * to default mode. All tools outside this read-only set remain denied. */
7
+ export const GEMINI_READONLY_POLICY = `[[rule]]
8
+ toolName = ["read_file", "read_many_files", "list_directory", "glob", "grep_search"]
9
+ decision = "allow"
10
+ priority = 999
11
+
12
+ [[rule]]
13
+ toolName = "*"
14
+ decision = "deny"
15
+ priority = 998
16
+ `;
17
+ export function assertGeminiAdminPolicyAvailable(options = {}) {
18
+ const platform = options.platform ?? process.platform;
19
+ const directory = platform === 'win32'
20
+ ? path.win32.join('C:\\ProgramData\\gemini-cli', 'policies')
21
+ : platform === 'darwin' ? '/Library/Application Support/GeminiCli/policies' : '/etc/gemini-cli/policies';
22
+ let entries;
23
+ try {
24
+ entries = (options.readDirectory ?? (directory => readdirSync(directory)))(directory);
25
+ }
26
+ catch (error) {
27
+ if (error.code === 'ENOENT')
28
+ return;
29
+ throw new AgentExecutionError('Cannot verify Gemini system policies for a read-only role. Check access to ' + directory, 'provider_capability_unsupported');
30
+ }
31
+ // Gemini deliberately ignores --admin-policy in the presence of system
32
+ // policy files. Refuse that environment instead of bypassing its policies.
33
+ if (entries.some(file => file.endsWith('.toml')))
34
+ throw new AgentExecutionError('Gemini system policies disable per-run admin policy enforcement. Select another provider for architect/reviewer, or ask the system administrator to configure a compatible environment: ' + directory, 'provider_capability_unsupported');
35
+ }
36
+ //# sourceMappingURL=gemini-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-policy.js","sourceRoot":"","sources":["../../src/agent-runtime/gemini-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD;;0EAE0E;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;CASrC,CAAA;AAED,MAAM,UAAU,gCAAgC,CAAC,UAA2F,EAAE;IAC5I,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACrD,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO;QACpC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,EAAE,UAAU,CAAC;QAC5D,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,0BAA0B,CAAA;IAC1G,IAAI,OAAiB,CAAA;IACrB,IAAI,CAAC;QAAC,OAAO,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAAC,CAAC;IAC7F,OAAO,KAAK,EAAE,CAAC;QACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAM;QAC9D,MAAM,IAAI,mBAAmB,CAAC,6EAA6E,GAAG,SAAS,EAAE,iCAAiC,CAAC,CAAA;IAC7J,CAAC;IACD,uEAAuE;IACvE,2EAA2E;IAC3E,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,0LAA0L,GAAG,SAAS,EAAE,iCAAiC,CAAC,CAAA;AAC5T,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { type PipelineContext, type PipelineState, type VerificationCommand } from '../../installer/runtime/pipeline-state.js';
2
+ import type { DesignConfidence } from './state.js';
3
+ export declare const SLUG: RegExp;
4
+ export declare function object(value: unknown): Record<string, unknown>;
5
+ /** Accepts the object wherever the model put it: bare, fenced, or surrounded by commentary. */
6
+ export declare function parseAgentObject(text: string): Record<string, unknown>;
7
+ /** All generated paths are relative and reject symlink ancestors, including
8
+ * already-existing archive/spec directories. */
9
+ export declare function child(root: string, relative: string): string;
10
+ export declare function write(file: string, content: string): void;
11
+ export declare function journal(context: PipelineContext): PipelineState;
12
+ export interface Architecture {
13
+ proposal: string;
14
+ design: string;
15
+ tasks: string[];
16
+ specs: Array<{
17
+ name: string;
18
+ content: string;
19
+ }>;
20
+ confidence: DesignConfidence;
21
+ question?: string;
22
+ verification: unknown;
23
+ }
24
+ /** Validates the architect's structured reply; throws `Invalid …` so the role gets one repair turn. */
25
+ export declare function parseArchitecture(raw: Record<string, unknown>): Architecture;
26
+ /**
27
+ * Writes the reviewed architecture artifacts. A low-confidence design that the
28
+ * project chose to proceed with is recorded as `medium` (the contract for a
29
+ * design resting on one named assumption) with its provenance kept alongside,
30
+ * because Core's design gate admits only high or medium confidence.
31
+ */
32
+ export declare function writeArchitecture(context: PipelineContext, change: string, architecture: Architecture, options?: {
33
+ assumed?: boolean;
34
+ }): void;
35
+ /** Commands the architect proposed for repositories the configuration leaves uncovered. */
36
+ export declare function proposedVerification(context: PipelineContext, configured: VerificationCommand[], verification: unknown): VerificationCommand[];
37
+ export declare function openTasks(context: PipelineContext, change: string): string[];
38
+ /** Archive is deterministic and replayable only with explicit write recovery.
39
+ * The reviewed specification documents are complete replacements, not deltas. */
40
+ export declare function archive(context: PipelineContext, change: string): void;