@opum-ai/lore 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -22
- package/bin/lore.cjs +35 -7
- package/package.json +17 -17
- package/src/adapters/backlog.ts +0 -1084
- package/src/adapters/git.ts +0 -221
- package/src/cli.ts +0 -667
- package/src/commands/agent.ts +0 -301
- package/src/commands/agents.ts +0 -302
- package/src/commands/args.ts +0 -209
- package/src/commands/changed.ts +0 -70
- package/src/commands/check.ts +0 -1031
- package/src/commands/codex-bridge.ts +0 -49
- package/src/commands/concurrency.ts +0 -48
- package/src/commands/context.ts +0 -292
- package/src/commands/discover.ts +0 -89
- package/src/commands/explorer.ts +0 -253
- package/src/commands/export.ts +0 -93
- package/src/commands/fswrite.ts +0 -928
- package/src/commands/graph.ts +0 -291
- package/src/commands/help.ts +0 -151
- package/src/commands/impact.ts +0 -59
- package/src/commands/init.ts +0 -583
- package/src/commands/instructions.ts +0 -91
- package/src/commands/link.ts +0 -929
- package/src/commands/new.ts +0 -476
- package/src/commands/orphans.ts +0 -457
- package/src/commands/path.ts +0 -67
- package/src/commands/provenance.ts +0 -68
- package/src/commands/query.ts +0 -312
- package/src/commands/reconcile-shared.ts +0 -280
- package/src/commands/rename.ts +0 -585
- package/src/commands/replace.ts +0 -320
- package/src/commands/scaffold.ts +0 -346
- package/src/commands/schema.ts +0 -293
- package/src/commands/snapshot.ts +0 -130
- package/src/commands/supersede.ts +0 -400
- package/src/commands/sync.ts +0 -371
- package/src/commands/tasks.ts +0 -271
- package/src/commands/traversal.ts +0 -151
- package/src/commands/validate.ts +0 -226
- package/src/config.ts +0 -598
- package/src/core/agent-bridge.ts +0 -287
- package/src/core/agent-context.ts +0 -498
- package/src/core/agent-profile.ts +0 -447
- package/src/core/bundle.ts +0 -893
- package/src/core/check.ts +0 -853
- package/src/core/codex-bridge.ts +0 -100
- package/src/core/concept.ts +0 -597
- package/src/core/consumer-scaffold.ts +0 -433
- package/src/core/context.ts +0 -271
- package/src/core/explorer-contract.ts +0 -441
- package/src/core/explorer-qualification.ts +0 -58
- package/src/core/explorer.ts +0 -518
- package/src/core/finding.ts +0 -31
- package/src/core/graph.ts +0 -201
- package/src/core/indexes.ts +0 -436
- package/src/core/instructions.ts +0 -209
- package/src/core/ladybug-driver.ts +0 -1795
- package/src/core/ladybug-lifecycle.ts +0 -1178
- package/src/core/ladybug-native.ts +0 -95
- package/src/core/ladybug-source.ts +0 -667
- package/src/core/links.ts +0 -681
- package/src/core/log.ts +0 -253
- package/src/core/managed-block.ts +0 -540
- package/src/core/manifest.ts +0 -718
- package/src/core/order.ts +0 -13
- package/src/core/profile.ts +0 -1007
- package/src/core/projection.ts +0 -195
- package/src/core/query.ts +0 -542
- package/src/core/reconcile.ts +0 -236
- package/src/core/replace.ts +0 -419
- package/src/core/retrieval.ts +0 -213
- package/src/core/rewrite.ts +0 -940
- package/src/core/scaffold.ts +0 -255
- package/src/core/schema.ts +0 -366
- package/src/core/snapshot-runtime.ts +0 -52
- package/src/core/snapshot-store.ts +0 -287
- package/src/core/snapshot.ts +0 -711
- package/src/core/template.ts +0 -429
- package/src/core/traversal.ts +0 -487
- package/src/core/validate.ts +0 -517
- package/src/core/workspace-contract.ts +0 -473
- package/src/core/workspace-projection.ts +0 -365
- package/src/core/workspace-retrieval.ts +0 -196
- package/src/core/workspace-source.ts +0 -174
- package/src/errors.ts +0 -697
- package/src/meta.ts +0 -7
- package/src/output.ts +0 -589
- package/src/scripts/upstream-backlog-watch.ts +0 -288
- package/src/state.ts +0 -390
package/src/core/manifest.ts
DELETED
|
@@ -1,718 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* core/manifest.ts — the machine-readable capability manifest `lore help --json`
|
|
3
|
-
* serves (cli-surface §help; cli-contract §2/§7).
|
|
4
|
-
*
|
|
5
|
-
* A single, self-contained registry describing every **shipped** command — its
|
|
6
|
-
* name, one-line summary, positional signature, flags, `--json` availability,
|
|
7
|
-
* success envelope `kind`, the exit codes it can return, and runnable examples —
|
|
8
|
-
* so an agent learns the whole CLI surface in one read instead of parsing prose.
|
|
9
|
-
* Content is code-resident and root-independent (no bundle load, no config), so
|
|
10
|
-
* the command layer needs no `root`.
|
|
11
|
-
*
|
|
12
|
-
* ## Exit codes are DERIVED from seams, not hand-listed
|
|
13
|
-
*
|
|
14
|
-
* `lore`'s exit codes are produced by a handful of shared "seam" helpers, and a
|
|
15
|
-
* command inherits the full code set of every seam its `runX` call chain reaches
|
|
16
|
-
* (verified against the real call chains — hand-listing per command drifted).
|
|
17
|
-
* Each command therefore declares the seams it touches and its codes are computed
|
|
18
|
-
* by {@link exitCodesFor} from one authoritative seam → code map ({@link SEAM_CODES}):
|
|
19
|
-
*
|
|
20
|
-
* - `bundle` (loadBundle) → 3 not_found, 4 denied, 6 validation
|
|
21
|
-
* - `read` (readSource / path stat) → 3 not_found, 4 denied
|
|
22
|
-
* - `profile` (loadProfile) → 6 validation (malformed profile)
|
|
23
|
-
* - `write` (fswrite: ensureDir/create/…) → 4 denied, 5 conflict
|
|
24
|
-
* - `backlog` (the Backlog adapter) → 3 not_found, 6 validation/drift
|
|
25
|
-
* - `git` (git log / commit seams) → 6 drift
|
|
26
|
-
*
|
|
27
|
-
* plus `0` (success) and the universal `2` (usage, from Commander parsing)
|
|
28
|
-
* on every command, and any command-specific `extra` code that is the command's own
|
|
29
|
-
* logic rather than an I/O seam — a `not_found` for an unknown `instructions` topic,
|
|
30
|
-
* or a gate/validation return (`validate`/`check`/`new`/`agents` all pass their
|
|
31
|
-
* principal `6` as `extra` so it survives a seam refactor, not left to a coincidental
|
|
32
|
-
* seam `6`). `1`
|
|
33
|
-
* (uncaught) is a global-only condition (cli-contract §5.1) and is never listed
|
|
34
|
-
* per command; the full taxonomy is in {@link Manifest.exitCodes}, sourced from
|
|
35
|
-
* `errors.ts` so it cannot drift. `test/help.test.ts` pins each command's derived
|
|
36
|
-
* `exitCodes` to a golden list transcribed from the call-chain trace, so a seam
|
|
37
|
-
* mis-declaration fails CI.
|
|
38
|
-
*
|
|
39
|
-
* The name+summary pairs are kept byte-identical to `core/agent-bridge.ts`'s
|
|
40
|
-
* `LORE_COMMANDS` (which the generated SKILL.md uses) — guarded by a test, not a
|
|
41
|
-
* runtime import, so the two agent catalogs can't drift while the live CLI stays
|
|
42
|
-
* decoupled from the SKILL generator. `--json` availability is universal, carried
|
|
43
|
-
* per entry so a single entry is self-describing. Every entry is a real `cli.ts`
|
|
44
|
-
* handler (never an aspirational `scaffold`), pinned to the handler registry
|
|
45
|
-
* in both directions by the lockstep test.
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
import { EXIT_CODES, EXIT_OK, EXIT_UNCAUGHT } from "../errors";
|
|
49
|
-
import { SCHEMA_VERSION } from "../output";
|
|
50
|
-
|
|
51
|
-
/** One flag in the manifest: the bare name (no leading `--`), whether it takes a value, and a one-liner. */
|
|
52
|
-
export interface ManifestFlag {
|
|
53
|
-
/** The flag name without the leading `--` (e.g. `dry-run`). */
|
|
54
|
-
readonly name: string;
|
|
55
|
-
/** A short alias without the leading `-` (e.g. `v` for `--version`), when the flag has one. */
|
|
56
|
-
readonly alias?: string;
|
|
57
|
-
/** Whether the flag consumes a following value (`--type <T>`) vs. a boolean switch (`--strict`). */
|
|
58
|
-
readonly takesValue: boolean;
|
|
59
|
-
/** Whether the flag may be repeated to accumulate values (`--tag a --tag b`). */
|
|
60
|
-
readonly repeatable?: boolean;
|
|
61
|
-
/** One-line description of what the flag does. */
|
|
62
|
-
readonly summary: string;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** One command in the manifest: everything an agent needs to invoke it correctly. */
|
|
66
|
-
export interface ManifestCommand {
|
|
67
|
-
/** The subcommand token, exactly as Commander and `cli.ts` dispatch it. */
|
|
68
|
-
readonly name: string;
|
|
69
|
-
/** One-line description of what the command does (kept in sync with `LORE_COMMANDS`). */
|
|
70
|
-
readonly summary: string;
|
|
71
|
-
/** The positional-argument signature (e.g. `<id> <taskId…>`), or `""` when the command takes none. */
|
|
72
|
-
readonly args: string;
|
|
73
|
-
/** The command's own flags (global `--json`/`--plain` are in {@link Manifest.globalFlags}, not repeated here). */
|
|
74
|
-
readonly flags: readonly ManifestFlag[];
|
|
75
|
-
/** Whether the command supports the `--json` envelope. Universal today, carried per command so an entry is self-describing. */
|
|
76
|
-
readonly json: boolean;
|
|
77
|
-
/** The `kind` of the command's `--json` success envelope (cli-contract §2.1), matching the live `kind:` literal. */
|
|
78
|
-
readonly kind: string;
|
|
79
|
-
/** The exit codes this command can return, derived from its seams (see the module docstring); `1` (uncaught) is global-only. */
|
|
80
|
-
readonly exitCodes: readonly number[];
|
|
81
|
-
/** One or more runnable invocations. */
|
|
82
|
-
readonly examples: readonly string[];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** The whole capability manifest: the contract version, the global exit-code taxonomy, the global flags, and every command. */
|
|
86
|
-
export interface Manifest {
|
|
87
|
-
/** The `--json` envelope/contract version (cli-contract §7); shared with every success envelope. */
|
|
88
|
-
readonly schemaVersion: number;
|
|
89
|
-
/** The semantic exit-code taxonomy: name → code, sourced from `errors.ts` so it cannot drift. */
|
|
90
|
-
readonly exitCodes: Readonly<Record<string, number>>;
|
|
91
|
-
/** The flags accepted in supported positions on every command (resolved by Commander, not the handler). */
|
|
92
|
-
readonly globalFlags: readonly ManifestFlag[];
|
|
93
|
-
/** Every shipped command, in `cli.ts` handler-registry order. */
|
|
94
|
-
readonly commands: readonly ManifestCommand[];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** A shared error "seam" a command's call chain can reach; each maps to a fixed set of exit codes. */
|
|
98
|
-
type Seam = "bundle" | "read" | "profile" | "write" | "backlog" | "git";
|
|
99
|
-
|
|
100
|
-
/** The non-zero exit codes each seam can produce (verified against the real call chains; see the module docstring). */
|
|
101
|
-
const SEAM_CODES: Readonly<Record<Seam, readonly number[]>> = {
|
|
102
|
-
bundle: [3, 4, 6], // loadBundle: not_found/denied (unreadable root), validation (malformed concept)
|
|
103
|
-
read: [3, 4], // readSource / path stat: not_found, denied
|
|
104
|
-
profile: [6], // loadProfile: validation (malformed .lore/profile.toml)
|
|
105
|
-
write: [4, 5], // fswrite: denied (EACCES/EPERM), conflict (EEXIST/ENOTDIR/EISDIR)
|
|
106
|
-
backlog: [3, 6], // Backlog adapter: not_found (binary/task missing), validation/drift
|
|
107
|
-
git: [6], // git log / commit seams: drift
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Derive a command's sorted exit-code set from the seams it reaches: `0` (success)
|
|
112
|
-
* and `2` (usage) are universal, each seam contributes {@link SEAM_CODES}, and
|
|
113
|
-
* `extra` carries any command-specific code that reaches no filesystem seam.
|
|
114
|
-
*/
|
|
115
|
-
function exitCodesFor(seams: readonly Seam[], extra: readonly number[] = []): readonly number[] {
|
|
116
|
-
const codes = new Set<number>([EXIT_OK, EXIT_CODES.usage, ...extra]);
|
|
117
|
-
for (const seam of seams) {
|
|
118
|
-
for (const code of SEAM_CODES[seam]) {
|
|
119
|
-
codes.add(code);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return [...codes].sort((a, b) => a - b);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Recursively `Object.freeze`s an array/object graph — the container itself plus
|
|
127
|
-
* every nested array/object it holds — so no level of the structure can be
|
|
128
|
-
* mutated after construction (a mutation attempt throws in strict-mode JS/TS,
|
|
129
|
-
* the module default, instead of silently corrupting the shared singleton).
|
|
130
|
-
* Mirrors the codebase's own `Object.freeze` convention (YAML_LOAD_OPTIONS /
|
|
131
|
-
* YAML_DUMP_OPTIONS in core/concept.ts, L124/L138) extended to nested structures,
|
|
132
|
-
* since the manifest's `readonly` TS modifiers are compile-time-only and don't
|
|
133
|
-
* stop an `as any`/plain-JS caller from mutating the singleton in place.
|
|
134
|
-
*/
|
|
135
|
-
function deepFreeze<T>(value: T): T {
|
|
136
|
-
if (Array.isArray(value)) {
|
|
137
|
-
for (const item of value) {
|
|
138
|
-
deepFreeze(item);
|
|
139
|
-
}
|
|
140
|
-
return Object.freeze(value) as T;
|
|
141
|
-
}
|
|
142
|
-
if (value !== null && typeof value === "object") {
|
|
143
|
-
for (const key of Object.keys(value)) {
|
|
144
|
-
deepFreeze((value as Record<string, unknown>)[key]);
|
|
145
|
-
}
|
|
146
|
-
return Object.freeze(value) as T;
|
|
147
|
-
}
|
|
148
|
-
return value;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** The four global flags Commander resolves for every invocation (cli-contract §1). */
|
|
152
|
-
const GLOBAL_FLAGS: readonly ManifestFlag[] = deepFreeze([
|
|
153
|
-
{
|
|
154
|
-
name: "json",
|
|
155
|
-
takesValue: false,
|
|
156
|
-
summary: "Machine-readable JSON output (the {schemaVersion, kind, data} envelope)",
|
|
157
|
-
},
|
|
158
|
-
{ name: "plain", takesValue: false, summary: "ANSI-free text output (auto-selected when stdout is piped)" },
|
|
159
|
-
{ name: "version", alias: "v", takesValue: false, summary: "Print the version and exit" },
|
|
160
|
-
{ name: "help", alias: "h", takesValue: false, summary: "Show help and exit" },
|
|
161
|
-
]);
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Every shipped command, in `cli.ts` handler-registry order. Flags, `kind` values, and the
|
|
165
|
-
* seam declarations behind `exitCodes` are transcribed from live source
|
|
166
|
-
* (`commands/*.ts` call chains and `kind:` literals); summaries are kept identical
|
|
167
|
-
* to `LORE_COMMANDS` (guarded by a test). The seam list passed to
|
|
168
|
-
* {@link exitCodesFor} is the exit-code rationale — no hand-listed code needs a comment.
|
|
169
|
-
*/
|
|
170
|
-
const LORE_MANIFEST: readonly ManifestCommand[] = deepFreeze([
|
|
171
|
-
{
|
|
172
|
-
name: "init",
|
|
173
|
-
summary: "Scaffold an OKF bundle; a bare TTY run also wizards the agent bridge/scaffolds/backlog check",
|
|
174
|
-
args: "",
|
|
175
|
-
flags: [
|
|
176
|
-
{
|
|
177
|
-
name: "yes",
|
|
178
|
-
takesValue: false,
|
|
179
|
-
summary: "Skip the interactive wizard even on a TTY; use flag defaults (alias: --non-interactive)",
|
|
180
|
-
},
|
|
181
|
-
{ name: "non-interactive", takesValue: false, summary: "Alias for --yes" },
|
|
182
|
-
{ name: "agents", takesValue: false, summary: "Alias for --claude" },
|
|
183
|
-
{ name: "claude", takesValue: false, summary: "Set up the Claude Code bridge (SKILL.md + CLAUDE.md)" },
|
|
184
|
-
{ name: "codex", takesValue: false, summary: "Set up the Codex bridge (SKILL.md + AGENTS.md)" },
|
|
185
|
-
{
|
|
186
|
-
name: "scaffold",
|
|
187
|
-
takesValue: true,
|
|
188
|
-
repeatable: true,
|
|
189
|
-
summary: "Also scaffold a downstream doc consumer (mkdocs|docusaurus|obsidian)",
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
name: "obsidian",
|
|
193
|
-
takesValue: false,
|
|
194
|
-
summary: "Also scaffold an Obsidian vault config (shorthand for --scaffold obsidian)",
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
name: "check-backlog",
|
|
198
|
-
takesValue: false,
|
|
199
|
-
summary: "Check --json-capable backlog coupling even with no other flag",
|
|
200
|
-
},
|
|
201
|
-
{ name: "no-backlog", takesValue: false, summary: "Skip the backlog-coupling capability check entirely" },
|
|
202
|
-
],
|
|
203
|
-
json: true,
|
|
204
|
-
kind: "init",
|
|
205
|
-
// The backlog-coupling check is ADVISORY ONLY (LORE-260): a missing/incapable `backlog` becomes
|
|
206
|
-
// a stderr warning plus a `backlog: {capable: false}` field, never a thrown error — so no
|
|
207
|
-
// `backlog` seam code is added here despite `runInit` calling `adapter.probe()`.
|
|
208
|
-
exitCodes: exitCodesFor(["profile", "write"]),
|
|
209
|
-
examples: ["lore init", "lore init --claude --codex", "lore init --yes --scaffold mkdocs"],
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
name: "new",
|
|
213
|
-
summary: "Scaffold a typed concept from a template",
|
|
214
|
-
args: '<type> "<title>"',
|
|
215
|
-
flags: [
|
|
216
|
-
{ name: "var", takesValue: true, repeatable: true, summary: "Fill a `{{k}}` template placeholder (k=v)" },
|
|
217
|
-
{ name: "template", takesValue: true, summary: "Template name under .lore/templates/" },
|
|
218
|
-
{ name: "summary", takesValue: true, summary: "One-sentence concept summary" },
|
|
219
|
-
{ name: "tags", takesValue: true, summary: "Comma-separated frontmatter tags" },
|
|
220
|
-
{ name: "out", takesValue: true, summary: "Override the output path" },
|
|
221
|
-
],
|
|
222
|
-
json: true,
|
|
223
|
-
kind: "new",
|
|
224
|
-
// extra 6 = an unfilled template placeholder / serialize-time validation (template.ts:263) —
|
|
225
|
-
// new's own validation, modeled explicitly rather than left to the coincidental profile 6.
|
|
226
|
-
exitCodes: exitCodesFor(["profile", "read", "write"], [6]),
|
|
227
|
-
examples: [
|
|
228
|
-
'lore new story "Bulk archive completed orders"',
|
|
229
|
-
'lore new adr "Use soft deletes" --tags retention,orders',
|
|
230
|
-
],
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: "validate",
|
|
234
|
-
summary: "Check concept files against OKF + the lore profile (per-file)",
|
|
235
|
-
args: "[paths…]",
|
|
236
|
-
flags: [
|
|
237
|
-
{ name: "type", takesValue: true, summary: "Limit the report to one concept type" },
|
|
238
|
-
{ name: "strict", takesValue: false, summary: "Treat warnings as errors for the exit code" },
|
|
239
|
-
],
|
|
240
|
-
json: true,
|
|
241
|
-
kind: "validate.report",
|
|
242
|
-
// extra 6 = the validation gate RETURN (validate.ts:81) — validate's principal failure, modeled
|
|
243
|
-
// explicitly so it survives a profile-seam refactor; a malformed profile also throws 6.
|
|
244
|
-
exitCodes: exitCodesFor(["profile", "read"], [6]),
|
|
245
|
-
examples: ["lore validate", "lore validate --type ADR --strict"],
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
name: "check",
|
|
249
|
-
summary: "Validate links/anchors + reconciliation drift across the bundle (CI gate)",
|
|
250
|
-
args: "[paths…]",
|
|
251
|
-
flags: [
|
|
252
|
-
{ name: "strict", takesValue: false, summary: "Treat portability warnings as failures for the exit code" },
|
|
253
|
-
{ name: "external", takesValue: false, summary: "Also probe external-URL liveness (advisory; never gates)" },
|
|
254
|
-
],
|
|
255
|
-
json: true,
|
|
256
|
-
kind: "check.report",
|
|
257
|
-
// extra 6 = the drift/link gate RETURN (check.ts:258) — check's principal failure, modeled
|
|
258
|
-
// explicitly rather than left to the coincidental adapter 6.
|
|
259
|
-
exitCodes: exitCodesFor(["read", "backlog"], [6]),
|
|
260
|
-
examples: ["lore check", "lore check --external"],
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
name: "replace",
|
|
264
|
-
summary: "Find-and-replace across the bundle, skipping managed regions",
|
|
265
|
-
args: '"<find>" "<replace>"',
|
|
266
|
-
flags: [
|
|
267
|
-
{ name: "regex", takesValue: false, summary: "Treat <find> as a regular expression" },
|
|
268
|
-
{ name: "in", takesValue: true, repeatable: true, summary: "Scope to a glob (default: whole bundle)" },
|
|
269
|
-
{ name: "dry-run", takesValue: false, summary: "Report matches, write nothing" },
|
|
270
|
-
],
|
|
271
|
-
json: true,
|
|
272
|
-
kind: "replace.result",
|
|
273
|
-
// No `bundle`/`profile` seam: replace rewrites raw bytes and never parses frontmatter, so no validation(6).
|
|
274
|
-
exitCodes: exitCodesFor(["read", "write"]),
|
|
275
|
-
examples: ['lore replace "soft delete" "soft-delete" --in "docs/stories/**"'],
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
name: "rename",
|
|
279
|
-
summary: "Move a concept and repoint every inbound link + ref",
|
|
280
|
-
args: "<oldId> <newId>",
|
|
281
|
-
flags: [{ name: "dry-run", takesValue: false, summary: "Report rewrites, move nothing" }],
|
|
282
|
-
json: true,
|
|
283
|
-
kind: "rename.result",
|
|
284
|
-
exitCodes: exitCodesFor(["bundle", "write", "backlog"]),
|
|
285
|
-
examples: ["lore rename stories/bulk-archive-orders stories/order-archival"],
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
name: "supersede",
|
|
289
|
-
summary: "Mark a concept superseded by another, wiring both ways",
|
|
290
|
-
args: "<oldId> <newId>",
|
|
291
|
-
flags: [
|
|
292
|
-
{ name: "rewrite-links", takesValue: false, summary: "Repoint inbound links to the successor" },
|
|
293
|
-
{ name: "dry-run", takesValue: false, summary: "Report the changes, write nothing" },
|
|
294
|
-
],
|
|
295
|
-
json: true,
|
|
296
|
-
kind: "supersede.result",
|
|
297
|
-
exitCodes: exitCodesFor(["bundle", "profile", "write"]),
|
|
298
|
-
examples: ["lore supersede adr/0007-old-decision adr/0012-new-decision --rewrite-links"],
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
name: "link",
|
|
302
|
-
summary: "Add task ids to a concept's tasks: + the doc: back-ref",
|
|
303
|
-
args: "<id> <taskId…>",
|
|
304
|
-
flags: [{ name: "no-back-ref", takesValue: false, summary: "Skip the doc: label write to the task" }],
|
|
305
|
-
json: true,
|
|
306
|
-
kind: "link.result",
|
|
307
|
-
exitCodes: exitCodesFor(["bundle", "profile", "write", "backlog"]),
|
|
308
|
-
examples: ["lore link stories/bulk-archive-orders task-42 task-57"],
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
name: "unlink",
|
|
312
|
-
summary: "Remove task ids from a concept's tasks: + the doc: back-ref",
|
|
313
|
-
args: "<id> <taskId…>",
|
|
314
|
-
flags: [
|
|
315
|
-
{ name: "no-back-ref", takesValue: false, summary: "Leave the doc: label on the task" },
|
|
316
|
-
{ name: "allow-missing", takesValue: false, summary: "Tolerate <id> not resolving to a live concept" },
|
|
317
|
-
],
|
|
318
|
-
json: true,
|
|
319
|
-
kind: "unlink.result",
|
|
320
|
-
exitCodes: exitCodesFor(["bundle", "profile", "write", "backlog"]),
|
|
321
|
-
examples: [
|
|
322
|
-
"lore unlink stories/bulk-archive-orders task-42",
|
|
323
|
-
"lore unlink stories/bulk-archive-orders task-42 --allow-missing",
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
name: "sync",
|
|
328
|
-
summary: "Reconcile status + managed task blocks, regen index/log, commit backlog/",
|
|
329
|
-
args: "[paths…]",
|
|
330
|
-
flags: [
|
|
331
|
-
{ name: "dry-run", takesValue: false, summary: "Report what would change, write nothing (docs/ or backlog/)" },
|
|
332
|
-
{ name: "no-index", takesValue: false, summary: "Skip index/log regeneration" },
|
|
333
|
-
],
|
|
334
|
-
json: true,
|
|
335
|
-
kind: "sync.result",
|
|
336
|
-
exitCodes: exitCodesFor(["bundle", "profile", "read", "write", "backlog", "git"]),
|
|
337
|
-
examples: ["lore sync", "lore sync --dry-run"],
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
name: "tasks",
|
|
341
|
-
summary: "Show the live status rollup for a concept's linked tasks",
|
|
342
|
-
args: "<id>",
|
|
343
|
-
flags: [{ name: "status", takesValue: true, summary: "Filter the rollup to one Backlog status" }],
|
|
344
|
-
json: true,
|
|
345
|
-
kind: "tasks.rollup",
|
|
346
|
-
exitCodes: exitCodesFor(["bundle", "backlog"]),
|
|
347
|
-
examples: [
|
|
348
|
-
"lore tasks stories/bulk-archive-orders",
|
|
349
|
-
'lore tasks stories/bulk-archive-orders --status "In Progress"',
|
|
350
|
-
],
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
name: "orphans",
|
|
354
|
-
summary: "Report tasks with no owning doc + docs whose linked task vanished",
|
|
355
|
-
args: "",
|
|
356
|
-
flags: [
|
|
357
|
-
{ name: "tasks-only", takesValue: false, summary: "Report only tasks with no owning doc" },
|
|
358
|
-
{ name: "docs-only", takesValue: false, summary: "Report only docs whose linked task vanished" },
|
|
359
|
-
{ name: "limit", takesValue: true, summary: "Cap each section's rows (default 20)" },
|
|
360
|
-
],
|
|
361
|
-
json: true,
|
|
362
|
-
kind: "orphans.report",
|
|
363
|
-
// Same seams as `tasks`: bundle (loadBundle) + backlog (listTasks snapshot). A report, not a gate
|
|
364
|
-
// (always exit 0 on success), so no `extra` gate-return code.
|
|
365
|
-
exitCodes: exitCodesFor(["bundle", "backlog"]),
|
|
366
|
-
examples: ["lore orphans", "lore orphans --tasks-only"],
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
name: "schema",
|
|
370
|
-
summary: "Export the profile's editor JSON Schemas to .lore/schemas/",
|
|
371
|
-
args: "export",
|
|
372
|
-
flags: [
|
|
373
|
-
{ name: "out", takesValue: true, summary: "Output directory (default .lore/schemas/)" },
|
|
374
|
-
{ name: "type", takesValue: true, summary: "Export one type's schema" },
|
|
375
|
-
],
|
|
376
|
-
json: true,
|
|
377
|
-
kind: "schema.result",
|
|
378
|
-
// No read seam / no id lookup → no not_found(3).
|
|
379
|
-
exitCodes: exitCodesFor(["profile", "write"]),
|
|
380
|
-
examples: ["lore schema export"],
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
name: "scaffold",
|
|
384
|
-
summary: "Generate a downstream docs consumer's config, additively outside docs/",
|
|
385
|
-
args: "<target>",
|
|
386
|
-
flags: [{ name: "force", takesValue: false, summary: "Overwrite an existing generated config" }],
|
|
387
|
-
json: true,
|
|
388
|
-
kind: "scaffold.result",
|
|
389
|
-
// An unknown/not-yet-implemented target is the universal usage(2); no command-specific extra.
|
|
390
|
-
exitCodes: exitCodesFor(["profile", "write"]),
|
|
391
|
-
examples: ["lore scaffold mkdocs", "lore scaffold mkdocs --force"],
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
name: "graph",
|
|
395
|
-
summary: "Emit the bundle's cross-link graph as json or dot",
|
|
396
|
-
args: "[<id>]",
|
|
397
|
-
flags: [
|
|
398
|
-
{ name: "dot", takesValue: false, summary: "Emit Graphviz DOT (mutually exclusive with --json)" },
|
|
399
|
-
{ name: "depth", takesValue: true, summary: "Bound the subgraph radius" },
|
|
400
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
401
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
402
|
-
],
|
|
403
|
-
json: true,
|
|
404
|
-
kind: "graph.export",
|
|
405
|
-
exitCodes: exitCodesFor(["bundle"]),
|
|
406
|
-
examples: ["lore graph", "lore graph stories/bulk-archive-orders --dot"],
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
name: "path",
|
|
410
|
-
summary: "Find bounded paths across exact authored concept and task edges",
|
|
411
|
-
args: "<from> <to>",
|
|
412
|
-
flags: [
|
|
413
|
-
{
|
|
414
|
-
name: "from-kind",
|
|
415
|
-
takesValue: true,
|
|
416
|
-
summary: "Typed origin: concept or task",
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
name: "to-kind",
|
|
420
|
-
takesValue: true,
|
|
421
|
-
summary: "Typed destination: concept or task",
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
name: "direction",
|
|
425
|
-
takesValue: true,
|
|
426
|
-
summary: "Traversal direction: outbound, inbound, or either",
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
name: "edge",
|
|
430
|
-
takesValue: true,
|
|
431
|
-
repeatable: true,
|
|
432
|
-
summary: "Allow one authored edge kind",
|
|
433
|
-
},
|
|
434
|
-
{
|
|
435
|
-
name: "max-depth",
|
|
436
|
-
takesValue: true,
|
|
437
|
-
summary: "Maximum traversal depth (default 4, max 16)",
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: "limit",
|
|
441
|
-
takesValue: true,
|
|
442
|
-
summary: "Maximum paths (default 20, max 100)",
|
|
443
|
-
},
|
|
444
|
-
{
|
|
445
|
-
name: "workspace",
|
|
446
|
-
takesValue: true,
|
|
447
|
-
summary: "Select an explicit workspace manifest",
|
|
448
|
-
},
|
|
449
|
-
{
|
|
450
|
-
name: "repository",
|
|
451
|
-
takesValue: true,
|
|
452
|
-
repeatable: true,
|
|
453
|
-
summary: "Select a workspace member",
|
|
454
|
-
},
|
|
455
|
-
],
|
|
456
|
-
json: true,
|
|
457
|
-
kind: "path.result",
|
|
458
|
-
exitCodes: exitCodesFor(["bundle", "backlog"]),
|
|
459
|
-
examples: ["lore path stories/orders LCLI-123 --from-kind concept --to-kind task --direction outbound"],
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
name: "impact",
|
|
463
|
-
summary: "Expand bounded impact across exact authored concept and task edges",
|
|
464
|
-
args: "<id>",
|
|
465
|
-
flags: [
|
|
466
|
-
{
|
|
467
|
-
name: "kind",
|
|
468
|
-
takesValue: true,
|
|
469
|
-
summary: "Typed root: concept or task",
|
|
470
|
-
},
|
|
471
|
-
{
|
|
472
|
-
name: "direction",
|
|
473
|
-
takesValue: true,
|
|
474
|
-
summary: "Traversal direction: outbound, inbound, or either",
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
name: "edge",
|
|
478
|
-
takesValue: true,
|
|
479
|
-
repeatable: true,
|
|
480
|
-
summary: "Allow one authored edge kind",
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
name: "max-depth",
|
|
484
|
-
takesValue: true,
|
|
485
|
-
summary: "Maximum traversal depth (default 4, max 16)",
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
name: "limit",
|
|
489
|
-
takesValue: true,
|
|
490
|
-
summary: "Maximum impacts (default 20, max 100)",
|
|
491
|
-
},
|
|
492
|
-
{
|
|
493
|
-
name: "workspace",
|
|
494
|
-
takesValue: true,
|
|
495
|
-
summary: "Select an explicit workspace manifest",
|
|
496
|
-
},
|
|
497
|
-
{
|
|
498
|
-
name: "repository",
|
|
499
|
-
takesValue: true,
|
|
500
|
-
repeatable: true,
|
|
501
|
-
summary: "Select a workspace member",
|
|
502
|
-
},
|
|
503
|
-
],
|
|
504
|
-
json: true,
|
|
505
|
-
kind: "impact.result",
|
|
506
|
-
exitCodes: exitCodesFor(["bundle", "backlog"]),
|
|
507
|
-
examples: ["lore impact LCLI-123 --kind task --direction inbound --max-depth 3"],
|
|
508
|
-
},
|
|
509
|
-
{
|
|
510
|
-
name: "snapshot",
|
|
511
|
-
summary: "Explicitly retain, list, or delete bounded projection snapshots",
|
|
512
|
-
args: "<retain|list|delete> [snapshot-key]",
|
|
513
|
-
flags: [
|
|
514
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
515
|
-
{ name: "workspace-id", takesValue: true, summary: "Select a workspace scope after its manifest is removed" },
|
|
516
|
-
{ name: "all", takesValue: false, summary: "Delete every explicitly retained snapshot in the selected scope" },
|
|
517
|
-
],
|
|
518
|
-
json: true,
|
|
519
|
-
kind: "snapshot.result",
|
|
520
|
-
exitCodes: exitCodesFor(["bundle", "backlog", "git", "read", "write"]),
|
|
521
|
-
examples: ["lore snapshot retain", "lore snapshot list --workspace lore-workspace.json"],
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
name: "changed",
|
|
525
|
-
summary: "Compare two retained snapshots with bounded authored-fact deltas",
|
|
526
|
-
args: "<from> <to>",
|
|
527
|
-
flags: [
|
|
528
|
-
{ name: "kind", takesValue: true, repeatable: true, summary: "Select concept, task, or edge changes" },
|
|
529
|
-
{ name: "limit", takesValue: true, summary: "Maximum returned changes (default 100, max 1000)" },
|
|
530
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
531
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
532
|
-
],
|
|
533
|
-
json: true,
|
|
534
|
-
kind: "changed.result",
|
|
535
|
-
exitCodes: exitCodesFor(["bundle", "backlog", "git", "read"], [5]),
|
|
536
|
-
examples: ["lore changed <from-snapshot> <to-snapshot>", "lore changed <from> <to> --kind edge --limit 200"],
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
name: "provenance",
|
|
540
|
-
summary: "Trace one retained concept, task, or edge to exact source evidence",
|
|
541
|
-
args: "<id>",
|
|
542
|
-
flags: [
|
|
543
|
-
{ name: "kind", takesValue: true, summary: "Retained fact kind: concept, task, or edge" },
|
|
544
|
-
{ name: "snapshot", takesValue: true, summary: "Exact retained snapshot key or unambiguous commit" },
|
|
545
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
546
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
547
|
-
],
|
|
548
|
-
json: true,
|
|
549
|
-
kind: "provenance.result",
|
|
550
|
-
exitCodes: exitCodesFor(["bundle", "backlog", "git", "read"], [5]),
|
|
551
|
-
examples: ["lore provenance stories/orders --kind concept --snapshot <snapshot-key>"],
|
|
552
|
-
},
|
|
553
|
-
{
|
|
554
|
-
name: "explorer",
|
|
555
|
-
summary: "Build a deterministic self-contained local graph explorer",
|
|
556
|
-
args: "",
|
|
557
|
-
flags: [
|
|
558
|
-
{ name: "out", takesValue: true, summary: "Repository-relative HTML output path" },
|
|
559
|
-
{ name: "force", takesValue: false, summary: "Replace a differing custom output file" },
|
|
560
|
-
{ name: "snapshot", takesValue: true, summary: "Explore one retained snapshot" },
|
|
561
|
-
{ name: "from", takesValue: true, summary: "Comparison source retained snapshot" },
|
|
562
|
-
{ name: "to", takesValue: true, summary: "Comparison target retained snapshot" },
|
|
563
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
564
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
565
|
-
],
|
|
566
|
-
json: true,
|
|
567
|
-
kind: "explorer.artifact",
|
|
568
|
-
exitCodes: exitCodesFor(["bundle", "backlog", "git", "read", "write"]),
|
|
569
|
-
examples: [
|
|
570
|
-
"lore explorer",
|
|
571
|
-
"lore explorer --snapshot <snapshot-key>",
|
|
572
|
-
"lore explorer --from <snapshot> --to <snapshot>",
|
|
573
|
-
],
|
|
574
|
-
},
|
|
575
|
-
{
|
|
576
|
-
name: "export",
|
|
577
|
-
summary: "Emit a deterministic, consumer-neutral OKF projection as JSONL",
|
|
578
|
-
args: "",
|
|
579
|
-
flags: [
|
|
580
|
-
{
|
|
581
|
-
name: "schema-version",
|
|
582
|
-
takesValue: true,
|
|
583
|
-
summary: "Projection schema version (currently 1.0)",
|
|
584
|
-
},
|
|
585
|
-
],
|
|
586
|
-
json: true,
|
|
587
|
-
kind: "projection.export",
|
|
588
|
-
exitCodes: exitCodesFor(["bundle", "backlog", "git"]),
|
|
589
|
-
examples: ["lore export", "lore export --schema-version 1.0"],
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
name: "query",
|
|
593
|
-
summary: "Full-text search the bundle with frontmatter filters",
|
|
594
|
-
args: '["<text>"]',
|
|
595
|
-
flags: [
|
|
596
|
-
{ name: "type", takesValue: true, summary: "Filter by concept type" },
|
|
597
|
-
{ name: "tag", takesValue: true, repeatable: true, summary: "Filter by tag" },
|
|
598
|
-
{ name: "status", takesValue: true, summary: "Filter by status" },
|
|
599
|
-
{ name: "limit", takesValue: true, summary: "Cap the number of hits" },
|
|
600
|
-
{ name: "field", takesValue: true, repeatable: true, summary: "Arbitrary frontmatter filter (k=v)" },
|
|
601
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
602
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
603
|
-
],
|
|
604
|
-
json: true,
|
|
605
|
-
kind: "query.results",
|
|
606
|
-
exitCodes: exitCodesFor(["bundle"]),
|
|
607
|
-
examples: ['lore query "soft delete retention"', "lore query --type Story --tag orders --status in-progress"],
|
|
608
|
-
},
|
|
609
|
-
{
|
|
610
|
-
name: "context",
|
|
611
|
-
summary: "Assemble a concept + neighbor summaries within a token budget",
|
|
612
|
-
args: "<id>",
|
|
613
|
-
flags: [
|
|
614
|
-
{ name: "max-tokens", takesValue: true, summary: "Token budget (labeled chars/4 estimate)" },
|
|
615
|
-
{ name: "depth", takesValue: true, summary: "Neighbor radius (default 1)" },
|
|
616
|
-
{ name: "workspace", takesValue: true, summary: "Select an explicit workspace manifest" },
|
|
617
|
-
{ name: "repository", takesValue: true, repeatable: true, summary: "Select a workspace member" },
|
|
618
|
-
],
|
|
619
|
-
json: true,
|
|
620
|
-
kind: "context.export",
|
|
621
|
-
exitCodes: exitCodesFor(["bundle"]),
|
|
622
|
-
examples: ["lore context stories/bulk-archive-orders --max-tokens 4000 --depth 2"],
|
|
623
|
-
},
|
|
624
|
-
{
|
|
625
|
-
name: "agent",
|
|
626
|
-
summary: "List context profiles or compile bounded task-scoped evidence",
|
|
627
|
-
args: "<list|show|context> [args…]",
|
|
628
|
-
flags: [
|
|
629
|
-
{ name: "task", takesValue: true, summary: "Assigned task text for context compilation" },
|
|
630
|
-
{ name: "task-file", takesValue: true, summary: "Read task text from a repo-relative path or stdin (-)" },
|
|
631
|
-
{ name: "max-tokens", takesValue: true, summary: "Override the profile's chars/4 token budget" },
|
|
632
|
-
{ name: "out", takesValue: true, summary: "Atomically save canonical Markdown to a repo-relative path" },
|
|
633
|
-
{ name: "force", takesValue: false, summary: "Replace a differing regular --out file" },
|
|
634
|
-
],
|
|
635
|
-
json: true,
|
|
636
|
-
kind: "agent.context.export",
|
|
637
|
-
// Profile/reference validation is command-owned (extra 6), unknown profiles are
|
|
638
|
-
// command-owned not_found (extra 3), and task-file/output paths reach read/write.
|
|
639
|
-
exitCodes: exitCodesFor(["bundle", "read", "write"], [3, 6]),
|
|
640
|
-
examples: [
|
|
641
|
-
"lore agent list",
|
|
642
|
-
"lore agent show frontend-dev",
|
|
643
|
-
'lore agent context frontend-dev --task "implement the checkout form"',
|
|
644
|
-
],
|
|
645
|
-
},
|
|
646
|
-
{
|
|
647
|
-
name: "instructions",
|
|
648
|
-
summary: "Print task-scoped agent guidance on demand",
|
|
649
|
-
args: "[<topic>]",
|
|
650
|
-
flags: [],
|
|
651
|
-
json: true,
|
|
652
|
-
kind: "instructions.text",
|
|
653
|
-
// Static registry, no filesystem seam; `extra` 3 is the unknown-topic not_found.
|
|
654
|
-
exitCodes: exitCodesFor([], [3]),
|
|
655
|
-
examples: ["lore instructions", "lore instructions linking"],
|
|
656
|
-
},
|
|
657
|
-
{
|
|
658
|
-
name: "agents",
|
|
659
|
-
summary: "Regenerate this bridge (SKILL.md + the CLAUDE.md nudge)",
|
|
660
|
-
args: "",
|
|
661
|
-
flags: [
|
|
662
|
-
{ name: "force", takesValue: false, summary: "Overwrite hand-edited generated files" },
|
|
663
|
-
{ name: "check", takesValue: false, summary: "Report drift without writing (CI gate for a stale bridge)" },
|
|
664
|
-
],
|
|
665
|
-
json: true,
|
|
666
|
-
kind: "agents.result",
|
|
667
|
-
// Writes the bridge (fswrite); `extra` 6 is the managed-block validation throw and the --check drift return.
|
|
668
|
-
exitCodes: exitCodesFor(["write"], [6]),
|
|
669
|
-
examples: ["lore agents", "lore agents --check"],
|
|
670
|
-
},
|
|
671
|
-
{
|
|
672
|
-
name: "help",
|
|
673
|
-
summary: "Show help, or the machine-readable command manifest under --json",
|
|
674
|
-
args: "[<command>]",
|
|
675
|
-
flags: [],
|
|
676
|
-
json: true,
|
|
677
|
-
kind: "help.manifest",
|
|
678
|
-
// Static registry, no filesystem seam; `extra` 3 is the unknown-command not_found.
|
|
679
|
-
exitCodes: exitCodesFor([], [3]),
|
|
680
|
-
examples: ["lore help", "lore help new", "lore help --json"],
|
|
681
|
-
},
|
|
682
|
-
]);
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* The semantic exit-code taxonomy, name → code, built from the `errors.ts`
|
|
686
|
-
* constants so it can never drift from the real mapping (`validation` and `drift`
|
|
687
|
-
* intentionally share `6`; cli-contract §5.1/§5.3).
|
|
688
|
-
*/
|
|
689
|
-
export function exitCodeTaxonomy(): Record<string, number> {
|
|
690
|
-
return { ok: EXIT_OK, uncaught: EXIT_UNCAUGHT, ...EXIT_CODES };
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Build the full {@link Manifest} for `lore help --json`. The returned envelope is
|
|
695
|
-
* deeply frozen (AC#1): `globalFlags`/`commands` are the already-frozen module
|
|
696
|
-
* singletons ({@link GLOBAL_FLAGS}/{@link LORE_MANIFEST}), `exitCodes` is a fresh
|
|
697
|
-
* object frozen here, and the envelope itself is frozen last — so no caller,
|
|
698
|
-
* however it bypasses the compile-time `readonly` modifiers, can mutate a manifest
|
|
699
|
-
* returned by this function or poison a later call's read.
|
|
700
|
-
*/
|
|
701
|
-
export function buildManifest(): Manifest {
|
|
702
|
-
return deepFreeze({
|
|
703
|
-
schemaVersion: SCHEMA_VERSION,
|
|
704
|
-
exitCodes: exitCodeTaxonomy(),
|
|
705
|
-
globalFlags: GLOBAL_FLAGS,
|
|
706
|
-
commands: LORE_MANIFEST,
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
/** Look up one command by its exact dispatch name (case-sensitive), or `undefined` if unknown. */
|
|
711
|
-
export function findManifestCommand(name: string): ManifestCommand | undefined {
|
|
712
|
-
return LORE_MANIFEST.find((command) => command.name === name);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/** Every command name the manifest advertises, in dispatch order — the set the lockstep test pins against the router. */
|
|
716
|
-
export function manifestCommandNames(): readonly string[] {
|
|
717
|
-
return LORE_MANIFEST.map((command) => command.name);
|
|
718
|
-
}
|