@semanticintent/phoenix-runtime 0.1.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.
- package/README.md +66 -0
- package/agents/A-00-SIGNAL-EXTRACTION.md +194 -0
- package/agents/A-01-BUSINESS-LOGIC-EXTRACTOR.md +163 -0
- package/agents/A-02-UI-ARCHAEOLOGIST.md +196 -0
- package/agents/A-03-REQUIREMENTS-SYNTHESIZER.md +193 -0
- package/agents/A-04-SOLUTION-ARCHITECT.md +218 -0
- package/agents/A-05-BUILDER.md +266 -0
- package/agents/A-06-VALIDATOR-CERTIFIER.md +304 -0
- package/bin/phoenix.js +3 -0
- package/dist/cli/commands/episode.d.ts +3 -0
- package/dist/cli/commands/episode.d.ts.map +1 -0
- package/dist/cli/commands/episode.js +125 -0
- package/dist/cli/commands/episode.js.map +1 -0
- package/dist/cli/commands/gate.d.ts +3 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +57 -0
- package/dist/cli/commands/gate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +77 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +56 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +23 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +41 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/display.d.ts +12 -0
- package/dist/cli/display.d.ts.map +1 -0
- package/dist/cli/display.js +28 -0
- package/dist/cli/display.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/episodes/manager.d.ts +16 -0
- package/dist/episodes/manager.d.ts.map +1 -0
- package/dist/episodes/manager.js +96 -0
- package/dist/episodes/manager.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/sil.d.ts +15 -0
- package/dist/parser/sil.d.ts.map +1 -0
- package/dist/parser/sil.js +137 -0
- package/dist/parser/sil.js.map +1 -0
- package/dist/pipeline/agents.d.ts +16 -0
- package/dist/pipeline/agents.d.ts.map +1 -0
- package/dist/pipeline/agents.js +72 -0
- package/dist/pipeline/agents.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +21 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +213 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/state.d.ts +34 -0
- package/dist/pipeline/state.d.ts.map +1 -0
- package/dist/pipeline/state.js +83 -0
- package/dist/pipeline/state.js.map +1 -0
- package/dist/prompts/loader.d.ts +3 -0
- package/dist/prompts/loader.d.ts.map +1 -0
- package/dist/prompts/loader.js +22 -0
- package/dist/prompts/loader.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Phase 1 — Agent Registry
|
|
2
|
+
// Defines the pipeline sequence and prerequisites for each agent.
|
|
3
|
+
export const AGENTS = [
|
|
4
|
+
{
|
|
5
|
+
id: 'a-00',
|
|
6
|
+
name: 'Signal Extraction',
|
|
7
|
+
promptFile: 'agents/A-00-SIGNAL-EXTRACTION.md',
|
|
8
|
+
requires: { agents: [], gates: [], constructs: [] },
|
|
9
|
+
produces: ['signal'],
|
|
10
|
+
humanGate: false,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: 'a-01',
|
|
14
|
+
name: 'Business Logic Extractor',
|
|
15
|
+
promptFile: 'agents/A-01-BUSINESS-LOGIC-EXTRACTOR.md',
|
|
16
|
+
requires: { agents: ['a-00'], gates: [], constructs: ['signal'] },
|
|
17
|
+
produces: ['workflow'],
|
|
18
|
+
humanGate: false,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'a-02',
|
|
22
|
+
name: 'UI Archaeologist',
|
|
23
|
+
promptFile: 'agents/A-02-UI-ARCHAEOLOGIST.md',
|
|
24
|
+
requires: { agents: ['a-01'], gates: [], constructs: ['workflow'] },
|
|
25
|
+
produces: ['screen'],
|
|
26
|
+
humanGate: false,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'a-03',
|
|
30
|
+
name: 'Requirements Synthesizer',
|
|
31
|
+
promptFile: 'agents/A-03-REQUIREMENTS-SYNTHESIZER.md',
|
|
32
|
+
requires: { agents: ['a-01', 'a-02'], gates: [], constructs: ['workflow', 'screen'] },
|
|
33
|
+
produces: ['spec'],
|
|
34
|
+
humanGate: false,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'a-04',
|
|
38
|
+
name: 'Solution Architect',
|
|
39
|
+
promptFile: 'agents/A-04-SOLUTION-ARCHITECT.md',
|
|
40
|
+
requires: { agents: ['a-03'], gates: [], constructs: ['spec'] },
|
|
41
|
+
produces: ['architecture', 'blueprint'],
|
|
42
|
+
humanGate: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'a-05',
|
|
46
|
+
name: 'Builder',
|
|
47
|
+
promptFile: 'agents/A-05-BUILDER.md',
|
|
48
|
+
requires: {
|
|
49
|
+
agents: ['a-04'],
|
|
50
|
+
gates: ['a-04-approved'],
|
|
51
|
+
constructs: ['spec', 'blueprint', 'screen'],
|
|
52
|
+
},
|
|
53
|
+
produces: ['build'],
|
|
54
|
+
humanGate: true, // six human gates — one per pass
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'a-06',
|
|
58
|
+
name: 'Validator & Certifier',
|
|
59
|
+
promptFile: 'agents/A-06-VALIDATOR-CERTIFIER.md',
|
|
60
|
+
requires: {
|
|
61
|
+
agents: ['a-05'],
|
|
62
|
+
gates: ['pass-1', 'pass-2', 'pass-3', 'pass-4', 'pass-5', 'pass-6'],
|
|
63
|
+
constructs: ['spec', 'build'],
|
|
64
|
+
},
|
|
65
|
+
produces: ['certification'],
|
|
66
|
+
humanGate: false,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
export function getAgent(id) {
|
|
70
|
+
return AGENTS.find((a) => a.id === id);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/pipeline/agents.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,kEAAkE;AAiBlE,MAAM,CAAC,MAAM,MAAM,GAAsB;IACvC;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,mBAAmB;QACzB,UAAU,EAAE,kCAAkC;QAC9C,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACnD,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,SAAS,EAAE,KAAK;KACjB;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,0BAA0B;QAChC,UAAU,EAAE,yCAAyC;QACrD,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;QACjE,QAAQ,EAAE,CAAC,UAAU,CAAC;QACtB,SAAS,EAAE,KAAK;KACjB;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,kBAAkB;QACxB,UAAU,EAAE,iCAAiC;QAC7C,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,UAAU,CAAC,EAAE;QACnE,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,SAAS,EAAE,KAAK;KACjB;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,0BAA0B;QAChC,UAAU,EAAE,yCAAyC;QACrD,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;QACrF,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,SAAS,EAAE,KAAK;KACjB;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,oBAAoB;QAC1B,UAAU,EAAE,mCAAmC;QAC/C,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE;QAC/D,QAAQ,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;QACvC,SAAS,EAAE,KAAK;KACjB;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,wBAAwB;QACpC,QAAQ,EAAE;YACR,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,KAAK,EAAE,CAAC,eAAe,CAAC;YACxB,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC;SAC5C;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,SAAS,EAAE,IAAI,EAAE,iCAAiC;KACnD;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,uBAAuB;QAC7B,UAAU,EAAE,oCAAoC;QAChD,QAAQ,EAAE;YACR,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACnE,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;SAC9B;QACD,QAAQ,EAAE,CAAC,eAAe,CAAC;QAC3B,SAAS,EAAE,KAAK;KACjB;CACF,CAAA;AAED,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AACxC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type PipelineState } from './state.js';
|
|
2
|
+
import type { ConstructType } from '../parser/sil.js';
|
|
3
|
+
export interface RunResult {
|
|
4
|
+
agentId: string;
|
|
5
|
+
ready: boolean;
|
|
6
|
+
reason?: string;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
episodeCount: number;
|
|
9
|
+
prerequisitesMet: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface ArtifactValidation {
|
|
12
|
+
agentId: string;
|
|
13
|
+
expected: ConstructType[];
|
|
14
|
+
found: Record<ConstructType, number>;
|
|
15
|
+
missing: ConstructType[];
|
|
16
|
+
lowConfidence: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function pipelineSummary(state: PipelineState, projectPath: string): string;
|
|
19
|
+
export declare function prepareRun(agentId: string, projectPath: string): Promise<RunResult>;
|
|
20
|
+
export declare function validateArtifacts(agentId: string, projectPath: string): ArtifactValidation;
|
|
21
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/pipeline/orchestrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAGlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACpC,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAsCD,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuFjF;AAkDD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,CAAC,CAkDpB;AAMD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,kBAAkB,CAoBpB"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { AGENTS, getAgent } from './agents.js';
|
|
4
|
+
import { readState, canRun } from './state.js';
|
|
5
|
+
import { readOpenEpisodes, episodesForAgent, buildEpisodeContext } from '../episodes/manager.js';
|
|
6
|
+
import { loadPrompt, runtimeRoot } from '../prompts/loader.js';
|
|
7
|
+
// ─────────────────────────────────────────
|
|
8
|
+
// Directory layout for construct types
|
|
9
|
+
// ─────────────────────────────────────────
|
|
10
|
+
const CONSTRUCT_DIRS = {
|
|
11
|
+
signal: 'signals',
|
|
12
|
+
workflow: 'workflows',
|
|
13
|
+
screen: 'screens',
|
|
14
|
+
spec: 'specs',
|
|
15
|
+
episode: 'episodes',
|
|
16
|
+
architecture: 'architecture',
|
|
17
|
+
blueprint: 'architecture',
|
|
18
|
+
build: 'build',
|
|
19
|
+
certification: 'certification',
|
|
20
|
+
};
|
|
21
|
+
function artifactDir(projectPath, construct) {
|
|
22
|
+
return join(projectPath, CONSTRUCT_DIRS[construct] ?? construct);
|
|
23
|
+
}
|
|
24
|
+
function countArtifacts(projectPath, construct) {
|
|
25
|
+
const dir = artifactDir(projectPath, construct);
|
|
26
|
+
if (!existsSync(dir))
|
|
27
|
+
return 0;
|
|
28
|
+
return readdirSync(dir).filter((f) => f.endsWith('.sil')).length;
|
|
29
|
+
}
|
|
30
|
+
// ─────────────────────────────────────────
|
|
31
|
+
// Pipeline summary — used in context block and status command
|
|
32
|
+
// ─────────────────────────────────────────
|
|
33
|
+
const STATUS_ICON = {
|
|
34
|
+
complete: '✓',
|
|
35
|
+
running: '⟳',
|
|
36
|
+
waiting: '○',
|
|
37
|
+
};
|
|
38
|
+
export function pipelineSummary(state, projectPath) {
|
|
39
|
+
const lines = [];
|
|
40
|
+
const line = '─'.repeat(51);
|
|
41
|
+
lines.push(`PROJECT: ${state.project}`);
|
|
42
|
+
lines.push(`PATH: ${state.path}`);
|
|
43
|
+
lines.push(line);
|
|
44
|
+
lines.push('');
|
|
45
|
+
lines.push('PIPELINE');
|
|
46
|
+
for (const agent of AGENTS) {
|
|
47
|
+
const run = state.agents[agent.id];
|
|
48
|
+
const check = canRun(agent.id, state);
|
|
49
|
+
let statusLabel;
|
|
50
|
+
let confidenceLabel;
|
|
51
|
+
let detail;
|
|
52
|
+
if (run) {
|
|
53
|
+
statusLabel = STATUS_ICON.complete;
|
|
54
|
+
confidenceLabel = run.confidence.padEnd(6);
|
|
55
|
+
const count = run.outputCount;
|
|
56
|
+
const produces = agent.produces[0];
|
|
57
|
+
detail = `${count} ${produces}${count !== 1 ? 's' : ''}`;
|
|
58
|
+
}
|
|
59
|
+
else if (check.can) {
|
|
60
|
+
statusLabel = STATUS_ICON.running;
|
|
61
|
+
confidenceLabel = '— ';
|
|
62
|
+
detail = 'ready to run';
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
statusLabel = STATUS_ICON.waiting;
|
|
66
|
+
confidenceLabel = '— ';
|
|
67
|
+
detail = `prereq: ${check.reason}`;
|
|
68
|
+
}
|
|
69
|
+
lines.push(` ${agent.id.toUpperCase()} ${statusLabel} ${confidenceLabel} ${detail}`);
|
|
70
|
+
}
|
|
71
|
+
lines.push('');
|
|
72
|
+
lines.push('HUMAN GATES');
|
|
73
|
+
const allGates = [
|
|
74
|
+
'a-04-approved',
|
|
75
|
+
'pass-1',
|
|
76
|
+
'pass-2',
|
|
77
|
+
'pass-3',
|
|
78
|
+
'pass-4',
|
|
79
|
+
'pass-5',
|
|
80
|
+
'pass-6',
|
|
81
|
+
];
|
|
82
|
+
for (const gateId of allGates) {
|
|
83
|
+
const gate = state.gates[gateId];
|
|
84
|
+
const icon = gate?.status === 'approved' ? '✓' : gate?.status === 'returned' ? '✗' : '○';
|
|
85
|
+
const label = gate?.status ?? 'pending';
|
|
86
|
+
lines.push(` ${gateId.padEnd(20)} ${icon} ${label}`);
|
|
87
|
+
}
|
|
88
|
+
if (state.openEpisodes.length > 0) {
|
|
89
|
+
lines.push('');
|
|
90
|
+
lines.push('OPEN EPISODES');
|
|
91
|
+
for (const epId of state.openEpisodes) {
|
|
92
|
+
lines.push(` ${epId}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
lines.push('');
|
|
96
|
+
lines.push('ARTIFACT COUNTS');
|
|
97
|
+
const constructs = [
|
|
98
|
+
'signal', 'workflow', 'screen', 'spec', 'architecture', 'build', 'certification',
|
|
99
|
+
];
|
|
100
|
+
for (const c of constructs) {
|
|
101
|
+
const count = countArtifacts(projectPath, c);
|
|
102
|
+
lines.push(` /${CONSTRUCT_DIRS[c]}/`.padEnd(20) + `${count} files`);
|
|
103
|
+
}
|
|
104
|
+
lines.push(line);
|
|
105
|
+
// Next action hint
|
|
106
|
+
const nextAgent = AGENTS.find((a) => !state.agents[a.id] && canRun(a.id, state).can);
|
|
107
|
+
if (nextAgent) {
|
|
108
|
+
lines.push(`Next: phoenix run ${nextAgent.id} --project .`);
|
|
109
|
+
}
|
|
110
|
+
return lines.join('\n');
|
|
111
|
+
}
|
|
112
|
+
// ─────────────────────────────────────────
|
|
113
|
+
// Project context block injected into every prompt
|
|
114
|
+
// ─────────────────────────────────────────
|
|
115
|
+
function buildProjectContext(agentId, state, projectPath) {
|
|
116
|
+
const agent = getAgent(agentId);
|
|
117
|
+
const line = '─'.repeat(42);
|
|
118
|
+
const readDirs = agent.requires.constructs.map((c) => {
|
|
119
|
+
const count = countArtifacts(projectPath, c);
|
|
120
|
+
return ` ${artifactDir(projectPath, c)} (${count} .sil files)`;
|
|
121
|
+
});
|
|
122
|
+
// Mission brief is always readable if it exists
|
|
123
|
+
const missionPath = join(projectPath, '_mission.sil');
|
|
124
|
+
if (existsSync(missionPath) && !readDirs.some((l) => l.includes('_mission'))) {
|
|
125
|
+
readDirs.unshift(` ${missionPath}`);
|
|
126
|
+
}
|
|
127
|
+
const writeDirs = agent.produces.map((c) => ` ${artifactDir(projectPath, c)}/`);
|
|
128
|
+
const lines = [
|
|
129
|
+
'PROJECT CONTEXT',
|
|
130
|
+
line,
|
|
131
|
+
`Project: ${state.project}`,
|
|
132
|
+
`Path: ${state.path}`,
|
|
133
|
+
'',
|
|
134
|
+
'READ FROM:',
|
|
135
|
+
...readDirs,
|
|
136
|
+
'',
|
|
137
|
+
'WRITE TO:',
|
|
138
|
+
...writeDirs,
|
|
139
|
+
'',
|
|
140
|
+
'PIPELINE STATE:',
|
|
141
|
+
pipelineSummary(state, projectPath),
|
|
142
|
+
];
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
// ─────────────────────────────────────────
|
|
146
|
+
// prepareRun — the main orchestrator entry point
|
|
147
|
+
// ─────────────────────────────────────────
|
|
148
|
+
export async function prepareRun(agentId, projectPath) {
|
|
149
|
+
const agent = getAgent(agentId);
|
|
150
|
+
if (!agent) {
|
|
151
|
+
return { agentId, ready: false, reason: `Unknown agent: ${agentId}`, episodeCount: 0, prerequisitesMet: [] };
|
|
152
|
+
}
|
|
153
|
+
// Load state
|
|
154
|
+
const state = readState(projectPath);
|
|
155
|
+
// Check prerequisites
|
|
156
|
+
const check = canRun(agentId, state);
|
|
157
|
+
if (!check.can) {
|
|
158
|
+
return { agentId, ready: false, reason: check.reason, episodeCount: 0, prerequisitesMet: [] };
|
|
159
|
+
}
|
|
160
|
+
const prerequisitesMet = [
|
|
161
|
+
...agent.requires.agents.map((a) => `${a} complete`),
|
|
162
|
+
...agent.requires.gates.map((g) => `gate ${g} approved`),
|
|
163
|
+
];
|
|
164
|
+
// Load open episodes for this agent
|
|
165
|
+
const allEpisodes = readOpenEpisodes(projectPath);
|
|
166
|
+
const relevantEpisodes = episodesForAgent(agentId, allEpisodes);
|
|
167
|
+
const episodeContext = buildEpisodeContext(relevantEpisodes);
|
|
168
|
+
// Load agent prompt
|
|
169
|
+
const agentPrompt = loadPrompt(agent.promptFile, runtimeRoot());
|
|
170
|
+
// Build project context
|
|
171
|
+
const projectContext = buildProjectContext(agentId, state, projectPath);
|
|
172
|
+
// Assemble final prompt:
|
|
173
|
+
// 1. Episode context (if any) — agent reads this first
|
|
174
|
+
// 2. Project context — where to read from, write to, current state
|
|
175
|
+
// 3. Agent prompt — the full agent instructions
|
|
176
|
+
const parts = [];
|
|
177
|
+
if (episodeContext)
|
|
178
|
+
parts.push(episodeContext);
|
|
179
|
+
parts.push(projectContext);
|
|
180
|
+
parts.push(agentPrompt);
|
|
181
|
+
const prompt = parts.join('\n\n' + '─'.repeat(42) + '\n\n');
|
|
182
|
+
return {
|
|
183
|
+
agentId,
|
|
184
|
+
ready: true,
|
|
185
|
+
prompt,
|
|
186
|
+
episodeCount: relevantEpisodes.length,
|
|
187
|
+
prerequisitesMet,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
// ─────────────────────────────────────────
|
|
191
|
+
// validateArtifacts — used by `phoenix validate <agent>`
|
|
192
|
+
// ─────────────────────────────────────────
|
|
193
|
+
export function validateArtifacts(agentId, projectPath) {
|
|
194
|
+
const agent = getAgent(agentId);
|
|
195
|
+
if (!agent)
|
|
196
|
+
throw new Error(`Unknown agent: ${agentId}`);
|
|
197
|
+
const found = {};
|
|
198
|
+
const missing = [];
|
|
199
|
+
for (const construct of agent.produces) {
|
|
200
|
+
const count = countArtifacts(projectPath, construct);
|
|
201
|
+
found[construct] = count;
|
|
202
|
+
if (count === 0)
|
|
203
|
+
missing.push(construct);
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
agentId,
|
|
207
|
+
expected: agent.produces,
|
|
208
|
+
found: found,
|
|
209
|
+
missing,
|
|
210
|
+
lowConfidence: [], // populated in Phase 4 with full .sil scan
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/pipeline/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface AgentRun {
|
|
2
|
+
agentId: string;
|
|
3
|
+
completedAt: string;
|
|
4
|
+
outputCount: number;
|
|
5
|
+
confidence: 'high' | 'medium' | 'low';
|
|
6
|
+
summary: string;
|
|
7
|
+
}
|
|
8
|
+
export interface GateRecord {
|
|
9
|
+
gateId: string;
|
|
10
|
+
status: 'pending' | 'approved' | 'returned';
|
|
11
|
+
reviewedAt?: string;
|
|
12
|
+
reviewer?: string;
|
|
13
|
+
notes?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PipelineState {
|
|
16
|
+
project: string;
|
|
17
|
+
path: string;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
updatedAt: string;
|
|
20
|
+
agents: Record<string, AgentRun>;
|
|
21
|
+
gates: Record<string, GateRecord>;
|
|
22
|
+
openEpisodes: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function initState(projectPath: string, projectName: string): PipelineState;
|
|
25
|
+
export declare function readState(projectPath: string): PipelineState;
|
|
26
|
+
export declare function writeState(projectPath: string, state: PipelineState): void;
|
|
27
|
+
export declare function canRun(agentId: string, state: PipelineState): {
|
|
28
|
+
can: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function markAgentComplete(agentId: string, run: AgentRun, state: PipelineState): PipelineState;
|
|
32
|
+
export declare function approveGate(gateId: string, notes: string, state: PipelineState): PipelineState;
|
|
33
|
+
export declare function returnGate(gateId: string, notes: string, state: PipelineState): PipelineState;
|
|
34
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/pipeline/state.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACjC,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AASD,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CAUjF;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAM5D;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAK1E;AAED,wBAAgB,MAAM,CACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,GACnB;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoBnC;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,aAAa,GACnB,aAAa,CAKf;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,aAAa,GACnB,aAAa,CAWf;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,aAAa,GACnB,aAAa,CAWf"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { AGENTS } from './agents.js';
|
|
4
|
+
const STATE_DIR = '.phoenix';
|
|
5
|
+
const STATE_FILE = 'state.json';
|
|
6
|
+
function statePath(projectPath) {
|
|
7
|
+
return join(projectPath, STATE_DIR, STATE_FILE);
|
|
8
|
+
}
|
|
9
|
+
export function initState(projectPath, projectName) {
|
|
10
|
+
return {
|
|
11
|
+
project: projectName,
|
|
12
|
+
path: projectPath,
|
|
13
|
+
createdAt: new Date().toISOString(),
|
|
14
|
+
updatedAt: new Date().toISOString(),
|
|
15
|
+
agents: {},
|
|
16
|
+
gates: {},
|
|
17
|
+
openEpisodes: [],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function readState(projectPath) {
|
|
21
|
+
const path = statePath(projectPath);
|
|
22
|
+
if (!existsSync(path)) {
|
|
23
|
+
throw new Error(`No .phoenix/state.json found at ${projectPath}. Run: phoenix init`);
|
|
24
|
+
}
|
|
25
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
26
|
+
}
|
|
27
|
+
export function writeState(projectPath, state) {
|
|
28
|
+
const dir = join(projectPath, STATE_DIR);
|
|
29
|
+
if (!existsSync(dir))
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
const updated = { ...state, updatedAt: new Date().toISOString() };
|
|
32
|
+
writeFileSync(statePath(projectPath), JSON.stringify(updated, null, 2), 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
export function canRun(agentId, state) {
|
|
35
|
+
const agent = AGENTS.find((a) => a.id === agentId);
|
|
36
|
+
if (!agent)
|
|
37
|
+
return { can: false, reason: `Unknown agent: ${agentId}` };
|
|
38
|
+
// All prerequisite agents must have completed
|
|
39
|
+
for (const reqAgent of agent.requires.agents) {
|
|
40
|
+
if (!state.agents[reqAgent]) {
|
|
41
|
+
return { can: false, reason: `${reqAgent} has not completed` };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// All prerequisite gates must be approved
|
|
45
|
+
for (const reqGate of agent.requires.gates) {
|
|
46
|
+
const gate = state.gates[reqGate];
|
|
47
|
+
if (!gate || gate.status !== 'approved') {
|
|
48
|
+
return { can: false, reason: `Gate "${reqGate}" is not approved` };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { can: true };
|
|
52
|
+
}
|
|
53
|
+
export function markAgentComplete(agentId, run, state) {
|
|
54
|
+
return {
|
|
55
|
+
...state,
|
|
56
|
+
agents: { ...state.agents, [agentId]: run },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function approveGate(gateId, notes, state) {
|
|
60
|
+
const record = {
|
|
61
|
+
gateId,
|
|
62
|
+
status: 'approved',
|
|
63
|
+
reviewedAt: new Date().toISOString(),
|
|
64
|
+
notes,
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
...state,
|
|
68
|
+
gates: { ...state.gates, [gateId]: record },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function returnGate(gateId, notes, state) {
|
|
72
|
+
const record = {
|
|
73
|
+
gateId,
|
|
74
|
+
status: 'returned',
|
|
75
|
+
reviewedAt: new Date().toISOString(),
|
|
76
|
+
notes,
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
...state,
|
|
80
|
+
gates: { ...state.gates, [gateId]: record },
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/pipeline/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AA4BpC,MAAM,SAAS,GAAG,UAAU,CAAA;AAC5B,MAAM,UAAU,GAAG,YAAY,CAAA;AAE/B,SAAS,SAAS,CAAC,WAAmB;IACpC,OAAO,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,WAAmB;IAChE,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,EAAE;QACT,YAAY,EAAE,EAAE;KACjB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAAmB;IAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,mCAAmC,WAAW,qBAAqB,CAAC,CAAA;IACtF,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAkB,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,KAAoB;IAClE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IACxC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzD,MAAM,OAAO,GAAG,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAA;IACjE,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,OAAe,EACf,KAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAA;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,OAAO,EAAE,EAAE,CAAA;IAEtE,8CAA8C;IAC9C,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,oBAAoB,EAAE,CAAA;QAChE,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACjC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,OAAO,mBAAmB,EAAE,CAAA;QACpE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,GAAa,EACb,KAAoB;IAEpB,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE;KAC5C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAAa,EACb,KAAoB;IAEpB,MAAM,MAAM,GAAe;QACzB,MAAM;QACN,MAAM,EAAE,UAAU;QAClB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,KAAK;KACN,CAAA;IACD,OAAO;QACL,GAAG,KAAK;QACR,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE;KAC5C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAc,EACd,KAAa,EACb,KAAoB;IAEpB,MAAM,MAAM,GAAe;QACzB,MAAM;QACN,MAAM,EAAE,UAAU;QAClB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,KAAK;KACN,CAAA;IACD,OAAO;QACL,GAAG,KAAK;QACR,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE;KAC5C,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/prompts/loader.ts"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAID,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CASlF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname } from 'node:path';
|
|
5
|
+
// Runtime root — the directory where phoenix-runtime is installed.
|
|
6
|
+
// Agent prompts ship with the package in /agents/*.md.
|
|
7
|
+
// PHOENIX_RUNTIME_ROOT env var overrides — useful for development and testing.
|
|
8
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../../');
|
|
9
|
+
export function runtimeRoot() {
|
|
10
|
+
return process.env['PHOENIX_RUNTIME_ROOT'] ?? PACKAGE_ROOT;
|
|
11
|
+
}
|
|
12
|
+
// Load an agent prompt from promptFile (relative to runtimeRoot).
|
|
13
|
+
// Throws clearly if the file is missing — agents/ must be populated.
|
|
14
|
+
export function loadPrompt(promptFile, root = PACKAGE_ROOT) {
|
|
15
|
+
const filePath = join(root, promptFile);
|
|
16
|
+
if (!existsSync(filePath)) {
|
|
17
|
+
throw new Error(`Agent prompt not found: ${filePath}\n` +
|
|
18
|
+
`Ensure agents/ directory is populated in ${root}`);
|
|
19
|
+
}
|
|
20
|
+
return readFileSync(filePath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/prompts/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,mEAAmE;AACnE,uDAAuD;AACvD,+EAA+E;AAC/E,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AAE/E,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,YAAY,CAAA;AAC5D,CAAC;AAED,kEAAkE;AAClE,qEAAqE;AACrE,MAAM,UAAU,UAAU,CAAC,UAAkB,EAAE,OAAe,YAAY;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACvC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,IAAI;YACrC,4CAA4C,IAAI,EAAE,CACrD,CAAA;IACH,CAAC;IACD,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACxC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@semanticintent/phoenix-runtime",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Phoenix Pipeline Runtime — orchestrate the 7-agent legacy modernization pipeline. Manages .sil artifact state, enforces human gates, injects episode context.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"bin": {
|
|
10
|
+
"phoenix": "./bin/phoenix.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/",
|
|
14
|
+
"bin/",
|
|
15
|
+
"agents/",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"test:run": "vitest run",
|
|
21
|
+
"test:coverage": "vitest run --coverage",
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "vitest watch",
|
|
24
|
+
"validate": "npm run build && npm run test:coverage",
|
|
25
|
+
"prepublishOnly": "npm run validate"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"phoenix",
|
|
29
|
+
"legacy-modernization",
|
|
30
|
+
"ember",
|
|
31
|
+
"sil",
|
|
32
|
+
"semantic-intent",
|
|
33
|
+
"agent-pipeline",
|
|
34
|
+
"business-logic-extraction"
|
|
35
|
+
],
|
|
36
|
+
"author": "Michael Shatny",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/semanticintent/phoenix-runtime.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://semanticintent.ai",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/semanticintent/phoenix-runtime/issues"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"chalk": "^5.3.0",
|
|
48
|
+
"commander": "^12.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.11.0",
|
|
52
|
+
"@vitest/coverage-v8": "^1.6.1",
|
|
53
|
+
"typescript": "^5.3.3",
|
|
54
|
+
"vitest": "^1.2.0"
|
|
55
|
+
}
|
|
56
|
+
}
|