@dougharness/cli 1.0.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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ablate.d.ts +96 -0
  3. package/dist/ablate.js +440 -0
  4. package/dist/ablate.js.map +1 -0
  5. package/dist/apply.d.ts +2 -0
  6. package/dist/apply.js +19 -0
  7. package/dist/apply.js.map +1 -0
  8. package/dist/bin.d.ts +2 -0
  9. package/dist/bin.js +80 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/board-page.d.ts +15 -0
  12. package/dist/board-page.js +27 -0
  13. package/dist/board-page.js.map +1 -0
  14. package/dist/board-serve-process.d.ts +24 -0
  15. package/dist/board-serve-process.js +227 -0
  16. package/dist/board-serve-process.js.map +1 -0
  17. package/dist/board-serve.d.ts +9 -0
  18. package/dist/board-serve.js +302 -0
  19. package/dist/board-serve.js.map +1 -0
  20. package/dist/board.d.ts +6 -0
  21. package/dist/board.js +515 -0
  22. package/dist/board.js.map +1 -0
  23. package/dist/detect/fs.d.ts +6 -0
  24. package/dist/detect/fs.js +50 -0
  25. package/dist/detect/fs.js.map +1 -0
  26. package/dist/detect/index.d.ts +3 -0
  27. package/dist/detect/index.js +13 -0
  28. package/dist/detect/index.js.map +1 -0
  29. package/dist/detect/node.d.ts +3 -0
  30. package/dist/detect/node.js +179 -0
  31. package/dist/detect/node.js.map +1 -0
  32. package/dist/detect/python.d.ts +2 -0
  33. package/dist/detect/python.js +388 -0
  34. package/dist/detect/python.js.map +1 -0
  35. package/dist/detect/repo.d.ts +2 -0
  36. package/dist/detect/repo.js +102 -0
  37. package/dist/detect/repo.js.map +1 -0
  38. package/dist/detect/types.d.ts +98 -0
  39. package/dist/detect/types.js +2 -0
  40. package/dist/detect/types.js.map +1 -0
  41. package/dist/diff.d.ts +12 -0
  42. package/dist/diff.js +105 -0
  43. package/dist/diff.js.map +1 -0
  44. package/dist/generate/agents.d.ts +19 -0
  45. package/dist/generate/agents.js +184 -0
  46. package/dist/generate/agents.js.map +1 -0
  47. package/dist/generate/claude-md.d.ts +9 -0
  48. package/dist/generate/claude-md.js +111 -0
  49. package/dist/generate/claude-md.js.map +1 -0
  50. package/dist/generate/config.d.ts +51 -0
  51. package/dist/generate/config.js +155 -0
  52. package/dist/generate/config.js.map +1 -0
  53. package/dist/generate/proposal.d.ts +11 -0
  54. package/dist/generate/proposal.js +175 -0
  55. package/dist/generate/proposal.js.map +1 -0
  56. package/dist/generate/settings.d.ts +35 -0
  57. package/dist/generate/settings.js +213 -0
  58. package/dist/generate/settings.js.map +1 -0
  59. package/dist/generate/skills.d.ts +8 -0
  60. package/dist/generate/skills.js +264 -0
  61. package/dist/generate/skills.js.map +1 -0
  62. package/dist/init.d.ts +10 -0
  63. package/dist/init.js +69 -0
  64. package/dist/init.js.map +1 -0
  65. package/dist/trace.d.ts +9 -0
  66. package/dist/trace.js +106 -0
  67. package/dist/trace.js.map +1 -0
  68. package/node_modules/@dougharness/flow/.claude-plugin/plugin.json +10 -0
  69. package/node_modules/@dougharness/flow/LICENSE +21 -0
  70. package/node_modules/@dougharness/flow/agents/adversary-claude.md +33 -0
  71. package/node_modules/@dougharness/flow/agents/adversary.md +29 -0
  72. package/node_modules/@dougharness/flow/agents/implementer.md +23 -0
  73. package/node_modules/@dougharness/flow/agents/lead.md +35 -0
  74. package/node_modules/@dougharness/flow/agents/planner.md +70 -0
  75. package/node_modules/@dougharness/flow/agents/researcher.md +31 -0
  76. package/node_modules/@dougharness/flow/agents/reviewer.md +26 -0
  77. package/node_modules/@dougharness/flow/agents/verifier.md +24 -0
  78. package/node_modules/@dougharness/flow/lib/board.mjs +840 -0
  79. package/node_modules/@dougharness/flow/lib/code-index.mjs +629 -0
  80. package/node_modules/@dougharness/flow/lib/cost.mjs +392 -0
  81. package/node_modules/@dougharness/flow/lib/decisions.mjs +314 -0
  82. package/node_modules/@dougharness/flow/lib/embeddings.mjs +539 -0
  83. package/node_modules/@dougharness/flow/lib/land.mjs +219 -0
  84. package/node_modules/@dougharness/flow/lib/learn.mjs +742 -0
  85. package/node_modules/@dougharness/flow/lib/memory-import.mjs +145 -0
  86. package/node_modules/@dougharness/flow/lib/memory.mjs +1641 -0
  87. package/node_modules/@dougharness/flow/lib/models.mjs +148 -0
  88. package/node_modules/@dougharness/flow/lib/plan.mjs +773 -0
  89. package/node_modules/@dougharness/flow/lib/rehearse.mjs +825 -0
  90. package/node_modules/@dougharness/flow/lib/worktrees.mjs +215 -0
  91. package/node_modules/@dougharness/flow/package.json +19 -0
  92. package/node_modules/@dougharness/flow/scripts/board.mjs +260 -0
  93. package/node_modules/@dougharness/flow/scripts/cost.mjs +66 -0
  94. package/node_modules/@dougharness/flow/scripts/learn.mjs +161 -0
  95. package/node_modules/@dougharness/flow/scripts/memory.mjs +1274 -0
  96. package/node_modules/@dougharness/flow/scripts/plan.mjs +547 -0
  97. package/node_modules/@dougharness/flow/scripts/rehearse.mjs +129 -0
  98. package/node_modules/@dougharness/flow/skills/core-next/SKILL.md +92 -0
  99. package/node_modules/@dougharness/flow/skills/doug-approve/SKILL.md +15 -0
  100. package/node_modules/@dougharness/flow/skills/doug-decide/SKILL.md +26 -0
  101. package/node_modules/@dougharness/flow/skills/doug-implement/SKILL.md +22 -0
  102. package/node_modules/@dougharness/flow/skills/doug-learn/SKILL.md +20 -0
  103. package/node_modules/@dougharness/flow/skills/doug-next/SKILL.md +87 -0
  104. package/node_modules/@dougharness/flow/skills/doug-plan/SKILL.md +22 -0
  105. package/node_modules/@dougharness/flow/skills/doug-swarm/SKILL.md +55 -0
  106. package/node_modules/@dougharness/flow/skills/harness-fix/SKILL.md +85 -0
  107. package/node_modules/@dougharness/flow/skills/research/SKILL.md +41 -0
  108. package/node_modules/@dougharness/flow/skills/run-report/SKILL.md +51 -0
  109. package/node_modules/@dougharness/flow/skills/swarm-launch/SKILL.md +27 -0
  110. package/node_modules/@dougharness/flow/workflows/doug-implement.js +2687 -0
  111. package/node_modules/@dougharness/gates/.claude-plugin/plugin.json +10 -0
  112. package/node_modules/@dougharness/gates/LICENSE +21 -0
  113. package/node_modules/@dougharness/gates/hooks/hooks.json +184 -0
  114. package/node_modules/@dougharness/gates/lib/agent-context.mjs +111 -0
  115. package/node_modules/@dougharness/gates/lib/anchor.mjs +110 -0
  116. package/node_modules/@dougharness/gates/lib/baseline.mjs +160 -0
  117. package/node_modules/@dougharness/gates/lib/bash-rules.mjs +1522 -0
  118. package/node_modules/@dougharness/gates/lib/block-ledger.mjs +127 -0
  119. package/node_modules/@dougharness/gates/lib/checkpoint.mjs +97 -0
  120. package/node_modules/@dougharness/gates/lib/config.mjs +168 -0
  121. package/node_modules/@dougharness/gates/lib/evidence.mjs +59 -0
  122. package/node_modules/@dougharness/gates/lib/glob.mjs +86 -0
  123. package/node_modules/@dougharness/gates/lib/io.mjs +91 -0
  124. package/node_modules/@dougharness/gates/lib/paths.mjs +101 -0
  125. package/node_modules/@dougharness/gates/lib/proposals.mjs +201 -0
  126. package/node_modules/@dougharness/gates/lib/run.mjs +147 -0
  127. package/node_modules/@dougharness/gates/lib/scope.mjs +117 -0
  128. package/node_modules/@dougharness/gates/lib/secret-rules.mjs +268 -0
  129. package/node_modules/@dougharness/gates/lib/state.mjs +114 -0
  130. package/node_modules/@dougharness/gates/lib/trace.mjs +196 -0
  131. package/node_modules/@dougharness/gates/package.json +17 -0
  132. package/node_modules/@dougharness/gates/scripts/edit-loop.mjs +39 -0
  133. package/node_modules/@dougharness/gates/scripts/format-on-edit.mjs +45 -0
  134. package/node_modules/@dougharness/gates/scripts/guard-bash.mjs +32 -0
  135. package/node_modules/@dougharness/gates/scripts/protect-paths.mjs +49 -0
  136. package/node_modules/@dougharness/gates/scripts/reanchor.mjs +81 -0
  137. package/node_modules/@dougharness/gates/scripts/research-cap.mjs +295 -0
  138. package/node_modules/@dougharness/gates/scripts/secret-scan.mjs +26 -0
  139. package/node_modules/@dougharness/gates/scripts/session-start-baseline.mjs +57 -0
  140. package/node_modules/@dougharness/gates/scripts/statusline.mjs +133 -0
  141. package/node_modules/@dougharness/gates/scripts/stop-gate.mjs +1422 -0
  142. package/node_modules/@dougharness/gates/scripts/trace.mjs +75 -0
  143. package/package.json +33 -0
  144. package/templates/board-app.js +533 -0
