open-wiki-spec 0.2.4 → 0.3.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 +54 -0
- package/README.md +50 -3
- package/dist/cli/commands/apply.d.ts.map +1 -1
- package/dist/cli/commands/apply.js +96 -4
- package/dist/cli/commands/apply.js.map +1 -1
- package/dist/cli/commands/archive.d.ts.map +1 -1
- package/dist/cli/commands/archive.js +19 -5
- package/dist/cli/commands/archive.js.map +1 -1
- package/dist/cli/commands/bulk-archive.d.ts +15 -0
- package/dist/cli/commands/bulk-archive.d.ts.map +1 -0
- package/dist/cli/commands/bulk-archive.js +97 -0
- package/dist/cli/commands/bulk-archive.js.map +1 -0
- package/dist/cli/commands/continue.d.ts.map +1 -1
- package/dist/cli/commands/continue.js +15 -2
- package/dist/cli/commands/continue.js.map +1 -1
- package/dist/cli/commands/error-handler.d.ts +1 -5
- package/dist/cli/commands/error-handler.d.ts.map +1 -1
- package/dist/cli/commands/error-handler.js +48 -3
- package/dist/cli/commands/error-handler.js.map +1 -1
- package/dist/cli/commands/init.d.ts +0 -3
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +22 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/list.d.ts +2 -17
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +15 -3
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +6 -9
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/propose.d.ts.map +1 -1
- package/dist/cli/commands/propose.js +46 -6
- package/dist/cli/commands/propose.js.map +1 -1
- package/dist/cli/commands/query.d.ts.map +1 -1
- package/dist/cli/commands/query.js +99 -4
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts +7 -0
- package/dist/cli/commands/retrieve.d.ts.map +1 -0
- package/dist/cli/commands/retrieve.js +70 -0
- package/dist/cli/commands/retrieve.js.map +1 -0
- package/dist/cli/commands/revert.d.ts +18 -0
- package/dist/cli/commands/revert.d.ts.map +1 -0
- package/dist/cli/commands/revert.js +109 -0
- package/dist/cli/commands/revert.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -19
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +42 -3
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +12 -1
- package/dist/cli/commands/verify.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +68 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/init-engine.d.ts.map +1 -1
- package/dist/cli/init/init-engine.js +19 -6
- package/dist/cli/init/init-engine.js.map +1 -1
- package/dist/cli/init/meta-files.d.ts +2 -1
- package/dist/cli/init/meta-files.d.ts.map +1 -1
- package/dist/cli/init/meta-files.js +167 -8
- package/dist/cli/init/meta-files.js.map +1 -1
- package/dist/cli/init/skill-generator.d.ts +3 -0
- package/dist/cli/init/skill-generator.d.ts.map +1 -1
- package/dist/cli/init/skill-generator.js +184 -3
- package/dist/cli/init/skill-generator.js.map +1 -1
- package/dist/cli/json-envelope.d.ts +15 -0
- package/dist/cli/json-envelope.d.ts.map +1 -0
- package/dist/cli/json-envelope.js +86 -0
- package/dist/cli/json-envelope.js.map +1 -0
- package/dist/cli/schema-check.d.ts +27 -0
- package/dist/cli/schema-check.d.ts.map +1 -0
- package/dist/cli/schema-check.js +33 -0
- package/dist/cli/schema-check.js.map +1 -0
- package/dist/cli/vault-discovery.d.ts.map +1 -1
- package/dist/cli/vault-discovery.js +16 -2
- package/dist/cli/vault-discovery.js.map +1 -1
- package/dist/core/embedding/cache.d.ts +12 -3
- package/dist/core/embedding/cache.d.ts.map +1 -1
- package/dist/core/embedding/cache.js +42 -5
- package/dist/core/embedding/cache.js.map +1 -1
- package/dist/core/embedding/embedder.d.ts.map +1 -1
- package/dist/core/embedding/embedder.js +73 -6
- package/dist/core/embedding/embedder.js.map +1 -1
- package/dist/core/index/build.d.ts.map +1 -1
- package/dist/core/index/build.js +54 -6
- package/dist/core/index/build.js.map +1 -1
- package/dist/core/index/resolve.d.ts.map +1 -1
- package/dist/core/index/resolve.js +27 -12
- package/dist/core/index/resolve.js.map +1 -1
- package/dist/core/index/scan.d.ts +10 -1
- package/dist/core/index/scan.d.ts.map +1 -1
- package/dist/core/index/scan.js +59 -10
- package/dist/core/index/scan.js.map +1 -1
- package/dist/core/index/schema-version.d.ts +28 -0
- package/dist/core/index/schema-version.d.ts.map +1 -1
- package/dist/core/index/schema-version.js +47 -0
- package/dist/core/index/schema-version.js.map +1 -1
- package/dist/core/migrate/change-converter.d.ts.map +1 -1
- package/dist/core/migrate/change-converter.js +52 -5
- package/dist/core/migrate/change-converter.js.map +1 -1
- package/dist/core/migrate/migrate.d.ts.map +1 -1
- package/dist/core/migrate/migrate.js +115 -1
- package/dist/core/migrate/migrate.js.map +1 -1
- package/dist/core/migrate/spec-converter.js +5 -0
- package/dist/core/migrate/spec-converter.js.map +1 -1
- package/dist/core/migrate/types.d.ts +9 -0
- package/dist/core/migrate/types.d.ts.map +1 -1
- package/dist/core/parser/frontmatter-parser.d.ts +0 -6
- package/dist/core/parser/frontmatter-parser.d.ts.map +1 -1
- package/dist/core/parser/frontmatter-parser.js +59 -2
- package/dist/core/parser/frontmatter-parser.js.map +1 -1
- package/dist/core/parser/requirement-parser.js +4 -0
- package/dist/core/parser/requirement-parser.js.map +1 -1
- package/dist/core/parser/task-parser.d.ts.map +1 -1
- package/dist/core/parser/task-parser.js +19 -0
- package/dist/core/parser/task-parser.js.map +1 -1
- package/dist/core/parser/wikilink-parser.d.ts.map +1 -1
- package/dist/core/parser/wikilink-parser.js +21 -5
- package/dist/core/parser/wikilink-parser.js.map +1 -1
- package/dist/core/retrieval/classify.d.ts +11 -4
- package/dist/core/retrieval/classify.d.ts.map +1 -1
- package/dist/core/retrieval/classify.js +76 -14
- package/dist/core/retrieval/classify.js.map +1 -1
- package/dist/core/retrieval/lexical.d.ts.map +1 -1
- package/dist/core/retrieval/lexical.js +31 -12
- package/dist/core/retrieval/lexical.js.map +1 -1
- package/dist/core/retrieval/retrieve.d.ts.map +1 -1
- package/dist/core/retrieval/retrieve.js +45 -5
- package/dist/core/retrieval/retrieve.js.map +1 -1
- package/dist/core/retrieval/scoring.d.ts.map +1 -1
- package/dist/core/retrieval/scoring.js +37 -12
- package/dist/core/retrieval/scoring.js.map +1 -1
- package/dist/core/schema/change.schema.d.ts.map +1 -1
- package/dist/core/schema/change.schema.js +6 -1
- package/dist/core/schema/change.schema.js.map +1 -1
- package/dist/core/schema/feature.schema.d.ts +1 -1
- package/dist/core/schema/feature.schema.d.ts.map +1 -1
- package/dist/core/schema/feature.schema.js +1 -0
- package/dist/core/schema/feature.schema.js.map +1 -1
- package/dist/core/schema/frontmatter.d.ts +15 -0
- package/dist/core/schema/frontmatter.d.ts.map +1 -1
- package/dist/core/schema/index.d.ts +15 -0
- package/dist/core/schema/index.d.ts.map +1 -1
- package/dist/core/schema/query.schema.d.ts +15 -0
- package/dist/core/schema/query.schema.d.ts.map +1 -1
- package/dist/core/schema/query.schema.js +5 -0
- package/dist/core/schema/query.schema.js.map +1 -1
- package/dist/core/schema/templates.d.ts +0 -4
- package/dist/core/schema/templates.d.ts.map +1 -1
- package/dist/core/schema/templates.js +25 -7
- package/dist/core/schema/templates.js.map +1 -1
- package/dist/core/sequencing/analyze.d.ts.map +1 -1
- package/dist/core/sequencing/analyze.js +3 -1
- package/dist/core/sequencing/analyze.js.map +1 -1
- package/dist/core/sequencing/priority-queue.d.ts +9 -3
- package/dist/core/sequencing/priority-queue.d.ts.map +1 -1
- package/dist/core/sequencing/priority-queue.js +10 -4
- package/dist/core/sequencing/priority-queue.js.map +1 -1
- package/dist/core/sequencing/stale-detector.d.ts.map +1 -1
- package/dist/core/sequencing/stale-detector.js +5 -0
- package/dist/core/sequencing/stale-detector.js.map +1 -1
- package/dist/core/workflow/apply/apply.d.ts.map +1 -1
- package/dist/core/workflow/apply/apply.js +429 -25
- package/dist/core/workflow/apply/apply.js.map +1 -1
- package/dist/core/workflow/apply/delta-parser.d.ts.map +1 -1
- package/dist/core/workflow/apply/delta-parser.js +43 -9
- package/dist/core/workflow/apply/delta-parser.js.map +1 -1
- package/dist/core/workflow/apply/feature-updater.d.ts.map +1 -1
- package/dist/core/workflow/apply/feature-updater.js +27 -11
- package/dist/core/workflow/apply/feature-updater.js.map +1 -1
- package/dist/core/workflow/apply/types.d.ts +9 -0
- package/dist/core/workflow/apply/types.d.ts.map +1 -1
- package/dist/core/workflow/continue/continue.d.ts +18 -0
- package/dist/core/workflow/continue/continue.d.ts.map +1 -1
- package/dist/core/workflow/continue/continue.js +134 -15
- package/dist/core/workflow/continue/continue.js.map +1 -1
- package/dist/core/workflow/continue/next-action.d.ts.map +1 -1
- package/dist/core/workflow/continue/next-action.js +16 -3
- package/dist/core/workflow/continue/next-action.js.map +1 -1
- package/dist/core/workflow/continue/types.d.ts +12 -0
- package/dist/core/workflow/continue/types.d.ts.map +1 -1
- package/dist/core/workflow/propose/note-creator.d.ts +2 -2
- package/dist/core/workflow/propose/note-creator.d.ts.map +1 -1
- package/dist/core/workflow/propose/note-creator.js +89 -12
- package/dist/core/workflow/propose/note-creator.js.map +1 -1
- package/dist/core/workflow/propose/propose.d.ts.map +1 -1
- package/dist/core/workflow/propose/propose.js +189 -47
- package/dist/core/workflow/propose/propose.js.map +1 -1
- package/dist/core/workflow/propose/query-normalizer.d.ts.map +1 -1
- package/dist/core/workflow/propose/query-normalizer.js +37 -5
- package/dist/core/workflow/propose/query-normalizer.js.map +1 -1
- package/dist/core/workflow/propose/types.d.ts +15 -0
- package/dist/core/workflow/propose/types.d.ts.map +1 -1
- package/dist/core/workflow/propose/types.js +6 -1
- package/dist/core/workflow/propose/types.js.map +1 -1
- package/dist/core/workflow/query/query-note-creator.js +4 -0
- package/dist/core/workflow/query/query-note-creator.js.map +1 -1
- package/dist/core/workflow/verify/coherence.d.ts +10 -0
- package/dist/core/workflow/verify/coherence.d.ts.map +1 -1
- package/dist/core/workflow/verify/coherence.js +91 -4
- package/dist/core/workflow/verify/coherence.js.map +1 -1
- package/dist/core/workflow/verify/completeness.d.ts +1 -1
- package/dist/core/workflow/verify/completeness.d.ts.map +1 -1
- package/dist/core/workflow/verify/completeness.js +53 -10
- package/dist/core/workflow/verify/completeness.js.map +1 -1
- package/dist/core/workflow/verify/correctness.d.ts +1 -1
- package/dist/core/workflow/verify/correctness.d.ts.map +1 -1
- package/dist/core/workflow/verify/correctness.js +95 -14
- package/dist/core/workflow/verify/correctness.js.map +1 -1
- package/dist/core/workflow/verify/vault-integrity.d.ts +11 -0
- package/dist/core/workflow/verify/vault-integrity.d.ts.map +1 -1
- package/dist/core/workflow/verify/vault-integrity.js +80 -3
- package/dist/core/workflow/verify/vault-integrity.js.map +1 -1
- package/dist/core/workflow/verify/verify.d.ts +0 -5
- package/dist/core/workflow/verify/verify.d.ts.map +1 -1
- package/dist/core/workflow/verify/verify.js +54 -3
- package/dist/core/workflow/verify/verify.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/types/cli-contracts.d.ts +78 -0
- package/dist/types/cli-contracts.d.ts.map +1 -0
- package/dist/types/cli-contracts.js +2 -0
- package/dist/types/cli-contracts.js.map +1 -0
- package/dist/types/error-codes.d.ts +25 -0
- package/dist/types/error-codes.d.ts.map +1 -0
- package/dist/types/error-codes.js +27 -0
- package/dist/types/error-codes.js.map +1 -0
- package/dist/types/frontmatter.d.ts +9 -2
- package/dist/types/frontmatter.d.ts.map +1 -1
- package/dist/types/next-action.d.ts +21 -0
- package/dist/types/next-action.d.ts.map +1 -1
- package/dist/types/retrieval.d.ts +17 -0
- package/dist/types/retrieval.d.ts.map +1 -1
- package/dist/types/verify.d.ts +58 -1
- package/dist/types/verify.d.ts.map +1 -1
- package/dist/types/verify.js +58 -1
- package/dist/types/verify.js.map +1 -1
- package/dist/utils/conventions.d.ts +9 -0
- package/dist/utils/conventions.d.ts.map +1 -0
- package/dist/utils/conventions.js +22 -0
- package/dist/utils/conventions.js.map +1 -0
- package/dist/utils/id-generator.d.ts.map +1 -1
- package/dist/utils/id-generator.js +8 -0
- package/dist/utils/id-generator.js.map +1 -1
- package/dist/utils/normalize.d.ts +7 -4
- package/dist/utils/normalize.d.ts.map +1 -1
- package/dist/utils/normalize.js +43 -6
- package/dist/utils/normalize.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.3.0] - 2026-04-13
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Unified CLI JSON envelope** — all commands now wrap `--json` success output in a common envelope:
|
|
9
|
+
```json
|
|
10
|
+
{ "ok": true, "command": "<name>", "envelope_version": "1", "version": "0.3.0", "data": { ... } }
|
|
11
|
+
```
|
|
12
|
+
Error output keeps the existing `{ "error": true, "code", "message" }` shape (unchanged).
|
|
13
|
+
`ENVELOPE_VERSION` constant is exported from the package for strict consumer pinning.
|
|
14
|
+
- `CliJsonEnvelope<T>` type export for TypeScript consumers of `--json` output.
|
|
15
|
+
- Feature ↔ Change bidirectional backlink verification (`MISSING_LINK` on mismatch).
|
|
16
|
+
- Commit-marker based atomic apply recovery — partial-rename crashes now roll back to a consistent pre-apply state instead of leaving mixed content.
|
|
17
|
+
- Early stale-base detection in `ows continue` — warns before apply when another Change modified the Feature.
|
|
18
|
+
- Korean intent detection in `propose` (수정/삭제/조사 keywords).
|
|
19
|
+
- `semantic_used` field in retrieval results so JSON consumers can detect lexical-only fallback.
|
|
20
|
+
- `classification_reason` field explains why `needs_confirmation` was chosen.
|
|
21
|
+
- Multi-Feature apply hard-fails on any Feature's semantic failure (was silent partial apply).
|
|
22
|
+
- `--force-stale` now records detailed bypass warnings per entry.
|
|
23
|
+
- `continue` exits with code 1 on `blocked` action (CI-friendly).
|
|
24
|
+
- Secret leak check covers AWS ASIA (temp session keys), GCP service account JSON, and generic hardcoded credentials.
|
|
25
|
+
- Embedder singleton-per-model prevents duplicate concurrent model loads.
|
|
26
|
+
- `migrate --allow-existing-vault` flag for explicit opt-in merging.
|
|
27
|
+
- `ows status` human output surfaces `guidance` + `templateHint` and prints a next-command hint.
|
|
28
|
+
- `ows propose` success output shows `Next: ows continue <id>`; `ows apply` shows `Next: ows verify <id>`.
|
|
29
|
+
- Envelope-only `envelope_version: "1"` field for future schema drift detection.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Migrated changes (from OpenSpec) with empty `delta_summary` are now reported as `warning` instead of `error` — fresh migrations pass `ows verify` out of the box; authors still must fill canonical delta_summary before `ows apply`.
|
|
33
|
+
- Migration post-processes Feature ↔ Change backlinks so the first `ows verify` after `ows migrate` passes cleanly.
|
|
34
|
+
- Apply no longer auto-transitions to `applied` when agent markers remain unfilled (safer default; prevents post-hoc `UNFILLED_APPLY_MARKER` after a silent lie).
|
|
35
|
+
- Semantic similarity scores clamped to [0, 1] to prevent bad embeddings from dominating rankings.
|
|
36
|
+
- Control characters (0x00-0x08, 0x0B, 0x0C, 0x0E-0x1F, 0x7F) stripped during normalization to block title/alias spoofing.
|
|
37
|
+
- Locale-independent deterministic sort for duplicate tie-break and list output (uses `Intl.Collator('en', { numeric: true })`).
|
|
38
|
+
- `init --force` preserves user-authored `wiki/00-meta/conventions.md` even on re-init.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- `ows apply` recovery from crashed runs no longer produces mixed pre-/post-apply state.
|
|
42
|
+
- Embedding cache merge-on-save prevents concurrent `propose` runs from dropping each other's entries.
|
|
43
|
+
- CLI EXDEV (cross-device rename) fallback to copy+unlink for Docker bind mounts and NFS.
|
|
44
|
+
- Log.md mutex reclaims locks held by dead PIDs (not just TTL).
|
|
45
|
+
- Apply file-mode preservation on temp writes (read-only vault stays read-only).
|
|
46
|
+
- `--force-target` + `--force-classification new_feature` rejected with clear error.
|
|
47
|
+
- `--confirm` + missing `--force-classification` on `needs_confirmation` rejected with clear error.
|
|
48
|
+
|
|
49
|
+
### Compatibility
|
|
50
|
+
- **JSON consumers**: must now access payload via `.data.*` instead of `.*` at root. Error responses unchanged.
|
|
51
|
+
- **Migration from OpenSpec**: `ows migrate` → `ows verify` produces a passing report out of the box (new behavior).
|
|
52
|
+
|
|
53
|
+
## [0.2.4]
|
|
54
|
+
- Previous release. See git history.
|
package/README.md
CHANGED
|
@@ -200,12 +200,12 @@ ows status
|
|
|
200
200
|
ows verify
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
`ows init` creates the vault structure and generates
|
|
203
|
+
`ows init` creates the vault structure and generates 12 Claude Code skill files (`.claude/commands/ows-*.md`) so you can invoke workflows directly:
|
|
204
204
|
|
|
205
205
|
```
|
|
206
206
|
/ows-propose /ows-continue /ows-apply /ows-verify
|
|
207
207
|
/ows-query /ows-status /ows-retrieve /ows-archive
|
|
208
|
-
/ows-init /ows-migrate
|
|
208
|
+
/ows-init /ows-migrate /ows-explore /ows-onboard
|
|
209
209
|
```
|
|
210
210
|
|
|
211
211
|
### Vault structure
|
|
@@ -235,8 +235,55 @@ wiki/
|
|
|
235
235
|
| `ows status` | Show change state and next action |
|
|
236
236
|
| `ows list` | List active changes |
|
|
237
237
|
| `ows archive` | Archive an applied change |
|
|
238
|
+
| `ows retrieve` | Run standalone retrieval scan (read-only) |
|
|
239
|
+
| `ows bulk-archive` | Archive all applied changes at once |
|
|
238
240
|
| `ows migrate` | Migrate from OpenSpec format |
|
|
239
241
|
|
|
242
|
+
### Versioning policy
|
|
243
|
+
|
|
244
|
+
ows uses two independent version numbers:
|
|
245
|
+
|
|
246
|
+
| Version | What it tracks | Bumped when |
|
|
247
|
+
|---------|----------------|-------------|
|
|
248
|
+
| `package.json` version (e.g., `0.2.4`) | npm release version | Any code change (follow semver) |
|
|
249
|
+
| `CURRENT_SCHEMA_VERSION` in `src/core/index/schema-version.ts` | Vault frontmatter/section schema | Breaking change to required sections, frontmatter fields, or file layout |
|
|
250
|
+
|
|
251
|
+
When a release bumps the schema version, existing vaults must be migrated. Run `ows --version` to see both numbers. `ows verify` emits `UNSUPPORTED_SCHEMA_VERSION` if a vault's schema version is not in `SUPPORTED_SCHEMA_VERSIONS`, and `BREAKING_CHANGE_WITHOUT_VERSION_BUMP` if the compile-time schema shape drifts from `BASELINE_SCHEMA_FINGERPRINT` without a version bump.
|
|
252
|
+
|
|
253
|
+
### Global flags
|
|
254
|
+
|
|
255
|
+
- `--verbose` — Enable verbose logging (sets `OWS_VERBOSE=1` for the child process)
|
|
256
|
+
- `--debug` — Enable debug logging (sets `OWS_DEBUG=1`, implies `--verbose`)
|
|
257
|
+
- `--json` — Output structured JSON (available on most commands)
|
|
258
|
+
|
|
259
|
+
### CLI exit codes
|
|
260
|
+
|
|
261
|
+
ows CLI commands use a consistent exit code policy:
|
|
262
|
+
|
|
263
|
+
| Code | Meaning |
|
|
264
|
+
|------|---------|
|
|
265
|
+
| `0` | Success (or `ows verify` reported no errors; warnings allowed unless `--strict`) |
|
|
266
|
+
| `1` | Runtime error (validation failure, I/O error, domain error) |
|
|
267
|
+
| `2` | Usage error (missing argument, unknown option, invalid flag value — Commander parse error) |
|
|
268
|
+
|
|
269
|
+
`ows verify` specifics:
|
|
270
|
+
- **Without `--strict`**: exit `0` if `error` count is `0`, regardless of warnings.
|
|
271
|
+
- **With `--strict`**: exit `0` only if `error` count AND `warning` count are both `0`.
|
|
272
|
+
- Any runtime error during verification → exit `1`.
|
|
273
|
+
|
|
274
|
+
CI integration: use plain `ows verify` to gate merges on errors only; use `ows verify --strict` to also block on warnings like `POTENTIAL_SECRET_LEAK` or `BREAKING_CHANGE_WITHOUT_VERSION_BUMP`.
|
|
275
|
+
|
|
276
|
+
### Environment variables
|
|
277
|
+
|
|
278
|
+
| Variable | Effect |
|
|
279
|
+
|----------|--------|
|
|
280
|
+
| `OWS_NO_LOG=1` | Skip appending to `wiki/00-meta/log.md` (equivalent to `--no-log` on propose/apply/archive) |
|
|
281
|
+
| `OWS_VERBOSE=1` | Enable verbose logging (same as `--verbose` flag) |
|
|
282
|
+
| `OWS_DEBUG=1` | Enable debug logging (same as `--debug` flag) |
|
|
283
|
+
| `OWS_TEST_OPENSPEC_DIR` | Override OpenSpec source directory in E2E tests |
|
|
284
|
+
|
|
285
|
+
**Precedence**: CLI flags and environment variables are OR'd — either one enables the behavior. Use the CLI flag for per-invocation control and the env var for session-wide defaults.
|
|
286
|
+
|
|
240
287
|
## Migrating from OpenSpec
|
|
241
288
|
|
|
242
289
|
Already using OpenSpec? Migrate in 3 steps:
|
|
@@ -282,7 +329,7 @@ See the full migration guide (available in `docs/migration.md` when building fro
|
|
|
282
329
|
- Installation -- prerequisites, install methods, build from source
|
|
283
330
|
- Getting Started -- step-by-step tutorial
|
|
284
331
|
- Core Concepts -- note types, requirements, delta summary, lifecycle
|
|
285
|
-
- CLI Commands -- all
|
|
332
|
+
- CLI Commands -- all 12 commands + 12 skill files
|
|
286
333
|
- Migration Guide -- OpenSpec to ows conversion
|
|
287
334
|
- Subagent Architecture -- how retrieval works
|
|
288
335
|
- Module Reference:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/apply.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/apply.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0J3D"}
|
|
@@ -3,7 +3,10 @@ import { handleCliError } from "./error-handler.js";
|
|
|
3
3
|
* CLI handler for `ows apply`.
|
|
4
4
|
*/
|
|
5
5
|
import * as path from 'node:path';
|
|
6
|
+
import * as nodeFs from 'node:fs';
|
|
6
7
|
import { discoverVaultPath } from '../vault-discovery.js';
|
|
8
|
+
import { warnOnUnsupportedSchema } from '../schema-check.js';
|
|
9
|
+
import { jsonEnvelope } from '../json-envelope.js';
|
|
7
10
|
import { appendLogEntry } from '../init/meta-files.js';
|
|
8
11
|
export function registerApplyCommand(program) {
|
|
9
12
|
program
|
|
@@ -15,14 +18,52 @@ export function registerApplyCommand(program) {
|
|
|
15
18
|
.option('--no-auto-transition', 'Do not auto-transition to applied when pending agent ops exist')
|
|
16
19
|
.option('--no-log', 'Skip appending to log.md (useful for CI/team workflows)')
|
|
17
20
|
.action(async (changeId, opts) => {
|
|
21
|
+
// Install signal handlers so Ctrl+C leaves a clear message and exits
|
|
22
|
+
// with the expected code. We also make a best-effort attempt to
|
|
23
|
+
// delete the lock file owned by THIS process — without it, the user
|
|
24
|
+
// would see "another apply operation is in progress" until the 5-
|
|
25
|
+
// minute stale TTL expires, which is a terrible interrupted-run
|
|
26
|
+
// experience. The lock stores `pid: process.pid`, and acquireLock's
|
|
27
|
+
// dead-pid recovery handles real races, so deleting only our own
|
|
28
|
+
// lock is safe.
|
|
29
|
+
const interrupt = (sig) => {
|
|
30
|
+
try {
|
|
31
|
+
const vaultPath = discoverVaultPath();
|
|
32
|
+
const lockPath = path.join(vaultPath, 'wiki', '.ows-lock');
|
|
33
|
+
if (nodeFs.existsSync(lockPath)) {
|
|
34
|
+
const content = nodeFs.readFileSync(lockPath, 'utf-8');
|
|
35
|
+
const parsed = JSON.parse(content);
|
|
36
|
+
if (parsed.pid === process.pid) {
|
|
37
|
+
nodeFs.unlinkSync(lockPath);
|
|
38
|
+
process.stderr.write(`\n[ows apply] ${sig} received. Released own lock at ${lockPath}. Next apply will auto-recover backup/temp files.\n`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
process.stderr.write(`\n[ows apply] ${sig} received. Lock belongs to pid ${parsed.pid}, not ours — left in place.\n`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
process.stderr.write(`\n[ows apply] ${sig} received. No lock held.\n`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
process.stderr.write(`\n[ows apply] ${sig} received. Best-effort lock cleanup failed; next apply will auto-recover.\n`);
|
|
50
|
+
}
|
|
51
|
+
process.exit(130);
|
|
52
|
+
};
|
|
53
|
+
process.once('SIGINT', () => interrupt('SIGINT'));
|
|
54
|
+
process.once('SIGTERM', () => interrupt('SIGTERM'));
|
|
18
55
|
try {
|
|
56
|
+
if (!changeId || changeId.trim().length === 0) {
|
|
57
|
+
throw new Error('Change ID cannot be empty. Use `ows list --json` to see active changes.');
|
|
58
|
+
}
|
|
19
59
|
const vaultPath = discoverVaultPath();
|
|
20
60
|
const { buildIndex } = await import('../../core/index/index.js');
|
|
21
61
|
const { parseNote } = await import('../../core/parser/index.js');
|
|
22
62
|
const { applyChange } = await import('../../core/workflow/apply/index.js');
|
|
23
|
-
const { writeFileSync, readFileSync, existsSync, mkdirSync, renameSync, unlinkSync } = await import('node:fs');
|
|
63
|
+
const { writeFileSync, readFileSync, existsSync, mkdirSync, renameSync, unlinkSync, copyFileSync, statSync, chmodSync } = await import('node:fs');
|
|
24
64
|
const { dirname } = await import('node:path');
|
|
25
65
|
const index = await buildIndex(vaultPath);
|
|
66
|
+
warnOnUnsupportedSchema(index);
|
|
26
67
|
const result = applyChange({
|
|
27
68
|
changeId,
|
|
28
69
|
vaultRoot: vaultPath,
|
|
@@ -34,16 +75,47 @@ export function registerApplyCommand(program) {
|
|
|
34
75
|
writeFile: (p, c) => writeFileSync(p, c, 'utf-8'),
|
|
35
76
|
readFile: (p) => readFileSync(p, 'utf-8'),
|
|
36
77
|
fileExists: (p) => existsSync(p),
|
|
37
|
-
|
|
78
|
+
// renameSync fails with EXDEV when `from` and `to` are on
|
|
79
|
+
// different mount points — common under Docker bind mounts,
|
|
80
|
+
// network shares, and /tmp on some Linux distributions. Fall
|
|
81
|
+
// back to copy+unlink so apply stays robust in those envs.
|
|
82
|
+
// The copy path is not atomic, but we already recover via
|
|
83
|
+
// backup files on failure, so a partial copy is no worse than
|
|
84
|
+
// a partial rename in practice.
|
|
85
|
+
moveFile: (from, to) => {
|
|
86
|
+
try {
|
|
87
|
+
renameSync(from, to);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (err.code !== 'EXDEV')
|
|
91
|
+
throw err;
|
|
92
|
+
// Cross-device fallback
|
|
93
|
+
copyFileSync(from, to);
|
|
94
|
+
try {
|
|
95
|
+
unlinkSync(from);
|
|
96
|
+
}
|
|
97
|
+
catch { /* leave stale from; not fatal */ }
|
|
98
|
+
}
|
|
99
|
+
},
|
|
38
100
|
ensureDir: (d) => mkdirSync(d, { recursive: true }),
|
|
39
101
|
deleteFile: (p) => unlinkSync(p),
|
|
102
|
+
// Copy the original Feature file's POSIX mode to the freshly
|
|
103
|
+
// written temp file so the final (post-rename) file inherits
|
|
104
|
+
// the same permissions. If the source doesn't exist (new
|
|
105
|
+
// Feature being created by this apply), silently skip.
|
|
106
|
+
copyFileMode: (source, target) => {
|
|
107
|
+
if (!existsSync(source))
|
|
108
|
+
return;
|
|
109
|
+
const mode = statSync(source).mode & 0o7777;
|
|
110
|
+
chmodSync(target, mode);
|
|
111
|
+
},
|
|
40
112
|
});
|
|
41
113
|
const skipLog = opts.log === false || process.env.OWS_NO_LOG === '1';
|
|
42
114
|
if (result.statusTransitioned && !skipLog) {
|
|
43
115
|
appendLogEntry(path.join(vaultPath, 'wiki'), 'apply', changeId);
|
|
44
116
|
}
|
|
45
117
|
if (opts.json) {
|
|
46
|
-
console.log(
|
|
118
|
+
console.log(jsonEnvelope('apply', result));
|
|
47
119
|
}
|
|
48
120
|
else {
|
|
49
121
|
if (opts.dryRun) {
|
|
@@ -61,15 +133,35 @@ export function registerApplyCommand(program) {
|
|
|
61
133
|
console.log(` Modified: ${f}`);
|
|
62
134
|
}
|
|
63
135
|
}
|
|
136
|
+
// Surface warnings in human output (previously only in JSON)
|
|
137
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
138
|
+
for (const w of result.warnings) {
|
|
139
|
+
console.log(` Warning: ${w}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (result.pendingAgentOps && result.pendingAgentOps.length > 0) {
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(` ${result.pendingAgentOps.length} marker(s) still need content — fill them then re-run apply.`);
|
|
145
|
+
}
|
|
146
|
+
// Lifecycle handoff: guide user to the next step
|
|
147
|
+
if (result.statusTransitioned) {
|
|
148
|
+
console.log(` Next: ows verify ${changeId} && ows archive ${changeId}`);
|
|
149
|
+
}
|
|
64
150
|
}
|
|
65
151
|
else {
|
|
66
152
|
console.log(`Change "${changeId}" could not be applied.`);
|
|
67
153
|
for (const err of result.errors) {
|
|
68
154
|
console.log(` - ${err}`);
|
|
69
155
|
}
|
|
156
|
+
// Surface warnings alongside errors for context
|
|
157
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
158
|
+
for (const w of result.warnings) {
|
|
159
|
+
console.log(` Warning: ${w}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
70
162
|
}
|
|
71
163
|
}
|
|
72
|
-
if (!
|
|
164
|
+
if (!result.success) {
|
|
73
165
|
process.exitCode = 1;
|
|
74
166
|
}
|
|
75
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/cli/commands/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD;;GAEG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SACzC,MAAM,CAAC,WAAW,EAAE,0BAA0B,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,yCAAyC,CAAC;SAClE,MAAM,CAAC,sBAAsB,EAAE,gEAAgE,CAAC;SAChG,MAAM,CAAC,UAAU,EAAE,yDAAyD,CAAC;SAC7E,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,IAAyG,EAAE,EAAE;QAC5I,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;YACtC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;YACjE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;YACjE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oCAAoC,CAAC,CAAC;YAC3E,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/cli/commands/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/archive.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAKvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C,aAAa,
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/archive.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAKvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C,aAAa,CAqEf;AAGD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,WAAW,EAAE,OAAO,GAAG,IAAI,CAqCjF"}
|
|
@@ -16,16 +16,27 @@ export function archiveChange(changeId, index, vaultPath, options) {
|
|
|
16
16
|
if (!change) {
|
|
17
17
|
throw new Error(`Change "${changeId}" not found in the vault index.`);
|
|
18
18
|
}
|
|
19
|
+
// Prevent re-archiving: refuse if the change is already in 99-archive/
|
|
20
|
+
if (change.path.startsWith('wiki/99-archive/')) {
|
|
21
|
+
throw new Error(`Change "${changeId}" is already archived at "${change.path}". ` +
|
|
22
|
+
`Archiving again would be a no-op.`);
|
|
23
|
+
}
|
|
24
|
+
const warnings = [];
|
|
19
25
|
if (change.status !== 'applied') {
|
|
20
|
-
|
|
26
|
+
if (!options?.force) {
|
|
27
|
+
throw new Error(`Only applied changes can be archived. "${changeId}" has status "${change.status}". ` +
|
|
28
|
+
`Use --force to archive a non-applied change.`);
|
|
29
|
+
}
|
|
30
|
+
warnings.push(`Archived with status "${change.status}" (not applied). Use with caution.`);
|
|
21
31
|
}
|
|
22
32
|
// Run verify to confirm cleanly applied
|
|
23
33
|
const verifyResult = verify(index, { changeId });
|
|
24
|
-
const warnings = [];
|
|
25
34
|
if (!verifyResult.pass) {
|
|
26
35
|
if (!options?.force) {
|
|
27
|
-
const
|
|
28
|
-
|
|
36
|
+
const errorIssues = verifyResult.issues.filter((i) => i.severity === 'error');
|
|
37
|
+
const top3 = errorIssues.slice(0, 3).map((i) => ` - [${i.code}] ${i.message}`).join('\n');
|
|
38
|
+
const more = errorIssues.length > 3 ? `\n ... and ${errorIssues.length - 3} more` : '';
|
|
39
|
+
throw new Error(`Verify found ${errorIssues.length} error(s) for change "${changeId}":\n${top3}${more}\n\nFix the issues above or use --force to archive anyway.`);
|
|
29
40
|
}
|
|
30
41
|
warnings.push(`Archived despite ${verifyResult.issues.length} verify issue(s).`);
|
|
31
42
|
}
|
|
@@ -68,12 +79,15 @@ export function registerArchiveCommand(program) {
|
|
|
68
79
|
try {
|
|
69
80
|
const { discoverVaultPath } = await import('../vault-discovery.js');
|
|
70
81
|
const { buildIndex } = await import('../../core/index/index.js');
|
|
82
|
+
const { warnOnUnsupportedSchema } = await import('../schema-check.js');
|
|
83
|
+
const { jsonEnvelope } = await import('../json-envelope.js');
|
|
71
84
|
const vaultPath = discoverVaultPath();
|
|
72
85
|
const index = await buildIndex(vaultPath);
|
|
86
|
+
warnOnUnsupportedSchema(index);
|
|
73
87
|
const noLog = opts.log === false || process.env.OWS_NO_LOG === '1';
|
|
74
88
|
const result = archiveChange(changeId, index, vaultPath, { force: opts.force, noLog });
|
|
75
89
|
if (opts.json) {
|
|
76
|
-
console.log(
|
|
90
|
+
console.log(jsonEnvelope('archive', result));
|
|
77
91
|
}
|
|
78
92
|
else {
|
|
79
93
|
console.log(`Archived change "${changeId}"`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/cli/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAU/D;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,KAAiB,EACjB,SAAiB,EACjB,OAA8C;IAE9C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,iCAAiC,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/cli/commands/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `ows bulk-archive`.
|
|
3
|
+
* Archives all applied Changes at once.
|
|
4
|
+
*/
|
|
5
|
+
import type { Command } from 'commander';
|
|
6
|
+
import type { ArchiveResult } from './archive.js';
|
|
7
|
+
export interface BulkArchiveResult {
|
|
8
|
+
archived: ArchiveResult[];
|
|
9
|
+
skipped: {
|
|
10
|
+
changeId: string;
|
|
11
|
+
reason: string;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
export declare function registerBulkArchiveCommand(program: Command): void;
|
|
15
|
+
//# sourceMappingURL=bulk-archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-archive.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/bulk-archive.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmGjE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { handleCliError } from "./error-handler.js";
|
|
2
|
+
import { archiveChange } from './archive.js';
|
|
3
|
+
import { jsonEnvelope } from '../json-envelope.js';
|
|
4
|
+
export function registerBulkArchiveCommand(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('bulk-archive')
|
|
7
|
+
.description('Archive all applied Changes at once')
|
|
8
|
+
.option('--json', 'Output result as JSON')
|
|
9
|
+
.option('--force', 'Archive even if verify finds errors')
|
|
10
|
+
.option('--no-log', 'Skip appending to log.md')
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
try {
|
|
13
|
+
const { discoverVaultPath } = await import('../vault-discovery.js');
|
|
14
|
+
const { buildIndex } = await import('../../core/index/index.js');
|
|
15
|
+
const { warnOnUnsupportedSchema } = await import('../schema-check.js');
|
|
16
|
+
const fs = await import('node:fs');
|
|
17
|
+
const pathMod = await import('node:path');
|
|
18
|
+
const vaultPath = discoverVaultPath();
|
|
19
|
+
// Lock awareness: refuse to bulk-archive while an `ows apply` is
|
|
20
|
+
// in progress. bulk-archive walks every applied Change and
|
|
21
|
+
// physically renames files; if apply is mid-write those files
|
|
22
|
+
// can be in temp/backup names and we'd move half-written state
|
|
23
|
+
// into 99-archive/. The apply lock's stale-TTL check still
|
|
24
|
+
// handles crashed writers — we only block live ones.
|
|
25
|
+
const lockPath = pathMod.join(vaultPath, 'wiki', '.ows-lock');
|
|
26
|
+
if (fs.existsSync(lockPath)) {
|
|
27
|
+
throw new Error(`Cannot bulk-archive while another process holds ${lockPath}. ` +
|
|
28
|
+
'Another `ows apply` may be in progress. Wait for it to finish or ' +
|
|
29
|
+
'delete the lock file if you have confirmed the apply crashed.');
|
|
30
|
+
}
|
|
31
|
+
let index = await buildIndex(vaultPath);
|
|
32
|
+
warnOnUnsupportedSchema(index);
|
|
33
|
+
const noLog = opts.log === false || process.env.OWS_NO_LOG === '1';
|
|
34
|
+
// Find all applied changes
|
|
35
|
+
const appliedChanges = [];
|
|
36
|
+
for (const [id, record] of index.records) {
|
|
37
|
+
if (record.type === 'change' && record.status === 'applied') {
|
|
38
|
+
appliedChanges.push(id);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (appliedChanges.length === 0) {
|
|
42
|
+
if (opts.json) {
|
|
43
|
+
console.log(jsonEnvelope('bulk-archive', { archived: [], skipped: [] }));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.log('No applied changes to archive.');
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const result = { archived: [], skipped: [] };
|
|
51
|
+
for (const changeId of appliedChanges) {
|
|
52
|
+
try {
|
|
53
|
+
const archiveResult = archiveChange(changeId, index, vaultPath, {
|
|
54
|
+
force: opts.force,
|
|
55
|
+
noLog,
|
|
56
|
+
});
|
|
57
|
+
result.archived.push(archiveResult);
|
|
58
|
+
// Rebuild index so subsequent iterations see the archived state.
|
|
59
|
+
// Prevents stale-index issues (e.g., re-archiving the same change,
|
|
60
|
+
// or verify picking up a now-moved file).
|
|
61
|
+
index = await buildIndex(vaultPath);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
result.skipped.push({
|
|
65
|
+
changeId,
|
|
66
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (opts.json) {
|
|
71
|
+
console.log(jsonEnvelope('bulk-archive', result));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (result.archived.length > 0) {
|
|
75
|
+
console.log(`Archived ${result.archived.length} change(s):`);
|
|
76
|
+
for (const a of result.archived) {
|
|
77
|
+
console.log(` ${a.changeId}: ${a.oldPath} → ${a.newPath}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (result.skipped.length > 0) {
|
|
81
|
+
console.log(`\nSkipped ${result.skipped.length} change(s):`);
|
|
82
|
+
for (const s of result.skipped) {
|
|
83
|
+
console.log(` ${s.changeId}: ${s.reason}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Exit with non-zero if any changes were skipped
|
|
88
|
+
if (result.skipped.length > 0) {
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
handleCliError(err, opts.json);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=bulk-archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-archive.js","sourceRoot":"","sources":["../../../src/cli/commands/bulk-archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continue.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/continue.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"continue.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/continue.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgD9D"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { handleCliError } from "./error-handler.js";
|
|
2
2
|
import { discoverVaultPath } from '../vault-discovery.js';
|
|
3
|
+
import { warnOnUnsupportedSchema } from '../schema-check.js';
|
|
4
|
+
import { jsonEnvelope } from '../json-envelope.js';
|
|
3
5
|
export function registerContinueCommand(program) {
|
|
4
6
|
program
|
|
5
7
|
.command('continue [changeId]')
|
|
@@ -13,23 +15,34 @@ export function registerContinueCommand(program) {
|
|
|
13
15
|
const { analyzeSequencing } = await import('../../core/sequencing/index.js');
|
|
14
16
|
const { parseNote } = await import('../../core/parser/index.js');
|
|
15
17
|
const { continueChange } = await import('../../core/workflow/continue/index.js');
|
|
16
|
-
const { writeFileSync, readFileSync } = await import('node:fs');
|
|
18
|
+
const { writeFileSync, readFileSync, renameSync, unlinkSync } = await import('node:fs');
|
|
17
19
|
const index = await buildIndex(vaultPath);
|
|
20
|
+
warnOnUnsupportedSchema(index);
|
|
18
21
|
const result = continueChange(index, {
|
|
19
22
|
analyzeSequencing,
|
|
20
23
|
parseNote,
|
|
21
24
|
writeFile: (p, c) => writeFileSync(p, c, 'utf-8'),
|
|
22
25
|
readFile: (p) => readFileSync(p, 'utf-8'),
|
|
26
|
+
renameFile: (from, to) => renameSync(from, to),
|
|
27
|
+
deleteFile: (p) => unlinkSync(p),
|
|
23
28
|
}, {
|
|
24
29
|
...(changeId ? { changeName: changeId } : {}),
|
|
25
30
|
...(opts.dryRun ? { dryRun: true } : {}),
|
|
26
31
|
});
|
|
27
32
|
if (opts.json) {
|
|
28
|
-
console.log(
|
|
33
|
+
console.log(jsonEnvelope('continue', result));
|
|
29
34
|
}
|
|
30
35
|
else {
|
|
31
36
|
console.log(result.summary);
|
|
32
37
|
}
|
|
38
|
+
// Exit code policy: mirror propose's `asked_user → 1` pattern.
|
|
39
|
+
// A `blocked` action means the change can't proceed without
|
|
40
|
+
// external resolution (unresolved depends_on). CI pipelines
|
|
41
|
+
// that run `ows continue` as a gate need exitCode=1 to detect
|
|
42
|
+
// this — otherwise a blocked change silently looks like success.
|
|
43
|
+
if (result.nextAction.action === 'blocked') {
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
33
46
|
}
|
|
34
47
|
catch (err) {
|
|
35
48
|
handleCliError(err, opts.json);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continue.js","sourceRoot":"","sources":["../../../src/cli/commands/continue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"continue.js","sourceRoot":"","sources":["../../../src/cli/commands/continue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,qBAAqB,CAAC;SAC9B,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SACzC,MAAM,CAAC,WAAW,EAAE,mDAAmD,CAAC;SACxE,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,IAA0C,EAAE,EAAE;QACzF,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;YACtC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;YACjE,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;YAC7E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;YACjE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,uCAAuC,CAAC,CAAC;YACjF,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YAExF,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;YAC1C,uBAAuB,CAAC,KAAK,CAAC,CAAC;YAE/B,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE;gBACnC,iBAAiB;gBACjB,SAAS;gBACT,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;gBACjD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;gBACzC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC9C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;aACjC,EAAE;gBACD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzC,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAED,+DAA+D;YAC/D,4DAA4D;YAC5D,4DAA4D;YAC5D,8DAA8D;YAC9D,iEAAiE;YACjE,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC3C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Common CLI error handler.
|
|
3
|
-
* Outputs JSON error when --json is set, plaintext otherwise.
|
|
4
|
-
*/
|
|
5
|
-
export declare function handleCliError(err: unknown, json?: boolean): void;
|
|
1
|
+
export declare function handleCliError(err: unknown, json?: boolean, code?: string): void;
|
|
6
2
|
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/error-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/error-handler.ts"],"names":[],"mappings":"AASA,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,GAAE,MAAkC,GAAG,IAAI,CAiD3G"}
|