@zhuk/spego 0.8.0 → 0.10.1

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 (105) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +57 -2
  3. package/dist/cli/body-input.d.ts +12 -0
  4. package/dist/cli/body-input.js +27 -0
  5. package/dist/cli/body-input.js.map +1 -0
  6. package/dist/cli/commands/artifact.d.ts +8 -0
  7. package/dist/cli/commands/artifact.js +171 -0
  8. package/dist/cli/commands/artifact.js.map +1 -0
  9. package/dist/cli/commands/delivery.d.ts +7 -0
  10. package/dist/cli/commands/delivery.js +99 -0
  11. package/dist/cli/commands/delivery.js.map +1 -0
  12. package/dist/cli/commands/index-rebuild.d.ts +5 -0
  13. package/dist/cli/commands/index-rebuild.js +31 -0
  14. package/dist/cli/commands/index-rebuild.js.map +1 -0
  15. package/dist/cli/commands/meta.d.ts +6 -0
  16. package/dist/cli/commands/meta.js +60 -0
  17. package/dist/cli/commands/meta.js.map +1 -0
  18. package/dist/cli/commands/orchestrate.d.ts +6 -0
  19. package/dist/cli/commands/orchestrate.js +51 -0
  20. package/dist/cli/commands/orchestrate.js.map +1 -0
  21. package/dist/cli/commands/skills.d.ts +5 -0
  22. package/dist/cli/commands/skills.js +49 -0
  23. package/dist/cli/commands/skills.js.map +1 -0
  24. package/dist/cli/commands/view.d.ts +8 -0
  25. package/dist/cli/commands/view.js +59 -0
  26. package/dist/cli/commands/view.js.map +1 -0
  27. package/dist/cli/commands/workspace.d.ts +5 -0
  28. package/dist/cli/commands/workspace.js +61 -0
  29. package/dist/cli/commands/workspace.js.map +1 -0
  30. package/dist/cli/errors.d.ts +20 -0
  31. package/dist/cli/errors.js +55 -0
  32. package/dist/cli/errors.js.map +1 -0
  33. package/dist/cli/output.d.ts +12 -0
  34. package/dist/cli/output.js +28 -0
  35. package/dist/cli/output.js.map +1 -0
  36. package/dist/cli/render.d.ts +7 -0
  37. package/dist/cli/render.js +22 -0
  38. package/dist/cli/render.js.map +1 -1
  39. package/dist/cli/runtime.d.ts +26 -0
  40. package/dist/cli/runtime.js +48 -0
  41. package/dist/cli/runtime.js.map +1 -0
  42. package/dist/cli.d.ts +8 -0
  43. package/dist/cli.js +65 -582
  44. package/dist/cli.js.map +1 -1
  45. package/dist/commands/registry.js +12 -0
  46. package/dist/commands/registry.js.map +1 -1
  47. package/dist/errors.d.ts +1 -1
  48. package/dist/errors.js.map +1 -1
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.js +1 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/orchestration/agents.d.ts +15 -0
  53. package/dist/orchestration/agents.js +156 -0
  54. package/dist/orchestration/agents.js.map +1 -0
  55. package/dist/orchestration/artifacts.d.ts +8 -0
  56. package/dist/orchestration/artifacts.js +20 -0
  57. package/dist/orchestration/artifacts.js.map +1 -0
  58. package/dist/orchestration/client.d.ts +59 -0
  59. package/dist/orchestration/client.js +107 -0
  60. package/dist/orchestration/client.js.map +1 -0
  61. package/dist/orchestration/config.d.ts +14 -0
  62. package/dist/orchestration/config.js +45 -0
  63. package/dist/orchestration/config.js.map +1 -0
  64. package/dist/orchestration/emit.d.ts +7 -0
  65. package/dist/orchestration/emit.js +19 -0
  66. package/dist/orchestration/emit.js.map +1 -0
  67. package/dist/orchestration/engine.d.ts +23 -0
  68. package/dist/orchestration/engine.js +136 -0
  69. package/dist/orchestration/engine.js.map +1 -0
  70. package/dist/orchestration/file-gate.d.ts +19 -0
  71. package/dist/orchestration/file-gate.js +25 -0
  72. package/dist/orchestration/file-gate.js.map +1 -0
  73. package/dist/orchestration/index.d.ts +18 -0
  74. package/dist/orchestration/index.js +12 -0
  75. package/dist/orchestration/index.js.map +1 -0
  76. package/dist/orchestration/manager.d.ts +13 -0
  77. package/dist/orchestration/manager.js +26 -0
  78. package/dist/orchestration/manager.js.map +1 -0
  79. package/dist/orchestration/prompts.d.ts +10 -0
  80. package/dist/orchestration/prompts.js +71 -0
  81. package/dist/orchestration/prompts.js.map +1 -0
  82. package/dist/orchestration/scheduler.d.ts +18 -0
  83. package/dist/orchestration/scheduler.js +49 -0
  84. package/dist/orchestration/scheduler.js.map +1 -0
  85. package/dist/orchestration/schema.d.ts +12 -0
  86. package/dist/orchestration/schema.js +78 -0
  87. package/dist/orchestration/schema.js.map +1 -0
  88. package/dist/orchestration/tiers.d.ts +14 -0
  89. package/dist/orchestration/tiers.js +57 -0
  90. package/dist/orchestration/tiers.js.map +1 -0
  91. package/dist/orchestration/types.d.ts +74 -0
  92. package/dist/orchestration/types.js +8 -0
  93. package/dist/orchestration/types.js.map +1 -0
  94. package/dist/orchestration/verifier.d.ts +14 -0
  95. package/dist/orchestration/verifier.js +66 -0
  96. package/dist/orchestration/verifier.js.map +1 -0
  97. package/dist/orchestration/worker.d.ts +16 -0
  98. package/dist/orchestration/worker.js +80 -0
  99. package/dist/orchestration/worker.js.map +1 -0
  100. package/dist/workspace/config.d.ts +69 -2
  101. package/dist/workspace/config.js +20 -0
  102. package/dist/workspace/config.js.map +1 -1
  103. package/dist/workspace/init.js +2 -0
  104. package/dist/workspace/init.js.map +1 -1
  105. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.10.1] - 2026-05-30
