@momentiq/dark-factory-cli 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/adapters/static-schema-lint.js +1 -1
  2. package/dist/cli.js +3 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/onboard.d.ts +64 -1
  5. package/dist/commands/onboard.d.ts.map +1 -1
  6. package/dist/commands/onboard.js +268 -53
  7. package/dist/commands/onboard.js.map +1 -1
  8. package/dist/doctor.d.ts.map +1 -1
  9. package/dist/doctor.js +20 -0
  10. package/dist/doctor.js.map +1 -1
  11. package/dist/mcp/server.d.ts.map +1 -1
  12. package/dist/mcp/server.js +2 -0
  13. package/dist/mcp/server.js.map +1 -1
  14. package/dist/mcp/tools/onboard.d.ts +6 -0
  15. package/dist/mcp/tools/onboard.d.ts.map +1 -0
  16. package/dist/mcp/tools/onboard.js +115 -0
  17. package/dist/mcp/tools/onboard.js.map +1 -0
  18. package/dist/onboard/analyzers/ci.d.ts.map +1 -1
  19. package/dist/onboard/analyzers/ci.js +32 -0
  20. package/dist/onboard/analyzers/ci.js.map +1 -1
  21. package/dist/onboard/analyzers/lockfile.d.ts.map +1 -1
  22. package/dist/onboard/analyzers/lockfile.js +154 -74
  23. package/dist/onboard/analyzers/lockfile.js.map +1 -1
  24. package/dist/onboard/apply-plan.d.ts +29 -0
  25. package/dist/onboard/apply-plan.d.ts.map +1 -0
  26. package/dist/onboard/apply-plan.js +80 -0
  27. package/dist/onboard/apply-plan.js.map +1 -0
  28. package/dist/onboard/auto-profile.d.ts +3 -0
  29. package/dist/onboard/auto-profile.d.ts.map +1 -0
  30. package/dist/onboard/auto-profile.js +20 -0
  31. package/dist/onboard/auto-profile.js.map +1 -0
  32. package/dist/onboard/generate-plan.d.ts +18 -0
  33. package/dist/onboard/generate-plan.d.ts.map +1 -0
  34. package/dist/onboard/generate-plan.js +72 -0
  35. package/dist/onboard/generate-plan.js.map +1 -0
  36. package/dist/onboard/llm-client.d.ts +45 -0
  37. package/dist/onboard/llm-client.d.ts.map +1 -0
  38. package/dist/onboard/llm-client.js +101 -0
  39. package/dist/onboard/llm-client.js.map +1 -0
  40. package/dist/onboard/prompts/scaffold.md +93 -0
  41. package/dist/onboard/prompts.d.ts +13 -0
  42. package/dist/onboard/prompts.d.ts.map +1 -0
  43. package/dist/onboard/prompts.js +54 -0
  44. package/dist/onboard/prompts.js.map +1 -0
  45. package/dist/onboard/scaffold-schema.d.ts +194 -0
  46. package/dist/onboard/scaffold-schema.d.ts.map +1 -0
  47. package/dist/onboard/scaffold-schema.js +73 -0
  48. package/dist/onboard/scaffold-schema.js.map +1 -0
  49. package/dist/onboard/schema.d.ts +10 -0
  50. package/dist/onboard/schema.d.ts.map +1 -1
  51. package/dist/onboard/schema.js +23 -1
  52. package/dist/onboard/schema.js.map +1 -1
  53. package/dist/onboard/seeders/adr.d.ts +3 -0
  54. package/dist/onboard/seeders/adr.d.ts.map +1 -0
  55. package/dist/onboard/seeders/adr.js +212 -0
  56. package/dist/onboard/seeders/adr.js.map +1 -0
  57. package/dist/onboard/seeders/agent-review-config/cloud.canonical.json +22 -0
  58. package/dist/onboard/seeders/agent-review-config/local.canonical.json +21 -0
  59. package/dist/onboard/seeders/agent-review-config.d.ts +3 -0
  60. package/dist/onboard/seeders/agent-review-config.d.ts.map +1 -0
  61. package/dist/onboard/seeders/agent-review-config.js +38 -0
  62. package/dist/onboard/seeders/agent-review-config.js.map +1 -0
  63. package/dist/onboard/seeders/cycle1-bootstrap.d.ts +3 -0
  64. package/dist/onboard/seeders/cycle1-bootstrap.d.ts.map +1 -0
  65. package/dist/onboard/seeders/cycle1-bootstrap.js +76 -0
  66. package/dist/onboard/seeders/cycle1-bootstrap.js.map +1 -0
  67. package/dist/onboard/seeders/index.d.ts +47 -0
  68. package/dist/onboard/seeders/index.d.ts.map +1 -0
  69. package/dist/onboard/seeders/index.js +37 -0
  70. package/dist/onboard/seeders/index.js.map +1 -0
  71. package/dist/onboard/seeders/runbook.d.ts +13 -0
  72. package/dist/onboard/seeders/runbook.d.ts.map +1 -0
  73. package/dist/onboard/seeders/runbook.js +144 -0
  74. package/dist/onboard/seeders/runbook.js.map +1 -0
  75. package/dist/onboard/seeders/templates/adr.md.tmpl +26 -0
  76. package/dist/onboard/seeders/templates/cycle1-bootstrap.md.tmpl +64 -0
  77. package/dist/onboard/seeders/templates/runbook.md.tmpl +26 -0
  78. package/dist/onboard/template-loader.d.ts +20 -0
  79. package/dist/onboard/template-loader.d.ts.map +1 -0
  80. package/dist/onboard/template-loader.js +152 -0
  81. package/dist/onboard/template-loader.js.map +1 -0
  82. package/dist/onboard/template-ref.d.ts +15 -0
  83. package/dist/onboard/template-ref.d.ts.map +1 -0
  84. package/dist/onboard/template-ref.js +45 -0
  85. package/dist/onboard/template-ref.js.map +1 -0
  86. package/dist/onboard/validate.d.ts +19 -0
  87. package/dist/onboard/validate.d.ts.map +1 -0
  88. package/dist/onboard/validate.js +127 -0
  89. package/dist/onboard/validate.js.map +1 -0
  90. package/dist/onboard/writers/dry-run-renderer.d.ts +6 -0
  91. package/dist/onboard/writers/dry-run-renderer.d.ts.map +1 -0
  92. package/dist/onboard/writers/dry-run-renderer.js +88 -0
  93. package/dist/onboard/writers/dry-run-renderer.js.map +1 -0
  94. package/dist/onboard/writers/emit.d.ts +6 -0
  95. package/dist/onboard/writers/emit.d.ts.map +1 -0
  96. package/dist/onboard/writers/emit.js +29 -0
  97. package/dist/onboard/writers/emit.js.map +1 -0
  98. package/dist/onboard/writers/merge.d.ts +16 -0
  99. package/dist/onboard/writers/merge.d.ts.map +1 -0
  100. package/dist/onboard/writers/merge.js +142 -0
  101. package/dist/onboard/writers/merge.js.map +1 -0
  102. package/dist/onboard/writers/pr-writer.d.ts +44 -0
  103. package/dist/onboard/writers/pr-writer.d.ts.map +1 -0
  104. package/dist/onboard/writers/pr-writer.js +104 -0
  105. package/dist/onboard/writers/pr-writer.js.map +1 -0
  106. package/dist/onboard/writers/skip.d.ts +9 -0
  107. package/dist/onboard/writers/skip.d.ts.map +1 -0
  108. package/dist/onboard/writers/skip.js +9 -0
  109. package/dist/onboard/writers/skip.js.map +1 -0
  110. package/package.json +4 -1
