@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
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.12.0] - 2026-07-12
|
|
6
|
+
|
|
7
|
+
### Security
|
|
8
|
+
- Reject symlinked workspace paths and artifact files so Spego cannot read or write outside `.spego`.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Renamed `src/commands/` to `src/command-meta/` for clarity — only the metadata registry lives there, not command implementations.
|
|
12
|
+
- Lint script now enforces zero warnings (`eslint src test --max-warnings 0`).
|
|
13
|
+
|
|
14
|
+
### Removed
|
|
15
|
+
- Removed `main` and `types` entry points and deleted `src/index.ts` — spego is CLI-only, not a library package.
|
|
16
|
+
- Removed legacy `orchestration` config block acceptance from `readConfig()`; workspaces with stale `orchestration:` in `.spego/config.yaml` now get a `VALIDATION_FAILED` error telling them to delete the property.
|
|
17
|
+
|
|
18
|
+
## [0.11.0] - 2026-05-31
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- OpenCode is now a first-class generated target. Workspaces can list `opencode` in `.spego/config.yaml` to emit `/spego-apply`, `/spego-verify`, and `/spego-explore` command files under `.opencode/commands/`.
|
|
22
|
+
- Spego no longer exposes daemon-backed `spego orchestrate`; apply/verify/explore workflows now run inside the active OpenCode instance.
|
|
23
|
+
- `/spego-apply` now defines explicit current-session phases (select, load context, plan tasks, execute work, verify results, update task checkboxes, summarize status) and allows OpenCode-native subagents only inside the active instance.
|
|
24
|
+
- `/spego-verify` and `/spego-explore` now state they run entirely inside the active OpenCode instance.
|
|
25
|
+
- Build now cleans `dist/` before TypeScript compilation to prevent stale daemon-backed files from being packaged.
|
|
26
|
+
- Generated OpenCode commands now clean up stale `opsx-*` commands and `openspec-*` skills when they carry the `spego_generated: true` marker.
|
|
27
|
+
|
|
28
|
+
### Removed
|
|
29
|
+
- Removed Spego-owned OpenCode REST orchestration code and stopped writing new `orchestration` server/model config blocks.
|
|
30
|
+
- Removed `ultracode/` sample directory (daemon-backed multi-agent orchestrator that no longer aligns with Spego's local CLI architecture).
|
|
31
|
+
|
|
5
32
|
## [0.10.1] - 2026-05-30
|
|
6
33
|
|
|
7
34
|
### Fixed
|
package/README.md
CHANGED
|
@@ -5,9 +5,8 @@ Agent-first product orchestration: markdown-first artifact engine with SQLite in
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npm install
|
|
9
|
-
|
|
10
|
-
spego init --agents claude --demo false
|
|
8
|
+
npm install --global @zhuk/spego
|
|
9
|
+
spego init --agents claude,opencode --demo false
|
|
11
10
|
```
|
|
12
11
|
|
|
13
12
|
## Commands
|
|
@@ -27,7 +26,6 @@ spego init --agents claude --demo false
|
|
|
27
26
|
| `spego skills` | Regenerate agent skill files |
|
|
28
27
|
| `spego epics` | List delivery epics |
|
|
29
28
|
| `spego tasks --change <name>` | List tasks for a change |
|
|
30
|
-
| `spego orchestrate --change <name>` | Run the multi-agent orchestration pipeline for a change |
|
|
31
29
|
| `spego index rebuild` | Rebuild SQLite index from files |
|
|
32
30
|
|
|
33
31
|
All commands accept `--cwd <dir>` to set the project root.
|
|
@@ -70,20 +68,12 @@ Workspace config lives at `.spego/config.yaml`:
|
|
|
70
68
|
version: 1
|
|
71
69
|
agents:
|
|
72
70
|
- claude
|
|
71
|
+
- opencode
|
|
73
72
|
demo: false
|
|
74
73
|
extraArtifactTypes: []
|
|
75
74
|
deliveryAdapter:
|
|
76
75
|
name: openspec
|
|
77
76
|
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
|
|
87
77
|
```
|
|
88
78
|
|
|
89
79
|
## OpenSpec Delivery View
|
|
@@ -101,46 +91,19 @@ The adapter is read-only. It observes OpenSpec state but does not create, contin
|
|
|
101
91
|
|
|
102
92
|
Archived changes under `openspec/changes/archive/` are excluded. A change with no `tasks.md` is reported as `planning-incomplete`.
|
|
103
93
|
|
|
104
|
-
##
|
|
94
|
+
## OpenCode Workflows
|
|
105
95
|
|
|
106
|
-
`
|
|
96
|
+
When `opencode` is listed in `.spego/config.yaml` agents, `spego init` and `spego skills` generate static OpenCode commands under `.opencode/commands/`:
|
|
107
97
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
- `/spego-apply` implements pending tasks from an OpenSpec change in the active OpenCode instance.
|
|
99
|
+
- `/spego-verify` checks completeness, correctness, coherence, and tests before archive.
|
|
100
|
+
- `/spego-explore` enters a read-only exploration stance for ideas, problems, or OpenSpec changes.
|
|
111
101
|
|
|
112
|
-
|
|
102
|
+
`/spego-apply` runs as a phased current-session workflow: select the change, load context, plan tasks, execute work, verify results, update task checkboxes, and summarize status. It may use OpenCode-native subagents only inside the active OpenCode instance for independent investigation, implementation review, or verification.
|
|
113
103
|
|
|
114
|
-
|
|
104
|
+
Spego does not start or control OpenCode through `opencode serve`, does not call the OpenCode REST API, does not create external OpenCode sessions, and does not own model selection. Configure models, variants, agents, and permissions in OpenCode itself.
|
|
115
105
|
|
|
116
|
-
|
|
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
|
-
```
|
|
106
|
+
There are no `spego apply`, `spego verify`, `spego explore`, or `spego orchestrate` CLI commands. Apply, verify, and explore are generated OpenCode workflows; spego remains the local artifact engine and read-only OpenSpec delivery view.
|
|
144
107
|
|
|
145
108
|
## Generated Files
|
|
146
109
|
|
|
@@ -149,8 +112,16 @@ For Claude agent targets, `spego init` generates:
|
|
|
149
112
|
- `.claude/skills/spego-<command>/SKILL.md` — skill definitions following Claude Code conventions
|
|
150
113
|
- `.claude/commands/spego/` — slash command wrappers
|
|
151
114
|
|
|
115
|
+
For OpenCode targets, `spego init` generates:
|
|
116
|
+
|
|
117
|
+
- `.opencode/commands/spego-apply.md`
|
|
118
|
+
- `.opencode/commands/spego-verify.md`
|
|
119
|
+
- `.opencode/commands/spego-explore.md`
|
|
120
|
+
|
|
152
121
|
Run `spego skills` to update generated files without reinitializing the workspace.
|
|
153
122
|
|
|
123
|
+
During regeneration, Spego removes stale generated OpenCode compatibility files such as old `opsx-*` commands, `openspec-*` skills, and retired orchestration assets only when they carry the `spego_generated: true` marker. User-owned OpenCode files without that marker are preserved and reported as skipped.
|
|
124
|
+
|
|
154
125
|
## Workflow Skills
|
|
155
126
|
|
|
156
127
|
Workflow skills guide an agent through a multi-persona process inside the chat, persisting results as spego artifacts at well-defined checkpoints.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type WorkspacePaths } from '../workspace/paths.js';
|
|
2
2
|
import { type IndexedArtifact, type ListOptions, type RebuildReport } from '../index/indexer.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ArtifactRecord } from './types.js';
|
|
4
4
|
import { type WorkspaceConfig } from '../workspace/config.js';
|
|
5
5
|
export interface EngineOptions {
|
|
6
6
|
/** Project root containing `.spego/`. Defaults to cwd. */
|
|
@@ -12,9 +12,11 @@ export declare class ArtifactEngine {
|
|
|
12
12
|
readonly config: WorkspaceConfig;
|
|
13
13
|
private readonly db;
|
|
14
14
|
private closed;
|
|
15
|
+
private readonly resolvedRoot;
|
|
15
16
|
private constructor();
|
|
16
17
|
static open(opts?: EngineOptions): Promise<ArtifactEngine>;
|
|
17
18
|
close(): void;
|
|
19
|
+
renderMarkdown(record: ArtifactRecord): string;
|
|
18
20
|
create(input: unknown): Promise<ArtifactRecord>;
|
|
19
21
|
private resolveCreateSlug;
|
|
20
22
|
readById(id: string): Promise<ArtifactRecord>;
|
|
@@ -35,11 +37,5 @@ export declare class ArtifactEngine {
|
|
|
35
37
|
}>;
|
|
36
38
|
readRevision(id: string, revision: number): Promise<ArtifactRecord>;
|
|
37
39
|
rebuildIndex(): Promise<RebuildReport>;
|
|
38
|
-
/**
|
|
39
|
-
* Direct accessor used by the export module. Resolves the latest record
|
|
40
|
-
* for an indexed entry without re-querying SQLite.
|
|
41
|
-
*/
|
|
42
40
|
readForIndexed(indexed: IndexedArtifact): Promise<ArtifactRecord>;
|
|
43
|
-
/** Convenience accessor for callers that need the latest frontmatter. */
|
|
44
|
-
static frontmatterFromRecord(record: ArtifactRecord): ArtifactFrontmatter;
|
|
45
41
|
}
|
package/dist/artifacts/engine.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { artifactFilePath, artifactTypeDir, resolveWorkspacePaths, } from '../workspace/paths.js';
|
|
4
|
-
import { closeIndexDb, ensureIndexSchema, openIndexDb
|
|
4
|
+
import { artifactFilePath, artifactTypeDir, resolveWorkspacePaths, resolveContainmentRoot, rejectIfSymlink, } from '../workspace/paths.js';
|
|
5
|
+
import { closeIndexDb, ensureIndexSchema, openIndexDb } from '../index/db.js';
|
|
5
6
|
import { getArtifactById, getArtifactByTypeSlug, listArtifacts, listRevisions, rebuildIndex, upsertArtifact, } from '../index/indexer.js';
|
|
6
|
-
import { atomicWriteFile, readArtifactFile, renderArtifactFile
|
|
7
|
+
import { atomicWriteFile, readArtifactFile, renderArtifactFile } from './storage.js';
|
|
7
8
|
import { writeRevisionSnapshot, readRevisionSnapshot } from '../index/revisions.js';
|
|
8
9
|
import { makeSlug, uniqueSlug } from './slug.js';
|
|
9
10
|
import { artifactFrontmatterSchema, } from './types.js';
|
|
@@ -16,13 +17,25 @@ export class ArtifactEngine {
|
|
|
16
17
|
config;
|
|
17
18
|
db;
|
|
18
19
|
closed = false;
|
|
19
|
-
|
|
20
|
+
resolvedRoot;
|
|
21
|
+
constructor(paths, config, db, resolvedRoot) {
|
|
20
22
|
this.paths = paths;
|
|
21
23
|
this.config = config;
|
|
22
24
|
this.db = db;
|
|
25
|
+
this.resolvedRoot = resolvedRoot;
|
|
23
26
|
}
|
|
24
27
|
static async open(opts = {}) {
|
|
25
|
-
const
|
|
28
|
+
const rawRoot = path.resolve(opts.projectRoot ?? process.cwd());
|
|
29
|
+
const paths = resolveWorkspacePaths(rawRoot);
|
|
30
|
+
// Lstat-guard owned components before resolving containment root.
|
|
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
|
+
// Resolve .spego realpath as containment root.
|
|
38
|
+
const resolvedRoot = await resolveContainmentRoot(paths.workspaceRoot);
|
|
26
39
|
let config;
|
|
27
40
|
try {
|
|
28
41
|
config = await readConfig(paths.configPath);
|
|
@@ -33,9 +46,15 @@ export class ArtifactEngine {
|
|
|
33
46
|
}
|
|
34
47
|
throw err;
|
|
35
48
|
}
|
|
49
|
+
// Reject symlinked type directories for all known types.
|
|
50
|
+
const known = knownArtifactTypes(config);
|
|
51
|
+
for (const t of known) {
|
|
52
|
+
await rejectIfSymlink(artifactTypeDir(paths, t));
|
|
53
|
+
await rejectIfSymlink(path.join(paths.revisionsRoot, t));
|
|
54
|
+
}
|
|
36
55
|
const db = openIndexDb(paths.indexDbPath);
|
|
37
56
|
ensureIndexSchema(db);
|
|
38
|
-
return new ArtifactEngine(paths, config, db);
|
|
57
|
+
return new ArtifactEngine(paths, config, db, resolvedRoot);
|
|
39
58
|
}
|
|
40
59
|
close() {
|
|
41
60
|
if (this.closed)
|
|
@@ -43,6 +62,9 @@ export class ArtifactEngine {
|
|
|
43
62
|
this.closed = true;
|
|
44
63
|
closeIndexDb(this.db);
|
|
45
64
|
}
|
|
65
|
+
renderMarkdown(record) {
|
|
66
|
+
return renderArtifactFile(record.frontmatter, record.body);
|
|
67
|
+
}
|
|
46
68
|
// ---------------------------------------------------------------- create
|
|
47
69
|
async create(input) {
|
|
48
70
|
const data = parseCreateInput(input);
|
|
@@ -63,14 +85,13 @@ export class ArtifactEngine {
|
|
|
63
85
|
});
|
|
64
86
|
const filePath = artifactFilePath(this.paths, fm.type, fm.slug);
|
|
65
87
|
// File-first: write canonical + snapshot, then mirror to index.
|
|
66
|
-
await atomicWriteFile(filePath, renderArtifactFile(fm, data.body));
|
|
67
|
-
const snapPath = await writeRevisionSnapshot(this.paths, fm, data.body);
|
|
88
|
+
await atomicWriteFile(filePath, renderArtifactFile(fm, data.body), this.resolvedRoot);
|
|
89
|
+
const snapPath = await writeRevisionSnapshot(this.paths, fm, data.body, this.resolvedRoot);
|
|
68
90
|
upsertArtifact(this.db, fm, filePath, snapPath);
|
|
69
91
|
return { frontmatter: fm, body: data.body, path: filePath };
|
|
70
92
|
}
|
|
71
93
|
async resolveCreateSlug(data) {
|
|
72
94
|
const desired = data.slug ? makeSlug(data.slug) : makeSlug(data.title);
|
|
73
|
-
// Existing slugs come from the index (fast) and fallback file scan (truth).
|
|
74
95
|
const existing = new Set();
|
|
75
96
|
for (const row of listArtifacts(this.db, { type: data.type, includeDeleted: true })) {
|
|
76
97
|
existing.add(row.slug);
|
|
@@ -125,7 +146,11 @@ export class ArtifactEngine {
|
|
|
125
146
|
const current = await readArtifactFile(indexed.path);
|
|
126
147
|
if (data.expectedRevision !== undefined &&
|
|
127
148
|
data.expectedRevision !== current.frontmatter.revision) {
|
|
128
|
-
throw new SpegoError('REVISION_CONFLICT', `Stale revision for ${id}: expected ${data.expectedRevision}, current ${current.frontmatter.revision}`, {
|
|
149
|
+
throw new SpegoError('REVISION_CONFLICT', `Stale revision for ${id}: expected ${data.expectedRevision}, current ${current.frontmatter.revision}`, {
|
|
150
|
+
id,
|
|
151
|
+
expectedRevision: data.expectedRevision,
|
|
152
|
+
currentRevision: current.frontmatter.revision,
|
|
153
|
+
});
|
|
129
154
|
}
|
|
130
155
|
if (data.meta !== undefined) {
|
|
131
156
|
data.meta = validateArtifactMeta(indexed.type, data.meta);
|
|
@@ -138,8 +163,8 @@ export class ArtifactEngine {
|
|
|
138
163
|
revision: current.frontmatter.revision + 1,
|
|
139
164
|
updatedAt: new Date().toISOString(),
|
|
140
165
|
});
|
|
141
|
-
await atomicWriteFile(indexed.path, renderArtifactFile(fm, nextBody));
|
|
142
|
-
const snapPath = await writeRevisionSnapshot(this.paths, fm, nextBody);
|
|
166
|
+
await atomicWriteFile(indexed.path, renderArtifactFile(fm, nextBody), this.resolvedRoot);
|
|
167
|
+
const snapPath = await writeRevisionSnapshot(this.paths, fm, nextBody, this.resolvedRoot);
|
|
143
168
|
upsertArtifact(this.db, fm, indexed.path, snapPath);
|
|
144
169
|
return { frontmatter: fm, body: nextBody, path: indexed.path };
|
|
145
170
|
}
|
|
@@ -166,8 +191,8 @@ export class ArtifactEngine {
|
|
|
166
191
|
updatedAt: new Date().toISOString(),
|
|
167
192
|
deletedAt: new Date().toISOString(),
|
|
168
193
|
});
|
|
169
|
-
await atomicWriteFile(indexed.path, renderArtifactFile(fm, current.body));
|
|
170
|
-
const snapPath = await writeRevisionSnapshot(this.paths, fm, current.body);
|
|
194
|
+
await atomicWriteFile(indexed.path, renderArtifactFile(fm, current.body), this.resolvedRoot);
|
|
195
|
+
const snapPath = await writeRevisionSnapshot(this.paths, fm, current.body, this.resolvedRoot);
|
|
171
196
|
upsertArtifact(this.db, fm, indexed.path, snapPath);
|
|
172
197
|
return { frontmatter: fm, body: current.body, path: indexed.path };
|
|
173
198
|
}
|
|
@@ -192,18 +217,9 @@ export class ArtifactEngine {
|
|
|
192
217
|
const known = knownArtifactTypes(this.config);
|
|
193
218
|
return rebuildIndex(this.db, this.paths, known);
|
|
194
219
|
}
|
|
195
|
-
// ------------------------------------------------------------ frontmatter
|
|
196
|
-
/**
|
|
197
|
-
* Direct accessor used by the export module. Resolves the latest record
|
|
198
|
-
* for an indexed entry without re-querying SQLite.
|
|
199
|
-
*/
|
|
200
220
|
async readForIndexed(indexed) {
|
|
201
221
|
const file = await readArtifactFile(indexed.path);
|
|
202
222
|
return { ...file, path: indexed.path };
|
|
203
223
|
}
|
|
204
|
-
/** Convenience accessor for callers that need the latest frontmatter. */
|
|
205
|
-
static frontmatterFromRecord(record) {
|
|
206
|
-
return record.frontmatter;
|
|
207
|
-
}
|
|
208
224
|
}
|
|
209
225
|
//# sourceMappingURL=engine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/artifacts/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/artifacts/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ export declare function parseArtifactFile(text: string, sourcePath: string): {
|
|
|
6
6
|
frontmatter: ArtifactFrontmatter;
|
|
7
7
|
body: string;
|
|
8
8
|
};
|
|
9
|
-
/** Read and parse a markdown artifact file from disk. */
|
|
9
|
+
/** Read and parse a markdown artifact file from disk, rejecting symlinked targets. */
|
|
10
10
|
export declare function readArtifactFile(absPath: string): Promise<{
|
|
11
11
|
frontmatter: ArtifactFrontmatter;
|
|
12
12
|
body: string;
|
|
@@ -14,5 +14,6 @@ export declare function readArtifactFile(absPath: string): Promise<{
|
|
|
14
14
|
/**
|
|
15
15
|
* Atomically write a markdown file: write to a temp sibling, fsync, rename.
|
|
16
16
|
* Rename on the same filesystem is atomic on POSIX and Windows (ReplaceFile).
|
|
17
|
+
* Verifies containment when `resolvedRoot` is provided.
|
|
17
18
|
*/
|
|
18
|
-
export declare function atomicWriteFile(absPath: string, contents: string): Promise<void>;
|
|
19
|
+
export declare function atomicWriteFile(absPath: string, contents: string, resolvedRoot?: string): Promise<void>;
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import YAML from 'yaml';
|
|
4
4
|
import { artifactFrontmatterSchema } from './types.js';
|
|
5
5
|
import { SpegoError } from '../errors.js';
|
|
6
|
+
import { assertParentContained } from '../workspace/paths.js';
|
|
6
7
|
const FENCE_OPEN = /^---\r?\n/;
|
|
7
8
|
const FENCE_CLOSE = /\r?\n---\r?\n?/;
|
|
8
9
|
/** Render frontmatter + body to a single markdown string. */
|
|
@@ -21,12 +22,16 @@ export function renderArtifactFile(frontmatter, body) {
|
|
|
21
22
|
export function parseArtifactFile(text, sourcePath) {
|
|
22
23
|
const openMatch = text.match(FENCE_OPEN);
|
|
23
24
|
if (!openMatch) {
|
|
24
|
-
throw new SpegoError('VALIDATION_FAILED', `Missing frontmatter block in ${sourcePath}`, {
|
|
25
|
+
throw new SpegoError('VALIDATION_FAILED', `Missing frontmatter block in ${sourcePath}`, {
|
|
26
|
+
path: sourcePath,
|
|
27
|
+
});
|
|
25
28
|
}
|
|
26
29
|
const afterOpen = text.slice(openMatch[0].length);
|
|
27
30
|
const closeMatch = afterOpen.match(FENCE_CLOSE);
|
|
28
31
|
if (!closeMatch || closeMatch.index === undefined) {
|
|
29
|
-
throw new SpegoError('VALIDATION_FAILED', `Unterminated frontmatter block in ${sourcePath}`, {
|
|
32
|
+
throw new SpegoError('VALIDATION_FAILED', `Unterminated frontmatter block in ${sourcePath}`, {
|
|
33
|
+
path: sourcePath,
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
const yamlText = afterOpen.slice(0, closeMatch.index);
|
|
32
37
|
const body = afterOpen.slice(closeMatch.index + closeMatch[0].length).replace(/^\n+/, '');
|
|
@@ -37,7 +42,10 @@ export function parseArtifactFile(text, sourcePath) {
|
|
|
37
42
|
data = YAML.parse(yamlText);
|
|
38
43
|
}
|
|
39
44
|
catch (err) {
|
|
40
|
-
throw new SpegoError('VALIDATION_FAILED', `Invalid YAML frontmatter in ${sourcePath}`, {
|
|
45
|
+
throw new SpegoError('VALIDATION_FAILED', `Invalid YAML frontmatter in ${sourcePath}`, {
|
|
46
|
+
path: sourcePath,
|
|
47
|
+
cause: err.message,
|
|
48
|
+
});
|
|
41
49
|
}
|
|
42
50
|
const result = artifactFrontmatterSchema.safeParse(data);
|
|
43
51
|
if (!result.success) {
|
|
@@ -48,8 +56,26 @@ export function parseArtifactFile(text, sourcePath) {
|
|
|
48
56
|
}
|
|
49
57
|
return { frontmatter: result.data, body };
|
|
50
58
|
}
|
|
51
|
-
/** Read and parse a markdown artifact file from disk. */
|
|
59
|
+
/** Read and parse a markdown artifact file from disk, rejecting symlinked targets. */
|
|
52
60
|
export async function readArtifactFile(absPath) {
|
|
61
|
+
// Reject if the file itself is a symlink.
|
|
62
|
+
let stat;
|
|
63
|
+
try {
|
|
64
|
+
stat = await fs.lstat(absPath);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err.code === 'ENOENT') {
|
|
68
|
+
throw new SpegoError('ARTIFACT_NOT_FOUND', `Artifact file not found at ${absPath}`, {
|
|
69
|
+
path: absPath,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
if (stat.isSymbolicLink()) {
|
|
75
|
+
throw new SpegoError('WORKSPACE_CONTAINMENT', `Symlinked artifact file at ${absPath}`, {
|
|
76
|
+
path: absPath,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
53
79
|
let text;
|
|
54
80
|
try {
|
|
55
81
|
text = await fs.readFile(absPath, 'utf8');
|
|
@@ -67,8 +93,12 @@ export async function readArtifactFile(absPath) {
|
|
|
67
93
|
/**
|
|
68
94
|
* Atomically write a markdown file: write to a temp sibling, fsync, rename.
|
|
69
95
|
* Rename on the same filesystem is atomic on POSIX and Windows (ReplaceFile).
|
|
96
|
+
* Verifies containment when `resolvedRoot` is provided.
|
|
70
97
|
*/
|
|
71
|
-
export async function atomicWriteFile(absPath, contents) {
|
|
98
|
+
export async function atomicWriteFile(absPath, contents, resolvedRoot) {
|
|
99
|
+
if (resolvedRoot) {
|
|
100
|
+
await assertParentContained(resolvedRoot, absPath);
|
|
101
|
+
}
|
|
72
102
|
await fs.mkdir(path.dirname(absPath), { recursive: true });
|
|
73
103
|
const tmp = `${absPath}.${process.pid}.${Date.now()}.tmp`;
|
|
74
104
|
const handle = await fs.open(tmp, 'w', 0o644);
|
|
@@ -76,14 +106,19 @@ export async function atomicWriteFile(absPath, contents) {
|
|
|
76
106
|
await handle.writeFile(contents, 'utf8');
|
|
77
107
|
await handle.sync();
|
|
78
108
|
}
|
|
79
|
-
|
|
109
|
+
catch (err) {
|
|
80
110
|
await handle.close();
|
|
111
|
+
await fs.unlink(tmp).catch(() => undefined);
|
|
112
|
+
throw new SpegoError('WRITE_FAILED', `Failed to write artifact to ${absPath}`, {
|
|
113
|
+
path: absPath,
|
|
114
|
+
cause: err.message,
|
|
115
|
+
});
|
|
81
116
|
}
|
|
117
|
+
await handle.close();
|
|
82
118
|
try {
|
|
83
119
|
await fs.rename(tmp, absPath);
|
|
84
120
|
}
|
|
85
121
|
catch (err) {
|
|
86
|
-
// Clean up temp file if rename failed.
|
|
87
122
|
await fs.unlink(tmp).catch(() => undefined);
|
|
88
123
|
throw new SpegoError('WRITE_FAILED', `Failed to write artifact to ${absPath}`, {
|
|
89
124
|
path: absPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/artifacts/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAA4B,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/artifacts/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,7 +60,7 @@ export function validateArtifactMeta(type, meta) {
|
|
|
60
60
|
return validateMetaForType(type, meta);
|
|
61
61
|
}
|
|
62
62
|
catch (err) {
|
|
63
|
-
if (err instanceof
|
|
63
|
+
if (err instanceof z.ZodError) {
|
|
64
64
|
throw new SpegoError('VALIDATION_FAILED', `Invalid metadata for artifact type: ${type}`, {
|
|
65
65
|
type,
|
|
66
66
|
issues: err.issues,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/artifacts/validation.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/artifacts/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/body-input.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* supplied so callers can leave the artifact body unchanged.
|
|
7
7
|
*/
|
|
8
8
|
import fs from 'node:fs/promises';
|
|
9
|
+
import { SpegoError } from '../errors.js';
|
|
9
10
|
async function readStdin() {
|
|
10
11
|
return new Promise((resolve, reject) => {
|
|
11
12
|
let buf = '';
|
|
@@ -20,8 +21,17 @@ async function readStdin() {
|
|
|
20
21
|
export async function resolveBody(opts) {
|
|
21
22
|
if (opts.bodyFile === '-')
|
|
22
23
|
return readStdin();
|
|
23
|
-
if (opts.bodyFile)
|
|
24
|
-
|
|
24
|
+
if (opts.bodyFile) {
|
|
25
|
+
try {
|
|
26
|
+
return await fs.readFile(opts.bodyFile, 'utf8');
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new SpegoError('VALIDATION_FAILED', `Cannot read body file: ${opts.bodyFile}`, {
|
|
30
|
+
path: opts.bodyFile,
|
|
31
|
+
cause: err instanceof Error ? err.message : String(err),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
25
35
|
return opts.body;
|
|
26
36
|
}
|
|
27
37
|
//# sourceMappingURL=body-input.js.map
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"body-input.js","sourceRoot":"","sources":["../../src/cli/body-input.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAO1C,KAAK,UAAU,SAAS;IACvB,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9C,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;YAC1C,GAAG,IAAI,KAAK,CAAC;QACd,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;IACnC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAsB;IACvD,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG;QAAE,OAAO,SAAS,EAAE,CAAC;IAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,IAAI,CAAC;YACJ,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,UAAU,CAAC,mBAAmB,EAAE,0BAA0B,IAAI,CAAC,QAAQ,EAAE,EAAE;gBACpF,IAAI,EAAE,IAAI,CAAC,QAAQ;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACvD,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC;AAClB,CAAC"}
|