6
+
7
+ ### Fixed
8
+ - `npm run build` now sets executable mode (`chmod 0o755`) on `dist/cli.js` after TypeScript compilation, fixing `EACCES` failures when CI executes the installed `spego` bin symlink on clean checkouts.
9
+
10
+ ## [0.10.0] - 2026-05-30
11
+
12
+ ### Added
13
+ - **Multi-agent orchestration** (`spego orchestrate --change <name>`): a manager → swarm → verifier pipeline that executes a planned OpenSpec change through the OpenCode REST API, ported to TypeScript under `src/orchestration/`. Supports `sequential`/`parallel`/`adaptive` scheduling, an in-process per-task file gate, a test-backed verdict, and run-artifact persistence under a configurable work dir.
14
+ - `orchestration` block in `.spego/config.yaml` (server URL, model tiers, max parallelism, work dir) with `SPEGO_ORCHESTRATION_*` and `OPENCODE_*` environment overrides. Model identifiers are fully configurable with no fictional defaults.
15
+ - `spego init` / `spego skills` now emit the OpenCode agent prompts (`ultramanager`, `ultraworker`, `ultraverifier`) and the `orchestrate` command under `.opencode/`.
16
+ - OpenSpec change `add-ultracode-orchestration` documenting and validating the capability.
17
+
18
+ ### Changed
19
+ - Archived the completed OpenSpec changes `2026-05-29-clean-cli-command-surface` and `add-ultracode-orchestration`, syncing their delta specs into the main specs tree.
20
+
21
+ ## [0.9.1] - 2026-05-30
22
+
23
+ Maintenance release: cleaned up the v0.9.0 commit history. No functional changes.
24
+
25
+ ## [0.9.0] - 2026-05-29
26
+
27
+ ### Changed
28
+ - Refactored the CLI into shared runtime helpers and per-command registrars, reducing duplicated JSON/output/error/engine lifecycle code while preserving public command names and flags.
29
+ - `spego update --json` now returns the artifact `frontmatter`, `body`, and `path` in addition to the existing `id` and `revision` fields, matching `spego read --json` for agent parsing.
30
+ - Human output is more consistent across commands: `create`, `delete`, and `index rebuild` now use the same section-header style as the rest of the CLI.
31
+ - JSON validation errors now always include `details: {}` and exit with code 2, matching other structured CLI failures.
32
+
33
+ ### Added
34
+ - Shared body input handling for `spego create` and `spego update`, including stdin support through `--body-file -`.
35
+ - End-to-end CLI coverage for `epics`, `tasks`, read selectors, revision reads, optimistic concurrency, view filters, body-file/stdin input, uninitialized status JSON, registry parity, and validation error envelopes.
36
+ - OpenSpec change `2026-05-29-clean-cli-command-surface` documenting and validating the CLI cleanup.
37
+
38
+ ### Fixed
39
+ - `npm run lint` now includes `test/cli-help-exit.test.ts` and the new CLI test files in ESLint project-service configuration.
40
+ - Installed package `spego` bin symlinks now execute the CLI entrypoint correctly.
41
+
3
42
  ## [0.8.0] - 2026-05-22
