@opum-ai/lore 0.1.0 → 0.2.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/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/agent-bridge.ts
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* core/agent-bridge.ts — the pure content + planning engine behind `lore agents` (LORE-36).
|
|
3
|
-
*
|
|
4
|
-
* `lore agents` generates the Claude Code "agent bridge" (docs/adr/0004-cli-first-skill-bridge):
|
|
5
|
-
* a `.claude/skills/lore/SKILL.md` that teaches an agent how to drive lore, and a tiny
|
|
6
|
-
* marker-delimited `CLAUDE.md` nudge that points at that skill and at `lore instructions`. Both
|
|
7
|
-
* are *generated*, not hand-maintained, so they stay in lockstep with the CLI surface.
|
|
8
|
-
*
|
|
9
|
-
* This module holds everything pure: the generated bytes ({@link buildSkillDoc},
|
|
10
|
-
* {@link buildNudgeBody}), the canonical command surface ({@link LORE_COMMANDS}), and the pure
|
|
11
|
-
* {@link planBridge planner} that — given each file's current bytes (or absence) and the `--force`
|
|
12
|
-
* flag — decides what each file's next state should be. All filesystem side effects live in the
|
|
13
|
-
* command layer (`commands/agents.ts`), per lore-design §2.1.
|
|
14
|
-
*
|
|
15
|
-
* ### Content is grounded in live source, not the runbook
|
|
16
|
-
*
|
|
17
|
-
* Every factual claim here (the command list, the `--json` envelope shape, the exit-code table, the
|
|
18
|
-
* canonical loop) is grounded in what the CLI *actually* does today — `src/cli.ts`, `src/output.ts`,
|
|
19
|
-
* `src/errors.ts`, and the shipped `core/instructions.ts` OVERVIEW — never in an aspirational
|
|
20
|
-
* runbook/ADR that also describes not-yet-shipped state. In particular the generated content names
|
|
21
|
-
* only **shipped** commands the real dispatcher handles (the LORE-37 phantom-command trap); the
|
|
22
|
-
* `agents.test.ts` lockstep guard re-checks {@link LORE_COMMANDS} against the real dispatcher.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { upsertManagedBlock } from "./managed-block";
|
|
26
|
-
|
|
27
|
-
/** The repo-relative path of the generated skill bridge (pinned by ADR-0004 §3 and cli-surface §agents). */
|
|
28
|
-
export const SKILL_REL_PATH = ".claude/skills/lore/SKILL.md";
|
|
29
|
-
|
|
30
|
-
/** The repo-relative path of the project memory file the nudge block is upserted into. */
|
|
31
|
-
export const CLAUDE_MD_REL_PATH = "CLAUDE.md";
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The label naming the `CLAUDE.md` nudge's managed block, consumed by
|
|
35
|
-
* {@link upsertManagedBlock} to build `<!-- lore:agents:begin -->` / `<!-- lore:agents:end -->`.
|
|
36
|
-
* Chosen to sit in lore's existing `lore:tasks` / `lore:index` marker namespace; kept stable
|
|
37
|
-
* because `--check` idempotency depends on the exact bytes.
|
|
38
|
-
*/
|
|
39
|
-
export const AGENT_BLOCK_LABEL = "lore:agents";
|
|
40
|
-
|
|
41
|
-
/** One `lore` subcommand and its one-line summary, as advertised to an agent by the generated bridge. */
|
|
42
|
-
export interface CommandSummary {
|
|
43
|
-
/** The subcommand token (`"sync"`), exactly as `src/cli.ts` dispatches it. */
|
|
44
|
-
readonly name: string;
|
|
45
|
-
/** A one-line description, distilled from the authoritative `cli.ts` USAGE text. */
|
|
46
|
-
readonly summary: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* The canonical `lore` command surface the bridge advertises — the single source both
|
|
51
|
-
* {@link buildSkillDoc} and the `agents.test.ts` lockstep guard read. Names and order mirror
|
|
52
|
-
* `src/cli.ts`'s Commander handler registry / USAGE; the guard runs each name through the real CLI to prove
|
|
53
|
-
* none is a phantom (the exact LORE-37 failure mode: teaching an agent a command that does not exist).
|
|
54
|
-
*/
|
|
55
|
-
export const LORE_COMMANDS: readonly CommandSummary[] = [
|
|
56
|
-
{
|
|
57
|
-
name: "init",
|
|
58
|
-
summary: "Scaffold an OKF bundle; a bare TTY run also wizards the agent bridge/scaffolds/backlog check",
|
|
59
|
-
},
|
|
60
|
-
{ name: "new", summary: "Scaffold a typed concept from a template" },
|
|
61
|
-
{ name: "validate", summary: "Check concept files against OKF + the lore profile (per-file)" },
|
|
62
|
-
{ name: "check", summary: "Validate links/anchors + reconciliation drift across the bundle (CI gate)" },
|
|
63
|
-
{ name: "replace", summary: "Find-and-replace across the bundle, skipping managed regions" },
|
|
64
|
-
{ name: "rename", summary: "Move a concept and repoint every inbound link + ref" },
|
|
65
|
-
{ name: "supersede", summary: "Mark a concept superseded by another, wiring both ways" },
|
|
66
|
-
{ name: "link", summary: "Add task ids to a concept's tasks: + the doc: back-ref" },
|
|
67
|
-
{ name: "unlink", summary: "Remove task ids from a concept's tasks: + the doc: back-ref" },
|
|
68
|
-
{ name: "sync", summary: "Reconcile status + managed task blocks, regen index/log, commit backlog/" },
|
|
69
|
-
{ name: "tasks", summary: "Show the live status rollup for a concept's linked tasks" },
|
|
70
|
-
{ name: "orphans", summary: "Report tasks with no owning doc + docs whose linked task vanished" },
|
|
71
|
-
{ name: "schema", summary: "Export the profile's editor JSON Schemas to .lore/schemas/" },
|
|
72
|
-
{ name: "scaffold", summary: "Generate a downstream docs consumer's config, additively outside docs/" },
|
|
73
|
-
{ name: "graph", summary: "Emit the bundle's cross-link graph as json or dot" },
|
|
74
|
-
{ name: "path", summary: "Find bounded paths across exact authored concept and task edges" },
|
|
75
|
-
{ name: "impact", summary: "Expand bounded impact across exact authored concept and task edges" },
|
|
76
|
-
{ name: "snapshot", summary: "Explicitly retain, list, or delete bounded projection snapshots" },
|
|
77
|
-
{ name: "changed", summary: "Compare two retained snapshots with bounded authored-fact deltas" },
|
|
78
|
-
{ name: "provenance", summary: "Trace one retained concept, task, or edge to exact source evidence" },
|
|
79
|
-
{ name: "explorer", summary: "Build a deterministic self-contained local graph explorer" },
|
|
80
|
-
{ name: "export", summary: "Emit a deterministic, consumer-neutral OKF projection as JSONL" },
|
|
81
|
-
{ name: "query", summary: "Full-text search the bundle with frontmatter filters" },
|
|
82
|
-
{ name: "context", summary: "Assemble a concept + neighbor summaries within a token budget" },
|
|
83
|
-
{ name: "agent", summary: "List context profiles or compile bounded task-scoped evidence" },
|
|
84
|
-
{ name: "instructions", summary: "Print task-scoped agent guidance on demand" },
|
|
85
|
-
{ name: "agents", summary: "Regenerate this bridge (SKILL.md + the CLAUDE.md nudge)" },
|
|
86
|
-
{ name: "help", summary: "Show help, or the machine-readable command manifest under --json" },
|
|
87
|
-
];
|
|
88
|
-
|
|
89
|
-
/** The four detail topics `lore instructions <topic>` serves, mirrored (not restated) by the bridge. */
|
|
90
|
-
const INSTRUCTION_DETAIL_TOPICS: ReadonlyArray<{ key: string; blurb: string }> = [
|
|
91
|
-
{ key: "linking", blurb: "Story <-> Task coupling (`lore link` / `lore unlink`)" },
|
|
92
|
-
{ key: "sync", blurb: "reconcile status + managed blocks (`lore sync`)" },
|
|
93
|
-
{ key: "check", blurb: "the CI gate: drift, links, anchors, portability (`lore check`)" },
|
|
94
|
-
{ key: "validation", blurb: "per-file OKF/schema conformance (`lore validate`)" },
|
|
95
|
-
];
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Render a left-aligned two-column list: a tight `` `left` `` code span, then padding *after* the
|
|
99
|
-
* backtick (never inside it, which would render as trailing whitespace in the code span) so the
|
|
100
|
-
* right column aligns in the raw text an agent reads.
|
|
101
|
-
*/
|
|
102
|
-
function twoColumn(rows: ReadonlyArray<{ left: string; right: string }>): string {
|
|
103
|
-
const width = Math.max(...rows.map((row) => row.left.length));
|
|
104
|
-
return rows.map((row) => `- \`${row.left}\`${" ".repeat(width - row.left.length + 2)}${row.right}`).join("\n");
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Build the full `SKILL.md` bytes: YAML frontmatter (the `name` + when-to-use `description` Claude
|
|
109
|
-
* Code loads the skill by) followed by a small, live-source-grounded teacher body. Deterministic and
|
|
110
|
-
* timestamp-free, so regenerating with no change is byte-identical (AC#1). Kept a thin pointer:
|
|
111
|
-
* `lore instructions` is the source of truth, and this file directs the agent there (AC#2).
|
|
112
|
-
*/
|
|
113
|
-
export function buildSkillDoc(): string {
|
|
114
|
-
const description =
|
|
115
|
-
"Author and maintain this repo's OKF documentation bundle (docs/) with the lore CLI. " +
|
|
116
|
-
"Use whenever reading, writing, linking, moving, or checking docs, so Story/Task coupling, " +
|
|
117
|
-
"managed blocks, and cross-links stay coherent. Run `lore instructions` for the canonical " +
|
|
118
|
-
"agent loop and `lore instructions <topic>` for just-in-time detail.";
|
|
119
|
-
|
|
120
|
-
const topicList = twoColumn(INSTRUCTION_DETAIL_TOPICS.map((t) => ({ left: t.key, right: t.blurb })));
|
|
121
|
-
const commandList = twoColumn(LORE_COMMANDS.map((c) => ({ left: c.name, right: c.summary })));
|
|
122
|
-
|
|
123
|
-
return `---
|
|
124
|
-
name: lore
|
|
125
|
-
description: "${description}"
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
# lore — OKF documentation CLI
|
|
129
|
-
|
|
130
|
-
\`lore\` is this repo's documentation engine: a deterministic, CLI-first tool (no LLM dependency)
|
|
131
|
-
for authoring and maintaining the OKF bundle under \`docs/\`. This skill is a thin pointer —
|
|
132
|
-
**\`lore instructions\` is the source of truth for how to drive lore.**
|
|
133
|
-
|
|
134
|
-
## When to use it
|
|
135
|
-
|
|
136
|
-
Reach for \`lore\` — not a plain editor — whenever you read, write, link, move, or verify docs in
|
|
137
|
-
this repo, so Story <-> Task coupling, managed blocks, and cross-links stay coherent.
|
|
138
|
-
|
|
139
|
-
## Start here
|
|
140
|
-
|
|
141
|
-
Run \`lore instructions\` for the canonical agent loop and the topic index, then pull just-in-time
|
|
142
|
-
detail with \`lore instructions <topic>\`:
|
|
143
|
-
|
|
144
|
-
${topicList}
|
|
145
|
-
|
|
146
|
-
## Commands
|
|
147
|
-
|
|
148
|
-
${commandList}
|
|
149
|
-
|
|
150
|
-
## Machine contract
|
|
151
|
-
|
|
152
|
-
Every command supports \`--json\` (the \`{schemaVersion, kind, data}\` envelope) and \`--plain\`
|
|
153
|
-
(ANSI-free, auto-selected off a TTY). Branch on the semantic exit code, never on prose:
|
|
154
|
-
\`0\` ok · \`2\` usage · \`3\` not_found · \`4\` denied · \`5\` conflict · \`6\` validation/drift.
|
|
155
|
-
|
|
156
|
-
## Optional task-scoped context
|
|
157
|
-
|
|
158
|
-
When native Claude Code instructions name a committed Lore profile, use this stable opt-in line:
|
|
159
|
-
|
|
160
|
-
> Lore profile: \`<name>\`. Before working, run \`lore agent context <name> --task "<assigned task>"\`
|
|
161
|
-
> and ground decisions in the returned source IDs.
|
|
162
|
-
|
|
163
|
-
Lore supplies evidence only. It does not create or patch native agents, prompts, tools, models,
|
|
164
|
-
permissions, or execution settings.
|
|
165
|
-
|
|
166
|
-
<!-- Generated by \`lore agents\`; do not hand-edit. Re-run \`lore agents --force\` to refresh. -->
|
|
167
|
-
`;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Build the inner body of the `CLAUDE.md` nudge — the bytes {@link upsertManagedBlock} places
|
|
172
|
-
* between the `lore:agents` markers. Deliberately tiny (ADR-0004: "the SKILL.md bridge costs ~30–50
|
|
173
|
-
* idle tokens"; the nudge carries no substantive guidance itself): its only job is discoverability —
|
|
174
|
-
* "lore exists, here is the skill, here is where to pull just-in-time detail." No trailing newline.
|
|
175
|
-
*/
|
|
176
|
-
export function buildNudgeBody(): string {
|
|
177
|
-
return `This repo uses **lore** — an OKF-native documentation CLI — for the docs bundle under \`docs/\`.
|
|
178
|
-
When working on documentation, drive it through \`lore\` (not a plain editor) so Story <-> Task
|
|
179
|
-
coupling, managed blocks, and cross-links stay coherent.
|
|
180
|
-
|
|
181
|
-
- **Skill:** \`${SKILL_REL_PATH}\` — how to drive lore.
|
|
182
|
-
- **Just-in-time detail:** run \`lore instructions\` for the canonical agent loop, then
|
|
183
|
-
\`lore instructions <topic>\` (\`linking\`, \`sync\`, \`check\`, \`validation\`).`;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/** What {@link planBridge} decided a single bridge file's next state should be. */
|
|
187
|
-
export type BridgeAction =
|
|
188
|
-
/** The file did not exist and will be created. */
|
|
189
|
-
| "created"
|
|
190
|
-
/** The file (or its managed block) differs and will be rewritten. */
|
|
191
|
-
| "updated"
|
|
192
|
-
/** The on-disk bytes already match — nothing to write. */
|
|
193
|
-
| "unchanged"
|
|
194
|
-
/**
|
|
195
|
-
* A whole lore-owned file (SKILL.md) differs but was left untouched: either it looks hand-edited
|
|
196
|
-
* and `--force` was not given, or this is a `--check` run — which never writes, so `--force`
|
|
197
|
-
* cannot actually take effect and must not be reported as if it had (LORE-129).
|
|
198
|
-
*/
|
|
199
|
-
| "protected";
|
|
200
|
-
|
|
201
|
-
/** One file's entry in a {@link BridgePlan}. */
|
|
202
|
-
export interface BridgeFilePlan {
|
|
203
|
-
/** Repo-relative path (`.claude/skills/lore/SKILL.md` or `CLAUDE.md`). */
|
|
204
|
-
readonly path: string;
|
|
205
|
-
/** The decided next state. */
|
|
206
|
-
readonly action: BridgeAction;
|
|
207
|
-
/** The full bytes to write, or `null` when nothing should be written (`unchanged`/`protected`). */
|
|
208
|
-
readonly contents: string | null;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/** The planned next state of every bridge file, computed purely from the on-disk bytes + `--force`. */
|
|
212
|
-
export interface BridgePlan {
|
|
213
|
-
readonly files: readonly BridgeFilePlan[];
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/** The current on-disk bytes of each bridge file (LF-normalized), or `null` when the file is absent, plus `--force`/`--check`. */
|
|
217
|
-
export interface PlanBridgeInput {
|
|
218
|
-
/** Current `SKILL.md` bytes, or `null` if it does not exist. */
|
|
219
|
-
readonly skillOnDisk: string | null;
|
|
220
|
-
/** Current `CLAUDE.md` bytes, or `null` if it does not exist. */
|
|
221
|
-
readonly claudeOnDisk: string | null;
|
|
222
|
-
/** Whether `--force` was given (permits overwriting a differing, possibly hand-edited SKILL.md). */
|
|
223
|
-
readonly force: boolean;
|
|
224
|
-
/**
|
|
225
|
-
* Whether this is a `--check` (report-only) run. `--check` never writes, so `force` must not be
|
|
226
|
-
* honored while planning: a `--check --force` run against a differing SKILL.md still reports
|
|
227
|
-
* `protected` (never `updated`, which would claim a write that never happens) — see
|
|
228
|
-
* {@link planSkill} (LORE-129).
|
|
229
|
-
*/
|
|
230
|
-
readonly check: boolean;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Decide the next state of both bridge files, purely (no IO). The two files have deliberately
|
|
235
|
-
* different write disciplines:
|
|
236
|
-
*
|
|
237
|
-
* - **SKILL.md is a whole lore-owned file.** Absent → `created`. Byte-equal to the generated
|
|
238
|
-
* content → `unchanged`. Differs → `updated` only under `--force` *and not* `--check` (a
|
|
239
|
-
* `--check` run never writes, so `--force` cannot take effect and must not be reported as if it
|
|
240
|
-
* had — LORE-129), else `protected` (left untouched — a differing generated file may be a
|
|
241
|
-
* hand-edit, and lore never silently clobbers it; the command reports "run with --force"). This
|
|
242
|
-
* is exactly the "overwrite hand-edited generated files" role cli-surface pins on `--force`.
|
|
243
|
-
* - **The CLAUDE.md nudge is a managed block**, so lore only ever rewrites the bytes between its own
|
|
244
|
-
* markers. Refreshing that block is by-design and needs no `--force`: absent file → `created`;
|
|
245
|
-
* block absent or stale → `updated` (the surrounding prose and any unrelated block, e.g.
|
|
246
|
-
* Backlog.md's, are preserved by {@link upsertManagedBlock}); already current → `unchanged`.
|
|
247
|
-
*
|
|
248
|
-
* {@link upsertManagedBlock} throws a `validation` {@link LoreError} if CLAUDE.md carries a malformed
|
|
249
|
-
* `lore:agents` marker pair — a fail-loud propagation the command surfaces (exit 6), never a guess.
|
|
250
|
-
*/
|
|
251
|
-
export function planBridge(input: PlanBridgeInput): BridgePlan {
|
|
252
|
-
return { files: [planSkill(input), planNudge(input)] };
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Plan the SKILL.md file (whole-file, `--force`-protected discipline). `--force` only ever permits
|
|
257
|
-
* an actual write, so it only ever yields `updated` on a real (non-`--check`) run: `--check` is
|
|
258
|
-
* read-only by contract, and `--check --force` against a differing file must still report
|
|
259
|
-
* `protected` — the check-safe, non-mutating label — never `updated`, which would falsely claim a
|
|
260
|
-
* write that this run never performs (LORE-129).
|
|
261
|
-
*/
|
|
262
|
-
function planSkill(input: PlanBridgeInput): BridgeFilePlan {
|
|
263
|
-
const desired = buildSkillDoc();
|
|
264
|
-
if (input.skillOnDisk === null) {
|
|
265
|
-
return { path: SKILL_REL_PATH, action: "created", contents: desired };
|
|
266
|
-
}
|
|
267
|
-
if (input.skillOnDisk === desired) {
|
|
268
|
-
return { path: SKILL_REL_PATH, action: "unchanged", contents: null };
|
|
269
|
-
}
|
|
270
|
-
if (input.force && !input.check) {
|
|
271
|
-
return { path: SKILL_REL_PATH, action: "updated", contents: desired };
|
|
272
|
-
}
|
|
273
|
-
return { path: SKILL_REL_PATH, action: "protected", contents: null };
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/** Plan the CLAUDE.md nudge (managed-block, always-refresh discipline). */
|
|
277
|
-
function planNudge(input: PlanBridgeInput): BridgeFilePlan {
|
|
278
|
-
const base = input.claudeOnDisk ?? "";
|
|
279
|
-
const desired = upsertManagedBlock(base, { label: AGENT_BLOCK_LABEL, body: buildNudgeBody() });
|
|
280
|
-
if (input.claudeOnDisk === null) {
|
|
281
|
-
return { path: CLAUDE_MD_REL_PATH, action: "created", contents: desired };
|
|
282
|
-
}
|
|
283
|
-
if (desired === input.claudeOnDisk) {
|
|
284
|
-
return { path: CLAUDE_MD_REL_PATH, action: "unchanged", contents: null };
|
|
285
|
-
}
|
|
286
|
-
return { path: CLAUDE_MD_REL_PATH, action: "updated", contents: desired };
|
|
287
|
-
}
|