@sdd-method/sdd-cli 0.21.0 → 0.22.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 +30 -10
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-harness.d.ts +20 -0
- package/dist/lib/agent-harness.d.ts.map +1 -0
- package/dist/lib/agent-harness.js +28 -0
- package/dist/lib/agent-harness.js.map +1 -0
- package/dist/lib/briefing/index.d.ts +15 -0
- package/dist/lib/briefing/index.d.ts.map +1 -0
- package/dist/lib/briefing/index.js +13 -0
- package/dist/lib/briefing/index.js.map +1 -0
- package/dist/lib/briefing/render.d.ts +57 -0
- package/dist/lib/briefing/render.d.ts.map +1 -0
- package/dist/lib/briefing/render.js +112 -0
- package/dist/lib/briefing/render.js.map +1 -0
- package/dist/lib/briefing/variables.d.ts +49 -0
- package/dist/lib/briefing/variables.d.ts.map +1 -0
- package/dist/lib/briefing/variables.js +92 -0
- package/dist/lib/briefing/variables.js.map +1 -0
- package/dist/lib/catalogue/aggregate.d.ts +19 -0
- package/dist/lib/catalogue/aggregate.d.ts.map +1 -1
- package/dist/lib/catalogue/aggregate.js +88 -0
- package/dist/lib/catalogue/aggregate.js.map +1 -1
- package/dist/lib/catalogue/build.d.ts.map +1 -1
- package/dist/lib/catalogue/build.js +24 -1
- package/dist/lib/catalogue/build.js.map +1 -1
- package/dist/lib/catalogue/builders/capabilities.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/capabilities.js +18 -4
- package/dist/lib/catalogue/builders/capabilities.js.map +1 -1
- package/dist/lib/catalogue/builders/feature-subscription-channels.d.ts +12 -0
- package/dist/lib/catalogue/builders/feature-subscription-channels.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/feature-subscription-channels.js +197 -0
- package/dist/lib/catalogue/builders/feature-subscription-channels.js.map +1 -0
- package/dist/lib/catalogue/builders/index.d.ts +4 -0
- package/dist/lib/catalogue/builders/index.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/index.js +2 -0
- package/dist/lib/catalogue/builders/index.js.map +1 -1
- package/dist/lib/catalogue/builders/product-platform-dependencies.d.ts +10 -0
- package/dist/lib/catalogue/builders/product-platform-dependencies.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/product-platform-dependencies.js +155 -0
- package/dist/lib/catalogue/builders/product-platform-dependencies.js.map +1 -0
- package/dist/lib/catalogue/canonical-schema.yaml +96 -1
- package/dist/lib/catalogue/traceability-loader.d.ts +17 -0
- package/dist/lib/catalogue/traceability-loader.d.ts.map +1 -1
- package/dist/lib/catalogue/traceability-loader.js +6 -0
- package/dist/lib/catalogue/traceability-loader.js.map +1 -1
- package/dist/lib/generate-briefing/index.d.ts +22 -0
- package/dist/lib/generate-briefing/index.d.ts.map +1 -0
- package/dist/lib/generate-briefing/index.js +77 -0
- package/dist/lib/generate-briefing/index.js.map +1 -0
- package/dist/lib/hooks-seed/copilot.d.ts +93 -0
- package/dist/lib/hooks-seed/copilot.d.ts.map +1 -0
- package/dist/lib/hooks-seed/copilot.js +167 -0
- package/dist/lib/hooks-seed/copilot.js.map +1 -0
- package/dist/lib/hooks-seed/index.d.ts +4 -0
- package/dist/lib/hooks-seed/index.d.ts.map +1 -1
- package/dist/lib/hooks-seed/index.js +2 -0
- package/dist/lib/hooks-seed/index.js.map +1 -1
- package/dist/lib/hooks-seed/lifecycle-mapping.d.ts +12 -0
- package/dist/lib/hooks-seed/lifecycle-mapping.d.ts.map +1 -0
- package/dist/lib/hooks-seed/lifecycle-mapping.js +28 -0
- package/dist/lib/hooks-seed/lifecycle-mapping.js.map +1 -0
- package/dist/lib/init/index.d.ts +6 -4
- package/dist/lib/init/index.d.ts.map +1 -1
- package/dist/lib/init/index.js +5 -26
- package/dist/lib/init/index.js.map +1 -1
- package/dist/lib/init/platform.d.ts +9 -0
- package/dist/lib/init/platform.d.ts.map +1 -1
- package/dist/lib/init/platform.js +8 -2
- package/dist/lib/init/platform.js.map +1 -1
- package/dist/lib/sync/briefing-merge.d.ts +34 -0
- package/dist/lib/sync/briefing-merge.d.ts.map +1 -0
- package/dist/lib/sync/briefing-merge.js +82 -0
- package/dist/lib/sync/briefing-merge.js.map +1 -0
- package/dist/lib/sync/copilot-hooks-merge.d.ts +30 -0
- package/dist/lib/sync/copilot-hooks-merge.d.ts.map +1 -0
- package/dist/lib/sync/copilot-hooks-merge.js +96 -0
- package/dist/lib/sync/copilot-hooks-merge.js.map +1 -0
- package/dist/lib/sync/index.d.ts +8 -3
- package/dist/lib/sync/index.d.ts.map +1 -1
- package/dist/lib/sync/index.js +63 -23
- package/dist/lib/sync/index.js.map +1 -1
- package/dist/verbs/generate-briefing.d.ts +3 -0
- package/dist/verbs/generate-briefing.d.ts.map +1 -0
- package/dist/verbs/generate-briefing.js +28 -0
- package/dist/verbs/generate-briefing.js.map +1 -0
- package/dist/verbs/init.d.ts.map +1 -1
- package/dist/verbs/init.js +11 -8
- package/dist/verbs/init.js.map +1 -1
- package/dist/verbs/sync.d.ts.map +1 -1
- package/dist/verbs/sync.js +11 -4
- package/dist/verbs/sync.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Method-layer CLI for the SDD method's SDD repository lifecycle.
|
|
4
4
|
|
|
5
5
|
**Status:** v0.3.0. All four verbs shipped across all three profiles; the
|
|
6
|
-
companion `generate-
|
|
6
|
+
companion `generate-briefing` verb lands alongside (replaces the v0.3–v0.21
|
|
7
|
+
`generate-claude-md` per ADR 0148).
|
|
7
8
|
|
|
8
9
|
## What this is
|
|
9
10
|
|
|
@@ -12,11 +13,11 @@ uses to manage SDD repositories. It has four verbs and three profiles:
|
|
|
12
13
|
|
|
13
14
|
| Verb | Behaviour | v0.3.0 |
|
|
14
15
|
|---|---|---|
|
|
15
|
-
| `init --profile {platform\|application\|integration}` | Scaffold a new SDD repository: render profile-specific manifests, apply the method baseline,
|
|
16
|
-
| `sync` | Pull the latest upstream method baseline into an existing SDD repository | Native TS |
|
|
16
|
+
| `init --profile {platform\|application\|integration}` | Scaffold a new SDD repository: render profile-specific manifests, apply the method baseline, emit `agent-instructions.md` + harness wrapper (per ADR 0148), `git init`, run post-bootstrap validation | Native TS |
|
|
17
|
+
| `sync` | Pull the latest upstream method baseline into an existing SDD repository (refreshes `agent-instructions.md` + the harness wrapper's method-managed block) | Native TS |
|
|
17
18
|
| `validate` | Run the method-level validation suite for this SDD repository (profile-aware dispatch; platform suite = 7 core + optional `docs-all` wrapper) | TS dispatch over bundled + target-repo bash validators |
|
|
18
19
|
| `list` | Enumerate SDD repositories discoverable in the workspace (text or JSON output; profile filter) | Native TS |
|
|
19
|
-
| `generate-
|
|
20
|
+
| `generate-briefing` | Regenerate `agent-instructions.md` + the harness wrapper for an existing SDD repo (no bundle sync) | Native TS |
|
|
20
21
|
| `mcp serve` | Start a local stdio Model Context Protocol (MCP) server exposing the SDD as resources and tools (ADR 0128, Phase 1) | Native TS |
|
|
21
22
|
|
|
22
23
|
Every verb is local git + filesystem. No authentication, no network calls,
|
|
@@ -71,14 +72,33 @@ sdd-cli list --workspace-root ~/Projects/contextua-applications \
|
|
|
71
72
|
--workspace-root ~/Projects/contextua-integrations
|
|
72
73
|
sdd-cli list --profile integration --format json
|
|
73
74
|
|
|
74
|
-
# Regenerate
|
|
75
|
-
sdd-cli generate-
|
|
76
|
-
--platform-name "Contextua" --allow-existing
|
|
75
|
+
# Regenerate the briefing files (agent-instructions.md + CLAUDE.md / AGENTS.md)
|
|
76
|
+
sdd-cli generate-briefing --agent-harness claude-code --allow-overwrite
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
###
|
|
79
|
+
### Briefing layer (`agent-instructions.md` + harness wrapper)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Per [ADR 0148](https://github.com/tomfosteruk/sdd-method/blob/main/docs/method/adr/ADR%200148:%20Method-Defined%20Agent%20Briefing%20Layer.md), `sdd-cli init` and `sdd-cli sync` emit two files at the SDD root:
|
|
82
|
+
|
|
83
|
+
- **`agent-instructions.md`** — fully method-managed, harness-neutral briefing. Overwritten unconditionally on every sync.
|
|
84
|
+
- **The harness wrapper** — `CLAUDE.md` under `--agent-harness claude-code`, `AGENTS.md` under `--agent-harness github-copilot-cli`. Thin pointer with `<!-- method-managed: begin/end -->` markers. The method-managed block is refreshed on sync; adopter content below survives.
|
|
85
|
+
|
|
86
|
+
Templates ship in the bundle at `orchestration/templates/briefing/`. Older bundles that pre-date ADR 0148 sync without emitting these files (graceful skip with a log line).
|
|
87
|
+
|
|
88
|
+
**Migration note (v0.21.x → v0.22.0):** the legacy `generate-claude-md` verb retired in favour of `generate-briefing`. The v0.3–v0.21 native CLAUDE.md renderer is gone — its rich-content shape is replaced by the upstream template-driven thin-pointer shape. Adopters with hand-edited CLAUDE.md files will see sync refuse the wrapper rewrite without `--allow-overwrite` on first run; rehome any custom content below the `method-managed: end` marker before sync, or pass `--allow-overwrite` after backing up.
|
|
89
|
+
|
|
90
|
+
### Agent-harness selection (`--agent-harness`)
|
|
91
|
+
|
|
92
|
+
Per [ADR 0141](https://github.com/tomfosteruk/sdd-method/blob/main/docs/method/adr/ADR%200141:%20Agent-Harness-Neutral%20Skills%20and%20Hooks.md), `sdd-cli init` and `sdd-cli sync` accept `--agent-harness <name>` to drive which hook configuration gets emitted. Supported values:
|
|
93
|
+
|
|
94
|
+
| Value | Hooks surface | MCP surface |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `claude-code` (default, reference) | `.claude/settings.json` `hooks` block — `PreToolUse` method-guard + `SessionStart` ADR-structure check | `.claude/settings.json` `mcpServers` block |
|
|
97
|
+
| `github-copilot-cli` | `.github/hooks/pre-tool-use.json` + `.github/hooks/session-start.json` (per `docs/method/methods/hook-contracts.md`) | not yet wired — ADR 0150 Phase 3 lands the Copilot-CLI MCP surface |
|
|
98
|
+
|
|
99
|
+
Adopters using Cursor / Cline / Aider / custom harnesses implement the portable contracts themselves per ADR 0141 §4.5 — see `docs/method/onboarding/agent-harness-adopter-responsibility.md` in the method baseline.
|
|
100
|
+
|
|
101
|
+
**Behavioural delta:** the flag now defaults to `claude-code` when omitted, where previous versions left it unset (no hooks seeded). The first `sdd-cli sync` after upgrading on an existing repo will start refreshing the Claude hooks block. The dedupe pre-pass shipped in v0.12.2 collapses any unmarked hand-rolled entries that match the method shape, so adopters on v0.12.2+ get sentinel-tagged-in-place rather than duplicates. Adopters on sdd-cli < v0.12.2 should `npm install -g @sdd-method/sdd-cli@latest` before re-syncing.
|
|
82
102
|
|
|
83
103
|
## MCP server (Phase 1)
|
|
84
104
|
|
|
@@ -137,7 +157,7 @@ npm install -g @sdd-method/sdd-cli
|
|
|
137
157
|
npm install
|
|
138
158
|
npm run build # tsc -> dist/
|
|
139
159
|
npm run typecheck # tsc --noEmit
|
|
140
|
-
npm run test # vitest: unit + parity + sync + init + validate + list + generate-
|
|
160
|
+
npm run test # vitest: unit + parity + sync + init + validate + list + generate-briefing + briefing + credential-free
|
|
141
161
|
```
|
|
142
162
|
|
|
143
163
|
Node.js 20 LTS or later is required.
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, CommanderError } from "commander";
|
|
2
2
|
import { getPackageVersion } from "./lib/package-version.js";
|
|
3
3
|
import { registerCatalogue } from "./verbs/catalogue.js";
|
|
4
|
-
import {
|
|
4
|
+
import { registerGenerateBriefing } from "./verbs/generate-briefing.js";
|
|
5
5
|
import { registerInit } from "./verbs/init.js";
|
|
6
6
|
import { registerList } from "./verbs/list.js";
|
|
7
7
|
import { registerMcp } from "./verbs/mcp.js";
|
|
@@ -29,7 +29,7 @@ function buildProgram() {
|
|
|
29
29
|
const program = new Command();
|
|
30
30
|
program
|
|
31
31
|
.name("sdd-cli")
|
|
32
|
-
.description("Method-layer CLI for SDD repository lifecycle — init, sync, validate, list, plan, generate-
|
|
32
|
+
.description("Method-layer CLI for SDD repository lifecycle — init, sync, validate, list, plan, generate-briefing.")
|
|
33
33
|
.version(getPackageVersion(), "-v, --version")
|
|
34
34
|
.addHelpText("after", `\nSpec: ${SPEC_URL}`)
|
|
35
35
|
.exitOverride()
|
|
@@ -42,7 +42,7 @@ function buildProgram() {
|
|
|
42
42
|
registerValidate(program);
|
|
43
43
|
registerList(program);
|
|
44
44
|
registerPlan(program);
|
|
45
|
-
|
|
45
|
+
registerGenerateBriefing(program);
|
|
46
46
|
registerMcp(program);
|
|
47
47
|
registerCatalogue(program);
|
|
48
48
|
for (const { verb, summary } of NOT_YET_IMPLEMENTED) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-harness identifiers — the value space of `--agent-harness` on
|
|
3
|
+
* `sdd-cli init` and `sdd-cli sync` per ADR 0141 §4.6.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code is the reference implementation per ADR 0141 §4.4 and
|
|
6
|
+
* the default. GitHub Copilot CLI is the second reference per
|
|
7
|
+
* `docs/method/methods/hook-contracts.md`. Adopters using a different
|
|
8
|
+
* harness implement the portable contracts themselves per ADR 0141 §4.5.
|
|
9
|
+
*/
|
|
10
|
+
export declare const AGENT_HARNESSES: readonly ["claude-code", "github-copilot-cli"];
|
|
11
|
+
export type AgentHarness = (typeof AGENT_HARNESSES)[number];
|
|
12
|
+
export declare const DEFAULT_AGENT_HARNESS: AgentHarness;
|
|
13
|
+
export declare function isAgentHarness(value: string): value is AgentHarness;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve an optional CLI input to a concrete harness, falling back to
|
|
16
|
+
* the reference default when unset. Throws on an unsupported value so
|
|
17
|
+
* the CLI can surface a clear error to the caller.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveAgentHarness(input: string | undefined): AgentHarness;
|
|
20
|
+
//# sourceMappingURL=agent-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-harness.d.ts","sourceRoot":"","sources":["../../src/lib/agent-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,eAAe,gDAAiD,CAAC;AAE9E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,eAAO,MAAM,qBAAqB,EAAE,YAA4B,CAAC;AAEjE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,YAAY,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAQ3E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-harness identifiers — the value space of `--agent-harness` on
|
|
3
|
+
* `sdd-cli init` and `sdd-cli sync` per ADR 0141 §4.6.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code is the reference implementation per ADR 0141 §4.4 and
|
|
6
|
+
* the default. GitHub Copilot CLI is the second reference per
|
|
7
|
+
* `docs/method/methods/hook-contracts.md`. Adopters using a different
|
|
8
|
+
* harness implement the portable contracts themselves per ADR 0141 §4.5.
|
|
9
|
+
*/
|
|
10
|
+
export const AGENT_HARNESSES = ["claude-code", "github-copilot-cli"];
|
|
11
|
+
export const DEFAULT_AGENT_HARNESS = "claude-code";
|
|
12
|
+
export function isAgentHarness(value) {
|
|
13
|
+
return AGENT_HARNESSES.includes(value);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve an optional CLI input to a concrete harness, falling back to
|
|
17
|
+
* the reference default when unset. Throws on an unsupported value so
|
|
18
|
+
* the CLI can surface a clear error to the caller.
|
|
19
|
+
*/
|
|
20
|
+
export function resolveAgentHarness(input) {
|
|
21
|
+
if (input === undefined)
|
|
22
|
+
return DEFAULT_AGENT_HARNESS;
|
|
23
|
+
if (!isAgentHarness(input)) {
|
|
24
|
+
throw new Error(`Unsupported --agent-harness "${input}". Supported: ${AGENT_HARNESSES.join(", ")}.`);
|
|
25
|
+
}
|
|
26
|
+
return input;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=agent-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-harness.js","sourceRoot":"","sources":["../../src/lib/agent-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,oBAAoB,CAAU,CAAC;AAI9E,MAAM,CAAC,MAAM,qBAAqB,GAAiB,aAAa,CAAC;AAEjE,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAQ,eAAqC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,qBAAqB,CAAC;IACtD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,iBAAiB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACpF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public facade for the briefing layer (ADR 0148).
|
|
3
|
+
*
|
|
4
|
+
* `agent-instructions.md` is the harness-neutral canonical briefing
|
|
5
|
+
* (fully method-managed; sync overwrites unconditionally). Harness
|
|
6
|
+
* wrappers (`CLAUDE.md`, `AGENTS.md`, …) are thin pointers with a
|
|
7
|
+
* `<!-- method-managed: begin/end -->` block at the top; adopter
|
|
8
|
+
* content below survives sync via the existing `writeMarkedBlockFile`
|
|
9
|
+
* machinery.
|
|
10
|
+
*/
|
|
11
|
+
export { AGENT_INSTRUCTIONS_REL_PATH, BRIEFING_TEMPLATE_ROOT, WRAPPER_BLOCK_BEGIN, WRAPPER_BLOCK_END, extractWrapperBlock, findUnresolvedPlaceholders, harnessWrapperOutputPath, renderAgentInstructions, renderHarnessWrapper, substitute, } from "./render.js";
|
|
12
|
+
export type { RenderResult } from "./render.js";
|
|
13
|
+
export { resolveBriefingVariables } from "./variables.js";
|
|
14
|
+
export type { BriefingVariables, ResolveVariablesOptions } from "./variables.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/briefing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public facade for the briefing layer (ADR 0148).
|
|
3
|
+
*
|
|
4
|
+
* `agent-instructions.md` is the harness-neutral canonical briefing
|
|
5
|
+
* (fully method-managed; sync overwrites unconditionally). Harness
|
|
6
|
+
* wrappers (`CLAUDE.md`, `AGENTS.md`, …) are thin pointers with a
|
|
7
|
+
* `<!-- method-managed: begin/end -->` block at the top; adopter
|
|
8
|
+
* content below survives sync via the existing `writeMarkedBlockFile`
|
|
9
|
+
* machinery.
|
|
10
|
+
*/
|
|
11
|
+
export { AGENT_INSTRUCTIONS_REL_PATH, BRIEFING_TEMPLATE_ROOT, WRAPPER_BLOCK_BEGIN, WRAPPER_BLOCK_END, extractWrapperBlock, findUnresolvedPlaceholders, harnessWrapperOutputPath, renderAgentInstructions, renderHarnessWrapper, substitute, } from "./render.js";
|
|
12
|
+
export { resolveBriefingVariables } from "./variables.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/briefing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,GACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for the briefing-layer templates per ADR 0148 + Phase 4 of
|
|
3
|
+
* `adopt-agent-instructions-briefing-layer.md`.
|
|
4
|
+
*
|
|
5
|
+
* Templates ship via the method baseline bundle and land at
|
|
6
|
+
* `<target>/orchestration/templates/briefing/...` after sync's
|
|
7
|
+
* `copyManagedFiles` step. Both `sdd-cli init` and `sdd-cli sync` read
|
|
8
|
+
* the on-disk templates and substitute the four canonical variables.
|
|
9
|
+
*
|
|
10
|
+
* Substitution is a deliberate Handlebars *subset* — `{{var}}` only,
|
|
11
|
+
* no helpers / conditionals / partials. Keeps the runtime-dep
|
|
12
|
+
* allowlist clean (no Handlebars package) and matches the template
|
|
13
|
+
* shapes shipped upstream.
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentHarness } from "../agent-harness.js";
|
|
16
|
+
import type { BriefingVariables } from "./variables.js";
|
|
17
|
+
export declare const BRIEFING_TEMPLATE_ROOT = "orchestration/templates/briefing";
|
|
18
|
+
export declare const AGENT_INSTRUCTIONS_REL_PATH = "agent-instructions.md";
|
|
19
|
+
/** Output filename per harness — e.g. `CLAUDE.md` or `AGENTS.md`. */
|
|
20
|
+
export declare function harnessWrapperOutputPath(harness: AgentHarness): string;
|
|
21
|
+
/**
|
|
22
|
+
* Marker pair the wrapper templates use to delimit the method-managed
|
|
23
|
+
* region. The wrapper sync path slices this region out of the freshly
|
|
24
|
+
* rendered template and hands it to `writeMarkedBlockFile`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const WRAPPER_BLOCK_BEGIN = "<!-- method-managed: begin -->";
|
|
27
|
+
export declare const WRAPPER_BLOCK_END = "<!-- method-managed: end -->";
|
|
28
|
+
/**
|
|
29
|
+
* Substitute the four canonical variables into a template string. Any
|
|
30
|
+
* `{{var}}` placeholder whose name is not in the variable set is left
|
|
31
|
+
* verbatim — callers may pre-check for leftovers if strict rendering
|
|
32
|
+
* is desired.
|
|
33
|
+
*/
|
|
34
|
+
export declare function substitute(template: string, vars: BriefingVariables): string;
|
|
35
|
+
/**
|
|
36
|
+
* Find any unresolved `{{var}}` placeholders. Returns the set of
|
|
37
|
+
* placeholder names (de-duplicated). Callers use this to decide
|
|
38
|
+
* whether to warn or hard-fail on a stale template.
|
|
39
|
+
*/
|
|
40
|
+
export declare function findUnresolvedPlaceholders(rendered: string): string[];
|
|
41
|
+
export interface RenderResult {
|
|
42
|
+
readonly content: string;
|
|
43
|
+
readonly unresolved: readonly string[];
|
|
44
|
+
}
|
|
45
|
+
export declare function renderAgentInstructions(targetRepo: string, vars: BriefingVariables): Promise<RenderResult | null>;
|
|
46
|
+
export declare function renderHarnessWrapper(targetRepo: string, harness: AgentHarness, vars: BriefingVariables): Promise<RenderResult | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Extract the method-managed slice (begin marker through end marker,
|
|
49
|
+
* inclusive) from a fully-rendered wrapper template. Used by the sync
|
|
50
|
+
* flow to drive marker-aware merge while preserving adopter content
|
|
51
|
+
* around the block.
|
|
52
|
+
*
|
|
53
|
+
* Throws when the markers aren't both found — that's a template-
|
|
54
|
+
* authoring bug, not an adopter-side issue.
|
|
55
|
+
*/
|
|
56
|
+
export declare function extractWrapperBlock(rendered: string): string;
|
|
57
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/briefing/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AACzE,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AAenE,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAEtE;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,mCAAmC,CAAC;AACpE,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAUR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrE;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAI9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU5D"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for the briefing-layer templates per ADR 0148 + Phase 4 of
|
|
3
|
+
* `adopt-agent-instructions-briefing-layer.md`.
|
|
4
|
+
*
|
|
5
|
+
* Templates ship via the method baseline bundle and land at
|
|
6
|
+
* `<target>/orchestration/templates/briefing/...` after sync's
|
|
7
|
+
* `copyManagedFiles` step. Both `sdd-cli init` and `sdd-cli sync` read
|
|
8
|
+
* the on-disk templates and substitute the four canonical variables.
|
|
9
|
+
*
|
|
10
|
+
* Substitution is a deliberate Handlebars *subset* — `{{var}}` only,
|
|
11
|
+
* no helpers / conditionals / partials. Keeps the runtime-dep
|
|
12
|
+
* allowlist clean (no Handlebars package) and matches the template
|
|
13
|
+
* shapes shipped upstream.
|
|
14
|
+
*/
|
|
15
|
+
import { access, readFile } from "node:fs/promises";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
export const BRIEFING_TEMPLATE_ROOT = "orchestration/templates/briefing";
|
|
18
|
+
export const AGENT_INSTRUCTIONS_REL_PATH = "agent-instructions.md";
|
|
19
|
+
const HARNESS_WRAPPER_TEMPLATE = {
|
|
20
|
+
"claude-code": {
|
|
21
|
+
templateRel: "claude-code/CLAUDE.md.hbs",
|
|
22
|
+
outputRel: "CLAUDE.md",
|
|
23
|
+
},
|
|
24
|
+
"github-copilot-cli": {
|
|
25
|
+
templateRel: "github-copilot-cli/AGENTS.md.hbs",
|
|
26
|
+
outputRel: "AGENTS.md",
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
/** Output filename per harness — e.g. `CLAUDE.md` or `AGENTS.md`. */
|
|
30
|
+
export function harnessWrapperOutputPath(harness) {
|
|
31
|
+
return HARNESS_WRAPPER_TEMPLATE[harness].outputRel;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Marker pair the wrapper templates use to delimit the method-managed
|
|
35
|
+
* region. The wrapper sync path slices this region out of the freshly
|
|
36
|
+
* rendered template and hands it to `writeMarkedBlockFile`.
|
|
37
|
+
*/
|
|
38
|
+
export const WRAPPER_BLOCK_BEGIN = "<!-- method-managed: begin -->";
|
|
39
|
+
export const WRAPPER_BLOCK_END = "<!-- method-managed: end -->";
|
|
40
|
+
/**
|
|
41
|
+
* Substitute the four canonical variables into a template string. Any
|
|
42
|
+
* `{{var}}` placeholder whose name is not in the variable set is left
|
|
43
|
+
* verbatim — callers may pre-check for leftovers if strict rendering
|
|
44
|
+
* is desired.
|
|
45
|
+
*/
|
|
46
|
+
export function substitute(template, vars) {
|
|
47
|
+
const map = {
|
|
48
|
+
sdd_name: vars.sdd_name,
|
|
49
|
+
repo_kind: vars.repo_kind,
|
|
50
|
+
baseline_version: vars.baseline_version,
|
|
51
|
+
sync_date: vars.sync_date,
|
|
52
|
+
};
|
|
53
|
+
return template.replace(/\{\{\s*([a-z_][a-z0-9_]*)\s*\}\}/g, (full, key) => {
|
|
54
|
+
return key in map ? map[key] : full;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Find any unresolved `{{var}}` placeholders. Returns the set of
|
|
59
|
+
* placeholder names (de-duplicated). Callers use this to decide
|
|
60
|
+
* whether to warn or hard-fail on a stale template.
|
|
61
|
+
*/
|
|
62
|
+
export function findUnresolvedPlaceholders(rendered) {
|
|
63
|
+
const found = new Set();
|
|
64
|
+
for (const m of rendered.matchAll(/\{\{\s*([a-z_][a-z0-9_]*)\s*\}\}/g)) {
|
|
65
|
+
found.add(m[1]);
|
|
66
|
+
}
|
|
67
|
+
return [...found];
|
|
68
|
+
}
|
|
69
|
+
export async function renderAgentInstructions(targetRepo, vars) {
|
|
70
|
+
const templatePath = join(targetRepo, BRIEFING_TEMPLATE_ROOT, "agent-instructions.md.hbs");
|
|
71
|
+
return renderFromPath(templatePath, vars);
|
|
72
|
+
}
|
|
73
|
+
export async function renderHarnessWrapper(targetRepo, harness, vars) {
|
|
74
|
+
const { templateRel } = HARNESS_WRAPPER_TEMPLATE[harness];
|
|
75
|
+
const templatePath = join(targetRepo, BRIEFING_TEMPLATE_ROOT, templateRel);
|
|
76
|
+
return renderFromPath(templatePath, vars);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Extract the method-managed slice (begin marker through end marker,
|
|
80
|
+
* inclusive) from a fully-rendered wrapper template. Used by the sync
|
|
81
|
+
* flow to drive marker-aware merge while preserving adopter content
|
|
82
|
+
* around the block.
|
|
83
|
+
*
|
|
84
|
+
* Throws when the markers aren't both found — that's a template-
|
|
85
|
+
* authoring bug, not an adopter-side issue.
|
|
86
|
+
*/
|
|
87
|
+
export function extractWrapperBlock(rendered) {
|
|
88
|
+
const beginIdx = rendered.indexOf(WRAPPER_BLOCK_BEGIN);
|
|
89
|
+
const endIdx = rendered.indexOf(WRAPPER_BLOCK_END, beginIdx);
|
|
90
|
+
if (beginIdx === -1 || endIdx === -1) {
|
|
91
|
+
throw new Error("Wrapper template missing method-managed markers: " +
|
|
92
|
+
`expected ${WRAPPER_BLOCK_BEGIN} ... ${WRAPPER_BLOCK_END} (template-authoring bug)`);
|
|
93
|
+
}
|
|
94
|
+
return rendered.slice(beginIdx, endIdx + WRAPPER_BLOCK_END.length);
|
|
95
|
+
}
|
|
96
|
+
async function renderFromPath(templatePath, vars) {
|
|
97
|
+
if (!(await fileExists(templatePath)))
|
|
98
|
+
return null;
|
|
99
|
+
const raw = await readFile(templatePath, "utf8");
|
|
100
|
+
const content = substitute(raw, vars);
|
|
101
|
+
return { content, unresolved: findUnresolvedPlaceholders(content) };
|
|
102
|
+
}
|
|
103
|
+
async function fileExists(path) {
|
|
104
|
+
try {
|
|
105
|
+
await access(path);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/lib/briefing/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable resolution for the briefing layer per ADR 0148 §4.1 + the
|
|
3
|
+
* Phase 4 setup notes in `adopt-agent-instructions-briefing-layer.md`.
|
|
4
|
+
*
|
|
5
|
+
* The four variables are sourced from target-repo state:
|
|
6
|
+
*
|
|
7
|
+
* sdd_name basename(targetRepo) — overridden by
|
|
8
|
+
* `.sdd/sdd-manifest.yaml::sdd_id` when present.
|
|
9
|
+
* repo_kind `.sdd-repo-kind` content (platform-product /
|
|
10
|
+
* application-product / integration-product /
|
|
11
|
+
* reverse-corpus).
|
|
12
|
+
* baseline_version forward-base bundle's `bundle_version` from
|
|
13
|
+
* `method-baseline.lock`.
|
|
14
|
+
* sync_date caller-supplied ISO date (today for init/sync).
|
|
15
|
+
*
|
|
16
|
+
* No new YAML parser added — the manifest is a single optional scalar
|
|
17
|
+
* read; existing scalar-line parser in src/lib/bundle.ts is the
|
|
18
|
+
* precedent for this style.
|
|
19
|
+
*/
|
|
20
|
+
import { type RepoKind } from "../repo-kind.js";
|
|
21
|
+
export interface BriefingVariables {
|
|
22
|
+
readonly sdd_name: string;
|
|
23
|
+
readonly repo_kind: RepoKind;
|
|
24
|
+
readonly baseline_version: string;
|
|
25
|
+
readonly sync_date: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ResolveVariablesOptions {
|
|
28
|
+
readonly targetRepo: string;
|
|
29
|
+
/**
|
|
30
|
+
* ISO date (YYYY-MM-DD) to record in the rendered briefing as the
|
|
31
|
+
* sync_date. Caller passes the canonical timestamp for the operation
|
|
32
|
+
* (init's or sync's now). Defaults to today's date in UTC.
|
|
33
|
+
*/
|
|
34
|
+
readonly syncDate?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Optional repo_kind override for init flows where the marker file
|
|
37
|
+
* may not exist yet at resolve time. When set, skips the
|
|
38
|
+
* `.sdd-repo-kind` read.
|
|
39
|
+
*/
|
|
40
|
+
readonly repoKindOverride?: RepoKind;
|
|
41
|
+
/**
|
|
42
|
+
* Optional baseline_version override. Sync uses this to pass the
|
|
43
|
+
* incoming bundle's version directly so the renderer doesn't have
|
|
44
|
+
* to wait for `method-baseline.lock` to be updated.
|
|
45
|
+
*/
|
|
46
|
+
readonly baselineVersionOverride?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function resolveBriefingVariables(opts: ResolveVariablesOptions): Promise<BriefingVariables>;
|
|
49
|
+
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../src/lib/briefing/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAS5B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable resolution for the briefing layer per ADR 0148 §4.1 + the
|
|
3
|
+
* Phase 4 setup notes in `adopt-agent-instructions-briefing-layer.md`.
|
|
4
|
+
*
|
|
5
|
+
* The four variables are sourced from target-repo state:
|
|
6
|
+
*
|
|
7
|
+
* sdd_name basename(targetRepo) — overridden by
|
|
8
|
+
* `.sdd/sdd-manifest.yaml::sdd_id` when present.
|
|
9
|
+
* repo_kind `.sdd-repo-kind` content (platform-product /
|
|
10
|
+
* application-product / integration-product /
|
|
11
|
+
* reverse-corpus).
|
|
12
|
+
* baseline_version forward-base bundle's `bundle_version` from
|
|
13
|
+
* `method-baseline.lock`.
|
|
14
|
+
* sync_date caller-supplied ISO date (today for init/sync).
|
|
15
|
+
*
|
|
16
|
+
* No new YAML parser added — the manifest is a single optional scalar
|
|
17
|
+
* read; existing scalar-line parser in src/lib/bundle.ts is the
|
|
18
|
+
* precedent for this style.
|
|
19
|
+
*/
|
|
20
|
+
import { access, readFile } from "node:fs/promises";
|
|
21
|
+
import { basename, join } from "node:path";
|
|
22
|
+
import { readLockFile } from "../lock-file.js";
|
|
23
|
+
import { readRepoKind } from "../repo-kind.js";
|
|
24
|
+
export async function resolveBriefingVariables(opts) {
|
|
25
|
+
const sdd_name = await resolveSddName(opts.targetRepo);
|
|
26
|
+
const repo_kind = opts.repoKindOverride ?? (await requireRepoKind(opts.targetRepo));
|
|
27
|
+
const baseline_version = opts.baselineVersionOverride ??
|
|
28
|
+
(await resolveBaselineVersion(opts.targetRepo));
|
|
29
|
+
const sync_date = opts.syncDate ?? todayIso();
|
|
30
|
+
return { sdd_name, repo_kind, baseline_version, sync_date };
|
|
31
|
+
}
|
|
32
|
+
async function resolveSddName(targetRepo) {
|
|
33
|
+
const fromManifest = await tryReadSddManifestId(targetRepo);
|
|
34
|
+
if (fromManifest !== null)
|
|
35
|
+
return fromManifest;
|
|
36
|
+
return basename(targetRepo);
|
|
37
|
+
}
|
|
38
|
+
async function tryReadSddManifestId(targetRepo) {
|
|
39
|
+
const path = join(targetRepo, ".sdd", "sdd-manifest.yaml");
|
|
40
|
+
if (!(await fileExists(path)))
|
|
41
|
+
return null;
|
|
42
|
+
let raw;
|
|
43
|
+
try {
|
|
44
|
+
raw = await readFile(path, "utf8");
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// Single-scalar line parse, matching bundle.ts style. The catalogue
|
|
50
|
+
// surface uses a full YAML loader elsewhere; here we only want one
|
|
51
|
+
// optional field, so this stays dependency-light.
|
|
52
|
+
for (const line of raw.split("\n")) {
|
|
53
|
+
const m = /^sdd_id: (.+)$/.exec(line.trim());
|
|
54
|
+
if (m) {
|
|
55
|
+
const value = m[1].trim().replace(/^["']|["']$/g, "");
|
|
56
|
+
if (value.length > 0)
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
async function requireRepoKind(targetRepo) {
|
|
63
|
+
const kind = await readRepoKind(targetRepo);
|
|
64
|
+
if (!kind) {
|
|
65
|
+
throw new Error(`Cannot resolve briefing variables: .sdd-repo-kind missing at ${targetRepo}`);
|
|
66
|
+
}
|
|
67
|
+
return kind;
|
|
68
|
+
}
|
|
69
|
+
async function resolveBaselineVersion(targetRepo) {
|
|
70
|
+
const lock = await readLockFile(targetRepo);
|
|
71
|
+
if (!lock) {
|
|
72
|
+
throw new Error(`Cannot resolve baseline_version: method-baseline.lock missing at ${targetRepo}`);
|
|
73
|
+
}
|
|
74
|
+
const forwardBase = lock.bundles.find((b) => b.isForwardBase);
|
|
75
|
+
if (!forwardBase) {
|
|
76
|
+
throw new Error(`Cannot resolve baseline_version: no forward-base bundle in method-baseline.lock at ${targetRepo}`);
|
|
77
|
+
}
|
|
78
|
+
return forwardBase.bundleVersion;
|
|
79
|
+
}
|
|
80
|
+
function todayIso() {
|
|
81
|
+
return new Date().toISOString().slice(0, 10);
|
|
82
|
+
}
|
|
83
|
+
async function fileExists(path) {
|
|
84
|
+
try {
|
|
85
|
+
await access(path);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../../src/lib/briefing/variables.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CatalogueDef } from "./schema-loader.js";
|
|
2
2
|
import { parseCatalogueCsv } from "./csv-reader.js";
|
|
3
3
|
import { type CatalogueRow } from "./csv-writer.js";
|
|
4
|
+
import { FindingsLog } from "./findings.js";
|
|
4
5
|
export interface AggregateInputs {
|
|
5
6
|
/** Path to the ecosystem-root SDD repo (defaults to cwd). */
|
|
6
7
|
readonly sddPath?: string;
|
|
@@ -31,6 +32,24 @@ export interface AggregateResult {
|
|
|
31
32
|
export type Writer = (s: string) => void;
|
|
32
33
|
export declare function runCatalogueAggregate(inputs: AggregateInputs, write: Writer): Promise<AggregateResult>;
|
|
33
34
|
declare function stampSourceSddId(catalogue: CatalogueDef, rows: readonly Record<string, string>[], sourceSddId: string): CatalogueRow[];
|
|
35
|
+
/**
|
|
36
|
+
* Derive `cross_sdd_platform_capability` rows by joining each consuming
|
|
37
|
+
* SDD's `product_platform_dependencies` rows against every platform SDD's
|
|
38
|
+
* `capability_service` rows on `target_service_id == service_id`.
|
|
39
|
+
*
|
|
40
|
+
* Emits one row per resolved (consuming-product, platform-capability)
|
|
41
|
+
* pair. A consuming dependency whose `target_service_id` doesn't resolve
|
|
42
|
+
* against any `capability_service` row is logged as an `orphan` finding
|
|
43
|
+
* and produces no row.
|
|
44
|
+
*
|
|
45
|
+
* Duplicate composite ids (same consuming-product → same platform-capability
|
|
46
|
+
* → same service) are deduped silently — they would arise only when the
|
|
47
|
+
* same service belongs to multiple capabilities on the platform side,
|
|
48
|
+
* which is itself a platform-side data quality concern surfaced elsewhere.
|
|
49
|
+
*
|
|
50
|
+
* Exported for testing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function deriveCrossSddPlatformCapability(productPlatformDeps: readonly CatalogueRow[], capabilityServices: readonly CatalogueRow[], findings: FindingsLog): CatalogueRow[];
|
|
34
53
|
export declare const __test_only__: {
|
|
35
54
|
stampSourceSddId: typeof stampSourceSddId;
|
|
36
55
|
parseCatalogueCsv: typeof parseCatalogueCsv;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/aggregate.ts"],"names":[],"mappings":"AA+BA,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClG,OAAO,EAAoB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/aggregate.ts"],"names":[],"mappings":"AA+BA,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClG,OAAO,EAAoB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,mEAAmE;IACnE,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzC,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,CAAC,CAmL1B;AAiFD,iBAAS,gBAAgB,CACvB,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EACvC,WAAW,EAAE,MAAM,GAClB,YAAY,EAAE,CAUhB;AA0LD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gCAAgC,CAC9C,mBAAmB,EAAE,SAAS,YAAY,EAAE,EAC5C,kBAAkB,EAAE,SAAS,YAAY,EAAE,EAC3C,QAAQ,EAAE,WAAW,GACpB,YAAY,EAAE,CA6DhB;AAID,eAAO,MAAM,aAAa;;;CAA0C,CAAC"}
|