@@ -0,0 +1,152 @@
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, ≤ MAX_TEMPLATE_FILES entries total — see
8
+ // the constant definition below for the current value).
9
+ //
10
+ // Cache key is the resolved sha — so `latest` and the sha it resolves to
11
+ // share one entry, no churn on re-runs.
12
+ //
13
+ // Ref parsing is delegated to template-ref.ts (Task 1's co-located foundation
14
+ // file) — this loader consumes parseTemplateRef + the parsed-ref types from
15
+ // there. Round-4 restructure-completion: keeping the parser in the foundation
16
+ // file means schema (Task 1) and loader (Task 3) cannot drift on the semantic
17
+ // check, AND no circular import is possible (template-ref.ts imports nothing
18
+ // from schema or loader, so the loader can import ScaffoldPlanSchema in the
19
+ // future if it ever needs to).
20
+ import { execFile } from "node:child_process";
21
+ import { promisify } from "node:util";
22
+ import { mkdir, readdir, readFile, rename, rm, stat, cp } from "node:fs/promises";
23
+ import { homedir } from "node:os";
24
+ import { join, relative } from "node:path";
25
+ import { parseTemplateRef, } from "./template-ref.js";
26
+ export { parseTemplateRef };
27
+ const ex = promisify(execFile);
28
+ // Raise-don't-filter: sage-blueprint's file inventory is intentional template
29
+ // content (Copier `.jinja` outputs, backend + frontend source, configs), so
30
+ // extension-whitelisting or expanding SKIP_DIRS would drop structural files
31
+ // the LLM needs to see. The 64 KB per-file ceiling + binary-skip are the
32
+ // real backstops; this cap is the count tripwire. See #140 for the original
33
+ // 200→ raise rationale. (A total-bytes cap for the assembled prompt is a
34
+ // follow-up — tracked separately so it can land with end-to-end metering.)
35
+ export const MAX_TEMPLATE_FILES = 1000;
36
+ export const MAX_TEMPLATE_FILE_SIZE = 65_536;
37
+ const SKIP_DIRS = new Set([".git", "node_modules", "dist", "build"]);
38
+ const FORTY_HEX = /^[0-9a-f]{40}$/i;
39
+ async function resolveSha(parsed) {
40
+ if (parsed.kind === "file") {
41
+ return parsed.ref;
42
+ }
43
+ if (FORTY_HEX.test(parsed.ref)) {
44
+ return parsed.ref.toLowerCase();
45
+ }
46
+ const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
47
+ const refArg = parsed.ref === "latest" ? "HEAD" :
48
+ parsed.ref.startsWith("refs/") ? parsed.ref :
49
+ parsed.ref;
50
+ const { stdout } = await ex("git", ["ls-remote", url, refArg]);
51
+ const sha = stdout.split(/\s/)[0];
52
+ if (!sha || !FORTY_HEX.test(sha)) {
53
+ throw new Error(`df onboard: could not resolve ref "${parsed.ref}" against ${url}. ` +
54
+ "Verify the ref exists and the repo is publicly readable.");
55
+ }
56
+ return sha.toLowerCase();
57
+ }
58
+ function cacheDirFor(parsed, sha, cacheRoot) {
59
+ if (parsed.kind === "gh") {
60
+ return join(cacheRoot, `${parsed.owner}__${parsed.repo}__${sha}`);
61
+ }
62
+ const tag = parsed.path.replace(/[^A-Za-z0-9._-]/g, "_");
63
+ return join(cacheRoot, `file__${tag}__${sha}`);
64
+ }
65
+ async function populateCache(parsed, sha, cacheDir) {
66
+ const tmp = `${cacheDir}.tmp-${process.pid}-${Date.now()}`;
67
+ await rm(tmp, { recursive: true, force: true });
68
+ if (parsed.kind === "file") {
69
+ await cp(parsed.path, tmp, { recursive: true });
70
+ }
71
+ else {
72
+ const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
73
+ await mkdir(tmp, { recursive: true });
74
+ await ex("git", ["init", "-q"], { cwd: tmp });
75
+ await ex("git", ["fetch", "--depth", "1", "-q", url, sha], { cwd: tmp });
76
+ await ex("git", ["checkout", "-q", "FETCH_HEAD"], { cwd: tmp });
77
+ await rm(join(tmp, ".git"), { recursive: true, force: true });
78
+ }
79
+ try {
80
+ await rename(tmp, cacheDir);
81
+ }
82
+ catch (err) {
83
+ await rm(tmp, { recursive: true, force: true });
84
+ try {
85
+ await stat(cacheDir);
86
+ }
87
+ catch {
88
+ throw err;
89
+ }
90
+ }
91
+ }
92
+ async function isBinary(filepath) {
93
+ const head = Buffer.alloc(8192);
94
+ const fh = await import("node:fs/promises").then((m) => m.open(filepath, "r"));
95
+ try {
96
+ const { bytesRead } = await fh.read(head, 0, head.length, 0);
97
+ for (let i = 0; i < bytesRead; i++)
98
+ if (head[i] === 0)
99
+ return true;
100
+ return false;
101
+ }
102
+ finally {
103
+ await fh.close();
104
+ }
105
+ }
106
+ async function walkTemplate(rootDir) {
107
+ const out = [];
108
+ async function recur(dir) {
109
+ const entries = await readdir(dir, { withFileTypes: true });
110
+ for (const e of entries) {
111
+ const abs = join(dir, e.name);
112
+ if (e.isDirectory()) {
113
+ if (SKIP_DIRS.has(e.name))
114
+ continue;
115
+ await recur(abs);
116
+ continue;
117
+ }
118
+ if (!e.isFile())
119
+ continue;
120
+ const st = await stat(abs);
121
+ if (st.size > MAX_TEMPLATE_FILE_SIZE)
122
+ continue;
123
+ if (await isBinary(abs))
124
+ continue;
125
+ const rel = relative(rootDir, abs);
126
+ out.push({ path: rel, content: await readFile(abs, "utf8") });
127
+ if (out.length > MAX_TEMPLATE_FILES) {
128
+ throw new Error(`df onboard: template file count exceeds ${MAX_TEMPLATE_FILES}. ` +
129
+ "Reduce the template surface or raise MAX_TEMPLATE_FILES " +
130
+ "(see #140 for the rationale behind the current ceiling).");
131
+ }
132
+ }
133
+ }
134
+ await recur(rootDir);
135
+ return out;
136
+ }
137
+ export async function loadTemplate(canonicalRef, opts = {}) {
138
+ const parsed = parseTemplateRef(canonicalRef);
139
+ const cacheRoot = opts.cacheRoot ?? join(homedir(), ".df", "cache", "templates");
140
+ await mkdir(cacheRoot, { recursive: true });
141
+ const sha = await resolveSha(parsed);
142
+ const cacheDir = cacheDirFor(parsed, sha, cacheRoot);
143
+ try {
144
+ await stat(cacheDir);
145
+ }
146
+ catch {
147
+ await populateCache(parsed, sha, cacheDir);
148
+ }
149
+ const files = await walkTemplate(cacheDir);
150
+ return { canonicalRef, resolvedSha: sha, cacheDir, files };
151
+ }
152
+ //# sourceMappingURL=template-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-loader.js","sourceRoot":"","sources":["../../src/onboard/template-loader.ts"],"names":[],"mappings":"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"}
@@ -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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"}
@@ -0,0 +1,6 @@
1
+ import type { EmitFilePlan } from "../scaffold-schema.js";
2
+ export interface EmitOptions {
3
+ force?: boolean;
4
+ }
5
+ export declare function writeEmit(rootDir: string, plan: EmitFilePlan, opts?: EmitOptions): Promise<void>;
6
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/onboard/writers/emit.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAcD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -0,0 +1,29 @@
1
+ // packages/cli/src/onboard/writers/emit.ts
2
+ import { mkdir, writeFile, stat } from "node:fs/promises";
3
+ import { dirname, isAbsolute, relative, resolve } from "node:path";
4
+ function safeResolve(root, p) {
5
+ if (isAbsolute(p)) {
6
+ throw new Error(`df onboard: refuses to emit to absolute path "${p}" (outside the target root).`);
7
+ }
8
+ const resolved = resolve(root, p);
9
+ const rel = relative(root, resolved);
10
+ if (rel.startsWith("..") || isAbsolute(rel)) {
11
+ throw new Error(`df onboard: path traversal blocked — "${p}" resolves outside the target root.`);
12
+ }
13
+ return resolved;
14
+ }
15
+ export async function writeEmit(rootDir, plan, opts = {}) {
16
+ const abs = safeResolve(rootDir, plan.path);
17
+ let exists = false;
18
+ try {
19
+ await stat(abs);
20
+ exists = true;
21
+ }
22
+ catch { }
23
+ if (exists && !opts.force) {
24
+ throw new Error(`df onboard: refuses to overwrite existing file "${plan.path}" (pass force=true to override).`);
25
+ }
26
+ await mkdir(dirname(abs), { recursive: true });
27
+ await writeFile(abs, plan.tailored_content, "utf8");
28
+ }
29
+ //# sourceMappingURL=emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../src/onboard/writers/emit.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAQ,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzE,SAAS,WAAW,CAAC,IAAY,EAAE,CAAS;IAC1C,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,8BAA8B,CAAC,CAAC;IACpG,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,qCAAqC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAe,EACf,IAAkB,EAClB,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,CAAC;QAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAChD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,mDAAmD,IAAI,CAAC,IAAI,kCAAkC,CAC/F,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { MergeFilePlan } from "../scaffold-schema.js";
2
+ export declare const BEGIN_MARKER = "<!-- df onboard: inserted-by-cycle-15 BEGIN -->";
3
+ export declare const END_MARKER = "<!-- df onboard: inserted-by-cycle-15 END -->";
4
+ export interface MergeOptions {
5
+ stderr?: (s: string) => void;
6
+ }
7
+ export interface MergeResult {
8
+ path: string;
9
+ action: "merge";
10
+ wrote: boolean;
11
+ skipped: boolean;
12
+ reason?: string;
13
+ fellBackToEmit?: boolean;
14
+ }
15
+ export declare function writeMerge(rootDir: string, plan: MergeFilePlan, opts?: MergeOptions): Promise<MergeResult>;
16
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/onboard/writers/merge.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,eAAO,MAAM,YAAY,oDAAoD,CAAC;AAC9E,eAAO,MAAM,UAAU,kDAAkD,CAAC;AAG1E,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA4ED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,EACnB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CA6CtB"}