citadel-ai 1.0.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 (62) hide show
  1. package/CONTRIBUTING.md +91 -0
  2. package/LICENSE +5 -0
  3. package/README.md +254 -0
  4. package/bin/citadel.js +2 -0
  5. package/dist/agents/registry.d.ts +16 -0
  6. package/dist/agents/registry.js +1108 -0
  7. package/dist/agents/registry.js.map +1 -0
  8. package/dist/cli/ide-rules.d.ts +5 -0
  9. package/dist/cli/ide-rules.js +176 -0
  10. package/dist/cli/ide-rules.js.map +1 -0
  11. package/dist/cli/index.d.ts +1 -0
  12. package/dist/cli/index.js +59 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli/init.d.ts +1 -0
  15. package/dist/cli/init.js +110 -0
  16. package/dist/cli/init.js.map +1 -0
  17. package/dist/cli/run.d.ts +1 -0
  18. package/dist/cli/run.js +64 -0
  19. package/dist/cli/run.js.map +1 -0
  20. package/dist/core/chinese-wall.d.ts +34 -0
  21. package/dist/core/chinese-wall.js +62 -0
  22. package/dist/core/chinese-wall.js.map +1 -0
  23. package/dist/core/gates.d.ts +19 -0
  24. package/dist/core/gates.js +38 -0
  25. package/dist/core/gates.js.map +1 -0
  26. package/dist/core/loops.d.ts +20 -0
  27. package/dist/core/loops.js +83 -0
  28. package/dist/core/loops.js.map +1 -0
  29. package/dist/core/memory.d.ts +23 -0
  30. package/dist/core/memory.js +116 -0
  31. package/dist/core/memory.js.map +1 -0
  32. package/dist/core/orchestrator.d.ts +22 -0
  33. package/dist/core/orchestrator.js +234 -0
  34. package/dist/core/orchestrator.js.map +1 -0
  35. package/dist/core/types.d.ts +139 -0
  36. package/dist/core/types.js +2 -0
  37. package/dist/core/types.js.map +1 -0
  38. package/dist/index.d.ts +9 -0
  39. package/dist/index.js +9 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/llm/provider.d.ts +8 -0
  42. package/dist/llm/provider.js +84 -0
  43. package/dist/llm/provider.js.map +1 -0
  44. package/dist/ui/terminal.d.ts +16 -0
  45. package/dist/ui/terminal.js +71 -0
  46. package/dist/ui/terminal.js.map +1 -0
  47. package/package.json +40 -0
  48. package/templates/.citadel/citadel.config.json +1 -0
  49. package/templates/.citadel/gates/gate-0-inception.json +1 -0
  50. package/templates/.citadel/gates/gate-1-predesign.json +1 -0
  51. package/templates/.citadel/gates/gate-2-prebuild.json +1 -0
  52. package/templates/.citadel/gates/gate-3-preship.json +1 -0
  53. package/templates/.citadel/gates/gate-4-postdeploy.json +1 -0
  54. package/templates/.citadel/memory/decisions.json +1 -0
  55. package/templates/.citadel/memory/errors.json +1 -0
  56. package/templates/.citadel/memory/project.json +1 -0
  57. package/templates/.citadel/memory/session.json +1 -0
  58. package/templates/.citadel/specs/adr.md +1 -0
  59. package/templates/.citadel/specs/data-model.md +1 -0
  60. package/templates/.citadel/specs/growth.md +1 -0
  61. package/templates/.citadel/specs/prd.md +1 -0
  62. package/templates/.citadel/specs/security.md +1 -0
