@momentiq/dark-factory-cli 2.0.0 → 2.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.
Files changed (142) hide show
  1. package/dist/adapters/static-schema-lint.js +1 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +18 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/onboard.d.ts +69 -0
  6. package/dist/commands/onboard.d.ts.map +1 -0
  7. package/dist/commands/onboard.js +323 -0
  8. package/dist/commands/onboard.js.map +1 -0
  9. package/dist/cycle-doc-validator/validate_cycle_doc.py +131 -60
  10. package/dist/doctor.d.ts.map +1 -1
  11. package/dist/doctor.js +20 -0
  12. package/dist/doctor.js.map +1 -1
  13. package/dist/mcp/server.d.ts.map +1 -1
  14. package/dist/mcp/server.js +2 -0
  15. package/dist/mcp/server.js.map +1 -1
  16. package/dist/mcp/tools/onboard.d.ts +6 -0
  17. package/dist/mcp/tools/onboard.d.ts.map +1 -0
  18. package/dist/mcp/tools/onboard.js +115 -0
  19. package/dist/mcp/tools/onboard.js.map +1 -0
  20. package/dist/onboard/analyze.d.ts +7 -0
  21. package/dist/onboard/analyze.d.ts.map +1 -0
  22. package/dist/onboard/analyze.js +86 -0
  23. package/dist/onboard/analyze.js.map +1 -0
  24. package/dist/onboard/analyzer.d.ts +15 -0
  25. package/dist/onboard/analyzer.d.ts.map +1 -0
  26. package/dist/onboard/analyzer.js +52 -0
  27. package/dist/onboard/analyzer.js.map +1 -0
  28. package/dist/onboard/analyzers/ci.d.ts +3 -0
  29. package/dist/onboard/analyzers/ci.d.ts.map +1 -0
  30. package/dist/onboard/analyzers/ci.js +112 -0
  31. package/dist/onboard/analyzers/ci.js.map +1 -0
  32. package/dist/onboard/analyzers/docs.d.ts +3 -0
  33. package/dist/onboard/analyzers/docs.d.ts.map +1 -0
  34. package/dist/onboard/analyzers/docs.js +151 -0
  35. package/dist/onboard/analyzers/docs.js.map +1 -0
  36. package/dist/onboard/analyzers/git.d.ts +3 -0
  37. package/dist/onboard/analyzers/git.d.ts.map +1 -0
  38. package/dist/onboard/analyzers/git.js +87 -0
  39. package/dist/onboard/analyzers/git.js.map +1 -0
  40. package/dist/onboard/analyzers/lockfile.d.ts +3 -0
  41. package/dist/onboard/analyzers/lockfile.d.ts.map +1 -0
  42. package/dist/onboard/analyzers/lockfile.js +285 -0
  43. package/dist/onboard/analyzers/lockfile.js.map +1 -0
  44. package/dist/onboard/analyzers/manifest.d.ts +3 -0
  45. package/dist/onboard/analyzers/manifest.d.ts.map +1 -0
  46. package/dist/onboard/analyzers/manifest.js +228 -0
  47. package/dist/onboard/analyzers/manifest.js.map +1 -0
  48. package/dist/onboard/analyzers/tree.d.ts +3 -0
  49. package/dist/onboard/analyzers/tree.d.ts.map +1 -0
  50. package/dist/onboard/analyzers/tree.js +196 -0
  51. package/dist/onboard/analyzers/tree.js.map +1 -0
  52. package/dist/onboard/apply-plan.d.ts +29 -0
  53. package/dist/onboard/apply-plan.d.ts.map +1 -0
  54. package/dist/onboard/apply-plan.js +80 -0
  55. package/dist/onboard/apply-plan.js.map +1 -0
  56. package/dist/onboard/auto-profile.d.ts +3 -0
  57. package/dist/onboard/auto-profile.d.ts.map +1 -0
  58. package/dist/onboard/auto-profile.js +20 -0
  59. package/dist/onboard/auto-profile.js.map +1 -0
  60. package/dist/onboard/fixtures/replay-git-history.d.ts +20 -0
  61. package/dist/onboard/fixtures/replay-git-history.d.ts.map +1 -0
  62. package/dist/onboard/fixtures/replay-git-history.js +91 -0
  63. package/dist/onboard/fixtures/replay-git-history.js.map +1 -0
  64. package/dist/onboard/generate-plan.d.ts +18 -0
  65. package/dist/onboard/generate-plan.d.ts.map +1 -0
  66. package/dist/onboard/generate-plan.js +68 -0
  67. package/dist/onboard/generate-plan.js.map +1 -0
  68. package/dist/onboard/llm-client.d.ts +45 -0
  69. package/dist/onboard/llm-client.d.ts.map +1 -0
  70. package/dist/onboard/llm-client.js +84 -0
  71. package/dist/onboard/llm-client.js.map +1 -0
  72. package/dist/onboard/prompts/scaffold.md +93 -0
  73. package/dist/onboard/prompts.d.ts +13 -0
  74. package/dist/onboard/prompts.d.ts.map +1 -0
  75. package/dist/onboard/prompts.js +54 -0
  76. package/dist/onboard/prompts.js.map +1 -0
  77. package/dist/onboard/scaffold-schema.d.ts +194 -0
  78. package/dist/onboard/scaffold-schema.d.ts.map +1 -0
  79. package/dist/onboard/scaffold-schema.js +73 -0
  80. package/dist/onboard/scaffold-schema.js.map +1 -0
  81. package/dist/onboard/schema.d.ts +545 -0
  82. package/dist/onboard/schema.d.ts.map +1 -0
  83. package/dist/onboard/schema.js +148 -0
  84. package/dist/onboard/schema.js.map +1 -0
  85. package/dist/onboard/seeders/adr.d.ts +3 -0
  86. package/dist/onboard/seeders/adr.d.ts.map +1 -0
  87. package/dist/onboard/seeders/adr.js +212 -0
  88. package/dist/onboard/seeders/adr.js.map +1 -0
  89. package/dist/onboard/seeders/agent-review-config/cloud.canonical.json +22 -0
  90. package/dist/onboard/seeders/agent-review-config/local.canonical.json +21 -0
  91. package/dist/onboard/seeders/agent-review-config.d.ts +3 -0
  92. package/dist/onboard/seeders/agent-review-config.d.ts.map +1 -0
  93. package/dist/onboard/seeders/agent-review-config.js +38 -0
  94. package/dist/onboard/seeders/agent-review-config.js.map +1 -0
  95. package/dist/onboard/seeders/cycle1-bootstrap.d.ts +3 -0
  96. package/dist/onboard/seeders/cycle1-bootstrap.d.ts.map +1 -0
  97. package/dist/onboard/seeders/cycle1-bootstrap.js +76 -0
  98. package/dist/onboard/seeders/cycle1-bootstrap.js.map +1 -0
  99. package/dist/onboard/seeders/index.d.ts +47 -0
  100. package/dist/onboard/seeders/index.d.ts.map +1 -0
  101. package/dist/onboard/seeders/index.js +37 -0
  102. package/dist/onboard/seeders/index.js.map +1 -0
  103. package/dist/onboard/seeders/runbook.d.ts +13 -0
  104. package/dist/onboard/seeders/runbook.d.ts.map +1 -0
  105. package/dist/onboard/seeders/runbook.js +85 -0
  106. package/dist/onboard/seeders/runbook.js.map +1 -0
  107. package/dist/onboard/seeders/templates/adr.md.tmpl +26 -0
  108. package/dist/onboard/seeders/templates/cycle1-bootstrap.md.tmpl +64 -0
  109. package/dist/onboard/seeders/templates/runbook.md.tmpl +26 -0
  110. package/dist/onboard/template-loader.d.ts +20 -0
  111. package/dist/onboard/template-loader.d.ts.map +1 -0
  112. package/dist/onboard/template-loader.js +143 -0
  113. package/dist/onboard/template-loader.js.map +1 -0
  114. package/dist/onboard/template-ref.d.ts +15 -0
  115. package/dist/onboard/template-ref.d.ts.map +1 -0
  116. package/dist/onboard/template-ref.js +45 -0
  117. package/dist/onboard/template-ref.js.map +1 -0
  118. package/dist/onboard/validate.d.ts +19 -0
  119. package/dist/onboard/validate.d.ts.map +1 -0
  120. package/dist/onboard/validate.js +127 -0
  121. package/dist/onboard/validate.js.map +1 -0
  122. package/dist/onboard/writers/dry-run-renderer.d.ts +6 -0
  123. package/dist/onboard/writers/dry-run-renderer.d.ts.map +1 -0
  124. package/dist/onboard/writers/dry-run-renderer.js +88 -0
  125. package/dist/onboard/writers/dry-run-renderer.js.map +1 -0
  126. package/dist/onboard/writers/emit.d.ts +6 -0
  127. package/dist/onboard/writers/emit.d.ts.map +1 -0
  128. package/dist/onboard/writers/emit.js +29 -0
  129. package/dist/onboard/writers/emit.js.map +1 -0
  130. package/dist/onboard/writers/merge.d.ts +16 -0
  131. package/dist/onboard/writers/merge.d.ts.map +1 -0
  132. package/dist/onboard/writers/merge.js +142 -0
  133. package/dist/onboard/writers/merge.js.map +1 -0
  134. package/dist/onboard/writers/pr-writer.d.ts +44 -0
  135. package/dist/onboard/writers/pr-writer.d.ts.map +1 -0
  136. package/dist/onboard/writers/pr-writer.js +104 -0
  137. package/dist/onboard/writers/pr-writer.js.map +1 -0
  138. package/dist/onboard/writers/skip.d.ts +9 -0
  139. package/dist/onboard/writers/skip.d.ts.map +1 -0
  140. package/dist/onboard/writers/skip.js +9 -0
  141. package/dist/onboard/writers/skip.js.map +1 -0
  142. package/package.json +8 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runbook.js","sourceRoot":"","sources":["../../../src/onboard/seeders/runbook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ # ADR {year}-{nn} — {title}