4
43
 
5
44
  ### Added
package/README.md CHANGED
@@ -27,6 +27,7 @@ spego init --agents claude --demo false
27
27
  | `spego skills` | Regenerate agent skill files |
28
28
  | `spego epics` | List delivery epics |
29
29
  | `spego tasks --change <name>` | List tasks for a change |
30
+ | `spego orchestrate --change <name>` | Run the multi-agent orchestration pipeline for a change |
30
31
  | `spego index rebuild` | Rebuild SQLite index from files |
31
32
 
32
33
  All commands accept `--cwd <dir>` to set the project root.
@@ -35,13 +36,17 @@ All commands accept `--cwd <dir>` to set the project root.
35
36
 
36
37
  Every spego command speaks two output modes:
37
38
 
38
- - **Human (default)** — pretty, scannable output for terminals. Section headers use a single emoji prefix (`📦 📄 🛠️ 🧭 📚 ✅`), summaries render as bordered boxes (`╭─ … ─╮`), lists render as aligned tables, and `view` separates artifacts with `────` dividers. Errors print as `⚠️ [CODE] message` to stderr.
39
- - **JSON (opt-in)** — pass the global `--json` flag to get deterministic, decoration-free JSON on stdout. Errors come back as `{ "error": { "code", "message", "details" } }` on stderr.
39
+ - **Human (default)** — pretty, scannable output for terminals. Section headers use a single emoji prefix (`📦 📄 🛠️ 🧭 📚 ✅ ✨ 🗑`), summaries render as bordered boxes (`╭─ … ─╮`), lists render as aligned tables, and `view` separates artifacts with `────` dividers. Errors print as `⚠️ [CODE] message` to stderr.
40
+ - **JSON (opt-in)** — pass the global `--json` flag to get deterministic, decoration-free JSON on stdout. Errors come back as `{ "error": { "code", "message", "details" } }` on stderr; `details` is always an object.
40
41
 
41
42
  Agents calling spego MUST pass `--json` so they get parseable output. Humans normally do not.
42
43
 
43
44
  The legacy `spego view --format markdown|json` flag is **deprecated** and will be removed in the next minor release. Use the global `--json` flag instead. The old flag still works during the deprecation window and prints a single `deprecated:` warning line to stderr.
44
45
 
46
+ `spego read --json` and `spego update --json` both return artifact records with `frontmatter`, `body`, and `path`; `update` also keeps the compatibility fields `id` and `revision`.
47
+
48
+ `spego create` and `spego update` accept body content through `--body`, `--body-file <path>`, or stdin via `--body-file -`.
49
+
45
50
  ## Architecture
46
51
 
47
52
  - Markdown files are the source of truth (`.spego/artifacts/<type>/<slug>.md`)
@@ -70,6 +75,15 @@ extraArtifactTypes: []
70
75
  deliveryAdapter:
71
76
  name: openspec
72
77
  options: {}