@@ -0,0 +1,19 @@
1
+ import type { GateId, GateState } from './types.js';
2
+ export declare class GateSystem {
3
+ private bp;
4
+ constructor(pp: string);
5
+ private gp;
6
+ private ld;
7
+ private sv;
8
+ initGate(id: GateId): GateState;
9
+ initAllGates(): void;
10
+ getGate(id: GateId): GateState;
11
+ passCheck(gid: GateId, cid: string, notes?: string): GateState;
12
+ failCheck(gid: GateId, cid: string, notes: string): GateState;
13
+ vetoGate(gid: GateId): GateState;
14
+ canProceed(gid: GateId): {
15
+ allowed: boolean;
16
+ blockers: string[];
17
+ };
18
+ getProgressSummary(gid: GateId): string;
19
+ }
@@ -0,0 +1,38 @@
1
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const G = {
4
+ 'gate-0': { name: 'INCEPTION', blocker: 'All C-levels must sign off', checks: [{ id: 'g0-1', description: 'Project validated', agent: 'orchestrator' }, { id: 'g0-2', description: 'Scope by CPO', agent: 'cpo' }, { id: 'g0-3', description: 'Tech by CTO', agent: 'cto' }, { id: 'g0-4', description: 'Security by CISO', agent: 'ciso' }, { id: 'g0-5', description: 'Data by CDO', agent: 'cdo' }, { id: 'g0-6', description: 'Growth by CGO', agent: 'cgo' }] },
5
+ 'gate-1': { name: 'PRE-DESIGN', blocker: 'PRD must be approved', checks: [{ id: 'g1-1', description: 'PRD approved', agent: 'cpo' }, { id: 'g1-2', description: 'Stories complete', agent: 'cpo' }] },
6
+ 'gate-2': { name: 'PRE-BUILD', blocker: 'Architecture locked', checks: [{ id: 'g2-1', description: 'ADR approved', agent: 'cto' }, { id: 'g2-2', description: 'Data model OK', agent: 'cdo' }, { id: 'g2-3', description: 'Security reviewed', agent: 'ciso' }] },
7
+ 'gate-3': { name: 'PRE-SHIP', blocker: 'CISO absolute veto', checks: [{ id: 'g3-1', description: 'Code reviewed', agent: 'code-reviewer' }, { id: 'g3-2', description: 'Tests 80%+', agent: 'test-engineer' }, { id: 'g3-3', description: 'Security clean', agent: 'security-auditor' }, { id: 'g3-4', description: 'CISO sign-off', agent: 'ciso' }] },
8
+ 'gate-4': { name: 'POST-DEPLOY', blocker: 'Auto-rollback', checks: [{ id: 'g4-1', description: 'Monitoring active', agent: 'devops-engineer' }, { id: 'g4-2', description: 'Rollback tested', agent: 'devops-engineer' }] },
9
+ };
10
+ export class GateSystem {
11
+ bp;
12
+ constructor(pp) { this.bp = join(pp, '.citadel', 'gates'); }
13
+ gp(id) { return join(this.bp, `${id}.json`); }
14
+ ld(id) { const p = this.gp(id); if (existsSync(p))
15
+ return JSON.parse(readFileSync(p, 'utf-8')); return this.initGate(id); }
16
+ sv(g) { writeFileSync(this.gp(g.id), JSON.stringify(g, null, 2), 'utf-8'); }
17
+ initGate(id) { const d = G[id]; if (!d)
18
+ throw new Error(`Unknown gate: ${id}`); const g = { id, name: d.name, status: 'pending', blocker: d.blocker, signoffs: {}, checks: d.checks.map(c => ({ ...c, status: 'pending', timestamp: null, notes: '' })) }; this.sv(g); return g; }
19
+ initAllGates() { Object.keys(G).forEach(id => this.initGate(id)); }
20
+ getGate(id) { return this.ld(id); }
21
+ passCheck(gid, cid, notes = '') { const g = this.ld(gid); const c = g.checks.find(x => x.id === cid); if (c) {
22
+ c.status = 'passed';
23
+ c.timestamp = new Date().toISOString();
24
+ c.notes = notes;
25
+ } g.status = g.checks.every(x => x.status === 'passed') ? 'passed' : 'in-progress'; this.sv(g); return g; }
26
+ failCheck(gid, cid, notes) { const g = this.ld(gid); const c = g.checks.find(x => x.id === cid); if (c) {
27
+ c.status = 'failed';
28
+ c.timestamp = new Date().toISOString();
29
+ c.notes = notes;
30
+ } g.status = 'failed'; this.sv(g); return g; }
31
+ vetoGate(gid) { const g = this.ld(gid); g.status = 'blocked'; g.signoffs['ciso'] = false; this.sv(g); return g; }
32
+ canProceed(gid) { const g = this.ld(gid); const b = []; if (g.status === 'blocked')
33
+ return { allowed: false, blockers: ['BLOCKED by CISO'] }; g.checks.filter(c => c.status !== 'passed').forEach(c => b.push(`[${c.status}] ${c.description}`)); if (gid === 'gate-3' && !g.signoffs['ciso'])
34
+ b.push('CISO not signed off'); return { allowed: b.length === 0, blockers: b }; }
35
+ getProgressSummary(gid) { const g = this.ld(gid); const p = g.checks.filter(c => c.status === 'passed').length; let s = `\n🚧 ${g.name} — ${p}/${g.checks.length} (${g.status})\n`; g.checks.forEach(c => { const i = c.status === 'passed' ? '✅' : c.status === 'failed' ? '❌' : '⬜'; s += ` ${i} ${c.description}\n`; }); if (g.status !== 'passed')
36
+ s += ` ⛔ ${g.blocker}\n`; return s; }
37
+ }
38
+ //# sourceMappingURL=gates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/core/gates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { LoopId, LoopState } from './types.js';
2
+ interface LoopDefinition {
3
+ id: LoopId;
4
+ name: string;
5
+ maxIterations: number;
6
+ agents: string[];
7
+ description: string;
8
+ }
9
+ export declare class LoopManager {
10
+ private activeLoop;
11
+ startLoop(loopId: LoopId): LoopState;
12
+ iterate(result: 'pass' | 'fail', reason: string): LoopState;
13
+ getActiveLoop(): LoopState | null;
14
+ getCurrentAgent(): string | null;
15
+ shouldEscalate(): boolean;
16
+ endLoop(): void;
17
+ getLoopInfo(loopId: LoopId): LoopDefinition | undefined;
18
+ static getAllLoops(): LoopDefinition[];
19
+ }
20
+ export {};
@@ -0,0 +1,83 @@
1
+ // ═══════════════════════════════════════════════════════════════
2
+ // CITADEL — Loop Manager (Iterative Refinement Cycles)
3
+ // ═══════════════════════════════════════════════════════════════
4
+ const LOOPS = {
5
+ design: {
6
+ id: 'design',
7
+ name: 'Design Loop',
8
+ maxIterations: 5,
9
+ agents: ['marty', 'jony', 'teresa', 'strunk', 'jakob', 'razor'],
10
+ description: 'CPO → UX → Analyst → Spec → UX Review → Scope Check',
11
+ },
12
+ build: {
13
+ id: 'build',
14
+ name: 'Build Loop',
15
+ maxIterations: 5,
16
+ agents: ['uncle-bob', 'dan', 'steipete', 'guido', 'kent', 'brendan'],
17
+ description: 'Backend → Frontend → Mobile → Code Review → Tests → Performance',
18
+ },
19
+ security: {
20
+ id: 'security',
21
+ name: 'Security Loop',
22
+ maxIterations: 3,
23
+ agents: ['filippo', 'moxie', 'max', 'charlie', 'window'],
24
+ description: 'Auth → Encryption → Compliance → Pentest → Audit',
25
+ },
26
+ debug: {
27
+ id: 'debug',
28
+ name: 'Debug Loop',
29
+ maxIterations: 10,
30
+ agents: ['uncle-bob', 'dan', 'kent', 'brendan'],
31
+ description: 'Identify → Fix → Test → Verify Performance',
32
+ },
33
+ };
34
+ export class LoopManager {
35
+ activeLoop = null;
36
+ startLoop(loopId) {
37
+ const def = LOOPS[loopId];
38
+ if (!def)
39
+ throw new Error(`Unknown loop: ${loopId}`);
40
+ this.activeLoop = {
41
+ loopId: def.id,
42
+ iteration: 1,
43
+ maxIterations: def.maxIterations,
44
+ agents: def.agents,
45
+ status: 'active',
46
+ reason: `Started: ${def.name}`,
47
+ };
48
+ return this.activeLoop;
49
+ }
50
+ iterate(result, reason) {
51
+ if (!this.activeLoop)
52
+ throw new Error('No active loop');
53
+ if (result === 'pass') {
54
+ this.activeLoop.status = 'completed';
55
+ this.activeLoop.reason = reason;
56
+ return this.activeLoop;
57
+ }
58
+ this.activeLoop.iteration++;
59
+ if (this.activeLoop.iteration > this.activeLoop.maxIterations) {
60
+ this.activeLoop.status = 'escaped';
61
+ this.activeLoop.reason = `Max iterations (${this.activeLoop.maxIterations}) reached. Escalating.`;
62
+ return this.activeLoop;
63
+ }
64
+ this.activeLoop.reason = reason;
65
+ return this.activeLoop;
66
+ }
67
+ getActiveLoop() { return this.activeLoop; }
68
+ getCurrentAgent() {
69
+ if (!this.activeLoop || this.activeLoop.status !== 'active')
70
+ return null;
71
+ const idx = (this.activeLoop.iteration - 1) % this.activeLoop.agents.length;
72
+ return this.activeLoop.agents[idx];
73
+ }
74
+ shouldEscalate() {
75
+ if (!this.activeLoop)
76
+ return false;
77
+ return this.activeLoop.iteration > 2; // Trigger web research after 2 iterations
78
+ }
79
+ endLoop() { this.activeLoop = null; }
80
+ getLoopInfo(loopId) { return LOOPS[loopId]; }
81
+ static getAllLoops() { return Object.values(LOOPS); }
82
+ }
83
+ //# sourceMappingURL=loops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loops.js","sourceRoot":"","sources":["../../src/core/loops.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,uDAAuD;AACvD,kEAAkE;AAYlE,MAAM,KAAK,GAAmC;IAC5C,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,aAAa;QACnB,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC;QAC/D,WAAW,EAAE,qDAAqD;KACnE;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC;QACpE,WAAW,EAAE,iEAAiE;KAC/E;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,eAAe;QACrB,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC;QACxD,WAAW,EAAE,kDAAkD;KAChE;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC;QAC/C,WAAW,EAAE,4CAA4C;KAC1D;CACF,CAAC;AAEF,MAAM,OAAO,WAAW;IACd,UAAU,GAAqB,IAAI,CAAC;IAE5C,SAAS,CAAC,MAAc;QACtB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;QAErD,IAAI,CAAC,UAAU,GAAG;YAChB,MAAM,EAAE,GAAG,CAAC,EAAE;YACd,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,YAAY,GAAG,CAAC,IAAI,EAAE;SAC/B,CAAC;QACF,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,MAAuB,EAAE,MAAc;QAC7C,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAExD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;YAChC,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;YAC9D,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,mBAAmB,IAAI,CAAC,UAAU,CAAC,aAAa,wBAAwB,CAAC;YAClG,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;QAChC,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,aAAa,KAAuB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE7D,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;QAC5E,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QACnC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,0CAA0C;IAClF,CAAC;IAED,OAAO,KAAW,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;IAE3C,WAAW,CAAC,MAAc,IAAgC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEjF,MAAM,CAAC,WAAW,KAAuB,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CACxE"}
@@ -0,0 +1,23 @@
1
+ import type { ProjectMemory, Decision, ErrorRecord, SessionState, PhaseId, ConversationMessage } from './types.js';
2
+ export declare class Memory {
3
+ private mp;
4
+ constructor(projectPath: string);
5
+ private read;
6
+ private write;
7
+ getProject(): ProjectMemory | null;
8
+ saveProject(p: ProjectMemory): void;
9
+ initProject(name: string, desc: string): ProjectMemory;
10
+ getDecisions(): Decision[];
11
+ addDecision(d: Omit<Decision, 'id' | 'timestamp'>): Decision;
12
+ getErrors(): ErrorRecord[];
13
+ addError(e: Omit<ErrorRecord, 'id' | 'timestamp'>): ErrorRecord;
14
+ getPreventionRules(): string[];
15
+ getSession(): SessionState | null;
16
+ saveSession(s: SessionState): void;
17
+ initSession(): SessionState;
18
+ addMessage(m: Omit<ConversationMessage, 'id' | 'timestamp'>): void;
19
+ setActiveAgent(id: string): void;
20
+ setPhase(p: PhaseId): void;
21
+ setGate(g: string): void;
22
+ buildContext(): string;
23
+ }
@@ -0,0 +1,116 @@
1
+ // ═══ CITADEL — 4-Layer Persistent Memory ═══
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ export class Memory {
5
+ mp;
6
+ constructor(projectPath) {
7
+ this.mp = join(projectPath, '.citadel', 'memory');
8
+ for (const d of [
9
+ join(projectPath, '.citadel'), this.mp,
10
+ join(projectPath, '.citadel', 'gates'),
11
+ join(projectPath, '.citadel', 'specs'),
12
+ ]) {
13
+ if (!existsSync(d))
14
+ mkdirSync(d, { recursive: true });
15
+ }
16
+ }
17
+ read(file, fallback) {
18
+ const p = join(this.mp, file);
19
+ if (!existsSync(p))
20
+ return fallback;
21
+ try {
22
+ return JSON.parse(readFileSync(p, 'utf-8'));
23
+ }
24
+ catch {
25
+ return fallback;
26
+ }
27
+ }
28
+ write(file, data) {
29
+ writeFileSync(join(this.mp, file), JSON.stringify(data, null, 2), 'utf-8');
30
+ }
31
+ // ── Project ──
32
+ getProject() { return this.read('project.json', null); }
33
+ saveProject(p) { p.updatedAt = new Date().toISOString(); this.write('project.json', p); }
34
+ initProject(name, desc) {
35
+ const p = { projectName: name, description: desc, techStack: {}, architecture: [], scope: [], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
36
+ this.saveProject(p);
37
+ return p;
38
+ }
39
+ // ── Decisions ──
40
+ getDecisions() { return this.read('decisions.json', []); }
41
+ addDecision(d) {
42
+ const ds = this.getDecisions();
43
+ const full = { ...d, id: `dec-${Date.now()}`, timestamp: new Date().toISOString() };
44
+ ds.push(full);
45
+ this.write('decisions.json', ds);
46
+ return full;
47
+ }
48
+ // ── Errors (prevents repeat mistakes) ──
49
+ getErrors() { return this.read('errors.json', []); }
50
+ addError(e) {
51
+ const es = this.getErrors();
52
+ const full = { ...e, id: `err-${Date.now()}`, timestamp: new Date().toISOString() };
53
+ es.push(full);
54
+ this.write('errors.json', es);
55
+ return full;
56
+ }
57
+ getPreventionRules() { return this.getErrors().map(e => e.preventionRule).filter(Boolean); }
58
+ // ── Session ──
59
+ getSession() { return this.read('session.json', null); }
60
+ saveSession(s) { s.updatedAt = new Date().toISOString(); this.write('session.json', s); }
61
+ initSession() {
62
+ const s = {
63
+ currentPhase: 'inception', currentGate: 'gate-0', activeAgent: 'orchestrator',
64
+ conversationHistory: [], loopState: null,
65
+ startedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
66
+ };
67
+ this.saveSession(s);
68
+ return s;
69
+ }
70
+ addMessage(m) {
71
+ const s = this.getSession();
72
+ if (!s)
73
+ return;
74
+ s.conversationHistory.push({ ...m, id: `msg-${Date.now()}`, timestamp: new Date().toISOString() });
75
+ if (s.conversationHistory.length > 100)
76
+ s.conversationHistory = s.conversationHistory.slice(-100);
77
+ this.saveSession(s);
78
+ }
79
+ setActiveAgent(id) { const s = this.getSession(); if (s) {
80
+ s.activeAgent = id;
81
+ this.saveSession(s);
82
+ } }
83
+ setPhase(p) { const s = this.getSession(); if (s) {
84
+ s.currentPhase = p;
85
+ this.saveSession(s);
86
+ } }
87
+ setGate(g) { const s = this.getSession(); if (s) {
88
+ s.currentGate = g;
89
+ this.saveSession(s);
90
+ } }
91
+ // ── Context builder for LLM ──
92
+ buildContext() {
93
+ const p = this.getProject(), s = this.getSession();
94
+ const ds = this.getDecisions().slice(-10), rules = this.getPreventionRules();
95
+ let ctx = '## PROJECT CONTEXT\n';
96
+ if (p) {
97
+ ctx += `Name: ${p.projectName}\nDescription: ${p.description}\n`;
98
+ if (Object.keys(p.techStack).length)
99
+ ctx += `Stack: ${JSON.stringify(p.techStack)}\n`;
100
+ }
101
+ if (s)
102
+ ctx += `\n## STATE\nPhase: ${s.currentPhase} | Gate: ${s.currentGate} | Agent: ${s.activeAgent}\n`;
103
+ if (ds.length) {
104
+ ctx += '\n## RECENT DECISIONS\n';
105
+ for (const d of ds)
106
+ ctx += `- [${d.agent}] ${d.title}\n`;
107
+ }
108
+ if (rules.length) {
109
+ ctx += '\n## ERROR PREVENTION\n';
110
+ for (const r of rules)
111
+ ctx += `- ${r}\n`;
112
+ }
113
+ return ctx;
114
+ }
115
+ }
116
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/core/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { CitadelConfig } from './types.js';
2
+ import { Memory } from './memory.js';
3
+ import { GateSystem } from './gates.js';
4
+ export declare class Orchestrator {
5
+ private config;
6
+ private memory;
7
+ private gates;
8
+ private loops;
9
+ private llm;
10
+ private totalTokens;
11
+ constructor(config: CitadelConfig);
12
+ getMemory(): Memory;
13
+ getGates(): GateSystem;
14
+ getTotalTokens(): number;
15
+ processMessage(userMessage: string): Promise<string>;
16
+ advancePhase(): Promise<string>;
17
+ private routeMessage;
18
+ private buildPrompt;
19
+ private isHelpRequest;
20
+ private handleHelp;
21
+ private formatResponse;
22
+ }
@@ -0,0 +1,234 @@
1
+ // ═══════════════════════════════════════════════════════════════
2
+ // CITADEL — Orchestrator (ATLAS Brain)
3
+ // ═══════════════════════════════════════════════════════════════
4
+ import { Memory } from './memory.js';
5
+ import { GateSystem } from './gates.js';
6
+ import { LoopManager } from './loops.js';
7
+ import { createLLMProvider } from '../llm/provider.js';
8
+ import { getAgent, AGENT_REGISTRY } from '../agents/registry.js';
9
+ // ── Phase Flow ──
10
+ const PHASE_ORDER = ['inception', 'specification', 'architecture', 'build', 'validation', 'ship'];
11
+ const PHASE_GATES = {
12
+ inception: 'gate-0',
13
+ specification: 'gate-1',
14
+ architecture: 'gate-2',
15
+ build: 'gate-3',
16
+ validation: 'gate-3',
17
+ ship: 'gate-4',
18
+ };
19
+ const PHASE_AGENTS = {
20
+ inception: ['atlas', 'marty', 'linus', 'bruce', 'sean', 'monica'],
21
+ specification: ['marty', 'teresa', 'strunk', 'jony'],
22
+ architecture: ['linus', 'codd', 'bruce', 'kelsey', 'harrison', 'alex', 'grace', 'charity'],
23
+ build: ['uncle-bob', 'dan', 'steipete', 'filippo', 'moxie', 'max', 'dj-patil', 'cyrus', 'chamath', 'karpathy', 'grace', 'charity', 'rich'],
24
+ validation: ['guido', 'kent', 'brendan', 'jakob', 'razor', 'lisa', 'nate', 'aleyda', 'peep', 'charlie', 'window', 'date', 'deming', 'flyway', 'aaron', 'trail'],
25
+ ship: ['kelsey', 'bruce', 'atlas'],
26
+ };
27
+ // ── Help / stuck detection (multilingual) ──
28
+ const HELP_PATTERNS = [
29
+ /\bhelp\b/i, /\bstuck\b/i, /\bconfused\b/i, /\blost\b/i,
30
+ /\baide\b/i, /\bbloqué\b/i, /\bperdu\b/i,
31
+ /\bayuda\b/i, /\batascado\b/i,
32
+ /\bhilfe\b/i, /\bfest\b/i,
33
+ /مساعدة/, /مشكل/,
34
+ /\bwhat now\b/i, /\bwhat do i do\b/i, /\bwhere am i\b/i,
35
+ /\bnext\s*step\b/i, /\bque faire\b/i,
36
+ ];
37
+ export class Orchestrator {
38
+ config;
39
+ memory;
40
+ gates;
41
+ loops;
42
+ llm;
43
+ totalTokens = 0;
44
+ constructor(config) {
45
+ this.config = config;
46
+ this.memory = new Memory(config.projectPath);
47
+ this.gates = new GateSystem(config.projectPath);
48
+ this.loops = new LoopManager();
49
+ this.llm = createLLMProvider(config.llm);
50
+ }
51
+ getMemory() { return this.memory; }
52
+ getGates() { return this.gates; }
53
+ getTotalTokens() { return this.totalTokens; }
54
+ // ═══ Main Entry Point ═══
55
+ async processMessage(userMessage) {
56
+ const session = this.memory.getSession() ?? this.memory.initSession();
57
+ // Store user message
58
+ this.memory.addMessage({
59
+ role: 'user', content: userMessage,
60
+ phase: session.currentPhase, gate: session.currentGate,
61
+ });
62
+ // Detect help/stuck
63
+ if (this.isHelpRequest(userMessage)) {
64
+ return this.handleHelp();
65
+ }
66
+ // Route to appropriate agent based on phase
67
+ const agentId = this.routeMessage(userMessage, session.currentPhase);
68
+ const agent = getAgent(agentId);
69
+ if (!agent)
70
+ return this.handleHelp();
71
+ this.memory.setActiveAgent(agentId);
72
+ // Build context-aware prompt
73
+ const messages = this.buildPrompt(agent.id, userMessage);
74
+ // Call LLM
75
+ const response = await this.llm.chat(messages);
76
+ this.totalTokens += response.tokensUsed;
77
+ // Format response with agent identity
78
+ const formatted = this.formatResponse(agent.icon, agent.name, agent.title, response.content);
79
+ // Store agent response
80
+ this.memory.addMessage({
81
+ role: 'agent', agent: agentId, content: response.content,
82
+ phase: session.currentPhase, gate: session.currentGate,
83
+ });
84
+ return formatted;
85
+ }
86
+ // ═══ Phase Advancement ═══
87
+ async advancePhase() {
88
+ const session = this.memory.getSession();
89
+ if (!session)
90
+ return '❌ No active session.';
91
+ const currentGate = PHASE_GATES[session.currentPhase];
92
+ const { allowed, blockers } = this.gates.canProceed(currentGate);
93
+ if (!allowed) {
94
+ let msg = `\n🚧 Cannot advance — gate ${currentGate} not passed:\n`;
95
+ for (const b of blockers)
96
+ msg += ` ⛔ ${b}\n`;
97
+ msg += `\nComplete the checks above first.`;
98
+ return msg;
99
+ }
100
+ const idx = PHASE_ORDER.indexOf(session.currentPhase);
101
+ if (idx >= PHASE_ORDER.length - 1)
102
+ return '🎉 All phases complete! Project is shipped.';
103
+ const nextPhase = PHASE_ORDER[idx + 1];
104
+ this.memory.setPhase(nextPhase);
105
+ this.memory.setGate(PHASE_GATES[nextPhase]);
106
+ const agents = PHASE_AGENTS[nextPhase];
107
+ const agentNames = agents.map(id => {
108
+ const a = getAgent(id);
109
+ return a ? `${a.icon} ${a.name}` : id;
110
+ }).join(', ');
111
+ return `\n✅ Advanced to: ${nextPhase.toUpperCase()}\n📍 Gate: ${PHASE_GATES[nextPhase]}\n👥 Active agents: ${agentNames}\n\nWhat would you like to work on?`;
112
+ }
113
+ // ═══ Routing Logic ═══
114
+ routeMessage(message, phase) {
115
+ const lower = message.toLowerCase();
116
+ const available = PHASE_AGENTS[phase] ?? ['atlas'];
117
+ // Direct agent mentions
118
+ for (const [id, agent] of AGENT_REGISTRY) {
119
+ if (lower.includes(agent.name.toLowerCase()) || lower.includes(`@${id}`)) {
120
+ if (available.includes(id))
121
+ return id;
122
+ }
123
+ }
124
+ // Keyword routing
125
+ const keywords = {
126
+ 'linus': ['architecture', 'tech stack', 'adr', 'technical', 'framework', 'typescript', 'backend vs frontend'],
127
+ 'marty': ['product', 'feature', 'user story', 'prd', 'requirement', 'scope', 'mvp', 'user need'],
128
+ 'sean': ['growth', 'analytics', 'seo', 'conversion', 'funnel', 'metric', 'kpi'],
129
+ 'bruce': ['security', 'auth', 'vulnerability', 'encrypt', 'password', 'token', 'owasp'],
130
+ 'monica': ['data', 'database', 'schema', 'migration', 'model', 'ai', 'ml'],
131
+ 'uncle-bob': ['backend', 'api', 'endpoint', 'server', 'service', 'controller', 'route'],
132
+ 'dan': ['frontend', 'component', 'react', 'ui', 'css', 'page', 'layout', 'form'],
133
+ 'steipete': ['mobile', 'ios', 'android', 'swift', 'kotlin', 'app', 'native'],
134
+ 'kelsey': ['deploy', 'docker', 'ci', 'cd', 'infrastructure', 'devops', 'monitor'],
135
+ 'jony': ['design', 'ux', 'wireframe', 'interface', 'user experience'],
136
+ 'filippo': ['login', 'signup', 'authentication', 'oauth', 'session', 'jwt'],
137
+ 'codd': ['table', 'column', 'index', 'normalize', 'relation', 'foreign key', 'sql'],
138
+ 'karpathy': ['prompt', 'llm', 'chatbot', 'ai model', 'gpt', 'claude', 'embedding'],
139
+ 'harrison': ['agent', 'multi-agent', 'tool use', 'mcp', 'langchain', 'agentic'],
140
+ 'alex': ['integration', 'mcp server', 'external api', 'webhook', 'transport'],
141
+ 'kent': ['test', 'coverage', 'tdd', 'unit test', 'integration test'],
142
+ 'guido': ['review', 'code quality', 'refactor', 'clean code'],
143
+ 'charlie': ['pentest', 'hack', 'exploit', 'vulnerability scan'],
144
+ 'grace': ['api', 'rest', 'graphql', 'endpoint', 'openapi', 'swagger', 'contract'],
145
+ 'charity': ['observability', 'logging', 'tracing', 'monitoring', 'dashboard', 'alert', 'sli', 'slo'],
146
+ 'rich': ['documentation', 'docs', 'readme', 'tutorial', 'how-to', 'guide'],
147
+ 'aaron': ['accessibility', 'a11y', 'wcag', 'screen reader', 'keyboard nav', 'aria'],
148
+ 'trail': ['audit', 'audit trail', 'compliance log', 'retention'],
149
+ };
150
+ for (const [agentId, words] of Object.entries(keywords)) {
151
+ if (available.includes(agentId) && words.some(w => lower.includes(w))) {
152
+ return agentId;
153
+ }
154
+ }
155
+ // Default to first available agent or atlas
156
+ return available[0] ?? 'atlas';
157
+ }
158
+ // ═══ Prompt Builder ═══
159
+ buildPrompt(agentId, userMessage) {
160
+ const agent = getAgent(agentId);
161
+ if (!agent)
162
+ return [{ role: 'user', content: userMessage }];
163
+ const context = this.memory.buildContext();
164
+ const session = this.memory.getSession();
165
+ // Build system prompt with agent personality + rules + context
166
+ let system = agent.systemPrompt + '\n\n';
167
+ system += '## YOUR RULES (IMMUTABLE)\n';
168
+ for (const rule of agent.rules)
169
+ system += `- ${rule}\n`;
170
+ system += '\n## YOUR PRINCIPLES\n';
171
+ for (const p of agent.principles)
172
+ system += `- ${p}\n`;
173
+ // Chinese Wall enforcement for checkers
174
+ if (agent.level === 'checker') {
175
+ system += '\n## CHINESE WALL ENFORCEMENT\n';
176
+ system += 'You are a CHECKER. You NEVER wrote or built the work you are reviewing.\n';
177
+ system += 'You provide independent, unbiased review. If you detect that you are being asked to review your own work, REFUSE.\n';
178
+ }
179
+ system += '\n' + context;
180
+ // Recent conversation for continuity
181
+ const messages = [{ role: 'system', content: system }];
182
+ if (session) {
183
+ const recent = session.conversationHistory.slice(-6);
184
+ for (const msg of recent) {
185
+ if (msg.role === 'user') {
186
+ messages.push({ role: 'user', content: msg.content });
187
+ }
188
+ else if (msg.role === 'agent') {
189
+ messages.push({ role: 'assistant', content: msg.content });
190
+ }
191
+ }
192
+ }
193
+ messages.push({ role: 'user', content: userMessage });
194
+ return messages;
195
+ }
196
+ // ═══ Help Handler ═══
197
+ isHelpRequest(message) {
198
+ return HELP_PATTERNS.some(p => p.test(message));
199
+ }
200
+ handleHelp() {
201
+ const session = this.memory.getSession();
202
+ if (!session)
203
+ return '🏰 Welcome to CITADEL! Run `citadel init` to start.';
204
+ const phase = session.currentPhase;
205
+ const gate = PHASE_GATES[phase];
206
+ const progress = this.gates.getProgressSummary(gate);
207
+ const agents = PHASE_AGENTS[phase].map(id => {
208
+ const a = getAgent(id);
209
+ return a ? ` ${a.icon} ${a.name} — ${a.title}` : ` ${id}`;
210
+ }).join('\n');
211
+ return `
212
+ 🏰 CITADEL — Status
213
+
214
+ 📍 Phase: ${phase.toUpperCase()}
215
+ 🚧 Gate: ${gate}
216
+ ${progress}
217
+
218
+ 👥 Active agents:
219
+ ${agents}
220
+
221
+ 💡 What you can do:
222
+ • Describe what you want to build
223
+ • Ask a specific question (I'll route to the right expert)
224
+ • Type "status" to see gate progress
225
+ • Type "advance" to move to next phase
226
+ • Mention an agent by name (@linus, @bruce, etc.)
227
+ `;
228
+ }
229
+ // ═══ Response Formatter ═══
230
+ formatResponse(icon, name, title, content) {
231
+ return `\n${icon} ${name} (${title}):\n${content}\n`;
232
+ }
233
+ }
234
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}