2
+
3
+ - **Status:** Proposed
4
+ - **Date:** {date}
5
+ - **Deciders:** {deciders}
6
+ - **Scope:** {scope}
7
+
8
+ ## Context
9
+
10
+ This decision was surfaced from the deterministic Stage A analysis of the repo at {repo_root}.
11
+ The relevant evidence:
12
+
13
+ {evidence_bullets}
14
+
15
+ ## Decision
16
+
17
+ {rationale}
18
+
19
+ ## Consequences
20
+
21
+ {consequences}
22
+
23
+ ---
24
+
25
+ Generated by `df onboard` (cycle 15 Phase C). The maintainer should expand each
26
+ section with repo-specific nuance the deterministic analysis could not produce.
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: "Cycle 1 — {repo_name} bootstrap"
3
+ status: "draft"
4
+ owner: "@{owner}-maintainers"
5
+ started: "{date}"
6
+ target: null
7
+ closed: null
8
+ related_issues: []
9
+ related_repos:
10
+ - "{canonical_name}"
11
+ tags:
12
+ - bootstrap
13
+ - cycle1
14
+ - agent-context
15
+ ---
16
+
17
+ # Cycle 1 — {repo_name} bootstrap
18
+
19
+ > Generated by `df onboard` (cycle 15 Phase C) from the deterministic Stage A
20
+ > analysis of this repo. The maintainer should expand each section with the
21
+ > nuance the analyzer could not produce.
22
+
23
+ ## Scope
24
+
25
+ Bootstrap the agent-context set for `{canonical_name}` so AI-driven development
26
+ (Claude Code, Cursor, Codex, Gemini) operates with the same architectural
27
+ context as a human maintainer. This cycle delivers the initial `CLAUDE.md`,
28
+ `AGENTS.md`, `docs/` skeleton, and the first ADRs surfaced from the repo's
29
+ existing decisions.
30
+
31
+ ## Stack
32
+
33
+ {stack_bullets}
34
+
35
+ ## Services
36
+
37
+ {services_bullets}
38
+
39
+ ## Deploy story
40
+
41
+ {deploy_story_body}
42
+
43
+ ## Dark Factory gate posture
44
+
45
+ {df_presence_body}
46
+
47
+ ## Agent context set
48
+
49
+ {agent_context_body}
50
+
51
+ ## Exit criteria
52
+
53
+ - [ ] `CLAUDE.md` lists every section relevant to this repo's actual stack + services.
54
+ - [ ] `AGENTS.md` documents the per-vendor critic posture this repo runs.
55
+ - [ ] `docs/PRINCIPLES.md` exists with the project's engineering principles.
56
+ - [ ] `docs/roadmap/` directory exists; this doc is its first entry.
57
+ - [ ] At least 3 ADRs under `docs/ADR/` (seeded from this repo's surfaced decisions).
58
+ - [ ] `df doctor` against this repo passes `agent_context_*` checks.
59
+
60
+ ## Open questions
61
+
62
+ - Which on-call rotation owns this repo's deploy story?
63
+ - Are there security boundaries beyond the standard DF gate posture above?
64
+ - Does this repo need a separate runbook beyond the seeded deploy runbook?
@@ -0,0 +1,26 @@
1
+ {{!-- packages/cli/src/onboard/seeders/runbook.md.tmpl --}}
2
+ # Runbook: {workflow_name}
3
+
4
+ > Generated by `df onboard` (cycle 15 Phase C) from the analysis of
5
+ > `{workflow_path}`. The maintainer should expand each section with the
6
+ > nuance the analyzer could not produce.
7
+
8
+ **Workflow:** [`{workflow_path}`]({workflow_path}){workflow_triggers_note}
9
+
10
+ ## Triggering
11
+
12
+ {triggering_body}
13
+
14
+ ## Verifying success
15
+
16
+ {verifying_body}
17
+
18
+ ## Rollback
19
+
20
+ {rollback_body}
21
+
22
+ ## On-call
23
+
24
+ - Who is paged when this workflow fails? (TODO: name the rotation)
25
+ - Where do alerts surface? (TODO: link the alert source)
26
+ - What is the SLO this workflow is meant to satisfy? (TODO)
@@ -0,0 +1,20 @@
1
+ import { parseTemplateRef, type ParsedTemplateRef, type GhTemplateRef, type FileTemplateRef } from "./template-ref.js";
2
+ export { parseTemplateRef };
3
+ export type { ParsedTemplateRef, GhTemplateRef, FileTemplateRef };
4
+ export declare const MAX_TEMPLATE_FILES = 200;
5
+ export declare const MAX_TEMPLATE_FILE_SIZE = 65536;
6
+ export interface TemplateFile {
7
+ path: string;
8
+ content: string;
9
+ }
10
+ export interface Template {
11
+ canonicalRef: string;
12
+ resolvedSha: string;
13
+ cacheDir: string;
14
+ files: TemplateFile[];
15
+ }
16
+ export interface LoadOptions {
17
+ cacheRoot?: string;
18
+ }
19
+ export declare function loadTemplate(canonicalRef: string, opts?: LoadOptions): Promise<Template>;
20
+ //# sourceMappingURL=template-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-loader.d.ts","sourceRoot":"","sources":["../../src/onboard/template-loader.ts"],"names":[],"mappings":"AAwBA,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC;AAIlE,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAG7C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiGD,wBAAsB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAalG"}
@@ -0,0 +1,143 @@
1
+ // packages/cli/src/onboard/template-loader.ts
2
+ //
3
+ // Template loader for `df onboard`'s Stage B input.
4
+ // Resolves a templateRef (gh:<owner>/<repo>@<ref> | file://<abs>@<ref>) to a
5
+ // content-addressed cache directory, then walks the directory and returns
6
+ // the file set (subject to the Phase B filter rules: no .git/node_modules,
7
+ // ≤ 64 KB per file, no binary, ≤ 200 entries total).
8
+ //
9
+ // Cache key is the resolved sha — so `latest` and the sha it resolves to
10
+ // share one entry, no churn on re-runs.
11
+ //
12
+ // Ref parsing is delegated to template-ref.ts (Task 1's co-located foundation
13
+ // file) — this loader consumes parseTemplateRef + the parsed-ref types from
14
+ // there. Round-4 restructure-completion: keeping the parser in the foundation
15
+ // file means schema (Task 1) and loader (Task 3) cannot drift on the semantic
16
+ // check, AND no circular import is possible (template-ref.ts imports nothing
17
+ // from schema or loader, so the loader can import ScaffoldPlanSchema in the
18
+ // future if it ever needs to).
19
+ import { execFile } from "node:child_process";
20
+ import { promisify } from "node:util";
21
+ import { mkdir, readdir, readFile, rename, rm, stat, cp } from "node:fs/promises";
22
+ import { homedir } from "node:os";
23
+ import { join, relative } from "node:path";
24
+ import { parseTemplateRef, } from "./template-ref.js";
25
+ export { parseTemplateRef };
26
+ const ex = promisify(execFile);
27
+ export const MAX_TEMPLATE_FILES = 200;
28
+ export const MAX_TEMPLATE_FILE_SIZE = 65_536;
29
+ const SKIP_DIRS = new Set([".git", "node_modules", "dist", "build"]);
30
+ const FORTY_HEX = /^[0-9a-f]{40}$/i;
31
+ async function resolveSha(parsed) {
32
+ if (parsed.kind === "file") {
33
+ return parsed.ref;
34
+ }
35
+ if (FORTY_HEX.test(parsed.ref)) {
36
+ return parsed.ref.toLowerCase();
37
+ }
38
+ const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
39
+ const refArg = parsed.ref === "latest" ? "HEAD" :
40
+ parsed.ref.startsWith("refs/") ? parsed.ref :
41
+ parsed.ref;
42
+ const { stdout } = await ex("git", ["ls-remote", url, refArg]);
43
+ const sha = stdout.split(/\s/)[0];
44
+ if (!sha || !FORTY_HEX.test(sha)) {
45
+ throw new Error(`df onboard: could not resolve ref "${parsed.ref}" against ${url}. ` +
46
+ "Verify the ref exists and the repo is publicly readable.");
47
+ }
48
+ return sha.toLowerCase();
49
+ }
50
+ function cacheDirFor(parsed, sha, cacheRoot) {
51
+ if (parsed.kind === "gh") {
52
+ return join(cacheRoot, `${parsed.owner}__${parsed.repo}__${sha}`);
53
+ }
54
+ const tag = parsed.path.replace(/[^A-Za-z0-9._-]/g, "_");
55
+ return join(cacheRoot, `file__${tag}__${sha}`);
56
+ }
57
+ async function populateCache(parsed, sha, cacheDir) {
58
+ const tmp = `${cacheDir}.tmp-${process.pid}-${Date.now()}`;
59
+ await rm(tmp, { recursive: true, force: true });
60
+ if (parsed.kind === "file") {
61
+ await cp(parsed.path, tmp, { recursive: true });
62
+ }
63
+ else {
64
+ const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
65
+ await mkdir(tmp, { recursive: true });
66
+ await ex("git", ["init", "-q"], { cwd: tmp });
67
+ await ex("git", ["fetch", "--depth", "1", "-q", url, sha], { cwd: tmp });
68
+ await ex("git", ["checkout", "-q", "FETCH_HEAD"], { cwd: tmp });
69
+ await rm(join(tmp, ".git"), { recursive: true, force: true });
70
+ }
71
+ try {
72
+ await rename(tmp, cacheDir);
73
+ }
74
+ catch (err) {
75
+ await rm(tmp, { recursive: true, force: true });
76
+ try {
77
+ await stat(cacheDir);
78
+ }
79
+ catch {
80
+ throw err;
81
+ }
82
+ }
83
+ }
84
+ async function isBinary(filepath) {
85
+ const head = Buffer.alloc(8192);
86
+ const fh = await import("node:fs/promises").then((m) => m.open(filepath, "r"));
87
+ try {
88
+ const { bytesRead } = await fh.read(head, 0, head.length, 0);
89
+ for (let i = 0; i < bytesRead; i++)
90
+ if (head[i] === 0)
91
+ return true;
92
+ return false;
93
+ }
94
+ finally {
95
+ await fh.close();
96
+ }
97
+ }
98
+ async function walkTemplate(rootDir) {
99
+ const out = [];
100
+ async function recur(dir) {
101
+ const entries = await readdir(dir, { withFileTypes: true });
102
+ for (const e of entries) {
103
+ const abs = join(dir, e.name);
104
+ if (e.isDirectory()) {
105
+ if (SKIP_DIRS.has(e.name))
106
+ continue;
107
+ await recur(abs);
108
+ continue;
109
+ }
110
+ if (!e.isFile())
111
+ continue;
112
+ const st = await stat(abs);
113
+ if (st.size > MAX_TEMPLATE_FILE_SIZE)
114
+ continue;
115
+ if (await isBinary(abs))
116
+ continue;
117
+ const rel = relative(rootDir, abs);
118
+ out.push({ path: rel, content: await readFile(abs, "utf8") });
119
+ if (out.length > MAX_TEMPLATE_FILES) {
120
+ throw new Error(`df onboard: template file count exceeds ${MAX_TEMPLATE_FILES}. ` +
121
+ "Reduce the template surface or raise MAX_TEMPLATE_FILES (cycle 15 Phase B / B-D4).");
122
+ }
123
+ }
124
+ }
125
+ await recur(rootDir);
126
+ return out;
127
+ }
128
+ export async function loadTemplate(canonicalRef, opts = {}) {
129
+ const parsed = parseTemplateRef(canonicalRef);
130
+ const cacheRoot = opts.cacheRoot ?? join(homedir(), ".df", "cache", "templates");
131
+ await mkdir(cacheRoot, { recursive: true });
132
+ const sha = await resolveSha(parsed);
133
+ const cacheDir = cacheDirFor(parsed, sha, cacheRoot);
134
+ try {
135
+ await stat(cacheDir);
136
+ }
137
+ catch {
138
+ await populateCache(parsed, sha, cacheDir);
139
+ }
140
+ const files = await walkTemplate(cacheDir);
141
+ return { canonicalRef, resolvedSha: sha, cacheDir, files };
142
+ }
143
+ //# sourceMappingURL=template-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-loader.js","sourceRoot":"","sources":["../../src/onboard/template-loader.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,oDAAoD;AACpD,6EAA6E;AAC7E,0EAA0E;AAC1E,2EAA2E;AAC3E,qDAAqD;AACrD,EAAE;AACF,yEAAyE;AACzE,wCAAwC;AACxC,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,+BAA+B;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,gBAAgB,GAIjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAG5B,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAkBrE,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAEpC,KAAK,UAAU,UAAU,CAAC,MAAyB;IACjD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,GAAG,CAAC;IACpB,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IACD,MAAM,GAAG,GAAG,sBAAsB,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC;IACpE,MAAM,MAAM,GACV,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,sCAAsC,MAAM,CAAC,GAAG,aAAa,GAAG,IAAI;YAClE,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,MAAyB,EAAE,GAAW,EAAE,SAAiB;IAC5E,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAAyB,EAAE,GAAW,EAAE,QAAgB;IACnF,MAAM,GAAG,GAAG,GAAG,QAAQ,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC3D,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,sBAAsB,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC;QACpE,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACzE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC;YAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,MAAM,GAAG,CAAC;QAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE;YAAE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe;IACzC,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,UAAU,KAAK,CAAC,GAAW;QAC9B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpB,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACpC,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC1B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,IAAI,GAAG,sBAAsB;gBAAE,SAAS;YAC/C,IAAI,MAAM,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9D,IAAI,GAAG,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CACb,2CAA2C,kBAAkB,IAAI;oBAC/D,oFAAoF,CACvF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,YAAoB,EAAE,OAAoB,EAAE;IAC7E,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACjF,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const TEMPLATE_REF_SHAPE_RE: RegExp;
2
+ export interface GhTemplateRef {
3
+ kind: "gh";
4
+ owner: string;
5
+ repo: string;
6
+ ref: string;
7
+ }
8
+ export interface FileTemplateRef {
9
+ kind: "file";
10
+ path: string;
11
+ ref: string;
12
+ }
13
+ export type ParsedTemplateRef = GhTemplateRef | FileTemplateRef;
14
+ export declare function parseTemplateRef(input: string): ParsedTemplateRef;
15
+ //# sourceMappingURL=template-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-ref.d.ts","sourceRoot":"","sources":["../../src/onboard/template-ref.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,qBAAqB,QAA+C,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,eAAe,CAAC;AAEhE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAyBjE"}
@@ -0,0 +1,45 @@
1
+ // packages/cli/src/onboard/template-ref.ts
2
+ //
3
+ // Template-ref foundation (round-4 advisor restructure-completion).
4
+ //
5
+ // Co-located foundation file: both `scaffold-schema.ts` (Task 1) and
6
+ // `template-loader.ts` (Task 3) import `parseTemplateRef` from here so
7
+ // the predicate has a single source of truth (schema and loader cannot
8
+ // drift on the semantic ref check) AND there's no circular import (the
9
+ // loader can also import ScaffoldPlanSchema if it ever needs to without
10
+ // creating a cycle, because template-ref.ts imports from neither).
11
+ //
12
+ // History — round-3 W3 advisor restructure. Rounds 1+2 tried to encode
13
+ // the NEGATIVE constraint ("not a 7–39 hex string") as a POSITIVE
14
+ // character class inside a single regex. Each round's tweak introduced
15
+ // a new false-positive or false-negative: round 1 ([A-Za-z._/-]) silently
16
+ // accepted short hex; round 2 ([g-zG-Z._/-]) rejected valid pure-digit
17
+ // refs like `123456` / `20260603`; gemini's prescribed round-3 lookahead
18
+ // fix STILL rejected `20260603` (an 8-digit ref is a subset of
19
+ // [0-9a-fA-F]). The negative constraint cannot compose cleanly with a
20
+ // positive class. The restructure: narrow the regex to SHAPE, delegate
21
+ // semantics to this parser. See commit log + plan §B-D3 for the
22
+ // iteration arc (round-1 → round-2 → round-3 regex iteration; round-4
23
+ // shared-module extraction).
24
+ export const TEMPLATE_REF_SHAPE_RE = /^(gh:[^/]+\/[^@]+|file:\/\/\/[^@]+)@[^@]+$/;
25
+ export function parseTemplateRef(input) {
26
+ const fileMatch = input.match(/^file:\/\/(\/[^@]+)@([A-Za-z0-9._/-]+)$/);
27
+ if (fileMatch) {
28
+ return { kind: "file", path: fileMatch[1], ref: fileMatch[2] };
29
+ }
30
+ const ghMatch = input.match(/^gh:([^/]+)\/([^@]+)@([A-Za-z0-9._/-]+)$/);
31
+ if (ghMatch) {
32
+ const [, owner, repo, ref] = ghMatch;
33
+ if (ref.length >= 7 &&
34
+ ref.length < 40 &&
35
+ /^[0-9a-fA-F]+$/.test(ref) &&
36
+ /[a-fA-F]/.test(ref)) {
37
+ throw new Error(`df onboard: short sha "${ref}" is not supported as a template ref. ` +
38
+ "Use the full 40-character sha, or a tag/branch name.");
39
+ }
40
+ return { kind: "gh", owner: owner, repo: repo, ref: ref };
41
+ }
42
+ throw new Error(`df onboard: malformed templateRef "${input}". ` +
43
+ "Expected gh:<owner>/<repo>@<ref> or file:///<abs-path>@<ref>.");
44
+ }
45
+ //# sourceMappingURL=template-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-ref.js","sourceRoot":"","sources":["../../src/onboard/template-ref.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,oEAAoE;AACpE,EAAE;AACF,qEAAqE;AACrE,uEAAuE;AACvE,uEAAuE;AACvE,uEAAuE;AACvE,wEAAwE;AACxE,mEAAmE;AACnE,EAAE;AACF,uEAAuE;AACvE,kEAAkE;AAClE,uEAAuE;AACvE,0EAA0E;AAC1E,uEAAuE;AACvE,yEAAyE;AACzE,+DAA+D;AAC/D,sEAAsE;AACtE,uEAAuE;AACvE,gEAAgE;AAChE,sEAAsE;AACtE,6BAA6B;AAE7B,MAAM,CAAC,MAAM,qBAAqB,GAAG,4CAA4C,CAAC;AAiBlF,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAE,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACxE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;QACrC,IACE,GAAI,CAAC,MAAM,IAAI,CAAC;YAChB,GAAI,CAAC,MAAM,GAAG,EAAE;YAChB,gBAAgB,CAAC,IAAI,CAAC,GAAI,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC,GAAI,CAAC,EACrB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,0BAA0B,GAAG,wCAAwC;gBACnE,sDAAsD,CACzD,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAM,EAAE,IAAI,EAAE,IAAK,EAAE,GAAG,EAAE,GAAI,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,IAAI,KAAK,CACb,sCAAsC,KAAK,KAAK;QAC9C,+DAA+D,CAClE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { DoctorCheck } from "@momentiq/dark-factory-schemas";
2
+ export interface CheckAgentContextSetOptions {
3
+ repoRoot: string;
4
+ /**
5
+ * The value of `loaded.config.context?.guidanceFiles` from the loaded
6
+ * AgentReviewConfig. The required-files walk (CLAUDE.md, AGENTS.md, etc.)
7
+ * runs UNCONDITIONALLY regardless of this value (per Decision #7 round-1
8
+ * revision — the cycle 15 D3 required-files set is the floor, not gated
9
+ * by the opt-in guidanceFiles field).
10
+ *
11
+ * - `undefined` or `[]` → guidance-file walk skipped; single
12
+ * `agent_context.guidance_not_configured` informational marker emitted.
13
+ * - Non-empty array → each path additionally checked; failures emit
14
+ * `agent_context.guidance_<i>` per Decision #7.
15
+ */
16
+ guidanceFiles: readonly string[] | undefined;
17
+ }
18
+ export declare function checkAgentContextSet(opts: CheckAgentContextSetOptions): Promise<DoctorCheck[]>;
19
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/onboard/validate.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC9C;AA2DD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,WAAW,EAAE,CAAC,CA+DxB"}
@@ -0,0 +1,127 @@
1
+ // Cycle 15 Phase C — `checkAgentContextSet()` for `df doctor`.
2
+ //
3
+ // Walks the cycle-15 D3 required-files set (CLAUDE.md, AGENTS.md,
4
+ // .claude/settings.json, docs/PRINCIPLES.md, docs/roadmap/cycles/cycle1-*.md,
5
+ // .agent-review/config.json) UNCONDITIONALLY, then optionally validates each
6
+ // path in `context.guidanceFiles` (from the loaded AgentReviewConfig) resolves
7
+ // to a real file under `repoRoot`.
8
+ //
9
+ // Per Decision #7 (round-1 revision): the required-files walk runs regardless
10
+ // of whether `context.guidanceFiles` is configured — the D3 set is the floor.
11
+ // The guidance-file walk is opt-in: when `guidanceFiles` is undefined OR `[]`,
12
+ // a single `agent_context.guidance_not_configured` informational marker is
13
+ // emitted (passed: true, optional: true) so operators see the field was
14
+ // skipped rather than silently absent.
15
+ //
16
+ // Cycle 15 exit-criterion lines 297–303: "the post-apply check fails loudly
17
+ // when any of [list] are missing or unwired (`context.guidanceFiles` does not
18
+ // point at real files). All current repos must pass `df doctor` after this
19
+ // lands."
20
+ import { access, readdir } from "node:fs/promises";
21
+ import { constants } from "node:fs";
22
+ import { resolve } from "node:path";
23
+ const REQUIRED_FILES = [
24
+ { key: "claude_md", name: "CLAUDE.md", path: "CLAUDE.md", isGlob: false },
25
+ { key: "agents_md", name: "AGENTS.md", path: "AGENTS.md", isGlob: false },
26
+ {
27
+ key: "claude_settings",
28
+ name: ".claude/settings.json",
29
+ path: ".claude/settings.json",
30
+ isGlob: false,
31
+ },
32
+ {
33
+ key: "principles",
34
+ name: "docs/PRINCIPLES.md",
35
+ path: "docs/PRINCIPLES.md",
36
+ isGlob: false,
37
+ },
38
+ {
39
+ key: "cycle1_bootstrap",
40
+ name: "docs/roadmap/cycles/cycle1-*.md",
41
+ path: "docs/roadmap/cycles",
42
+ isGlob: true,
43
+ },
44
+ {
45
+ key: "config",
46
+ name: ".agent-review/config.json",
47
+ path: ".agent-review/config.json",
48
+ isGlob: false,
49
+ },
50
+ ];
51
+ async function fileExists(path) {
52
+ try {
53
+ await access(path, constants.F_OK);
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ async function cycle1GlobMatches(dir) {
61
+ try {
62
+ const entries = await readdir(dir);
63
+ return entries.some((name) => /^cycle1-.*\.md$/.test(name));
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ const REMEDIATION = "run `df onboard --apply` to generate the missing agent-context files, or restore the file from version control";
70
+ export async function checkAgentContextSet(opts) {
71
+ const out = [];
72
+ // Required-file walk — runs UNCONDITIONALLY per Decision #7 (round-1
73
+ // revision). The cycle 15 exit-criterion lines 297–303 say "fails loudly
74
+ // when any of [list] are missing OR unwired"; a repo without a
75
+ // `context.guidanceFiles` block in .agent-review/config.json should still
76
+ // fail when CLAUDE.md is missing.
77
+ for (const req of REQUIRED_FILES) {
78
+ const fullPath = resolve(opts.repoRoot, req.path);
79
+ const exists = req.isGlob
80
+ ? await cycle1GlobMatches(fullPath)
81
+ : await fileExists(fullPath);
82
+ out.push(exists
83
+ ? {
84
+ name: `agent_context.${req.key}`,
85
+ passed: true,
86
+ detail: `${req.name} present at ${fullPath}`,
87
+ }
88
+ : {
89
+ name: `agent_context.${req.key}`,
90
+ passed: false,
91
+ detail: `${req.name} missing at ${fullPath}`,
92
+ remediation: REMEDIATION,
93
+ });
94
+ }
95
+ // Guidance-file walk — additional check, runs only when the guidanceFiles
96
+ // field is non-empty. The field is opt-in (NOT a gate for the required-
97
+ // files set above).
98
+ if (opts.guidanceFiles === undefined || opts.guidanceFiles.length === 0) {
99
+ out.push({
100
+ name: "agent_context.guidance_not_configured",
101
+ passed: true,
102
+ optional: true,
103
+ detail: ".agent-review/config.json has no `context.guidanceFiles` block — additional per-path validation skipped (the required-files walk above still ran).",
104
+ });
105
+ }
106
+ else {
107
+ for (let i = 0; i < opts.guidanceFiles.length; i++) {
108
+ const rel = opts.guidanceFiles[i];
109
+ const full = resolve(opts.repoRoot, rel);
110
+ const exists = await fileExists(full);
111
+ out.push(exists
112
+ ? {
113
+ name: `agent_context.guidance_${i}`,
114
+ passed: true,
115
+ detail: `guidanceFiles[${i}] (${rel}) resolves to ${full}`,
116
+ }
117
+ : {
118
+ name: `agent_context.guidance_${i}`,
119
+ passed: false,
120
+ detail: `guidanceFiles[${i}] (${rel}) does not resolve to a real file under ${opts.repoRoot}`,
121
+ remediation: `fix the path in .agent-review/config.json's context.guidanceFiles[${i}] or create the file`,
122
+ });
123
+ }
124
+ }
125
+ return out;
126
+ }
127
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/onboard/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ScaffoldPlan } from "../scaffold-schema.js";
2
+ export interface DryRunOptions {
3
+ color?: boolean;
4
+ }
5
+ export declare function renderDryRun(rootDir: string, plan: ScaffoldPlan, opts?: DryRunOptions): Promise<string>;
6
+ //# sourceMappingURL=dry-run-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dry-run-renderer.d.ts","sourceRoot":"","sources":["../../../src/onboard/writers/dry-run-renderer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,uBAAuB,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA4DD,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
@@ -0,0 +1,88 @@
1
+ // packages/cli/src/onboard/writers/dry-run-renderer.ts
2
+ //
3
+ // Render a human-readable preview of a ScaffoldPlan against a target dir.
4
+ // Shows per-file actions: emit (new or overwrite-diff), merge (additive
5
+ // append preview), skip (no-op). Colorized by default; honors NO_COLOR.
6
+ import { readFile } from "node:fs/promises";
7
+ import { join } from "node:path";
8
+ import { createPatch } from "diff";
9
+ const C = {
10
+ reset: "\x1b[0m",
11
+ bold: "\x1b[1m",
12
+ red: "\x1b[31m",
13
+ green: "\x1b[32m",
14
+ yellow: "\x1b[33m",
15
+ cyan: "\x1b[36m",
16
+ dim: "\x1b[2m",
17
+ };
18
+ function colored(s, code, on) {
19
+ return on ? `${code}${s}${C.reset}` : s;
20
+ }
21
+ async function readIfExists(p) {
22
+ try {
23
+ return await readFile(p, "utf8");
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function diffBlock(path, existing, proposed, color) {
30
+ const patch = createPatch(path, existing, proposed, "existing", "proposed");
31
+ if (!color)
32
+ return patch;
33
+ // Colorize +/- lines.
34
+ return patch.split("\n").map((line) => {
35
+ if (line.startsWith("+++") || line.startsWith("---"))
36
+ return colored(line, C.bold, true);
37
+ if (line.startsWith("+"))
38
+ return colored(line, C.green, true);
39
+ if (line.startsWith("-"))
40
+ return colored(line, C.red, true);
41
+ if (line.startsWith("@@"))
42
+ return colored(line, C.cyan, true);
43
+ return line;
44
+ }).join("\n");
45
+ }
46
+ async function renderFile(rootDir, file, color) {
47
+ const path = file.path;
48
+ if (file.action === "skip") {
49
+ return colored(`skip ${path}`, C.yellow, color) +
50
+ colored(` — ${file.rationale}`, C.dim, color) + "\n";
51
+ }
52
+ if (file.action === "emit") {
53
+ const existing = await readIfExists(join(rootDir, path));
54
+ if (existing === null) {
55
+ const header = colored(`emit ${path} (new file)`, C.green, color) + "\n";
56
+ const body = file.tailored_content.split("\n").map((l) => `+ ${l}`).join("\n");
57
+ return header + (color ? colored(body, C.green, true) : body) + "\n";
58
+ }
59
+ const header = colored(`emit ${path} (overwrite — diff below)`, C.bold, color) + "\n";
60
+ return header + diffBlock(path, existing, file.tailored_content, color) + "\n";
61
+ }
62
+ // merge
63
+ const existing = await readIfExists(join(rootDir, path));
64
+ if (existing === null) {
65
+ const header = colored(`merge ${path} (target absent — falling back to emit)`, C.yellow, color) + "\n";
66
+ return header + (color ? colored(file.tailored_content, C.green, true) : file.tailored_content) + "\n";
67
+ }
68
+ const header = colored(`merge ${path} (additive append)`, C.bold, color) + "\n";
69
+ const body = file.tailored_content.split("\n").map((l) => `+ ${l}`).join("\n");
70
+ return header + (color ? colored(body, C.green, true) : body) + "\n";
71
+ }
72
+ export async function renderDryRun(rootDir, plan, opts = {}) {
73
+ const color = opts.color ?? (process.env["NO_COLOR"] === undefined || process.env["NO_COLOR"] === "");
74
+ const lines = [];
75
+ lines.push(colored(`# df onboard — dry-run preview`, C.bold, color));
76
+ lines.push(`# template: ${plan.templateRef}`);
77
+ lines.push(`# generated: ${plan.generatedAtIso}`);
78
+ lines.push(`# files: ${plan.files.length}`);
79
+ lines.push("");
80
+ for (const file of plan.files) {
81
+ lines.push(await renderFile(rootDir, file, color));
82
+ }
83
+ lines.push("");
84
+ lines.push(colored("Summary: ", C.bold, color) + plan.summary);
85
+ lines.push(colored("Dry-run only — pass --apply to write, --pr to open a PR.", C.dim, color));
86
+ return lines.join("\n") + "\n";
87
+ }
88
+ //# sourceMappingURL=dry-run-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dry-run-renderer.js","sourceRoot":"","sources":["../../../src/onboard/writers/dry-run-renderer.ts"],"names":[],"mappings":"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"}