78
+ orchestration:
79
+ serverUrl: http://127.0.0.1:4096
80
+ models:
81
+ manager: ""
82
+ worker: ""
83
+ verifier: ""
84
+ fallback: ""
85
+ maxParallel: 4
86
+ workDir: .spego/orchestration
73
87
  ```
74
88
 
75
89
  ## OpenSpec Delivery View
@@ -87,6 +101,47 @@ The adapter is read-only. It observes OpenSpec state but does not create, contin
87
101
 
88
102
  Archived changes under `openspec/changes/archive/` are excluded. A change with no `tasks.md` is reported as `planning-incomplete`.
89
103
 
104
+ ## Orchestration
105
+
106
+ `spego orchestrate --change <name>` executes a planned OpenSpec change through a multi-agent pipeline (ported from the `ultracode/` reference implementation), driven over the OpenCode REST API:
107
+
108
+ 1. **Manager** decomposes the change requirement into a validated `TaskBreakdown`.
109
+ 2. **Swarm** implements each sub-task in isolated sessions — `sequential`, `parallel`, or `adaptive` (dependency-tier) mode — under a per-task file gate that reverts out-of-scope edits.
110
+ 3. **Verifier** runs the test command, checks acceptance criteria, and emits a verdict.
111
+
112
+ Run artifacts (`breakdown.json`, `result_<id>.json`, `swarm.log`, `verdict.json`) are written under the configured work dir (default `.spego/orchestration/<change>/`).
113
+
114
+ Orchestration consumes the change read-only and never mutates OpenSpec lifecycle state (apply/verify/sync/archive); it may modify the working tree as workers implement sub-tasks.
115
+
116
+ ### Prerequisites
117
+
118
+ - A reachable OpenCode server: `opencode serve --port 4096`.
119
+ - Configured model identifiers — there are no fictional defaults baked into the code.
120
+
121
+ ### Configuration
122
+
123
+ Add an `orchestration` block to `.spego/config.yaml`:
124
+
125
+ ```yaml
126
+ orchestration:
127
+ serverUrl: http://127.0.0.1:4096
128
+ models:
129
+ manager: <provider/model>
130
+ worker: <provider/model>
131
+ verifier: <provider/model>
132
+ fallback: <provider/model>
133
+ maxParallel: 4
134
+ workDir: .spego/orchestration
135
+ ```
136
+
137
+ Environment overrides: `SPEGO_ORCHESTRATION_SERVER_URL` (or `OPENCODE_BASE_URL`), `SPEGO_ORCHESTRATION_MODEL_{MANAGER,WORKER,VERIFIER,FALLBACK}`, `SPEGO_ORCHESTRATION_MAX_PARALLEL`, `SPEGO_ORCHESTRATION_WORK_DIR`, and `OPENCODE_SERVER_USERNAME`/`OPENCODE_SERVER_PASSWORD` for basic auth.
138
+
139
+ `spego init` / `spego skills` emit the OpenCode agent prompts and the `orchestrate` command under `.opencode/`.
140
+
141
+ ```sh
142
+ spego orchestrate --change <change-name> --json
143
+ ```
144
+
90
145
  ## Generated Files
91
146
 
92
147
  For Claude agent targets, `spego init` generates:
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Unified body-input resolution for `spego create` and `spego update`.
3
+ *
4
+ * Accepts either an inline `--body` string, a `--body-file <path>` reference,
5
+ * or stdin when `--body-file -`. Returns `undefined` when no body source was
6
+ * supplied so callers can leave the artifact body unchanged.
7
+ */
8
+ export interface BodyInputOptions {
9
+ body?: string;
10
+ bodyFile?: string;
11
+ }
12
+ export declare function resolveBody(opts: BodyInputOptions): Promise<string | undefined>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Unified body-input resolution for `spego create` and `spego update`.
3
+ *
4
+ * Accepts either an inline `--body` string, a `--body-file <path>` reference,
5
+ * or stdin when `--body-file -`. Returns `undefined` when no body source was
6
+ * supplied so callers can leave the artifact body unchanged.
7
+ */
8
+ import fs from 'node:fs/promises';
9
+ async function readStdin() {
10
+ return new Promise((resolve, reject) => {
11
+ let buf = '';
12
+ process.stdin.setEncoding('utf8');
13
+ process.stdin.on('data', (chunk) => {
14
+ buf += chunk;
15
+ });
16
+ process.stdin.on('end', () => resolve(buf));
17
+ process.stdin.on('error', reject);
18
+ });
19
+ }
20
+ export async function resolveBody(opts) {
21
+ if (opts.bodyFile === '-')
22
+ return readStdin();
23
+ if (opts.bodyFile)
24
+ return fs.readFile(opts.bodyFile, 'utf8');
25
+ return opts.body;
26
+ }
27
+ //# sourceMappingURL=body-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-input.js","sourceRoot":"","sources":["../../src/cli/body-input.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAOlC,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,GAAG,IAAI,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAsB;IACtD,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG;QAAE,OAAO,SAAS,EAAE,CAAC;IAC9C,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Artifact CRUD commands: `create`, `read`, `update`, `delete`, `list`.
3
+ *
4
+ * All five share the artifact-engine runtime helper so neither engine
5
+ * lifecycle nor `--json` resolution is duplicated per command.
6
+ */
7
+ import type { Command } from 'commander';
8
+ export declare function registerArtifact(program: Command): void;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Artifact CRUD commands: `create`, `read`, `update`, `delete`, `list`.
3
+ *
4
+ * All five share the artifact-engine runtime helper so neither engine
5
+ * lifecycle nor `--json` resolution is duplicated per command.
6
+ */
7
+ import path from 'node:path';
8
+ import { renderArtifactFile } from '../../artifacts/storage.js';
9
+ import { SpegoError } from '../../errors.js';
10
+ import { renderDivider, renderHeader, renderTable } from '../render.js';
11
+ import { runEngineCommand } from '../runtime.js';
12
+ import { resolveBody } from '../body-input.js';
13
+ function renderArtifactHeader(fm) {
14
+ return `📄 ${fm.type}/${fm.slug} rev ${fm.revision} (${fm.id})`;
15
+ }
16
+ function renderRecordHuman(record) {
17
+ return `${renderArtifactHeader(record.frontmatter)}\n${renderDivider()}\n${record.body}`;
18
+ }
19
+ export function registerArtifact(program) {
20
+ program
21
+ .command('create')
22
+ .description('Create an artifact')
23
+ .requiredOption('--type <type>', 'artifact type, e.g. prd|api|architecture')
24
+ .requiredOption('--title <title>', 'artifact title')
25
+ .option('--slug <slug>', 'optional explicit slug')
26
+ .option('--body <text>', 'inline markdown body')
27
+ .option('--body-file <path>', 'read markdown body from a file (use - for stdin)')
28
+ .option('--meta <json>', 'JSON object of metadata', '{}')
29
+ .option('--cwd <dir>', 'project root')
30
+ .action(async (opts) => {
31
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
32
+ const body = (await resolveBody(opts)) ?? '';
33
+ const meta = JSON.parse(opts.meta);
34
+ const record = await engine.create({
35
+ type: opts.type,
36
+ title: opts.title,
37
+ slug: opts.slug,
38
+ body,
39
+ meta,
40
+ });
41
+ const payload = {
42
+ id: record.frontmatter.id,
43
+ type: record.frontmatter.type,
44
+ slug: record.frontmatter.slug,
45
+ revision: record.frontmatter.revision,
46
+ path: record.path,
47
+ markdown: renderArtifactFile(record.frontmatter, record.body),
48
+ };
49
+ const human = () => [
50
+ renderHeader('✨', `Created ${record.frontmatter.type}/${record.frontmatter.slug} rev ${record.frontmatter.revision}`),
51
+ ` path: ${record.path}`,
52
+ ].join('\n');
53
+ return { payload, human };
54
+ });
55
+ });
56
+ program
57
+ .command('read')
58
+ .description('Read an artifact by id or type+slug')
59
+ .option('--id <id>', 'artifact id')
60
+ .option('--type <type>', 'artifact type (with --slug)')
61
+ .option('--slug <slug>', 'artifact slug (with --type)')
62
+ .option('--path <path>', 'read artifact by absolute file path')
63
+ .option('--revision <n>', 'specific revision number')
64
+ .option('--cwd <dir>', 'project root')
65
+ .action(async (opts) => {
66
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
67
+ let record;
68
+ if (opts.id) {
69
+ record =
70
+ opts.revision !== undefined
71
+ ? await engine.readRevision(opts.id, Number(opts.revision))
72
+ : await engine.readById(opts.id);
73
+ }
74
+ else if (opts.type && opts.slug) {
75
+ record = await engine.readByTypeSlug(opts.type, opts.slug);
76
+ }
77
+ else if (opts.path) {
78
+ record = await engine.readByPath(path.resolve(opts.path));
79
+ }
80
+ else {
81
+ throw new SpegoError('VALIDATION_FAILED', 'Provide --id, --type and --slug, or --path');
82
+ }
83
+ return {
84
+ payload: { frontmatter: record.frontmatter, body: record.body, path: record.path },
85
+ human: () => renderRecordHuman(record),
86
+ };
87
+ });
88
+ });
89
+ program
90
+ .command('update')
91
+ .description('Update an artifact (requires id)')
92
+ .requiredOption('--id <id>', 'artifact id')
93
+ .option('--title <title>', 'new title')
94
+ .option('--body <text>', 'new markdown body')
95
+ .option('--body-file <path>', 'read body from file (use - for stdin)')
96
+ .option('--meta <json>', 'replace metadata (JSON object)')
97
+ .option('--expected-revision <n>', 'expected current revision (optimistic concurrency)')
98
+ .option('--cwd <dir>', 'project root')
99
+ .action(async (opts) => {
100
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
101
+ const body = await resolveBody(opts);
102
+ const patch = {};
103
+ if (opts.title !== undefined)
104
+ patch.title = opts.title;
105
+ if (body !== undefined)
106
+ patch.body = body;
107
+ if (opts.meta !== undefined)
108
+ patch.meta = JSON.parse(opts.meta);
109
+ if (opts.expectedRevision !== undefined)
110
+ patch.expectedRevision = Number(opts.expectedRevision);
111
+ const record = await engine.update(opts.id, patch);
112
+ return {
113
+ payload: {
114
+ id: record.frontmatter.id,
115
+ revision: record.frontmatter.revision,
116
+ path: record.path,
117
+ frontmatter: record.frontmatter,
118
+ body: record.body,
119
+ },
120
+ human: () => renderRecordHuman(record),
121
+ };
122
+ });
123
+ });
124
+ program
125
+ .command('delete')
126
+ .description('Soft-delete an artifact')
127
+ .requiredOption('--id <id>', 'artifact id')
128
+ .option('--cwd <dir>', 'project root')
129
+ .action(async (opts) => {
130
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
131
+ const record = await engine.softDelete(opts.id);
132
+ return {
133
+ payload: {
134
+ id: record.frontmatter.id,
135
+ deletedAt: record.frontmatter.deletedAt,
136
+ revision: record.frontmatter.revision,
137
+ },
138
+ human: () => [
139
+ renderHeader('🗑', `Deleted ${record.frontmatter.id}`),
140
+ ` at: ${record.frontmatter.deletedAt}`,
141
+ ].join('\n'),
142
+ };
143
+ });
144
+ });
145
+ program
146
+ .command('list')
147
+ .description('List artifacts')
148
+ .option('--type <type>', 'filter by type')
149
+ .option('--include-deleted', 'include soft-deleted artifacts', false)
150
+ .option('--cwd <dir>', 'project root')
151
+ .action(async (opts) => {
152
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
153
+ const items = engine.list({ type: opts.type, includeDeleted: opts.includeDeleted });
154
+ const human = () => {
155
+ if (items.length === 0)
156
+ return 'No artifacts.';
157
+ const rows = items.map((a) => [
158
+ `${a.type}/${a.slug}`,
159
+ String(a.revision),
160
+ a.deletedAt ? 'deleted' : 'active',
161
+ a.title,
162
+ a.id,
163
+ ]);
164
+ const table = renderTable(['type/slug', 'rev', 'status', 'title', 'id'], rows);
165
+ return `${renderHeader('📦', 'Artifacts')}\n${table}`;
166
+ };
167
+ return { payload: items, human };
168
+ });
169
+ });
170
+ }
171
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../../src/cli/commands/artifact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Delivery commands: read-only `epics` and `tasks` views over the configured
3
+ * delivery adapter (default: OpenSpec). Mutating actions are rejected with
4
+ * `DELIVERY_READ_ONLY` so users get a structured pointer to the right tool.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerDelivery(program: Command): void;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Delivery commands: read-only `epics` and `tasks` views over the configured
3
+ * delivery adapter (default: OpenSpec). Mutating actions are rejected with
4
+ * `DELIVERY_READ_ONLY` so users get a structured pointer to the right tool.
5
+ */
6
+ import path from 'node:path';
7
+ import { resolveWorkspacePaths } from '../../workspace/paths.js';
8
+ import { readConfig } from '../../workspace/config.js';
9
+ import { resolveAdapter } from '../../delivery/index.js';
10
+ import { SpegoError } from '../../errors.js';
11
+ import { renderHeader, renderTable } from '../render.js';
12
+ import { runCommand } from '../runtime.js';
13
+ const READ_ONLY_ACTIONS = new Set(['list', 'get']);
14
+ function assertReadOnlyAction(action, surface) {
15
+ if (!action || READ_ONLY_ACTIONS.has(action))
16
+ return;
17
+ throw new SpegoError('DELIVERY_READ_ONLY', `Cannot '${action}' delivery ${surface} through spego. Use the OpenSpec CLI for delivery mutations.`, { attemptedAction: action, suggestedTool: 'openspec' });
18
+ }
19
+ function renderEpicRow(epic) {
20
+ const progress = epic.taskCount != null ? `${epic.tasksDone ?? 0}/${epic.taskCount}` : '—';
21
+ return [epic.externalId, epic.status, progress, epic.title];
22
+ }
23
+ function renderTaskRow(task) {
24
+ return [task.status === 'done' ? '[x]' : '[ ]', task.title];
25
+ }
26
+ export function registerDelivery(program) {
27
+ program
28
+ .command('epics')
29
+ .description('List epics or get a single epic')
30
+ .argument('[action]', 'list (default) or get')
31
+ .option('--change <name>', 'get a single epic by name')
32
+ .option('--cwd <dir>', 'project root')
33
+ .action(async (action, opts) => {
34
+ await runCommand({ program }, async () => {
35
+ assertReadOnlyAction(action, 'epics');
36
+ const projectRoot = path.resolve(opts.cwd ?? process.cwd());
37
+ const wsPaths = resolveWorkspacePaths(projectRoot);
38
+ const config = await readConfig(wsPaths.configPath);
39
+ const adapter = resolveAdapter(projectRoot, config);
40
+ if (opts.change) {
41
+ const epic = await adapter.getEpic(opts.change);
42
+ return {
43
+ payload: epic,
44
+ human: () => {
45
+ const table = renderTable(['id', 'status', 'progress', 'title'], [renderEpicRow(epic)]);
46
+ return `${renderHeader('📚', `Epic (${adapter.name})`)}\n${table}`;
47
+ },
48
+ };
49
+ }
50
+ const epics = await adapter.listEpics();
51
+ return {
52
+ payload: epics,
53
+ human: () => {
54
+ if (epics.length === 0)
55
+ return 'No epics.';
56
+ const table = renderTable(['id', 'status', 'progress', 'title'], epics.map(renderEpicRow));
57
+ return `${renderHeader('📚', `Epics (${adapter.name})`)}\n${table}`;
58
+ },
59
+ };
60
+ });
61
+ });
62
+ program
63
+ .command('tasks')
64
+ .description('List tasks for a change or get a single task')
65
+ .argument('[action]', 'list (default) or get')
66
+ .requiredOption('--change <name>', 'the epic/change name')
67
+ .option('--task <id>', 'get a single task by id')
68
+ .option('--cwd <dir>', 'project root')
69
+ .action(async (action, opts) => {
70
+ await runCommand({ program }, async () => {
71
+ assertReadOnlyAction(action, 'tasks');
72
+ const projectRoot = path.resolve(opts.cwd ?? process.cwd());
73
+ const wsPaths = resolveWorkspacePaths(projectRoot);
74
+ const config = await readConfig(wsPaths.configPath);
75
+ const adapter = resolveAdapter(projectRoot, config);
76
+ if (opts.task) {
77
+ const task = await adapter.getTask(opts.change, opts.task);
78
+ return {
79
+ payload: task,
80
+ human: () => {
81
+ const table = renderTable(['done', 'title'], [renderTaskRow(task)]);
82
+ return `${renderHeader('✅', `Task: ${opts.change} (${adapter.name})`)}\n${table}`;
83
+ },
84
+ };
85
+ }
86
+ const tasks = await adapter.listTasks(opts.change);
87
+ return {
88
+ payload: tasks,
89
+ human: () => {
90
+ if (tasks.length === 0)
91
+ return `No tasks for ${opts.change}.`;
92
+ const table = renderTable(['done', 'title'], tasks.map(renderTaskRow));
93
+ return `${renderHeader('✅', `Tasks: ${opts.change} (${adapter.name})`)}\n${table}`;
94
+ },
95
+ };
96
+ });
97
+ });
98
+ }
99
+ //# sourceMappingURL=delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../../src/cli/commands/delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Index maintenance: `spego index rebuild`.
3
+ */
4
+ import type { Command } from 'commander';
5
+ export declare function registerIndex(program: Command): void;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Index maintenance: `spego index rebuild`.
3
+ */
4
+ import { renderBox, renderHeader, renderTable } from '../render.js';
5
+ import { runEngineCommand } from '../runtime.js';
6
+ export function registerIndex(program) {
7
+ const indexCmd = program.command('index').description('Index maintenance');
8
+ indexCmd
9
+ .command('rebuild')
10
+ .description('Rebuild the SQLite index from markdown files')
11
+ .option('--cwd <dir>', 'project root')
12
+ .action(async (opts) => {
13
+ await runEngineCommand({ program, cwd: opts.cwd }, async (engine) => {
14
+ const report = await engine.rebuildIndex();
15
+ const human = () => {
16
+ const summary = renderBox('Index rebuild', [
17
+ ['scanned', String(report.scannedFiles)],
18
+ ['indexed', String(report.indexedArtifacts)],
19
+ ['invalid', String(report.invalidFiles.length)],
20
+ ]);
21
+ const header = renderHeader('📦', 'Index rebuild');
22
+ if (report.invalidFiles.length === 0)
23
+ return `${header}\n${summary}`;
24
+ const table = renderTable(['path', 'error'], report.invalidFiles.map((i) => [i.path, i.error]), { maxWidth: 80 });
25
+ return `${header}\n${summary}\n\nInvalid files:\n${table}`;
26
+ };
27
+ return { payload: report, human };
28
+ });
29
+ });
30
+ }
31
+ //# sourceMappingURL=index-rebuild.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-rebuild.js","sourceRoot":"","sources":["../../../src/cli/commands/index-rebuild.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAE3E,QAAQ;SACL,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC;SACrC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAClE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,GAAW,EAAE;gBACzB,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,EAAE;oBACzC,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;oBACxC,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;oBAC5C,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;iBAChD,CAAC,CAAC;gBACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACnD,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC;gBACrE,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,MAAM,EAAE,OAAO,CAAC,EACjB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EACjD,EAAE,QAAQ,EAAE,EAAE,EAAE,CACjB,CAAC;gBACF,OAAO,GAAG,MAAM,KAAK,OAAO,uBAAuB,KAAK,EAAE,CAAC;YAC7D,CAAC,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Metadata commands: `commands` and `workflows`.
3
+ * Both are read-only listings backed by static registries.
4
+ */
5
+ import type { Command } from 'commander';
6
+ export declare function registerMeta(program: Command): void;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Metadata commands: `commands` and `workflows`.
3
+ * Both are read-only listings backed by static registries.
4
+ */
5
+ import { COMMAND_REGISTRY } from '../../commands/registry.js';
6
+ import { WORKFLOW_REGISTRY } from '../../workflows/registry.js';
7
+ import { renderHeader, renderTable } from '../render.js';
8
+ import { runCommand } from '../runtime.js';
9
+ function renderCommandsHuman() {
10
+ const order = ['workspace', 'artifact', 'view', 'planning'];
11
+ const titles = {
12
+ workspace: 'Workspace',
13
+ artifact: 'Artifacts',
14
+ view: 'View',
15
+ planning: 'Planning',
16
+ };
17
+ const sections = order
18
+ .map((cat) => {
19
+ const items = COMMAND_REGISTRY.filter((c) => c.category === cat);
20
+ if (items.length === 0)
21
+ return '';
22
+ const table = renderTable(['name', 'description'], items.map((c) => [c.name, c.description]));
23
+ return `${titles[cat]}\n${table}`;
24
+ })
25
+ .filter((s) => s.length > 0);
26
+ return [renderHeader('🛠️', 'Commands'), '', sections.join('\n\n')].join('\n');
27
+ }
28
+ function renderWorkflowsHuman() {
29
+ const rows = WORKFLOW_REGISTRY.map((w) => [w.name, String(w.phases.length), w.description]);
30
+ const table = renderTable(['name', 'phases', 'description'], rows, { maxWidth: 80 });
31
+ return [renderHeader('🧭', 'Workflows'), '', table].join('\n');
32
+ }
33
+ export function registerMeta(program) {
34
+ program
35
+ .command('commands')
36
+ .description('List available spego commands with metadata')
37
+ .action(async () => {
38
+ await runCommand({ program }, async () => ({
39
+ payload: COMMAND_REGISTRY,
40
+ human: renderCommandsHuman,
41
+ }));
42
+ });
43
+ program
44
+ .command('workflows')
45
+ .description('List available workflow skills')
46
+ .action(async () => {
47
+ await runCommand({ program }, async () => {
48
+ const entries = WORKFLOW_REGISTRY.map((w) => ({
49
+ name: w.name,
50
+ description: w.description,
51
+ personas: w.personas,
52
+ phases: w.phases,
53
+ inputs: w.inputs,
54
+ outputs: w.outputs,
55
+ }));
56
+ return { payload: entries, human: renderWorkflowsHuman };
57
+ });
58
+ });
59
+ }
60
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/cli/commands/meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * `spego orchestrate` — run the multi-agent orchestration pipeline over an
3
+ * OpenSpec change and emit a structured verdict in human or `--json` mode.
4
+ */
5
+ import type { Command } from 'commander';
6
+ export declare function registerOrchestrate(program: Command): void;