@zhuk/spego 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +19 -48
- package/dist/artifacts/engine.d.ts +3 -7
- package/dist/artifacts/engine.js +39 -23
- package/dist/artifacts/engine.js.map +1 -1
- package/dist/artifacts/storage.d.ts +3 -2
- package/dist/artifacts/storage.js +42 -7
- package/dist/artifacts/storage.js.map +1 -1
- package/dist/artifacts/validation.js +1 -1
- package/dist/artifacts/validation.js.map +1 -1
- package/dist/cli/body-input.js +12 -2
- package/dist/cli/body-input.js.map +1 -1
- package/dist/cli/commands/artifact.js +53 -12
- package/dist/cli/commands/artifact.js.map +1 -1
- package/dist/cli/commands/meta.js +1 -1
- package/dist/cli/commands/meta.js.map +1 -1
- package/dist/cli/commands/skills.js +0 -2
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/view.js +29 -27
- package/dist/cli/commands/view.js.map +1 -1
- package/dist/cli/runtime.d.ts +2 -0
- package/dist/cli/runtime.js +2 -1
- package/dist/cli/runtime.js.map +1 -1
- package/dist/cli.js +0 -2
- package/dist/cli.js.map +1 -1
- package/dist/{commands → command-meta}/registry.js +0 -12
- package/dist/command-meta/registry.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/generator/claude.d.ts +1 -0
- package/dist/generator/claude.js +17 -2
- package/dist/generator/claude.js.map +1 -1
- package/dist/generator/index.js +2 -0
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/opencode.d.ts +5 -0
- package/dist/generator/opencode.js +207 -0
- package/dist/generator/opencode.js.map +1 -0
- package/dist/generator/write.d.ts +1 -0
- package/dist/generator/write.js +14 -0
- package/dist/generator/write.js.map +1 -1
- package/dist/index/indexer.js +37 -8
- package/dist/index/indexer.js.map +1 -1
- package/dist/index/revisions.d.ts +2 -2
- package/dist/index/revisions.js +18 -3
- package/dist/index/revisions.js.map +1 -1
- package/dist/workspace/config.d.ts +0 -69
- package/dist/workspace/config.js +4 -21
- package/dist/workspace/config.js.map +1 -1
- package/dist/workspace/init.js +16 -4
- package/dist/workspace/init.js.map +1 -1
- package/dist/workspace/paths.d.ts +12 -0
- package/dist/workspace/paths.js +69 -0
- package/dist/workspace/paths.js.map +1 -1
- package/package.json +3 -5
- package/dist/cli/commands/orchestrate.d.ts +0 -6
- package/dist/cli/commands/orchestrate.js +0 -51
- package/dist/cli/commands/orchestrate.js.map +0 -1
- package/dist/commands/registry.js.map +0 -1
- package/dist/index.d.ts +0 -33
- package/dist/index.js +0 -20
- package/dist/index.js.map +0 -1
- package/dist/orchestration/agents.d.ts +0 -15
- package/dist/orchestration/agents.js +0 -156
- package/dist/orchestration/agents.js.map +0 -1
- package/dist/orchestration/artifacts.d.ts +0 -8
- package/dist/orchestration/artifacts.js +0 -20
- package/dist/orchestration/artifacts.js.map +0 -1
- package/dist/orchestration/client.d.ts +0 -59
- package/dist/orchestration/client.js +0 -107
- package/dist/orchestration/client.js.map +0 -1
- package/dist/orchestration/config.d.ts +0 -14
- package/dist/orchestration/config.js +0 -45
- package/dist/orchestration/config.js.map +0 -1
- package/dist/orchestration/emit.d.ts +0 -7
- package/dist/orchestration/emit.js +0 -19
- package/dist/orchestration/emit.js.map +0 -1
- package/dist/orchestration/engine.d.ts +0 -23
- package/dist/orchestration/engine.js +0 -136
- package/dist/orchestration/engine.js.map +0 -1
- package/dist/orchestration/file-gate.d.ts +0 -19
- package/dist/orchestration/file-gate.js +0 -25
- package/dist/orchestration/file-gate.js.map +0 -1
- package/dist/orchestration/index.d.ts +0 -18
- package/dist/orchestration/index.js +0 -12
- package/dist/orchestration/index.js.map +0 -1
- package/dist/orchestration/manager.d.ts +0 -13
- package/dist/orchestration/manager.js +0 -26
- package/dist/orchestration/manager.js.map +0 -1
- package/dist/orchestration/prompts.d.ts +0 -10
- package/dist/orchestration/prompts.js +0 -71
- package/dist/orchestration/prompts.js.map +0 -1
- package/dist/orchestration/scheduler.d.ts +0 -18
- package/dist/orchestration/scheduler.js +0 -49
- package/dist/orchestration/scheduler.js.map +0 -1
- package/dist/orchestration/schema.d.ts +0 -12
- package/dist/orchestration/schema.js +0 -78
- package/dist/orchestration/schema.js.map +0 -1
- package/dist/orchestration/tiers.d.ts +0 -14
- package/dist/orchestration/tiers.js +0 -57
- package/dist/orchestration/tiers.js.map +0 -1
- package/dist/orchestration/types.d.ts +0 -74
- package/dist/orchestration/types.js +0 -8
- package/dist/orchestration/types.js.map +0 -1
- package/dist/orchestration/verifier.d.ts +0 -14
- package/dist/orchestration/verifier.js +0 -66
- package/dist/orchestration/verifier.js.map +0 -1
- package/dist/orchestration/worker.d.ts +0 -16
- package/dist/orchestration/worker.js +0 -80
- package/dist/orchestration/worker.js.map +0 -1
- /package/dist/{commands → command-meta}/registry.d.ts +0 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { writeGeneratedFile, removeGeneratedFile } from './write.js';
|
|
3
|
+
import { GENERATOR_VERSION } from './types.js';
|
|
4
|
+
const SPEGO_APPLY = `---
|
|
5
|
+
description: Implement tasks from an OpenSpec change using the active OpenCode instance
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Implement tasks from an OpenSpec change.
|
|
9
|
+
|
|
10
|
+
Input: optionally specify a change name after \`/spego-apply\`. If omitted, infer it from conversation context only when unambiguous. If multiple active changes could apply, run \`openspec list --json\` and ask the user to choose.
|
|
11
|
+
|
|
12
|
+
## Phases
|
|
13
|
+
|
|
14
|
+
### Phase 1 — Select the change
|
|
15
|
+
|
|
16
|
+
- If a change name is provided, announce: \`Using change: <name>\`.
|
|
17
|
+
- If omitted, run \`openspec list --json\` and ask the user to choose when multiple active changes exist.
|
|
18
|
+
- Do not guess or infer when more than one active change is possible.
|
|
19
|
+
|
|
20
|
+
### Phase 2 — Load context
|
|
21
|
+
|
|
22
|
+
- Run \`openspec status --change "<name>" --json\` to get current state.
|
|
23
|
+
- Run \`openspec instructions apply --change "<name>" --json\` to get context file paths.
|
|
24
|
+
- Read every file listed in \`contextFiles\`. Follow the schema-specific instruction from the CLI output; do not assume fixed artifact names.
|
|
25
|
+
|
|
26
|
+
### Phase 3 — Plan tasks
|
|
27
|
+
|
|
28
|
+
- Review the tasks artifact and identify all pending (unchecked) tasks.
|
|
29
|
+
- Determine execution order based on task dependencies and the change's design doc.
|
|
30
|
+
- Present the planned order to the user before proceeding.
|
|
31
|
+
|
|
32
|
+
### Phase 4 — Execute work
|
|
33
|
+
|
|
34
|
+
- Implement pending tasks in order, keeping each change minimal and scoped.
|
|
35
|
+
- Follow the repository's existing conventions, imports, and patterns.
|
|
36
|
+
- After completing each task, mark its checkbox in the tasks artifact from \`- [ ]\` to \`- [x]\`.
|
|
37
|
+
|
|
38
|
+
### Phase 5 — Verify results
|
|
39
|
+
|
|
40
|
+
- After each task, confirm the implementation aligns with the relevant spec and design decisions.
|
|
41
|
+
- Run available tests when the change or repository identifies them.
|
|
42
|
+
- If a task fails verification, note the issue and either fix it or pause for guidance.
|
|
43
|
+
|
|
44
|
+
### Phase 6 — Update task checkboxes
|
|
45
|
+
|
|
46
|
+
- After verifying a task, ensure its checkbox is marked \`- [x]\` in the tasks artifact.
|
|
47
|
+
- Only mark tasks complete when implementation and verification both succeed.
|
|
48
|
+
- Do not mark tasks that were skipped or left incomplete.
|
|
49
|
+
|
|
50
|
+
### Phase 7 — Summarize status
|
|
51
|
+
|
|
52
|
+
- Report completed tasks, remaining tasks, and any blockers encountered.
|
|
53
|
+
- Recommend the next OpenSpec action (continue, verify, or archive).
|
|
54
|
+
- Pause and ask the user when a task is ambiguous, implementation exposes a design/spec issue, or a blocker prevents safe progress.
|
|
55
|
+
|
|
56
|
+
## Subagents
|
|
57
|
+
|
|
58
|
+
Subagents may be used ONLY inside the current OpenCode session for independent investigation, implementation review, or verification. All subagent work runs within this instance using its existing model, agents, and permissions.
|
|
59
|
+
|
|
60
|
+
The following are forbidden:
|
|
61
|
+
|
|
62
|
+
- Spego spawning agents or orchestrating subagent pools.
|
|
63
|
+
- Spego choosing or switching models for subagents.
|
|
64
|
+
- Creating external sessions, connecting to daemons, or calling REST APIs.
|
|
65
|
+
- Any operation that leaves the current OpenCode process boundary.
|
|
66
|
+
|
|
67
|
+
## Guardrails
|
|
68
|
+
|
|
69
|
+
- Do not call the removed Spego orchestration command.
|
|
70
|
+
- Do not start or require a separate OpenCode daemon.
|
|
71
|
+
- Do not mutate OpenSpec lifecycle state except task checkboxes required by apply workflow.
|
|
72
|
+
- Use OpenCode's current model, agents, permissions, and runtime configuration.
|
|
73
|
+
`;
|
|
74
|
+
const SPEGO_VERIFY = `---
|
|
75
|
+
description: Verify implementation against OpenSpec change artifacts before archive
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
Verify that implementation matches a change's OpenSpec artifacts.
|
|
79
|
+
|
|
80
|
+
This command runs entirely inside the active OpenCode instance. Do not connect to a daemon or REST API.
|
|
81
|
+
|
|
82
|
+
Input: optionally specify a change name after \`/spego-verify\`. If omitted, ask the user to choose from active changes; do not guess.
|
|
83
|
+
|
|
84
|
+
## Steps
|
|
85
|
+
|
|
86
|
+
1. Select the change. If needed, run \`openspec list --json\` and ask the user.
|
|
87
|
+
|
|
88
|
+
2. Check status:
|
|
89
|
+
|
|
90
|
+
\`\`\`bash
|
|
91
|
+
openspec status --change "<name>" --json
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
3. Load context paths:
|
|
95
|
+
|
|
96
|
+
\`\`\`bash
|
|
97
|
+
openspec instructions apply --change "<name>" --json
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
4. Read all available files from \`contextFiles\`, including proposal, design, specs, and tasks when present.
|
|
101
|
+
|
|
102
|
+
5. Verify completeness: task checkboxes, requirement coverage, and any documented acceptance criteria.
|
|
103
|
+
|
|
104
|
+
6. Verify correctness: compare implementation evidence with each requirement and scenario. Reference concrete files and lines where possible.
|
|
105
|
+
|
|
106
|
+
7. Verify coherence: compare implementation with design decisions and repository patterns.
|
|
107
|
+
|
|
108
|
+
8. Run relevant tests when the change or repository identifies them. If no test command is obvious, state that explicitly.
|
|
109
|
+
|
|
110
|
+
9. Report findings grouped as CRITICAL, WARNING, and SUGGESTION, followed by a final archive-readiness assessment.
|
|
111
|
+
|
|
112
|
+
## Guardrails
|
|
113
|
+
|
|
114
|
+
- Do not call the removed Spego orchestration command.
|
|
115
|
+
- Do not start or require a separate OpenCode daemon.
|
|
116
|
+
- Do not mark OpenSpec lifecycle state complete or archive the change.
|
|
117
|
+
- Prefer actionable findings with file references over vague recommendations.
|
|
118
|
+
`;
|
|
119
|
+
const SPEGO_EXPLORE = `---
|
|
120
|
+
description: Explore ideas, problems, or OpenSpec changes without implementing code
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
Enter explore mode. Think through ideas, investigate code, clarify requirements, and surface options without implementing code.
|
|
124
|
+
|
|
125
|
+
This command runs entirely inside the active OpenCode instance. Do not connect to a daemon or REST API.
|
|
126
|
+
|
|
127
|
+
Input: anything after \`/spego-explore\` is the topic, problem, or change name to explore.
|
|
128
|
+
|
|
129
|
+
## Stance
|
|
130
|
+
|
|
131
|
+
- Be curious and grounded in the repository.
|
|
132
|
+
- Ask questions that emerge naturally from the evidence.
|
|
133
|
+
- Use concise diagrams or tables when they clarify trade-offs.
|
|
134
|
+
- Follow interesting threads without forcing a fixed workflow.
|
|
135
|
+
|
|
136
|
+
## OpenSpec Awareness
|
|
137
|
+
|
|
138
|
+
At the start, check active changes when relevant:
|
|
139
|
+
|
|
140
|
+
\`\`\`bash
|
|
141
|
+
openspec list --json
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
If the user names a change, read its available artifacts such as proposal, design, specs, and tasks. Reference them naturally in the discussion.
|
|
145
|
+
|
|
146
|
+
## Capture Options
|
|
147
|
+
|
|
148
|
+
When insights crystallize, offer to capture them in the right OpenSpec artifact. Do not auto-capture unless the user asks.
|
|
149
|
+
|
|
150
|
+
## Guardrails
|
|
151
|
+
|
|
152
|
+
- Do not implement application code in explore mode.
|
|
153
|
+
- Do not call the removed Spego orchestration command.
|
|
154
|
+
- Do not start or require a separate OpenCode daemon.
|
|
155
|
+
- Creating or editing OpenSpec artifacts is allowed only when the user explicitly asks to capture the thinking.
|
|
156
|
+
`;
|
|
157
|
+
const COMMAND_ASSETS = [
|
|
158
|
+
{ relPath: '.opencode/commands/spego-apply.md', content: SPEGO_APPLY },
|
|
159
|
+
{ relPath: '.opencode/commands/spego-verify.md', content: SPEGO_VERIFY },
|
|
160
|
+
{ relPath: '.opencode/commands/spego-explore.md', content: SPEGO_EXPLORE },
|
|
161
|
+
];
|
|
162
|
+
const STALE_ASSET_PATHS = [
|
|
163
|
+
'.opencode/commands/orchestrate.md',
|
|
164
|
+
'.opencode/commands/workflow.md',
|
|
165
|
+
'.opencode/commands/opsx-new.md',
|
|
166
|
+
'.opencode/commands/opsx-continue.md',
|
|
167
|
+
'.opencode/commands/opsx-ff.md',
|
|
168
|
+
'.opencode/commands/opsx-apply.md',
|
|
169
|
+
'.opencode/commands/opsx-verify.md',
|
|
170
|
+
'.opencode/commands/opsx-archive.md',
|
|
171
|
+
'.opencode/commands/opsx-bulk-archive.md',
|
|
172
|
+
'.opencode/commands/opsx-sync.md',
|
|
173
|
+
'.opencode/commands/opsx-explore.md',
|
|
174
|
+
'.opencode/agents/ultramanager.md',
|
|
175
|
+
'.opencode/agents/ultraworker.md',
|
|
176
|
+
'.opencode/agents/ultraverifier.md',
|
|
177
|
+
'.opencode/agents/orchestrate.md',
|
|
178
|
+
'.opencode/skills/openspec-new-change/SKILL.md',
|
|
179
|
+
'.opencode/skills/openspec-continue-change/SKILL.md',
|
|
180
|
+
'.opencode/skills/openspec-ff-change/SKILL.md',
|
|
181
|
+
'.opencode/skills/openspec-apply-change/SKILL.md',
|
|
182
|
+
'.opencode/skills/openspec-verify-change/SKILL.md',
|
|
183
|
+
'.opencode/skills/openspec-archive-change/SKILL.md',
|
|
184
|
+
'.opencode/skills/openspec-bulk-archive-change/SKILL.md',
|
|
185
|
+
'.opencode/skills/openspec-sync-specs/SKILL.md',
|
|
186
|
+
'.opencode/skills/openspec-explore/SKILL.md',
|
|
187
|
+
'.opencode/skills/openspec-onboard/SKILL.md',
|
|
188
|
+
];
|
|
189
|
+
export class OpencodeGenerator {
|
|
190
|
+
targetName = 'opencode';
|
|
191
|
+
async generate(projectRoot) {
|
|
192
|
+
const files = [];
|
|
193
|
+
for (const relPath of STALE_ASSET_PATHS) {
|
|
194
|
+
const filePath = path.join(projectRoot, relPath);
|
|
195
|
+
const action = await removeGeneratedFile(filePath);
|
|
196
|
+
if (action)
|
|
197
|
+
files.push({ path: filePath, action });
|
|
198
|
+
}
|
|
199
|
+
for (const asset of COMMAND_ASSETS) {
|
|
200
|
+
const filePath = path.join(projectRoot, asset.relPath);
|
|
201
|
+
const action = await writeGeneratedFile(filePath, asset.content);
|
|
202
|
+
files.push({ path: filePath, action });
|
|
203
|
+
}
|
|
204
|
+
return { target: this.targetName, files, version: GENERATOR_VERSION };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/generator/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAQ/C,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqEnB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CpB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCrB,CAAC;AAEF,MAAM,cAAc,GAA2B;IAC7C,EAAE,OAAO,EAAE,mCAAmC,EAAE,OAAO,EAAE,WAAW,EAAE;IACtE,EAAE,OAAO,EAAE,oCAAoC,EAAE,OAAO,EAAE,YAAY,EAAE;IACxE,EAAE,OAAO,EAAE,qCAAqC,EAAE,OAAO,EAAE,aAAa,EAAE;CAC3E,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,mCAAmC;IACnC,gCAAgC;IAChC,gCAAgC;IAChC,qCAAqC;IACrC,+BAA+B;IAC/B,kCAAkC;IAClC,mCAAmC;IACnC,oCAAoC;IACpC,yCAAyC;IACzC,iCAAiC;IACjC,oCAAoC;IACpC,kCAAkC;IAClC,iCAAiC;IACjC,mCAAmC;IACnC,iCAAiC;IACjC,+CAA+C;IAC/C,oDAAoD;IACpD,8CAA8C;IAC9C,iDAAiD;IACjD,kDAAkD;IAClD,mDAAmD;IACnD,wDAAwD;IACxD,+CAA+C;IAC/C,4CAA4C;IAC5C,4CAA4C;CAC7C,CAAC;AAEF,MAAM,OAAO,iBAAiB;IACnB,UAAU,GAAG,UAAU,CAAC;IAEjC,KAAK,CAAC,QAAQ,CAAC,WAAmB;QAChC,MAAM,KAAK,GAAoB,EAAE,CAAC;QAElC,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACjE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IACxE,CAAC;CACF"}
|
package/dist/generator/write.js
CHANGED
|
@@ -25,4 +25,18 @@ export async function writeGeneratedFile(absPath, content) {
|
|
|
25
25
|
await fs.writeFile(absPath, marked, 'utf8');
|
|
26
26
|
return 'created';
|
|
27
27
|
}
|
|
28
|
+
export async function removeGeneratedFile(absPath) {
|
|
29
|
+
let existing;
|
|
30
|
+
try {
|
|
31
|
+
existing = await fs.readFile(absPath, 'utf8');
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (!isSpegoGenerated(existing) && !isLegacySpegoGenerated(existing)) {
|
|
37
|
+
return 'skipped';
|
|
38
|
+
}
|
|
39
|
+
await fs.unlink(absPath);
|
|
40
|
+
return 'removed';
|
|
41
|
+
}
|
|
28
42
|
//# sourceMappingURL=write.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/generator/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,OAAe;IAEf,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/generator/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,OAAe;IAEf,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/index/indexer.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { artifactFilePath
|
|
4
|
-
import { parseArtifactFile
|
|
3
|
+
import { artifactFilePath } from '../workspace/paths.js';
|
|
4
|
+
import { parseArtifactFile } from '../artifacts/storage.js';
|
|
5
5
|
import { ensureIndexSchema, transaction } from './db.js';
|
|
6
6
|
import { SpegoError } from '../errors.js';
|
|
7
|
+
function formatIndexError(err) {
|
|
8
|
+
return err instanceof SpegoError ? `${err.code}: ${err.message}` : err.message;
|
|
9
|
+
}
|
|
7
10
|
function rowToArtifact(row) {
|
|
8
11
|
return {
|
|
9
12
|
id: row.id,
|
|
@@ -86,9 +89,7 @@ export function getArtifactById(db, id) {
|
|
|
86
89
|
return row ? rowToArtifact(row) : null;
|
|
87
90
|
}
|
|
88
91
|
export function getArtifactByTypeSlug(db, type, slug) {
|
|
89
|
-
const row = db
|
|
90
|
-
.prepare(`SELECT * FROM artifacts WHERE type = ? AND slug = ?`)
|
|
91
|
-
.get(type, slug);
|
|
92
|
+
const row = db.prepare(`SELECT * FROM artifacts WHERE type = ? AND slug = ?`).get(type, slug);
|
|
92
93
|
return row ? rowToArtifact(row) : null;
|
|
93
94
|
}
|
|
94
95
|
export function listRevisions(db, artifactId) {
|
|
@@ -128,11 +129,15 @@ export async function rebuildIndex(db, paths, knownTypes) {
|
|
|
128
129
|
const typeDir = path.join(paths.artifactsRoot, type);
|
|
129
130
|
let stat;
|
|
130
131
|
try {
|
|
131
|
-
stat = await fs.
|
|
132
|
+
stat = await fs.lstat(typeDir);
|
|
132
133
|
}
|
|
133
134
|
catch {
|
|
134
135
|
continue;
|
|
135
136
|
}
|
|
137
|
+
if (stat.isSymbolicLink()) {
|
|
138
|
+
report.invalidFiles.push({ path: typeDir, error: 'SYMLINK: type directory is a symlink' });
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
136
141
|
if (!stat.isDirectory())
|
|
137
142
|
continue;
|
|
138
143
|
const entries = await fs.readdir(typeDir);
|
|
@@ -141,6 +146,18 @@ export async function rebuildIndex(db, paths, knownTypes) {
|
|
|
141
146
|
continue;
|
|
142
147
|
const file = path.join(typeDir, entry);
|
|
143
148
|
report.scannedFiles += 1;
|
|
149
|
+
let entryStat;
|
|
150
|
+
try {
|
|
151
|
+
entryStat = await fs.lstat(file);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
report.invalidFiles.push({ path: file, error: 'STAT_FAILED: cannot stat file' });
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (entryStat.isSymbolicLink()) {
|
|
158
|
+
report.invalidFiles.push({ path: file, error: 'SYMLINK: artifact file is a symlink' });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
144
161
|
try {
|
|
145
162
|
const text = await fs.readFile(file, 'utf8');
|
|
146
163
|
const { frontmatter } = parseArtifactFile(text, file);
|
|
@@ -162,7 +179,7 @@ export async function rebuildIndex(db, paths, knownTypes) {
|
|
|
162
179
|
report.indexedArtifacts += 1;
|
|
163
180
|
}
|
|
164
181
|
catch (err) {
|
|
165
|
-
const message = err
|
|
182
|
+
const message = formatIndexError(err);
|
|
166
183
|
report.invalidFiles.push({ path: file, error: message });
|
|
167
184
|
}
|
|
168
185
|
}
|
|
@@ -188,6 +205,18 @@ async function reindexRevisions(db, paths, fm, report) {
|
|
|
188
205
|
continue;
|
|
189
206
|
const file = path.join(revDir, entry);
|
|
190
207
|
try {
|
|
208
|
+
let entryStat;
|
|
209
|
+
try {
|
|
210
|
+
entryStat = await fs.lstat(file);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
report.invalidFiles.push({ path: file, error: 'STAT_FAILED: cannot stat revision' });
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (entryStat.isSymbolicLink()) {
|
|
217
|
+
report.invalidFiles.push({ path: file, error: 'SYMLINK: revision file is a symlink' });
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
191
220
|
const text = await fs.readFile(file, 'utf8');
|
|
192
221
|
const { frontmatter } = parseArtifactFile(text, file);
|
|
193
222
|
if (frontmatter.id !== fm.id)
|
|
@@ -211,7 +240,7 @@ async function reindexRevisions(db, paths, fm, report) {
|
|
|
211
240
|
});
|
|
212
241
|
}
|
|
213
242
|
catch (err) {
|
|
214
|
-
const message = err
|
|
243
|
+
const message = formatIndexError(err);
|
|
215
244
|
report.invalidFiles.push({ path: file, error: message });
|
|
216
245
|
}
|
|
217
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/index/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/index/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,8 @@ import type { ArtifactFrontmatter } from '../artifacts/types.js';
|
|
|
4
4
|
* Persist a snapshot of an artifact at the given revision under
|
|
5
5
|
* `.spego/revisions/<type>/<slug>.r<n>.md`.
|
|
6
6
|
*/
|
|
7
|
-
export declare function writeRevisionSnapshot(paths: WorkspacePaths, frontmatter: ArtifactFrontmatter, body: string): Promise<string>;
|
|
8
|
-
/** Read a previously snapshotted revision. */
|
|
7
|
+
export declare function writeRevisionSnapshot(paths: WorkspacePaths, frontmatter: ArtifactFrontmatter, body: string, resolvedRoot?: string): Promise<string>;
|
|
8
|
+
/** Read a previously snapshotted revision, rejecting symlinked files. */
|
|
9
9
|
export declare function readRevisionSnapshot(paths: WorkspacePaths, type: string, slug: string, revision: number): Promise<{
|
|
10
10
|
frontmatter: ArtifactFrontmatter;
|
|
11
11
|
body: string;
|
package/dist/index/revisions.js
CHANGED
|
@@ -6,14 +6,29 @@ import { SpegoError } from '../errors.js';
|
|
|
6
6
|
* Persist a snapshot of an artifact at the given revision under
|
|
7
7
|
* `.spego/revisions/<type>/<slug>.r<n>.md`.
|
|
8
8
|
*/
|
|
9
|
-
export async function writeRevisionSnapshot(paths, frontmatter, body) {
|
|
9
|
+
export async function writeRevisionSnapshot(paths, frontmatter, body, resolvedRoot) {
|
|
10
10
|
const dest = revisionFilePath(paths, frontmatter.type, frontmatter.slug, frontmatter.revision);
|
|
11
|
-
await atomicWriteFile(dest, renderArtifactFile(frontmatter, body));
|
|
11
|
+
await atomicWriteFile(dest, renderArtifactFile(frontmatter, body), resolvedRoot);
|
|
12
12
|
return dest;
|
|
13
13
|
}
|
|
14
|
-
/** Read a previously snapshotted revision. */
|
|
14
|
+
/** Read a previously snapshotted revision, rejecting symlinked files. */
|
|
15
15
|
export async function readRevisionSnapshot(paths, type, slug, revision) {
|
|
16
16
|
const file = revisionFilePath(paths, type, slug, revision);
|
|
17
|
+
let stat;
|
|
18
|
+
try {
|
|
19
|
+
stat = await fs.lstat(file);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err.code === 'ENOENT') {
|
|
23
|
+
throw new SpegoError('REVISION_NOT_FOUND', `Revision ${revision} not found for ${type}/${slug}`, { type, slug, revision, path: file });
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
if (stat.isSymbolicLink()) {
|
|
28
|
+
throw new SpegoError('WORKSPACE_CONTAINMENT', `Symlinked revision file at ${file}`, {
|
|
29
|
+
path: file,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
17
32
|
let raw;
|
|
18
33
|
try {
|
|
19
34
|
raw = await fs.readFile(file, 'utf8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revisions.js","sourceRoot":"","sources":["../../src/index/revisions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAuB,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAqB,EACrB,WAAgC,EAChC,IAAY;
|
|
1
|
+
{"version":3,"file":"revisions.js","sourceRoot":"","sources":["../../src/index/revisions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAuB,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAqB,EACrB,WAAgC,EAChC,IAAY,EACZ,YAAqB;IAErB,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/F,MAAM,eAAe,CAAC,IAAI,EAAE,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IACjF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAqB,EACrB,IAAY,EACZ,IAAY,EACZ,QAAgB;IAEhB,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,UAAU,CAClB,oBAAoB,EACpB,YAAY,QAAQ,kBAAkB,IAAI,IAAI,IAAI,EAAE,EACpD,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CACrC,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uBAAuB,EAAE,8BAA8B,IAAI,EAAE,EAAE;YAClF,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IACD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,UAAU,CAClB,oBAAoB,EACpB,YAAY,QAAQ,kBAAkB,IAAI,IAAI,IAAI,EAAE,EACpD,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CACrC,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export declare const SUPPORTED_AGENTS: readonly ["claude", "cursor", "opencode", "amp"];
|
|
3
|
-
export type SupportedAgent = (typeof SUPPORTED_AGENTS)[number];
|
|
4
2
|
export declare const workspaceConfigSchema: z.ZodObject<{
|
|
5
3
|
/** Schema version. Bump when config layout changes. */
|
|
6
4
|
version: z.ZodDefault<z.ZodLiteral<1>>;
|
|
@@ -20,51 +18,6 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
20
18
|
options?: Record<string, unknown> | undefined;
|
|
21
19
|
name?: string | undefined;
|
|
22
20
|
}>>;
|
|
23
|
-
/**
|
|
24
|
-
* Multi-agent orchestration backend (OpenCode). Model identifiers default
|
|
25
|
-
* to empty — they MUST be supplied here or via SPEGO_ORCHESTRATION_MODEL_*.
|
|
26
|
-
*/
|
|
27
|
-
orchestration: z.ZodDefault<z.ZodObject<{
|
|
28
|
-
serverUrl: z.ZodDefault<z.ZodString>;
|
|
29
|
-
models: z.ZodDefault<z.ZodObject<{
|
|
30
|
-
manager: z.ZodDefault<z.ZodString>;
|
|
31
|
-
worker: z.ZodDefault<z.ZodString>;
|
|
32
|
-
verifier: z.ZodDefault<z.ZodString>;
|
|
33
|
-
fallback: z.ZodDefault<z.ZodString>;
|
|
34
|
-
}, "strip", z.ZodTypeAny, {
|
|
35
|
-
manager: string;
|
|
36
|
-
worker: string;
|
|
37
|
-
verifier: string;
|
|
38
|
-
fallback: string;
|
|
39
|
-
}, {
|
|
40
|
-
manager?: string | undefined;
|
|
41
|
-
worker?: string | undefined;
|
|
42
|
-
verifier?: string | undefined;
|
|
43
|
-
fallback?: string | undefined;
|
|
44
|
-
}>>;
|
|
45
|
-
maxParallel: z.ZodDefault<z.ZodNumber>;
|
|
46
|
-
workDir: z.ZodDefault<z.ZodString>;
|
|
47
|
-
}, "strip", z.ZodTypeAny, {
|
|
48
|
-
serverUrl: string;
|
|
49
|
-
models: {
|
|
50
|
-
manager: string;
|
|
51
|
-
worker: string;
|
|
52
|
-
verifier: string;
|
|
53
|
-
fallback: string;
|
|
54
|
-
};
|
|
55
|
-
maxParallel: number;
|
|
56
|
-
workDir: string;
|
|
57
|
-
}, {
|
|
58
|
-
serverUrl?: string | undefined;
|
|
59
|
-
models?: {
|
|
60
|
-
manager?: string | undefined;
|
|
61
|
-
worker?: string | undefined;
|
|
62
|
-
verifier?: string | undefined;
|
|
63
|
-
fallback?: string | undefined;
|
|
64
|
-
} | undefined;
|
|
65
|
-
maxParallel?: number | undefined;
|
|
66
|
-
workDir?: string | undefined;
|
|
67
|
-
}>>;
|
|
68
21
|
}, "strict", z.ZodTypeAny, {
|
|
69
22
|
agents: string[];
|
|
70
23
|
demo: boolean;
|
|
@@ -74,17 +27,6 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
74
27
|
options: Record<string, unknown>;
|
|
75
28
|
name: string;
|
|
76
29
|
};
|
|
77
|
-
orchestration: {
|
|
78
|
-
serverUrl: string;
|
|
79
|
-
models: {
|
|
80
|
-
manager: string;
|
|
81
|
-
worker: string;
|
|
82
|
-
verifier: string;
|
|
83
|
-
fallback: string;
|
|
84
|
-
};
|
|
85
|
-
maxParallel: number;
|
|
86
|
-
workDir: string;
|
|
87
|
-
};
|
|
88
30
|
}, {
|
|
89
31
|
agents?: string[] | undefined;
|
|
90
32
|
demo?: boolean | undefined;
|
|
@@ -94,17 +36,6 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
94
36
|
options?: Record<string, unknown> | undefined;
|
|
95
37
|
name?: string | undefined;
|
|
96
38
|
} | undefined;
|
|
97
|
-
orchestration?: {
|
|
98
|
-
serverUrl?: string | undefined;
|
|
99
|
-
models?: {
|
|
100
|
-
manager?: string | undefined;
|
|
101
|
-
worker?: string | undefined;
|
|
102
|
-
verifier?: string | undefined;
|
|
103
|
-
fallback?: string | undefined;
|
|
104
|
-
} | undefined;
|
|
105
|
-
maxParallel?: number | undefined;
|
|
106
|
-
workDir?: string | undefined;
|
|
107
|
-
} | undefined;
|
|
108
39
|
}>;
|
|
109
40
|
export type WorkspaceConfig = z.infer<typeof workspaceConfigSchema>;
|
|
110
41
|
export declare function defaultConfig(overrides?: Partial<WorkspaceConfig>): WorkspaceConfig;
|
package/dist/workspace/config.js
CHANGED
|
@@ -3,7 +3,6 @@ import YAML from 'yaml';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { SpegoError } from '../errors.js';
|
|
5
5
|
import { BUILTIN_ARTIFACT_TYPES } from '../artifacts/types.js';
|
|
6
|
-
export const SUPPORTED_AGENTS = ['claude', 'cursor', 'opencode', 'amp'];
|
|
7
6
|
export const workspaceConfigSchema = z
|
|
8
7
|
.object({
|
|
9
8
|
/** Schema version. Bump when config layout changes. */
|
|
@@ -20,26 +19,6 @@ export const workspaceConfigSchema = z
|
|
|
20
19
|
name: z.string().default('openspec'),
|
|
21
20
|
options: z.record(z.string(), z.unknown()).default({}),
|
|
22
21
|
}).default({ name: 'openspec', options: {} }),
|
|
23
|
-
/**
|
|
24
|
-
* Multi-agent orchestration backend (OpenCode). Model identifiers default
|
|
25
|
-
* to empty — they MUST be supplied here or via SPEGO_ORCHESTRATION_MODEL_*.
|
|
26
|
-
*/
|
|
27
|
-
orchestration: z.object({
|
|
28
|
-
serverUrl: z.string().default('http://127.0.0.1:4096'),
|
|
29
|
-
models: z.object({
|
|
30
|
-
manager: z.string().default(''),
|
|
31
|
-
worker: z.string().default(''),
|
|
32
|
-
verifier: z.string().default(''),
|
|
33
|
-
fallback: z.string().default(''),
|
|
34
|
-
}).default({ manager: '', worker: '', verifier: '', fallback: '' }),
|
|
35
|
-
maxParallel: z.number().int().positive().default(4),
|
|
36
|
-
workDir: z.string().default('.spego/orchestration'),
|
|
37
|
-
}).default({
|
|
38
|
-
serverUrl: 'http://127.0.0.1:4096',
|
|
39
|
-
models: { manager: '', worker: '', verifier: '', fallback: '' },
|
|
40
|
-
maxParallel: 4,
|
|
41
|
-
workDir: '.spego/orchestration',
|
|
42
|
-
}),
|
|
43
22
|
})
|
|
44
23
|
.strict();
|
|
45
24
|
export function defaultConfig(overrides = {}) {
|
|
@@ -74,6 +53,10 @@ export async function readConfig(configPath) {
|
|
|
74
53
|
cause: err.message,
|
|
75
54
|
});
|
|
76
55
|
}
|
|
56
|
+
// Reject legacy orchestration block that users must delete from config.
|
|
57
|
+
if (typeof data === 'object' && data !== null && 'orchestration' in data) {
|
|
58
|
+
throw new SpegoError('VALIDATION_FAILED', `Legacy orchestration block found in workspace config at ${configPath}. Delete the orchestration property from the config file.`, { path: configPath });
|
|
59
|
+
}
|
|
77
60
|
const parsed = workspaceConfigSchema.safeParse(data);
|
|
78
61
|
if (!parsed.success) {
|
|
79
62
|
throw new SpegoError('VALIDATION_FAILED', 'Invalid workspace config', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/workspace/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/workspace/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACnC,MAAM,CAAC;IACN,uDAAuD;IACvD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAChC,8CAA8C;IAC9C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/C,0CAA0C;IAC1C,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAChC,iEAAiE;IACjE,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE;QAC1E,OAAO,EAAE,uFAAuF;KACjG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACf,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;QACpC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACvD,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;CAC9C,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,UAAU,aAAa,CAAC,YAAsC,EAAE;IACpE,OAAO,qBAAqB,CAAC,KAAK,CAAC;QACjC,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC;QACtC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,KAAK;QAC7B,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,IAAI,EAAE;QACtD,eAAe,EAAE,SAAS,CAAC,eAAe;KAC3C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,UAAU,CAAC,qBAAqB,EAAE,gCAAgC,UAAU,EAAE,EAAE;gBACxF,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,UAAU,CAAC,mBAAmB,EAAE,uCAAuC,UAAU,EAAE,EAAE;YAC7F,IAAI,EAAE,UAAU;YAChB,KAAK,EAAG,GAAa,CAAC,OAAO;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,wEAAwE;IACxE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;QACzE,MAAM,IAAI,UAAU,CAClB,mBAAmB,EACnB,2DAA2D,UAAU,2DAA2D,EAChI,EAAE,IAAI,EAAE,UAAU,EAAE,CACrB,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,mBAAmB,EAAE,0BAA0B,EAAE;YACpE,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB,EAAE,MAAuB;IAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IACtD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,MAAuB;IACxD,OAAO,IAAI,GAAG,CAAS,CAAC,GAAG,sBAAsB,EAAE,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;AACpF,CAAC"}
|
package/dist/workspace/init.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { resolveWorkspacePaths } from './paths.js';
|
|
3
|
+
import { resolveWorkspacePaths, rejectIfSymlink } from './paths.js';
|
|
4
4
|
import { defaultConfig, readConfig, writeConfig } from './config.js';
|
|
5
5
|
import { BUILTIN_ARTIFACT_TYPES } from '../artifacts/types.js';
|
|
6
6
|
import { SpegoError } from '../errors.js';
|
|
7
7
|
import { openIndexDb, ensureIndexSchema, closeIndexDb } from '../index/db.js';
|
|
8
8
|
import { generateAll } from '../generator/index.js';
|
|
9
|
-
import { emitOrchestrationAssets } from '../orchestration/emit.js';
|
|
10
9
|
async function ensureDir(dir, created) {
|
|
11
10
|
try {
|
|
12
11
|
await fs.mkdir(dir, { recursive: false });
|
|
@@ -28,6 +27,18 @@ export async function initWorkspace(options = {}) {
|
|
|
28
27
|
const projectRoot = path.resolve(options.projectRoot ?? process.cwd());
|
|
29
28
|
const paths = resolveWorkspacePaths(projectRoot);
|
|
30
29
|
const created = [];
|
|
30
|
+
// Reject symlinked existing owned components before any I/O.
|
|
31
|
+
await rejectIfSymlink(paths.workspaceRoot);
|
|
32
|
+
await rejectIfSymlink(paths.artifactsRoot);
|
|
33
|
+
await rejectIfSymlink(paths.revisionsRoot);
|
|
34
|
+
await rejectIfSymlink(paths.indexRoot);
|
|
35
|
+
await rejectIfSymlink(paths.configPath);
|
|
36
|
+
await rejectIfSymlink(paths.indexDbPath);
|
|
37
|
+
// Reject symlinked built-in type dirs that already exist.
|
|
38
|
+
for (const t of BUILTIN_ARTIFACT_TYPES) {
|
|
39
|
+
await rejectIfSymlink(path.join(paths.artifactsRoot, t));
|
|
40
|
+
await rejectIfSymlink(path.join(paths.revisionsRoot, t));
|
|
41
|
+
}
|
|
31
42
|
// Detect prior workspace state before any side effects.
|
|
32
43
|
let existingConfig;
|
|
33
44
|
try {
|
|
@@ -80,7 +91,6 @@ export async function initWorkspace(options = {}) {
|
|
|
80
91
|
if (config.agents.length > 0) {
|
|
81
92
|
generationReports = await generateAll(projectRoot, config.agents);
|
|
82
93
|
}
|
|
83
|
-
generationReports.push(await emitOrchestrationAssets(projectRoot));
|
|
84
94
|
return {
|
|
85
95
|
projectRoot: paths.projectRoot,
|
|
86
96
|
workspaceRoot: paths.workspaceRoot,
|
|
@@ -110,7 +120,9 @@ export async function workspaceStatus(projectRoot = process.cwd()) {
|
|
|
110
120
|
agents: config.agents,
|
|
111
121
|
};
|
|
112
122
|
}
|
|
113
|
-
catch {
|
|
123
|
+
catch (err) {
|
|
124
|
+
if (err instanceof SpegoError && err.code !== 'WORKSPACE_NOT_FOUND')
|
|
125
|
+
throw err;
|
|
114
126
|
return {
|
|
115
127
|
initialized: false,
|
|
116
128
|
projectRoot: paths.projectRoot,
|