@@ -0,0 +1,102 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { exists, isDir, listDir, readText } from "./fs.js";
3
+ const MIGRATION_DIR_CANDIDATES = [
4
+ "prisma/migrations", "drizzle", "drizzle/migrations", "migrations", "db/migrate", "db/migrations",
5
+ "alembic/versions", "supabase/migrations", "src/migrations", "database/migrations",
6
+ ];
7
+ const GENERATED_DIR_CANDIDATES = ["dist", "build", "out", ".next", ".nuxt", ".output", "coverage", "generated", "__generated__", ".turbo", ".svelte-kit"];
8
+ const AGENT_FILES = [
9
+ "AGENTS.md", ".cursorrules", ".cursor/rules", ".github/copilot-instructions.md", ".windsurfrules", ".clinerules", ".devin/rules",
10
+ ];
11
+ const INFRA_SKIP_DIRS = new Set(["node_modules", ".git"]);
12
+ const INFRA_WALK_MAX_LEVEL = 3;
13
+ // Walks the repo (skipping node_modules, .git, and the detected generated dirs, at every level) up to three
14
+ // directory levels deep looking for a *.tfvars or terraform.tfstate file, at the root or nested. glob.mjs's
15
+ // patterns are slash-free basename matches, so *.tfvars and terraform.tfstate already match at any depth: only
16
+ // presence (root or nested) matters, not where. listDir/isDir already fail open (return [] / false) on an
17
+ // unreadable directory, so the walk never throws.
18
+ function collectTfMarkers(dir, generatedDirs) {
19
+ const skip = new Set([...INFRA_SKIP_DIRS, ...generatedDirs]);
20
+ let hasTfvars = false;
21
+ let hasTfstate = false;
22
+ function walk(rel, level) {
23
+ for (const name of listDir(dir, rel)) {
24
+ const relPath = rel === "." ? name : `${rel}/${name}`;
25
+ if (isDir(dir, relPath)) {
26
+ if (skip.has(name))
27
+ continue;
28
+ if (level + 1 <= INFRA_WALK_MAX_LEVEL)
29
+ walk(relPath, level + 1);
30
+ continue;
31
+ }
32
+ if (/\.tfvars$/.test(name))
33
+ hasTfvars = true;
34
+ else if (name === "terraform.tfstate")
35
+ hasTfstate = true;
36
+ }
37
+ }
38
+ walk(".", 0);
39
+ return { hasTfvars, hasTfstate };
40
+ }
41
+ function detectInfraPaths(dir, generatedDirs) {
42
+ const { hasTfvars, hasTfstate } = collectTfMarkers(dir, generatedDirs);
43
+ const infraPaths = [];
44
+ if (isDir(dir, "infra/prod"))
45
+ infraPaths.push("infra/prod/**");
46
+ if (hasTfvars)
47
+ infraPaths.push("*.tfvars");
48
+ if (hasTfstate)
49
+ infraPaths.push("terraform.tfstate");
50
+ return infraPaths;
51
+ }
52
+ function git(dir, args) {
53
+ try {
54
+ return execFileSync("git", args, { cwd: dir, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5000 }).trim();
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ export function detectRepo(dir, notes) {
61
+ const isGit = git(dir, ["rev-parse", "--is-inside-work-tree"]) === "true";
62
+ let defaultBranch = null;
63
+ if (isGit) {
64
+ const remoteHead = git(dir, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
65
+ if (remoteHead)
66
+ defaultBranch = remoteHead.replace(/^origin\//, "");
67
+ else {
68
+ const current = git(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
69
+ if (current && current !== "HEAD")
70
+ defaultBranch = current;
71
+ }
72
+ }
73
+ const ci = [];
74
+ if (isDir(dir, ".github/workflows"))
75
+ ci.push(...listDir(dir, ".github/workflows").filter((f) => /\.ya?ml$/.test(f)).map((f) => `.github/workflows/${f}`));
76
+ for (const f of [".gitlab-ci.yml", ".circleci/config.yml", "Jenkinsfile", "bitbucket-pipelines.yml", "azure-pipelines.yml"])
77
+ if (exists(dir, f))
78
+ ci.push(f);
79
+ const gitHooks = [];
80
+ if (isDir(dir, ".husky"))
81
+ gitHooks.push("husky");
82
+ if (exists(dir, "lefthook.yml") || exists(dir, ".lefthook.yml"))
83
+ gitHooks.push("lefthook");
84
+ if (exists(dir, ".pre-commit-config.yaml"))
85
+ gitHooks.push("pre-commit");
86
+ if (["commitlint.config.js", "commitlint.config.cjs", "commitlint.config.mjs", "commitlint.config.ts", ".commitlintrc", ".commitlintrc.json", ".commitlintrc.js"].some((f) => exists(dir, f)))
87
+ gitHooks.push("commitlint");
88
+ const envFiles = listDir(dir).filter((f) => /^\.env(\..+)?$/.test(f) && !/\.example$|\.sample$|\.template$/.test(f));
89
+ const gitignore = readText(dir, ".gitignore") || "";
90
+ if (envFiles.length && !/^\s*\.env/m.test(gitignore))
91
+ notes.push("Env files exist but .gitignore does not mention .env.");
92
+ const migrationDirs = MIGRATION_DIR_CANDIDATES.filter((d) => isDir(dir, d));
93
+ const generatedDirs = GENERATED_DIR_CANDIDATES.filter((d) => isDir(dir, d) || new RegExp(`^/?${d.replace(".", "\\.")}/?$`, "m").test(gitignore));
94
+ const infraPaths = detectInfraPaths(dir, generatedDirs);
95
+ const existingAgentFiles = AGENT_FILES.filter((f) => exists(dir, f));
96
+ const hasClaudeMd = exists(dir, "CLAUDE.md");
97
+ const hasClaudeSettings = exists(dir, ".claude/settings.json");
98
+ const readme = readText(dir, "README.md") || "";
99
+ const readmeHasSetup = /^#+\s*(getting started|setup|installation|install|development|running)/im.test(readme);
100
+ return { isGit, defaultBranch, ci, gitHooks, envFiles, migrationDirs, generatedDirs, infraPaths, existingAgentFiles, hasClaudeMd, hasClaudeSettings, readmeHasSetup };
101
+ }
102
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/detect/repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,wBAAwB,GAAG;IAC/B,mBAAmB,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe;IACjG,kBAAkB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB;CACnF,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAE1J,MAAM,WAAW,GAAG;IAClB,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,iCAAiC,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc;CACjI,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAC1D,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,4GAA4G;AAC5G,4GAA4G;AAC5G,+GAA+G;AAC/G,0GAA0G;AAC1G,kDAAkD;AAClD,SAAS,gBAAgB,CAAC,GAAW,EAAE,aAAuB;IAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC;IAC7D,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,SAAS,IAAI,CAAC,GAAW,EAAE,KAAa;QACtC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;gBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC7B,IAAI,KAAK,GAAG,CAAC,IAAI,oBAAoB;oBAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAChE,SAAS;YACX,CAAC;YACD,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS,GAAG,IAAI,CAAC;iBACxC,IAAI,IAAI,KAAK,mBAAmB;gBAAE,UAAU,GAAG,IAAI,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACb,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,aAAuB;IAC5D,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACvE,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/D,IAAI,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,UAAU;QAAE,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACrD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc;IACtC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9H,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,KAAe;IACrD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,KAAK,MAAM,CAAC;IAC1E,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,0BAA0B,CAAC,CAAC,CAAC;QACrF,IAAI,UAAU;YAAE,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;aAC/D,CAAC;YACJ,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;YAChE,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM;gBAAE,aAAa,GAAG,OAAO,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,EAAE,GAAa,EAAE,CAAC;IACxB,IAAI,KAAK,CAAC,GAAG,EAAE,mBAAmB,CAAC;QAAE,EAAE,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1J,KAAK,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,aAAa,EAAE,yBAAyB,EAAE,qBAAqB,CAAC;QAAE,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5J,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAC/C,IAAI,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,eAAe,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3F,IAAI,MAAM,CAAC,GAAG,EAAE,yBAAyB,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxE,IAAI,CAAC,sBAAsB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE3N,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrH,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACpD,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IAE1H,MAAM,aAAa,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,aAAa,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAEjJ,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAExD,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,cAAc,GAAG,0EAA0E,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE/G,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC;AACxK,CAAC"}
@@ -0,0 +1,98 @@
1
+ export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
2
+ export interface ScriptCommand {
3
+ /** Name of the package.json script, e.g. "test". */
4
+ script: string;
5
+ /** Full shell command to run it, e.g. "pnpm test". */
6
+ command: string;
7
+ /** What the script runs, verbatim from package.json. */
8
+ body: string;
9
+ }
10
+ export interface NodeDetection {
11
+ present: boolean;
12
+ packageManager: PackageManager | null;
13
+ packageManagerSource: "packageManager-field" | "lockfile" | "default" | null;
14
+ nodeVersion: string | null;
15
+ nodeVersionSource: string | null;
16
+ scripts: Record<string, string>;
17
+ commands: {
18
+ install: string | null;
19
+ test: ScriptCommand | null;
20
+ "test:unit": ScriptCommand | null;
21
+ lint: ScriptCommand | null;
22
+ typecheck: ScriptCommand | null;
23
+ build: ScriptCommand | null;
24
+ format: ScriptCommand | null;
25
+ };
26
+ testFramework: "vitest" | "jest" | "mocha" | "node:test" | null;
27
+ singleTestCommand: string | null;
28
+ formatter: {
29
+ name: "prettier" | "biome";
30
+ command: string[];
31
+ extensions: string[];
32
+ } | null;
33
+ linter: "eslint" | "biome" | null;
34
+ typescript: boolean;
35
+ tsStrict: boolean | null;
36
+ monorepo: {
37
+ tool: "pnpm-workspace" | "npm-workspaces" | "turbo" | "nx" | "lerna";
38
+ packages: string[];
39
+ }[];
40
+ lockfile: string | null;
41
+ }
42
+ export type PythonManager = "uv" | "poetry" | "pdm" | "pipenv" | "hatch" | "pip";
43
+ export interface PythonDetection {
44
+ present: boolean;
45
+ manager: PythonManager | null;
46
+ managerSource: string | null;
47
+ lockfile: string | null;
48
+ runPrefix: string | null;
49
+ pythonVersion: string | null;
50
+ pythonVersionSource: string | null;
51
+ venvDir: string | null;
52
+ venvBinDir: string | null;
53
+ commands: {
54
+ install: string | null;
55
+ test: string | null;
56
+ lint: string | null;
57
+ format: string | null;
58
+ formatCheck: string | null;
59
+ typecheck: string | null;
60
+ };
61
+ testFramework: "pytest" | null;
62
+ testConfigFile: string | null;
63
+ testDirs: string[];
64
+ singleTestCommand: string | null;
65
+ singleTestNodeIdCommand: string | null;
66
+ linter: "ruff" | null;
67
+ formatter: {
68
+ name: "ruff" | "black";
69
+ command: string;
70
+ } | null;
71
+ typeChecker: "mypy" | null;
72
+ typeCheckerConfigFile: string | null;
73
+ srcLayout: boolean;
74
+ migrationDirs: string[];
75
+ generatedDirs: string[];
76
+ }
77
+ export interface RepoDetection {
78
+ isGit: boolean;
79
+ defaultBranch: string | null;
80
+ ci: string[];
81
+ gitHooks: ("husky" | "lefthook" | "pre-commit" | "commitlint")[];
82
+ envFiles: string[];
83
+ migrationDirs: string[];
84
+ generatedDirs: string[];
85
+ infraPaths: string[];
86
+ existingAgentFiles: string[];
87
+ hasClaudeMd: boolean;
88
+ hasClaudeSettings: boolean;
89
+ readmeHasSetup: boolean;
90
+ }
91
+ export interface Detection {
92
+ dir: string;
93
+ node: NodeDetection;
94
+ python: PythonDetection;
95
+ repo: RepoDetection;
96
+ /** Human-readable notes about why a decision was made. Shown in the proposal. */
97
+ notes: string[];
98
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/detect/types.ts"],"names":[],"mappings":""}
package/dist/diff.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export interface FileChange {
2
+ path: string;
3
+ before: string | null;
4
+ after: string | null;
5
+ /** Why this file is proposed. Shown above the diff. */
6
+ reason?: string;
7
+ }
8
+ export interface DiffOptions {
9
+ color?: boolean;
10
+ context?: number;
11
+ }
12
+ export declare function renderDiff(change: FileChange, opts?: DiffOptions): string;
package/dist/diff.js ADDED
@@ -0,0 +1,105 @@
1
+ // Unified diff rendering with no dependencies. Line-based LCS; fine for config-sized files.
2
+ function lcsOps(a, b) {
3
+ const n = a.length;
4
+ const m = b.length;
5
+ const dp = [];
6
+ for (let i = 0; i <= n; i++)
7
+ dp.push(new Uint32Array(m + 1));
8
+ for (let i = n - 1; i >= 0; i--) {
9
+ for (let j = m - 1; j >= 0; j--) {
10
+ dp[i][j] = a[i] === b[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
11
+ }
12
+ }
13
+ const ops = [];
14
+ let i = 0;
15
+ let j = 0;
16
+ while (i < n && j < m) {
17
+ if (a[i] === b[j]) {
18
+ ops.push({ kind: " ", line: a[i] });
19
+ i++;
20
+ j++;
21
+ }
22
+ else if (dp[i + 1][j] >= dp[i][j + 1]) {
23
+ ops.push({ kind: "-", line: a[i] });
24
+ i++;
25
+ }
26
+ else {
27
+ ops.push({ kind: "+", line: b[j] });
28
+ j++;
29
+ }
30
+ }
31
+ while (i < n)
32
+ ops.push({ kind: "-", line: a[i++] });
33
+ while (j < m)
34
+ ops.push({ kind: "+", line: b[j++] });
35
+ return ops;
36
+ }
37
+ function splitLines(s) {
38
+ if (s === null || s === "")
39
+ return [];
40
+ const lines = s.split("\n");
41
+ if (lines[lines.length - 1] === "")
42
+ lines.pop();
43
+ return lines;
44
+ }
45
+ export function renderDiff(change, opts = {}) {
46
+ const color = opts.color ?? false;
47
+ const ctx = opts.context ?? 3;
48
+ const c = (code, s) => (color ? `[${code}m${s}` : s);
49
+ const a = splitLines(change.before);
50
+ const b = splitLines(change.after);
51
+ const header = [];
52
+ const status = change.before === null ? "create" : change.after === null ? "delete" : "modify";
53
+ header.push(c("1", `${status} ${change.path}`));
54
+ if (change.reason)
55
+ header.push(c("2", ` ${change.reason}`));
56
+ header.push(c("36", `--- ${change.before === null ? "/dev/null" : "a/" + change.path}`));
57
+ header.push(c("36", `+++ ${change.after === null ? "/dev/null" : "b/" + change.path}`));
58
+ const ops = lcsOps(a, b);
59
+ if (ops.every((o) => o.kind === " "))
60
+ return header[0] + "\n (no changes)";
61
+ // Group into hunks with context.
62
+ const out = [...header];
63
+ let i = 0;
64
+ while (i < ops.length) {
65
+ if (ops[i].kind === " ") {
66
+ i++;
67
+ continue;
68
+ }
69
+ const start = Math.max(0, i - ctx);
70
+ let end = i;
71
+ let lastChange = i;
72
+ while (end < ops.length && end - lastChange <= ctx) {
73
+ if (ops[end].kind !== " ")
74
+ lastChange = end;
75
+ end++;
76
+ }
77
+ end = Math.min(ops.length, lastChange + ctx + 1);
78
+ // Compute line numbers for the hunk header.
79
+ let aLine = 1;
80
+ let bLine = 1;
81
+ for (let k = 0; k < start; k++) {
82
+ if (ops[k].kind !== "+")
83
+ aLine++;
84
+ if (ops[k].kind !== "-")
85
+ bLine++;
86
+ }
87
+ let aCount = 0;
88
+ let bCount = 0;
89
+ for (let k = start; k < end; k++) {
90
+ if (ops[k].kind !== "+")
91
+ aCount++;
92
+ if (ops[k].kind !== "-")
93
+ bCount++;
94
+ }
95
+ out.push(c("36", `@@ -${aLine},${aCount} +${bLine},${bCount} @@`));
96
+ for (let k = start; k < end; k++) {
97
+ const o = ops[k];
98
+ const text = o.kind + o.line;
99
+ out.push(o.kind === "+" ? c("32", text) : o.kind === "-" ? c("31", text) : text);
100
+ }
101
+ i = end;
102
+ }
103
+ return out.join("\n");
104
+ }
105
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Detection } from "../detect/types.js";
2
+ import type { DougConfig } from "./config.js";
3
+ export declare const AGENT_MARK = "doug: generated";
4
+ /** The old HTML-comment marker, kept only so isDougAgent still recognizes files written by the old generator. */
5
+ export declare const LEGACY_AGENT_MARK = "<!-- Generated by doug init. It refreshes this file while this line is present; remove the line to own the file. -->";
6
+ /** The heading that starts the user-owned section every generated agent file ends with. */
7
+ export declare const PROJECT_NOTES_HEADING = "## Project notes";
8
+ export declare function isDougAgent(text: string): boolean;
9
+ /**
10
+ * Returns `generated` with its (empty) `## Project notes` section replaced by the verbatim section from
11
+ * `existing`, when `existing` has that heading (as its own line; the first such line if there is more than
12
+ * one), else returns `generated` unchanged (an old-form file with no such section). Pure: no filesystem.
13
+ */
14
+ export declare function spliceProjectNotes(generated: string, existing: string): string;
15
+ export interface AgentFile {
16
+ path: string;
17
+ content: string;
18
+ }
19
+ export declare function generateAgents(d: Detection, cfg: DougConfig): AgentFile[];
@@ -0,0 +1,184 @@
1
+ // Generates standard project subagents under .claude/agents/: coder, architect, reviewer, researcher, and
2
+ // (when a test framework is detected) tester. Pure function of its arguments: no filesystem,
3
+ // no clock, no randomness, so the same inputs give byte-identical output.
4
+ export const AGENT_MARK = "doug: generated";
5
+ /** The old HTML-comment marker, kept only so isDougAgent still recognizes files written by the old generator. */
6
+ export const LEGACY_AGENT_MARK = "<!-- Generated by doug init. It refreshes this file while this line is present; remove the line to own the file. -->";
7
+ /** The heading that starts the user-owned section every generated agent file ends with. */
8
+ export const PROJECT_NOTES_HEADING = "## Project notes";
9
+ export function isDougAgent(text) {
10
+ if (text.includes(LEGACY_AGENT_MARK))
11
+ return true;
12
+ const withoutBom = text.startsWith("") ? text.slice(1) : text;
13
+ const lines = withoutBom.split("\n").map((l) => (l.endsWith("\r") ? l.slice(0, -1) : l));
14
+ if (lines[0] !== "---")
15
+ return false;
16
+ const closingIdx = lines.indexOf("---", 1);
17
+ if (closingIdx <= 0)
18
+ return false;
19
+ return lines.slice(0, closingIdx).includes(AGENT_MARK);
20
+ }
21
+ function escapeRegExp(s) {
22
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
23
+ }
24
+ // Line-anchored: matches only a line that equals PROJECT_NOTES_HEADING exactly, never a substring
25
+ // (a mid-line mention, or a "### Project notes" heading with an extra "#").
26
+ const PROJECT_NOTES_HEADING_RE = new RegExp(`^${escapeRegExp(PROJECT_NOTES_HEADING)}$`, "m");
27
+ /**
28
+ * Returns `generated` with its (empty) `## Project notes` section replaced by the verbatim section from
29
+ * `existing`, when `existing` has that heading (as its own line; the first such line if there is more than
30
+ * one), else returns `generated` unchanged (an old-form file with no such section). Pure: no filesystem.
31
+ */
32
+ export function spliceProjectNotes(generated, existing) {
33
+ const existingMatch = PROJECT_NOTES_HEADING_RE.exec(existing);
34
+ if (!existingMatch)
35
+ return generated;
36
+ const genMatch = PROJECT_NOTES_HEADING_RE.exec(generated);
37
+ if (!genMatch)
38
+ return generated;
39
+ return generated.slice(0, genMatch.index) + existing.slice(existingMatch.index);
40
+ }
41
+ function buildFacts(d, cfg, opts) {
42
+ const n = d.node;
43
+ const facts = [];
44
+ if (opts.pm && n.packageManager)
45
+ facts.push(`Use ${n.packageManager} only.`);
46
+ if (opts.pm && d.python.present && d.python.manager)
47
+ facts.push(`Use ${d.python.manager} only for Python.`);
48
+ if (opts.singleTest && n.singleTestCommand)
49
+ facts.push(`Run one test file with: ${n.singleTestCommand}`);
50
+ if (opts.singleTest && d.python.present && d.python.singleTestCommand) {
51
+ facts.push(`Run one Python test file with: ${d.python.singleTestCommand}`);
52
+ }
53
+ if (opts.gate && cfg.stopGate.commands.length) {
54
+ facts.push(`Before finishing run: ${cfg.stopGate.commands.map((name) => cfg.commands[name]).join(" then ")}`);
55
+ }
56
+ if (opts.monorepo && n.monorepo.length) {
57
+ facts.push(`Monorepo (${n.monorepo.map((m) => m.tool).join(",")}): run scripts from the package you are changing.`);
58
+ }
59
+ if (opts.ci && d.repo.ci.length) {
60
+ facts.push(`CI: ${d.repo.ci.join(",")}. Mirror its checks locally.`);
61
+ }
62
+ return facts;
63
+ }
64
+ function renderAgent(spec) {
65
+ const lines = [];
66
+ lines.push("---");
67
+ lines.push(`name: ${spec.name}`);
68
+ lines.push(`description: ${JSON.stringify(spec.description)}`);
69
+ lines.push("model: inherit");
70
+ if (spec.readOnly) {
71
+ lines.push(`tools: ${spec.tools ?? "Read, Grep, Glob, Bash"}`);
72
+ lines.push("disallowedTools: Edit, Write, MultiEdit, NotebookEdit");
73
+ }
74
+ else {
75
+ lines.push("disallowedTools: Agent");
76
+ }
77
+ lines.push(AGENT_MARK);
78
+ lines.push("---");
79
+ lines.push("");
80
+ if (spec.facts.length) {
81
+ lines.push("## Facts");
82
+ lines.push("");
83
+ for (const f of spec.facts)
84
+ lines.push(`- ${f}`);
85
+ lines.push("");
86
+ }
87
+ lines.push("## Rules");
88
+ lines.push("");
89
+ for (const r of spec.rules)
90
+ lines.push(`- ${r}`);
91
+ lines.push("");
92
+ lines.push(PROJECT_NOTES_HEADING);
93
+ return lines.join("\n") + "\n";
94
+ }
95
+ export function generateAgents(d, cfg) {
96
+ const n = d.node;
97
+ const coder = {
98
+ name: "coder",
99
+ description: "Implements a requested change in this repository, runs its checks, and reports what it ran",
100
+ readOnly: false,
101
+ facts: buildFacts(d, cfg, { pm: true, singleTest: true, gate: true, monorepo: true }),
102
+ rules: [
103
+ "Do only what was asked, no refactors or renames beyond it.",
104
+ "Add or update the test with the change.",
105
+ "Never bypass hooks with --no-verify.",
106
+ "Do not claim done until the gate passed in this session.",
107
+ "Report every command run with its exit status.",
108
+ "Return partial=true only after a hook tells you `[doug] Worker context at <pct>% of <window> tokens`: stop at a boundary (finish the file you are on and its named test, then commit), and say what's done, what's left, what to do next, and how to verify it. Never claim partial to dodge a hard task.",
109
+ "When a test contradicts the brief or the card's goal, do not change production code to fit the test; stop and report the conflict, quoting both, so the lead can send it back to the tester.",
110
+ "Apply each mutation in a scratch copy or git worktree under `.doug/.state`, run the one test file there, and remove the copy.",
111
+ "Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.",
112
+ "Run any command that can take over 120 s, such as pnpm test:unit, with the Bash timeout set to 600000, and hand back only after it exits.",
113
+ ],
114
+ };
115
+ const architect = {
116
+ name: "architect",
117
+ description: "Reads the code and returns a design: files to change, tests to add, and the command that verifies each; writes no code",
118
+ readOnly: true,
119
+ facts: buildFacts(d, cfg, { monorepo: true, singleTest: true, gate: true }),
120
+ rules: [
121
+ "Read before proposing.",
122
+ "Return a numbered list of files with what changes in each.",
123
+ "Name the test file and verify command per item.",
124
+ "Do not edit.",
125
+ ],
126
+ };
127
+ const reviewer = {
128
+ name: "reviewer",
129
+ description: "Reviews a diff against its request, runs the project checks, and reports blocker, major, and minor findings; never edits",
130
+ readOnly: true,
131
+ facts: buildFacts(d, cfg, { gate: true, singleTest: true, ci: true }),
132
+ rules: [
133
+ "Review `git diff` (or `git diff <base>...HEAD` when a base is named).",
134
+ "Run the gate commands and report real exit codes.",
135
+ "When the change's point is that a mechanism exists, mutate or remove it, rerun the test, and confirm it fails before reverting.",
136
+ "Severity blocker/major/minor with blocker meaning the change must not merge.",
137
+ "Do not ask for work beyond the request.",
138
+ "Apply each mutation in a scratch copy or git worktree under `.doug/.state`, run the one test file there, and remove the copy.",
139
+ "Run any command that can take over 120 s, such as pnpm test:unit, with the Bash timeout set to 600000, and hand back only after it exits.",
140
+ ],
141
+ };
142
+ const researcher = {
143
+ name: "researcher",
144
+ description: "Answers one question about a fact outside this repository (a CLI's output, a third-party API, a package's constraints) from primary sources, quoting each fact's URL or command output and marking the rest unverified; never writes",
145
+ readOnly: true,
146
+ tools: "Read, Grep, Glob, Bash, WebFetch, WebSearch",
147
+ facts: buildFacts(d, cfg, { pm: true }),
148
+ rules: [
149
+ "Answer the one question asked; leave any other researcher's question alone.",
150
+ "Primary sources first (official docs, the tool's own --help, the package's repository); quote each fact with its URL or the command and its output, and say whether it was observed or documented.",
151
+ "Never install, write, or change the machine; a fact that needs an install is unverified, with the command that would show it.",
152
+ "Mark anything unconfirmed unverified, with what was tried; never guess.",
153
+ "Budget: at most 6 WebSearch plus WebFetch calls for your question (research.maxFetches; a hook denies the next one). Try sources in the order the question lists them, and write your findings before the budget runs out, marking anything still unanswered unverified.",
154
+ ],
155
+ };
156
+ const files = [
157
+ { path: ".claude/agents/coder.md", content: renderAgent(coder) },
158
+ { path: ".claude/agents/architect.md", content: renderAgent(architect) },
159
+ { path: ".claude/agents/reviewer.md", content: renderAgent(reviewer) },
160
+ { path: ".claude/agents/researcher.md", content: renderAgent(researcher) },
161
+ ];
162
+ if (n.testFramework || d.python.testFramework) {
163
+ const frameworkName = n.testFramework ?? "pytest";
164
+ const tester = {
165
+ name: "tester",
166
+ description: `Writes and runs tests with ${frameworkName} for a named behavior; edits test files only`,
167
+ readOnly: false,
168
+ facts: buildFacts(d, cfg, { pm: true, singleTest: true }),
169
+ rules: [
170
+ "A new test must fail without the behavior and pass with it.",
171
+ "Edit only test files.",
172
+ "Run each test file you touch with the single-test command.",
173
+ "Report what ran.",
174
+ 'When your new tests are meant to stay red until the coder\'s change, end your final message with a JSON object {"tests_red_by_design": ["<test file>", ...]} naming every test file you left failing by its repository-relative path, report the red once, and do not rerun the suite to make a gate pass. Put that JSON line either as the last line of your final plain-text message or inside your hand-back message: the SubagentStop gate reads your last plain-text message first and, when that holds no claim, your last hand-back call.',
175
+ "Scratch files go under `.doug/.state/scratch`; protect-paths keeps refusing the Claude Code session scratchpad, which is outside the project.",
176
+ "Run any command that can take over 120 s, such as pnpm test:unit, with the Bash timeout set to 600000, and hand back only after it exits.",
177
+ "On a tests-only card, run the brief's mutation list yourself in a scratch copy or git worktree under `.doug/.state`, run the one test file there, report each result, and remove the copy; never edit a production file in the live checkout.",
178
+ ],
179
+ };
180
+ files.push({ path: ".claude/agents/tester.md", content: renderAgent(tester) });
181
+ }
182
+ return files;
183
+ }
184
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/generate/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Detection } from "../detect/types.js";
2
+ import type { DougConfig } from "./config.js";
3
+ export declare function generateClaudeMd(d: Detection, cfg: DougConfig): string;
4
+ /**
5
+ * The Models table: which model and effort does which work when doug-flow runs a plan.
6
+ * Parsed deterministically by doug-flow's plan CLI (lib/models.mjs) and resolved into the plan
7
+ * before the workflow runs. "inherit" keeps the session model or the role's default effort.
8
+ */
9
+ export declare const MODELS_SECTION: string[];