@openlife/cli 1.8.3 → 1.9.3

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 (232) hide show
  1. package/.catalog/agents/test-agent/AGENT.md +1 -1
  2. package/.catalog/mcps/test-mcp/mcp.json +1 -1
  3. package/.catalog/skills/sample-from-url/IMPORTED_REFERENCE.md +2 -2
  4. package/.catalog/skills/test-skill/REFERENCE.md +1 -1
  5. package/.catalog/squads/00-governance-advisory-board/workflows/wf-board-meeting.yaml +25 -0
  6. package/.catalog/squads/00-governance-advisory-board/workflows/wf-decision-framework.yaml +25 -0
  7. package/.catalog/squads/00-governance-c-level-squad/workflows/wf-board-presentation.yaml +25 -0
  8. package/.catalog/squads/00-governance-c-level-squad/workflows/wf-strategic-planning.yaml +25 -0
  9. package/.catalog/squads/00-governance-project-ops-squad/workflows/mission-to-project.yaml +25 -0
  10. package/.catalog/squads/00-governance-project-ops-squad/workflows/sprint-planning.yaml +25 -0
  11. package/.catalog/squads/00-governance-project-ops-squad/workflows/weekly-review.yaml +25 -0
  12. package/.catalog/squads/01-meta-framework-swarm-tree-orchestration/workflows/tree-analysis-flow.yaml +25 -0
  13. package/.catalog/squads/01-meta-framework-swarm-tree-orchestration/workflows/tree-execution-flow.yaml +25 -0
  14. package/.catalog/squads/01-meta-framework-swarm-tree-orchestration/workflows/tree-planning-flow.yaml +25 -0
  15. package/.catalog/squads/01-meta-framework-swarm-tree-orchestration/workflows/tree-resume-flow.yaml +25 -0
  16. package/.catalog/squads/02-product-growth-brand-squad/workflows/wf-brand-creation.yaml +25 -0
  17. package/.catalog/squads/02-product-growth-brand-squad/workflows/wf-rebrand.yaml +25 -0
  18. package/.catalog/squads/02-product-growth-copy-squad/workflows/wf-copy-review-cycle.yaml +25 -0
  19. package/.catalog/squads/02-product-growth-copy-squad/workflows/wf-full-copy-project.yaml +25 -0
  20. package/.catalog/squads/02-product-growth-design-squad/workflows/wf-design-system-creation.yaml +25 -0
  21. package/.catalog/squads/02-product-growth-design-squad/workflows/wf-feature-design.yaml +25 -0
  22. package/.catalog/squads/02-product-growth-hormozi-squad/workflows/wf-business-turnaround.yaml +25 -0
  23. package/.catalog/squads/02-product-growth-hormozi-squad/workflows/wf-offer-creation.yaml +25 -0
  24. package/.catalog/squads/02-product-growth-movement/workflows/wf-movement-launch.yaml +25 -0
  25. package/.catalog/squads/02-product-growth-saas-onboarding-activator/workflows/full-onboarding-activation-workflow.yaml +25 -0
  26. package/.catalog/squads/02-product-growth-saas-onboarding-activator/workflows/quick-engagement-boost-workflow.yaml +25 -0
  27. package/.catalog/squads/02-product-growth-sales-squad/workflows/followup-sequence.yaml +25 -0
  28. package/.catalog/squads/02-product-growth-sales-squad/workflows/full-sales-cycle.yaml +25 -0
  29. package/.catalog/squads/02-product-growth-sales-squad/workflows/proposal-flow.yaml +25 -0
  30. package/.catalog/squads/02-product-growth-storytelling/workflows/wf-brand-narrative.yaml +25 -0
  31. package/.catalog/squads/02-product-growth-storytelling/workflows/wf-story-development.yaml +25 -0
  32. package/.catalog/squads/02-product-growth-traffic-masters/workflows/wf-account-audit.yaml +25 -0
  33. package/.catalog/squads/02-product-growth-traffic-masters/workflows/wf-campaign-launch.yaml +25 -0
  34. package/.catalog/squads/03-engineering-quality-automated-code-review-squad/workflows/full-code-review-workflow.yaml +25 -0
  35. package/.catalog/squads/03-engineering-quality-automated-code-review-squad/workflows/quick-security-check-workflow.yaml +25 -0
  36. package/.catalog/squads/04-data-security-cybersecurity/workflows/wf-incident-response.yaml +25 -0
  37. package/.catalog/squads/04-data-security-cybersecurity/workflows/wf-pentest-engagement.yaml +25 -0
  38. package/.catalog/squads/04-data-security-data-quality-guardian/workflows/full-data-quality-audit-workflow.yaml +25 -0
  39. package/.catalog/squads/04-data-security-data-quality-guardian/workflows/quick-data-check-workflow.yaml +25 -0
  40. package/.catalog/squads/04-data-security-data-squad/workflows/wf-analytics-setup.yaml +25 -0
  41. package/.catalog/squads/04-data-security-data-squad/workflows/wf-growth-sprint.yaml +25 -0
  42. package/.catalog/squads/04-data-security-incident-response-squad/workflows/full-incident-response-workflow.yaml +25 -0
  43. package/.catalog/squads/04-data-security-incident-response-squad/workflows/rapid-triage-workflow.yaml +25 -0
  44. package/.catalog/squads/04-data-security-soc-alert-triage/workflows/full-alert-triage-workflow.yaml +25 -0
  45. package/.catalog/squads/04-data-security-soc-alert-triage/workflows/rapid-classification-workflow.yaml +25 -0
  46. package/.catalog/squads/05-domain-specialists-adaptive-tutor-k12/workflows/full-tutoring-cycle-workflow.yaml +25 -0
  47. package/.catalog/squads/05-domain-specialists-adaptive-tutor-k12/workflows/quick-practice-session-workflow.yaml +25 -0
  48. package/.catalog/squads/05-domain-specialists-ambient-clinical-scribe/workflows/full-documentation-workflow.yaml +25 -0
  49. package/.catalog/squads/05-domain-specialists-ambient-clinical-scribe/workflows/quick-note-workflow.yaml +25 -0
  50. package/.catalog/squads/05-domain-specialists-contract-review-squad/workflows/full-contract-review-workflow.yaml +25 -0
  51. package/.catalog/squads/05-domain-specialists-contract-review-squad/workflows/quick-risk-assessment-workflow.yaml +25 -0
  52. package/.catalog/squads/05-domain-specialists-crypto-token-forge/workflows/full-token-launch-workflow.yaml +25 -0
  53. package/.catalog/squads/05-domain-specialists-crypto-token-forge/workflows/memecoin-express-workflow.yaml +25 -0
  54. package/.catalog/squads/05-domain-specialists-crypto-token-forge/workflows/utility-token-launch-workflow.yaml +25 -0
  55. package/.catalog/squads/05-domain-specialists-resume-screener-squad/workflows/full-resume-screening-workflow.yaml +25 -0
  56. package/.catalog/squads/05-domain-specialists-resume-screener-squad/workflows/quick-skills-match-workflow.yaml +25 -0
  57. package/.catalog/squads/test-squad/SQUAD.md +1 -1
  58. package/.openlife/method/agents/atlas.md +102 -0
  59. package/.openlife/method/agents/builder.md +92 -0
  60. package/.openlife/method/agents/conductor.md +93 -0
  61. package/.openlife/method/agents/forge.md +96 -0
  62. package/.openlife/method/agents/genesis.md +115 -0
  63. package/.openlife/method/agents/lyra.md +85 -0
  64. package/.openlife/method/agents/maestro.md +92 -0
  65. package/.openlife/method/agents/mesh.md +101 -0
  66. package/.openlife/method/agents/prism.md +85 -0
  67. package/.openlife/method/agents/sentinel.md +115 -0
  68. package/.openlife/method/agents/steward.md +93 -0
  69. package/.openlife/method/agents/vortex.md +94 -0
  70. package/dist/cli/CommandFlowRunner.js +167 -0
  71. package/dist/cli/install/Phases.js +43 -0
  72. package/dist/index.js +118 -0
  73. package/dist/orchestrator/ProjectMetadata.js +183 -0
  74. package/dist/test_flow_run_cli.js +183 -0
  75. package/dist/test_host_uninstaller.js +12 -2
  76. package/dist/test_openlife_method_inventory.js +183 -0
  77. package/dist/test_workflow_e2e.js +10 -3
  78. package/dist-templates/claude-code/agents/openlife-atlas.md +12 -44
  79. package/dist-templates/claude-code/agents/openlife-builder.md +20 -0
  80. package/dist-templates/claude-code/agents/openlife-conductor.md +20 -0
  81. package/dist-templates/claude-code/agents/openlife-forge.md +12 -34
  82. package/dist-templates/claude-code/agents/openlife-genesis.md +12 -51
  83. package/dist-templates/claude-code/agents/openlife-lyra.md +12 -32
  84. package/dist-templates/claude-code/agents/openlife-maestro.md +27 -41
  85. package/dist-templates/claude-code/agents/openlife-mesh.md +20 -0
  86. package/dist-templates/claude-code/agents/openlife-prism.md +20 -0
  87. package/dist-templates/claude-code/agents/openlife-sentinel.md +20 -0
  88. package/dist-templates/claude-code/agents/openlife-steward.md +20 -0
  89. package/dist-templates/claude-code/agents/openlife-vortex.md +20 -0
  90. package/dist-templates/claude-code/commands/openlife/agents/atlas.md +24 -0
  91. package/dist-templates/claude-code/commands/openlife/agents/builder.md +24 -0
  92. package/dist-templates/claude-code/commands/openlife/agents/conductor.md +24 -0
  93. package/dist-templates/claude-code/commands/openlife/agents/forge.md +24 -0
  94. package/dist-templates/claude-code/commands/openlife/agents/genesis.md +24 -0
  95. package/dist-templates/claude-code/commands/openlife/agents/lyra.md +24 -0
  96. package/dist-templates/claude-code/commands/openlife/agents/maestro.md +24 -0
  97. package/dist-templates/claude-code/commands/openlife/agents/mesh.md +24 -0
  98. package/dist-templates/claude-code/commands/openlife/agents/prism.md +24 -0
  99. package/dist-templates/claude-code/commands/openlife/agents/sentinel.md +24 -0
  100. package/dist-templates/claude-code/commands/openlife/agents/steward.md +24 -0
  101. package/dist-templates/claude-code/commands/openlife/agents/vortex.md +24 -0
  102. package/dist-templates/claude-code/commands/openlife/ask.md +13 -7
  103. package/dist-templates/claude-code/commands/openlife/audit.md +14 -0
  104. package/dist-templates/claude-code/commands/openlife/doctor.md +11 -14
  105. package/dist-templates/claude-code/commands/openlife/dream.md +10 -16
  106. package/dist-templates/claude-code/commands/openlife/explore.md +14 -0
  107. package/dist-templates/claude-code/commands/openlife/flow/brownfield-discovery.md +20 -0
  108. package/dist-templates/claude-code/commands/openlife/flow/brownfield-fullstack.md +20 -0
  109. package/dist-templates/claude-code/commands/openlife/flow/brownfield-service.md +20 -0
  110. package/dist-templates/claude-code/commands/openlife/flow/brownfield-ui.md +20 -0
  111. package/dist-templates/claude-code/commands/openlife/flow/epic.md +20 -0
  112. package/dist-templates/claude-code/commands/openlife/flow/greenfield-fullstack.md +20 -0
  113. package/dist-templates/claude-code/commands/openlife/flow/greenfield-service.md +20 -0
  114. package/dist-templates/claude-code/commands/openlife/flow/greenfield-ui.md +20 -0
  115. package/dist-templates/claude-code/commands/openlife/flow/qa-loop.md +20 -0
  116. package/dist-templates/claude-code/commands/openlife/flow/release.md +20 -0
  117. package/dist-templates/claude-code/commands/openlife/flow/spec-pipeline.md +20 -0
  118. package/dist-templates/claude-code/commands/openlife/flow/story-cycle.md +20 -0
  119. package/dist-templates/claude-code/commands/openlife/health.md +14 -0
  120. package/dist-templates/claude-code/commands/openlife/plan.md +14 -0
  121. package/dist-templates/claude-code/commands/openlife/review.md +14 -0
  122. package/dist-templates/claude-code/commands/openlife/ship.md +14 -0
  123. package/dist-templates/claude-code/commands/openlife/start.md +25 -0
  124. package/dist-templates/claude-code/commands/openlife/status.md +10 -10
  125. package/dist-templates/claude-code/commands/openlife/story.md +18 -0
  126. package/dist-templates/codex/agents/openlife-atlas.md +12 -44
  127. package/dist-templates/codex/agents/openlife-builder.md +20 -0
  128. package/dist-templates/codex/agents/openlife-conductor.md +20 -0
  129. package/dist-templates/codex/agents/openlife-forge.md +12 -34
  130. package/dist-templates/codex/agents/openlife-genesis.md +12 -51
  131. package/dist-templates/codex/agents/openlife-lyra.md +12 -32
  132. package/dist-templates/codex/agents/openlife-maestro.md +27 -41
  133. package/dist-templates/codex/agents/openlife-mesh.md +20 -0
  134. package/dist-templates/codex/agents/openlife-prism.md +20 -0
  135. package/dist-templates/codex/agents/openlife-sentinel.md +20 -0
  136. package/dist-templates/codex/agents/openlife-steward.md +20 -0
  137. package/dist-templates/codex/agents/openlife-vortex.md +20 -0
  138. package/dist-templates/codex/commands/openlife/agents/atlas.md +24 -0
  139. package/dist-templates/codex/commands/openlife/agents/builder.md +24 -0
  140. package/dist-templates/codex/commands/openlife/agents/conductor.md +24 -0
  141. package/dist-templates/codex/commands/openlife/agents/forge.md +24 -0
  142. package/dist-templates/codex/commands/openlife/agents/genesis.md +24 -0
  143. package/dist-templates/codex/commands/openlife/agents/lyra.md +24 -0
  144. package/dist-templates/codex/commands/openlife/agents/maestro.md +24 -0
  145. package/dist-templates/codex/commands/openlife/agents/mesh.md +24 -0
  146. package/dist-templates/codex/commands/openlife/agents/prism.md +24 -0
  147. package/dist-templates/codex/commands/openlife/agents/sentinel.md +24 -0
  148. package/dist-templates/codex/commands/openlife/agents/steward.md +24 -0
  149. package/dist-templates/codex/commands/openlife/agents/vortex.md +24 -0
  150. package/dist-templates/codex/commands/openlife/ask.md +13 -7
  151. package/dist-templates/codex/commands/openlife/audit.md +14 -0
  152. package/dist-templates/codex/commands/openlife/doctor.md +11 -14
  153. package/dist-templates/codex/commands/openlife/dream.md +10 -16
  154. package/dist-templates/codex/commands/openlife/explore.md +14 -0
  155. package/dist-templates/codex/commands/openlife/flow/brownfield-discovery.md +20 -0
  156. package/dist-templates/codex/commands/openlife/flow/brownfield-fullstack.md +20 -0
  157. package/dist-templates/codex/commands/openlife/flow/brownfield-service.md +20 -0
  158. package/dist-templates/codex/commands/openlife/flow/brownfield-ui.md +20 -0
  159. package/dist-templates/codex/commands/openlife/flow/epic.md +20 -0
  160. package/dist-templates/codex/commands/openlife/flow/greenfield-fullstack.md +20 -0
  161. package/dist-templates/codex/commands/openlife/flow/greenfield-service.md +20 -0
  162. package/dist-templates/codex/commands/openlife/flow/greenfield-ui.md +20 -0
  163. package/dist-templates/codex/commands/openlife/flow/qa-loop.md +20 -0
  164. package/dist-templates/codex/commands/openlife/flow/release.md +20 -0
  165. package/dist-templates/codex/commands/openlife/flow/spec-pipeline.md +20 -0
  166. package/dist-templates/codex/commands/openlife/flow/story-cycle.md +20 -0
  167. package/dist-templates/codex/commands/openlife/health.md +14 -0
  168. package/dist-templates/codex/commands/openlife/plan.md +14 -0
  169. package/dist-templates/codex/commands/openlife/review.md +14 -0
  170. package/dist-templates/codex/commands/openlife/ship.md +14 -0
  171. package/dist-templates/codex/commands/openlife/start.md +25 -0
  172. package/dist-templates/codex/commands/openlife/status.md +10 -10
  173. package/dist-templates/codex/commands/openlife/story.md +18 -0
  174. package/dist-templates/gemini-cli/agents/openlife-atlas.md +12 -44
  175. package/dist-templates/gemini-cli/agents/openlife-builder.md +20 -0
  176. package/dist-templates/gemini-cli/agents/openlife-conductor.md +20 -0
  177. package/dist-templates/gemini-cli/agents/openlife-forge.md +12 -34
  178. package/dist-templates/gemini-cli/agents/openlife-genesis.md +12 -51
  179. package/dist-templates/gemini-cli/agents/openlife-lyra.md +12 -32
  180. package/dist-templates/gemini-cli/agents/openlife-maestro.md +27 -41
  181. package/dist-templates/gemini-cli/agents/openlife-mesh.md +20 -0
  182. package/dist-templates/gemini-cli/agents/openlife-prism.md +20 -0
  183. package/dist-templates/gemini-cli/agents/openlife-sentinel.md +20 -0
  184. package/dist-templates/gemini-cli/agents/openlife-steward.md +20 -0
  185. package/dist-templates/gemini-cli/agents/openlife-vortex.md +20 -0
  186. package/dist-templates/gemini-cli/commands/openlife/agents/atlas.md +24 -0
  187. package/dist-templates/gemini-cli/commands/openlife/agents/builder.md +24 -0
  188. package/dist-templates/gemini-cli/commands/openlife/agents/conductor.md +24 -0
  189. package/dist-templates/gemini-cli/commands/openlife/agents/forge.md +24 -0
  190. package/dist-templates/gemini-cli/commands/openlife/agents/genesis.md +24 -0
  191. package/dist-templates/gemini-cli/commands/openlife/agents/lyra.md +24 -0
  192. package/dist-templates/gemini-cli/commands/openlife/agents/maestro.md +24 -0
  193. package/dist-templates/gemini-cli/commands/openlife/agents/mesh.md +24 -0
  194. package/dist-templates/gemini-cli/commands/openlife/agents/prism.md +24 -0
  195. package/dist-templates/gemini-cli/commands/openlife/agents/sentinel.md +24 -0
  196. package/dist-templates/gemini-cli/commands/openlife/agents/steward.md +24 -0
  197. package/dist-templates/gemini-cli/commands/openlife/agents/vortex.md +24 -0
  198. package/dist-templates/gemini-cli/commands/openlife/ask.md +13 -7
  199. package/dist-templates/gemini-cli/commands/openlife/audit.md +14 -0
  200. package/dist-templates/gemini-cli/commands/openlife/doctor.md +11 -14
  201. package/dist-templates/gemini-cli/commands/openlife/dream.md +10 -16
  202. package/dist-templates/gemini-cli/commands/openlife/explore.md +14 -0
  203. package/dist-templates/gemini-cli/commands/openlife/flow/brownfield-discovery.md +20 -0
  204. package/dist-templates/gemini-cli/commands/openlife/flow/brownfield-fullstack.md +20 -0
  205. package/dist-templates/gemini-cli/commands/openlife/flow/brownfield-service.md +20 -0
  206. package/dist-templates/gemini-cli/commands/openlife/flow/brownfield-ui.md +20 -0
  207. package/dist-templates/gemini-cli/commands/openlife/flow/epic.md +20 -0
  208. package/dist-templates/gemini-cli/commands/openlife/flow/greenfield-fullstack.md +20 -0
  209. package/dist-templates/gemini-cli/commands/openlife/flow/greenfield-service.md +20 -0
  210. package/dist-templates/gemini-cli/commands/openlife/flow/greenfield-ui.md +20 -0
  211. package/dist-templates/gemini-cli/commands/openlife/flow/qa-loop.md +20 -0
  212. package/dist-templates/gemini-cli/commands/openlife/flow/release.md +20 -0
  213. package/dist-templates/gemini-cli/commands/openlife/flow/spec-pipeline.md +20 -0
  214. package/dist-templates/gemini-cli/commands/openlife/flow/story-cycle.md +20 -0
  215. package/dist-templates/gemini-cli/commands/openlife/health.md +14 -0
  216. package/dist-templates/gemini-cli/commands/openlife/plan.md +14 -0
  217. package/dist-templates/gemini-cli/commands/openlife/review.md +14 -0
  218. package/dist-templates/gemini-cli/commands/openlife/ship.md +14 -0
  219. package/dist-templates/gemini-cli/commands/openlife/start.md +25 -0
  220. package/dist-templates/gemini-cli/commands/openlife/status.md +10 -10
  221. package/dist-templates/gemini-cli/commands/openlife/story.md +18 -0
  222. package/dist-templates/workflows/brownfield-fullstack.yaml +131 -0
  223. package/dist-templates/workflows/brownfield-service.yaml +111 -0
  224. package/dist-templates/workflows/brownfield-ui.yaml +115 -0
  225. package/dist-templates/workflows/continuous-deployment.yaml +139 -0
  226. package/dist-templates/workflows/epic-orchestration.yaml +101 -0
  227. package/dist-templates/workflows/greenfield-service.yaml +154 -0
  228. package/dist-templates/workflows/greenfield-ui.yaml +140 -0
  229. package/dist-templates/workflows/spec-pipeline.yaml +135 -0
  230. package/package.json +5 -2
  231. package/scripts/generate-slash-commands.js +220 -0
  232. package/scripts/generate-squad-workflow-stubs.js +144 -0
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ // src/test_flow_run_cli.ts
3
+ // Smoke test for the v1.9.0 `openlife flow` CLI surface and
4
+ // `openlife project-mode` commands. Exercises the runtime path without
5
+ // requiring an LLM or external CI.
6
+ //
7
+ // Covers:
8
+ // 1. listFlows() returns all 12 expected workflows from bundled source
9
+ // 2. findFlow(id) resolves a known workflow
10
+ // 3. dryRunFlow(id) produces a phase plan with > 0 steps
11
+ // 4. ProjectMetadata read/write roundtrip
12
+ // 5. detectMode + recommendWorkflow produce sane defaults
13
+ // 6. project mode persistence file shape is valid JSON
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ const fs = __importStar(require("fs"));
49
+ const os = __importStar(require("os"));
50
+ const path = __importStar(require("path"));
51
+ const CommandFlowRunner_1 = require("./cli/CommandFlowRunner");
52
+ const ProjectMetadata_1 = require("./orchestrator/ProjectMetadata");
53
+ let passed = 0;
54
+ let failed = 0;
55
+ function check(name, cond, detail) {
56
+ if (cond) {
57
+ passed++;
58
+ console.log(` ✓ ${name}`);
59
+ }
60
+ else {
61
+ failed++;
62
+ console.error(` ✗ ${name}${detail ? ` — ${detail}` : ''}`);
63
+ }
64
+ }
65
+ const REPO_ROOT = path.resolve(__dirname, '..');
66
+ // ── 1. listFlows ───────────────────────────────────────────────────────
67
+ console.log('\n[1] CommandFlowRunner.listFlows()');
68
+ const flows = (0, CommandFlowRunner_1.listFlows)(REPO_ROOT);
69
+ check('at least 12 workflows surfaced', flows.length >= 12, `got ${flows.length}`);
70
+ const flowIds = new Set(flows.map(f => f.id));
71
+ for (const expected of ['greenfield-fullstack', 'greenfield-service', 'greenfield-ui',
72
+ 'brownfield-discovery', 'brownfield-fullstack', 'brownfield-service',
73
+ 'brownfield-ui', 'story-development-cycle', 'qa-loop',
74
+ 'spec-pipeline', 'epic-orchestration', 'continuous-deployment']) {
75
+ check(`flow "${expected}" listed`, flowIds.has(expected));
76
+ }
77
+ // Every entry has the right shape
78
+ for (const f of flows.slice(0, 3)) {
79
+ check(`flow "${f.id}" has type`, !!f.type);
80
+ check(`flow "${f.id}" has steps > 0`, f.steps > 0, `steps=${f.steps}`);
81
+ }
82
+ // ── 2. findFlow ────────────────────────────────────────────────────────
83
+ console.log('\n[2] CommandFlowRunner.findFlow()');
84
+ const greenfieldFs = (0, CommandFlowRunner_1.findFlow)('greenfield-fullstack', REPO_ROOT);
85
+ check('findFlow("greenfield-fullstack") returns a workflow', greenfieldFs !== null);
86
+ check('found workflow has correct id', greenfieldFs?.workflow.id === 'greenfield-fullstack');
87
+ check('source is bundled when running from repo', greenfieldFs?.source === 'bundled' || greenfieldFs?.source === 'local');
88
+ const notFound = (0, CommandFlowRunner_1.findFlow)('definitely-does-not-exist', REPO_ROOT);
89
+ check('findFlow returns null for unknown id', notFound === null);
90
+ // ── 3. dryRunFlow ──────────────────────────────────────────────────────
91
+ console.log('\n[3] CommandFlowRunner.dryRunFlow()');
92
+ const summary = (0, CommandFlowRunner_1.dryRunFlow)('greenfield-service', REPO_ROOT);
93
+ check('dryRunFlow("greenfield-service") returns summary', summary !== null);
94
+ if (summary) {
95
+ check('summary has id', summary.id === 'greenfield-service');
96
+ check('summary has > 5 steps', summary.steps.length > 5, `got ${summary.steps.length}`);
97
+ check('summary has at least one phase marker', summary.steps.some(s => s.phase !== undefined));
98
+ check('summary has at least one executable step', summary.steps.some(s => s.id !== undefined));
99
+ const rendered = (0, CommandFlowRunner_1.renderDryRun)(summary);
100
+ check('renderDryRun produces > 5 lines', rendered.length > 5);
101
+ }
102
+ // ── 4. ProjectMetadata roundtrip ───────────────────────────────────────
103
+ console.log('\n[4] ProjectMetadata read/write roundtrip');
104
+ const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'openlife-method-test-'));
105
+ try {
106
+ const meta = (0, ProjectMetadata_1.buildMetadata)('greenfield', tmpRoot, 'test-run-note');
107
+ const fp = (0, ProjectMetadata_1.writeProjectMetadata)(meta, tmpRoot);
108
+ check('writeProjectMetadata returns path', fp.endsWith('project.json'));
109
+ check('file was actually written', fs.existsSync(fp));
110
+ const readBack = (0, ProjectMetadata_1.readProjectMetadata)(tmpRoot);
111
+ check('readProjectMetadata returns metadata', readBack !== null);
112
+ check('read mode matches written mode', readBack?.mode === 'greenfield');
113
+ check('read createdAt is ISO string', /\d{4}-\d{2}-\d{2}T/.test(readBack?.createdAt || ''));
114
+ check('read recommendedWorkflow is non-empty', !!readBack?.recommendedWorkflow);
115
+ check('read notes preserved', readBack?.notes === 'test-run-note');
116
+ // Round-trip with brownfield
117
+ const meta2 = (0, ProjectMetadata_1.buildMetadata)('brownfield', tmpRoot);
118
+ (0, ProjectMetadata_1.writeProjectMetadata)(meta2, tmpRoot);
119
+ const readBack2 = (0, ProjectMetadata_1.readProjectMetadata)(tmpRoot);
120
+ check('brownfield mode roundtrips', readBack2?.mode === 'brownfield');
121
+ check('brownfield recommends discovery', readBack2?.recommendedWorkflow === 'brownfield-discovery');
122
+ }
123
+ finally {
124
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
125
+ }
126
+ // ── 5. detectMode + recommendWorkflow ──────────────────────────────────
127
+ console.log('\n[5] Heuristic detection');
128
+ // Empty tmpdir → greenfield
129
+ const emptyDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openlife-empty-'));
130
+ try {
131
+ const mode = (0, ProjectMetadata_1.detectMode)(emptyDir);
132
+ check('empty dir → greenfield', mode === 'greenfield');
133
+ const rec = (0, ProjectMetadata_1.recommendWorkflow)(mode, []);
134
+ check('greenfield + no stack → greenfield-fullstack', rec === 'greenfield-fullstack');
135
+ }
136
+ finally {
137
+ fs.rmSync(emptyDir, { recursive: true, force: true });
138
+ }
139
+ // Tmp with package.json but no git → still greenfield
140
+ const pkgDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openlife-pkg-'));
141
+ try {
142
+ fs.writeFileSync(path.join(pkgDir, 'package.json'), JSON.stringify({ name: 'x', dependencies: { react: '*' } }));
143
+ const stack = (0, ProjectMetadata_1.detectStack)(pkgDir);
144
+ check('detectStack finds node', stack.includes('node'));
145
+ check('detectStack finds react', stack.includes('react'));
146
+ const rec = (0, ProjectMetadata_1.recommendWorkflow)('greenfield', stack);
147
+ check('greenfield + react → greenfield-ui (no server)', rec === 'greenfield-ui');
148
+ }
149
+ finally {
150
+ fs.rmSync(pkgDir, { recursive: true, force: true });
151
+ }
152
+ // Brownfield always recommends discovery
153
+ const rec3 = (0, ProjectMetadata_1.recommendWorkflow)('brownfield', ['node', 'typescript', 'react']);
154
+ check('brownfield → discovery regardless of stack', rec3 === 'brownfield-discovery');
155
+ // ── 6. JSON file shape ─────────────────────────────────────────────────
156
+ console.log('\n[6] project.json shape');
157
+ const tmpRoot2 = fs.mkdtempSync(path.join(os.tmpdir(), 'openlife-shape-'));
158
+ try {
159
+ const meta = (0, ProjectMetadata_1.buildMetadata)('greenfield', tmpRoot2);
160
+ (0, ProjectMetadata_1.writeProjectMetadata)(meta, tmpRoot2);
161
+ const raw = fs.readFileSync((0, ProjectMetadata_1.projectMetadataPath)(tmpRoot2), 'utf-8');
162
+ let parsed = {};
163
+ try {
164
+ parsed = JSON.parse(raw);
165
+ }
166
+ catch { /* shape check below catches it */ }
167
+ check('file is valid JSON', !!parsed.mode);
168
+ check('has createdAt', typeof parsed.createdAt === 'string');
169
+ check('has updatedAt', typeof parsed.updatedAt === 'string');
170
+ check('has detectedStack array', Array.isArray(parsed.detectedStack));
171
+ check('has recommendedWorkflow string', typeof parsed.recommendedWorkflow === 'string');
172
+ }
173
+ finally {
174
+ fs.rmSync(tmpRoot2, { recursive: true, force: true });
175
+ }
176
+ // ── Done ───────────────────────────────────────────────────────────────
177
+ console.log('');
178
+ console.log(`Results: ${passed} passed, ${failed} failed`);
179
+ if (failed > 0) {
180
+ console.error('TEST_FLOW_RUN_CLI_FAIL');
181
+ process.exit(1);
182
+ }
183
+ console.log('TEST_FLOW_RUN_CLI_OK');
@@ -99,9 +99,19 @@ function testUninstallRemovesAllInstalledArtifacts() {
99
99
  // The openlife/ commands namespace directory should be removed (it was all ours and is now empty).
100
100
  const cmdsNs = path.join(tempRoot, '.claude', 'commands', 'openlife');
101
101
  assert(!fs.existsSync(cmdsNs), `empty openlife/ commands namespace should be removed: ${cmdsNs}`);
102
- // Counted: 5 agents + 4 commands + 1 mcp snippet = 10 removals.
102
+ // Count dynamically from dist-templates/claude-code/. The uninstaller
103
+ // removes top-level files (agents + top-level commands + MCP snippet),
104
+ // not files inside nested commands/openlife/{agents,flow}/ subdirs.
105
+ const distTemplateRoot = path.join(__dirname, '..', 'dist-templates', 'claude-code');
106
+ const agentCount = fs.existsSync(path.join(distTemplateRoot, 'agents'))
107
+ ? fs.readdirSync(path.join(distTemplateRoot, 'agents')).filter((f) => f.endsWith('.md')).length
108
+ : 0;
109
+ const commandCount = fs.existsSync(path.join(distTemplateRoot, 'commands', 'openlife'))
110
+ ? fs.readdirSync(path.join(distTemplateRoot, 'commands', 'openlife')).filter((f) => f.endsWith('.md')).length
111
+ : 0;
112
+ const expectedRemoved = agentCount + commandCount + 1; // +1 for MCP snippet
103
113
  const removed = result.files.filter((f) => f.action === 'removed').length;
104
- assert(removed === 10, `expected 10 'removed' actions (5 agents + 4 commands + 1 mcp); got ${removed}: ` +
114
+ assert(removed === expectedRemoved, `expected ${expectedRemoved} 'removed' actions (${agentCount} agents + ${commandCount} top-level commands + 1 mcp); got ${removed}: ` +
105
115
  JSON.stringify(result.files.map((f) => `${path.basename(f.destination)}:${f.action}`)));
106
116
  }
107
117
  finally {
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ // src/test_openlife_method_inventory.ts
3
+ // Invariants for the v1.9.0 OpenLife method framework layer.
4
+ //
5
+ // Verifies:
6
+ // 1. 12 deep persona files exist under .openlife/method/agents/
7
+ // 2. 12 ambassador shims per host under dist-templates/<host>/agents/
8
+ // 3. 12 workflows under dist-templates/workflows/ all parse cleanly
9
+ // 4. 36 slash commands per host under dist-templates/<host>/commands/openlife/
10
+ // 5. .openlife/method/agents/ files have valid frontmatter
11
+ // 6. No string "aiox" appears in any shipped file under dist-templates/ or
12
+ // .openlife/method/ (policy enforcement: no AIOX brand leaks)
13
+ //
14
+ // Fail-fast: any drift from expected counts surfaces immediately.
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const WorkflowParser_1 = require("./orchestrator/workflow/WorkflowParser");
52
+ const REPO_ROOT = path.resolve(__dirname, '..');
53
+ const HOSTS = ['claude-code', 'gemini-cli', 'codex'];
54
+ const EXPECTED_PERSONAS = [
55
+ 'maestro', 'lyra', 'forge', 'atlas', 'genesis',
56
+ 'builder', 'sentinel', 'steward', 'conductor', 'vortex', 'mesh', 'prism',
57
+ ];
58
+ const EXPECTED_WORKFLOWS = [
59
+ 'greenfield-fullstack', 'greenfield-service', 'greenfield-ui',
60
+ 'brownfield-discovery', 'brownfield-fullstack', 'brownfield-service', 'brownfield-ui',
61
+ 'story-development-cycle', 'qa-loop', 'spec-pipeline',
62
+ 'epic-orchestration', 'continuous-deployment',
63
+ ];
64
+ let passed = 0;
65
+ let failed = 0;
66
+ const failures = [];
67
+ function check(name, cond, detail) {
68
+ if (cond) {
69
+ passed++;
70
+ }
71
+ else {
72
+ failed++;
73
+ const msg = detail ? `${name} — ${detail}` : name;
74
+ failures.push(msg);
75
+ }
76
+ }
77
+ function readUtf8(fp) {
78
+ return fs.readFileSync(fp, 'utf-8');
79
+ }
80
+ // ── 1. Deep personas ───────────────────────────────────────────────────
81
+ console.log('[1] Deep personas in .openlife/method/agents/');
82
+ const personasDir = path.join(REPO_ROOT, '.openlife', 'method', 'agents');
83
+ for (const id of EXPECTED_PERSONAS) {
84
+ const fp = path.join(personasDir, `${id}.md`);
85
+ check(`persona ${id}.md exists`, fs.existsSync(fp));
86
+ if (fs.existsSync(fp)) {
87
+ const content = readUtf8(fp);
88
+ check(`persona ${id} has frontmatter`, /^---\n[\s\S]+?\n---/.test(content));
89
+ check(`persona ${id} declares id field`, new RegExp(`id: openlife-${id}`).test(content));
90
+ check(`persona ${id} has Commands section`, /## Commands/.test(content));
91
+ check(`persona ${id} has Hand-offs section`, /## Hand-offs/.test(content));
92
+ }
93
+ }
94
+ // ── 2. Ambassador shims (one per host) ─────────────────────────────────
95
+ console.log('[2] Ambassador shims');
96
+ for (const host of HOSTS) {
97
+ const dir = path.join(REPO_ROOT, 'dist-templates', host, 'agents');
98
+ check(`host dir ${host}/agents exists`, fs.existsSync(dir));
99
+ for (const id of EXPECTED_PERSONAS) {
100
+ const fp = path.join(dir, `openlife-${id}.md`);
101
+ check(`${host}/agents/openlife-${id}.md exists`, fs.existsSync(fp));
102
+ if (fs.existsSync(fp)) {
103
+ const content = readUtf8(fp);
104
+ check(`${host}/${id} ambassador frontmatter`, /^---\nname: openlife-/.test(content));
105
+ check(`${host}/${id} ambassador points to runtime`, content.includes(`.openlife/method/agents/${id}.md`));
106
+ }
107
+ }
108
+ }
109
+ // ── 3. Workflows ───────────────────────────────────────────────────────
110
+ console.log('[3] Workflows in dist-templates/workflows/');
111
+ const workflowsDir = path.join(REPO_ROOT, 'dist-templates', 'workflows');
112
+ for (const id of EXPECTED_WORKFLOWS) {
113
+ const fp = path.join(workflowsDir, `${id}.yaml`);
114
+ check(`workflow ${id}.yaml exists`, fs.existsSync(fp));
115
+ if (fs.existsSync(fp)) {
116
+ const parsed = (0, WorkflowParser_1.parseWorkflowFile)(fp);
117
+ check(`workflow ${id} parses cleanly`, !parsed.errors || parsed.errors.length === 0, parsed.errors ? parsed.errors[0]?.message?.slice(0, 80) : undefined);
118
+ if (parsed.workflow) {
119
+ check(`workflow ${id} id matches filename`, parsed.workflow.id === id);
120
+ check(`workflow ${id} has sequence`, (parsed.workflow.sequence || []).length > 0);
121
+ }
122
+ }
123
+ }
124
+ // ── 4. Slash commands ──────────────────────────────────────────────────
125
+ console.log('[4] Slash commands per host');
126
+ const EXPECTED_TOP = ['ask', 'doctor', 'status', 'dream', 'start', 'plan', 'story', 'review', 'ship', 'explore', 'audit', 'health'];
127
+ const EXPECTED_FLOWS = ['greenfield-fullstack', 'greenfield-service', 'greenfield-ui', 'brownfield-discovery', 'brownfield-fullstack', 'brownfield-service', 'brownfield-ui', 'story-cycle', 'qa-loop', 'spec-pipeline', 'epic', 'release'];
128
+ for (const host of HOSTS) {
129
+ const base = path.join(REPO_ROOT, 'dist-templates', host, 'commands', 'openlife');
130
+ for (const name of EXPECTED_TOP) {
131
+ check(`${host}/commands/openlife/${name}.md exists`, fs.existsSync(path.join(base, `${name}.md`)));
132
+ }
133
+ for (const id of EXPECTED_PERSONAS) {
134
+ check(`${host}/commands/openlife/agents/${id}.md exists`, fs.existsSync(path.join(base, 'agents', `${id}.md`)));
135
+ }
136
+ for (const flow of EXPECTED_FLOWS) {
137
+ check(`${host}/commands/openlife/flow/${flow}.md exists`, fs.existsSync(path.join(base, 'flow', `${flow}.md`)));
138
+ }
139
+ }
140
+ // ── 5. No "aiox" leak in shipped content ───────────────────────────────
141
+ console.log('[5] AIOX brand leak check');
142
+ function scanForAiox(root) {
143
+ const hits = [];
144
+ if (!fs.existsSync(root))
145
+ return hits;
146
+ function walk(dir) {
147
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
148
+ const fp = path.join(dir, entry.name);
149
+ if (entry.isDirectory()) {
150
+ walk(fp);
151
+ continue;
152
+ }
153
+ if (!/\.(md|yaml|yml|json|js|ts)$/.test(entry.name))
154
+ continue;
155
+ try {
156
+ const content = fs.readFileSync(fp, 'utf-8');
157
+ if (/\baiox\b/i.test(content)) {
158
+ hits.push(path.relative(REPO_ROOT, fp));
159
+ }
160
+ }
161
+ catch { /* skip binary */ }
162
+ }
163
+ }
164
+ walk(root);
165
+ return hits;
166
+ }
167
+ const aioxInDistTemplates = scanForAiox(path.join(REPO_ROOT, 'dist-templates'));
168
+ const aioxInOpenLifeMethod = scanForAiox(path.join(REPO_ROOT, '.openlife', 'method'));
169
+ check('no aiox leak in dist-templates/', aioxInDistTemplates.length === 0, aioxInDistTemplates.length > 0 ? `found in ${aioxInDistTemplates.length} files: ${aioxInDistTemplates.slice(0, 3).join(', ')}` : undefined);
170
+ check('no aiox leak in .openlife/method/', aioxInOpenLifeMethod.length === 0, aioxInOpenLifeMethod.length > 0 ? `found in ${aioxInOpenLifeMethod.length} files: ${aioxInOpenLifeMethod.slice(0, 3).join(', ')}` : undefined);
171
+ // ── 6. Summary ─────────────────────────────────────────────────────────
172
+ console.log('');
173
+ console.log(`Results: ${passed} passed, ${failed} failed`);
174
+ if (failed > 0) {
175
+ console.error('TEST_OPENLIFE_METHOD_INVENTORY_FAIL');
176
+ console.error('Failures:');
177
+ for (const f of failures.slice(0, 25))
178
+ console.error(' - ' + f);
179
+ if (failures.length > 25)
180
+ console.error(` ... and ${failures.length - 25} more`);
181
+ process.exit(1);
182
+ }
183
+ console.log('TEST_OPENLIFE_METHOD_INVENTORY_OK');
@@ -116,10 +116,17 @@ function scenarioList() {
116
116
  assert(r.status === 0, `list exit code: ${r.status}, stderr: ${r.stderr}`);
117
117
  const obj = extractJson(r.stdout);
118
118
  assert(obj.ok === true, 'list must return ok:true');
119
- assert(obj.count === 4, `expected 4 workflows, got ${obj.count}`);
119
+ // v1.9.0+: original 4 workflows still ship + 8 new (greenfield/brownfield
120
+ // variants, spec-pipeline, epic-orchestration, continuous-deployment) =
121
+ // 12 total. Test asserts >= 4 (original guarantees) and that the
122
+ // original 4 ids still resolve, instead of an exact count that drifts.
123
+ assert(obj.count >= 4, `expected at least 4 workflows, got ${obj.count}`);
120
124
  const ids = obj.workflows.map((w) => w.id).sort();
121
- assert(JSON.stringify(ids) === JSON.stringify(['brownfield-discovery', 'greenfield-fullstack', 'qa-loop', 'story-development-cycle']), `unexpected workflow ids: ${ids.join(', ')}`);
122
- console.log('✅ scenario 1: workflow list (4 workflows)');
125
+ const required = ['brownfield-discovery', 'greenfield-fullstack', 'qa-loop', 'story-development-cycle'];
126
+ for (const r of required) {
127
+ assert(ids.includes(r), `workflow list missing required id "${r}". Got: ${ids.join(', ')}`);
128
+ }
129
+ console.log(`✅ scenario 1: workflow list (${obj.count} workflows, all 4 original ids present)`);
123
130
  }
124
131
  finally {
125
132
  rmTmp(tmp);
@@ -1,52 +1,20 @@
1
1
  ---
2
2
  name: openlife-atlas
3
- description: Codebase mapping and architectural analysis specialist. Use for dependency tracing, identifying which files/classes own a behavior, mapping subsystems, surfacing architectural drift, or producing the architecture section of a planning doc. Not for writing new code — that's the default flow. Not for prose writeups — that's LYRA.
4
- tools: Read, Grep, Glob, Bash
5
- model: sonnet
3
+ description: System Architect in the OpenLife method codebase mapping, ADRs, technology selection, impact analysis, complexity assessment
4
+ tools: [Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion]
5
+ model: claude-opus-4-7
6
6
  ---
7
7
 
8
- You are **ATLAS**, the codebase mapping specialist for OpenLife.
8
+ You are **Atlas**, the System Architect in the OpenLife method.
9
9
 
10
- ## What you own
10
+ **Persona definition:** Read `.openlife/method/agents/atlas.md` in full before responding. It defines what you own (system architecture, tech selection, high-level data architecture, integration patterns, complexity assessment), what you delegate (DDL to Mesh, UI architecture to Prism, app code to Builder), and the 5-dimension complexity scoring (Scope, Integration, Infrastructure, Knowledge, Risk).
11
11
 
12
- - **Subsystem mapping**: Given a feature, identify every file/class involved
13
- - **Dependency tracing**: Where is X imported? What does Y depend on?
14
- - **Drift detection**: Compare current code structure to documented architecture (`.planning/codebase/ARCHITECTURE.md`, CLAUDE.md)
15
- - **Impact analysis**: If we change file A, what else breaks?
12
+ **Activation:**
13
+ 1. Read the persona file
14
+ 2. Display: `🏛️ Atlas analyzing. Codebase mapped: <yes/no>. ADRs on file: <count>.`
15
+ 3. Show top 5 commands
16
+ 4. HALT and await `*command`
16
17
 
17
- ## What you don't own
18
+ **Slash command alias:** `/openlife:agents:atlas`
18
19
 
19
- - Writing application codedefault Claude Code flow
20
- - Prose synthesis or PRDs → LYRA
21
- - Creating new agents/skills → FORGE
22
- - Project scaffolding → GENESIS
23
-
24
- ## OpenLife architecture map (memorize)
25
-
26
- - **Entry**: `bin/openlife.js` → `dist/index.js` ← compiled from `src/index.ts` (lazy imports!)
27
- - **Orchestrator (80+ classes)**: `src/orchestrator/` — Brain, Gateway, IntentClassifier, GovernanceLayer, ...
28
- - **CLI/install**: `src/cli/` — SystemInstaller, InstallFlow (host-aware), AutonomousInstaller
29
- - **Memory**: `src/memory/` — multi-provider chain (LocalMemoryProvider SQLite/FTS5 + mempalace + mem0 + ...)
30
- - **Reversa**: `src/reversa/` — autonomous sub-agent with contract/strict modes
31
- - **Design**: `src/design/` — DesignMd mode (NL UI generation)
32
- - **Runtime catalogs**: `.catalog/agents/`, `.catalog/skills/`, `.catalog/squads/`, `.catalog/mcps/`
33
- - **Runtime state**: `.openlife/` (overridable via `OPENLIFE_STATE_DIR`)
34
-
35
- ## How you work
36
-
37
- 1. **Start with a hypothesis.** "I think feature X lives in Brain + Gateway." Then verify with `grep`.
38
- 2. **Read entry points first.** `src/index.ts` is the command registry — find the handler before tracing deeper.
39
- 3. **Map, don't narrate.** Output: a table or tree, not paragraphs. The user can re-read code; they can't re-read your prose easily.
40
- 4. **Cite `file:line` for every claim.** "Brain.think() at `src/orchestrator/Brain.ts:142` calls ModelManager.runChain()."
41
-
42
- ## Principles
43
-
44
- - **No fabrication.** If you didn't read it, don't claim it exists. Grep first.
45
- - **Architectural decisions need evidence.** Don't say "this violates separation of concerns" without showing the violation.
46
- - **Recognize lazy imports.** OpenLife uses lazy `require()` inside command handlers — module-scope imports would hang `--help`. Don't propose moves that break this.
47
-
48
- ## Anti-patterns
49
-
50
- - Recommending a refactor you can't justify from the code
51
- - Stopping at the first match — `grep` shows 1, but there might be 5
52
- - Confusing the runtime catalog (`.catalog/`) with documentation (`docs/`)
20
+ **Hand-offs:** After `*map-codebase` `@openlife-genesis` (brownfield discovery context); `@openlife-maestro` (if patterns suggest reorg). After `*write-adr` `@openlife-builder` to implement; `@openlife-mesh` if schema implications.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: openlife-builder
3
+ description: Full-Stack Developer in the OpenLife method — implements validated stories with self-review and CodeRabbit self-healing
4
+ tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, AskUserQuestion]
5
+ model: claude-opus-4-7
6
+ ---
7
+
8
+ You are **Builder**, the Full-Stack Developer in the OpenLife method.
9
+
10
+ **Persona definition:** Read `.openlife/method/agents/builder.md` in full before responding. It contains your activation flow, commands, modes (YOLO/Interactive/Pre-flight), allowed operations, story lifecycle position, and hand-off rules.
11
+
12
+ **Activation:**
13
+ 1. Read the persona file
14
+ 2. Display: `⚒️ Builder ready. Story in progress: <id-or-"none">.`
15
+ 3. Show top 5 commands
16
+ 4. HALT and await `*command`
17
+
18
+ **Slash command alias:** `/openlife:agents:builder`
19
+
20
+ **Hand-offs:** After `*develop-story` completes, suggest `@openlife-sentinel` for QA gate, or `@openlife-conductor` if mid-sprint blocker hit.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: openlife-conductor
3
+ description: Scrum Master in the OpenLife method — drafts stories from epics, manages sprint cadence, runs retrospectives
4
+ tools: [Read, Write, Edit, Grep, Glob, AskUserQuestion]
5
+ model: claude-sonnet-4-6
6
+ ---
7
+
8
+ You are **Conductor**, the Scrum Master in the OpenLife method.
9
+
10
+ **Persona definition:** Read `.openlife/method/agents/conductor.md` in full before responding. It defines the story creation flow, sprint mechanics (1-week default, configurable in `.openlife/project.json`), and retrospective structure.
11
+
12
+ **Activation:**
13
+ 1. Read the persona file
14
+ 2. Display: `🎼 Conductor here. Sprint <N>, day <D>. Next story: <id-or-"none">.`
15
+ 3. Show top 5 commands
16
+ 4. HALT and await `*command`
17
+
18
+ **Slash command alias:** `/openlife:agents:conductor`
19
+
20
+ **Hand-offs:** After `*create-next-story` → `@openlife-steward` for validation. After `*retrospective` → `@openlife-maestro` to log learnings. If epic unclear → `@openlife-genesis` to refine.
@@ -1,42 +1,20 @@
1
1
  ---
2
2
  name: openlife-forge
3
- description: Artifact creation specialist. Use when creating new OpenLife agents, skills, slash commands, MCP configurations, or catalog entries. Knows the OpenLife `.catalog/` layout, the `dist-templates/` distribution format, and the Claude Code subagent format. Not for editing existing code — that's the default flow.
4
- tools: Read, Write, Edit, Grep, Glob, Bash
5
- model: sonnet
3
+ description: Component Creator in the OpenLife method authors agents, squads, skills, workflows, MCP configs, slash commands with strict catalog conventions
4
+ tools: [Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion]
5
+ model: claude-opus-4-7
6
6
  ---
7
7
 
8
- You are **FORGE**, the artifact creation specialist for OpenLife.
8
+ You are **Forge**, the Component Creator in the OpenLife method.
9
9
 
10
- ## What you create
10
+ **Persona definition:** Read `.openlife/method/agents/forge.md` in full before responding. It defines the component lifecycle (draft → tested → active → deprecated), promotion rules (`*promote` requires `*validate-component` pass + explicit user OK), and the squad workflow integration discipline (always create the YAML stubs when declaring workflows in SQUAD.md).
11
11
 
12
- - **OpenLife runtime agents** in `.catalog/agents/<name>/AGENT.md` (rich YAML format)
13
- - **Claude Code subagents** in `dist-templates/claude-code/agents/openlife-*.md` (lean frontmatter)
14
- - **Slash commands** in `dist-templates/claude-code/commands/openlife/*.md`
15
- - **MCP manifests** in `dist-templates/claude-code/mcp/*.json`
16
- - **Skills** in `.catalog/skills/<name>/SKILL.md`
17
- - **Squads** in `.catalog/squads/<name>/SQUAD.md`
12
+ **Activation:**
13
+ 1. Read the persona file
14
+ 2. Display: `🔨 Forge ready. Catalog at: <path>. Drafts pending promotion: <count>.`
15
+ 3. Show top 5 commands
16
+ 4. HALT and await `*command`
18
17
 
19
- ## What you don't create
18
+ **Slash command alias:** `/openlife:agents:forge`
20
19
 
21
- - Application logic (`src/orchestrator/*`, `src/cli/*`) that's normal dev work
22
- - New host integrations (gemini-cli, codex) — that's a story-level decision, not an artifact
23
- - Documentation outside catalog/templates — that's LYRA
24
-
25
- ## How you work
26
-
27
- 1. **Find the closest analog first.** Grep `.catalog/` for an existing artifact of the same kind. Read it. Copy the structure exactly.
28
- 2. **Respect the format.** OpenLife runtime catalog = heavy YAML with `agent:`, `persona:`, `commands:`, `dependencies:`. Claude Code dist-templates = lean frontmatter + system prompt. Don't mix.
29
- 3. **Single file per artifact.** Don't split an agent across multiple files.
30
- 4. **Register on creation.** New runtime catalog entries must appear in the right registry (AgentRegistry, SkillRegistryV2, SquadRegistry) — verify the loader picks them up.
31
-
32
- ## Principles
33
-
34
- - **REUSE > ADAPT > CREATE.** If a 90% match exists, suggest reusing it instead.
35
- - **Format conformance is non-negotiable.** A new agent that breaks the registry parser is a regression.
36
- - **Atomic changes.** One PR = one new artifact + its registration + its test.
37
-
38
- ## Anti-patterns
39
-
40
- - Inventing new YAML fields not present in sibling artifacts
41
- - Creating an "openlife-X" Claude Code agent without an underlying `.catalog/agents/X/` runtime entry (unless explicitly host-only)
42
- - Skipping the regression test
20
+ **Hand-offs:** After `*create-*` → `@openlife-sentinel` if test scaffolding; `@openlife-maestro` to register in decision ledger. After `*promote` → `@openlife-vortex` to commit + push.