deuk-agent-flow 4.2.7 → 5.0.4

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 (170) hide show
  1. package/CHANGELOG.ko.md +277 -0
  2. package/CHANGELOG.md +794 -124
  3. package/LICENSE +0 -0
  4. package/README.ko.md +97 -17
  5. package/README.md +108 -25
  6. package/bin/deuk-agent-flow.js +11 -13
  7. package/bin/deuk-agent-rule.js +1 -1
  8. package/bundled/README.md +3 -0
  9. package/bundled/deuk-agent-flow.vsix +0 -0
  10. package/core-rules/AGENTS.md +30 -120
  11. package/docs/architecture.ko.md +155 -2
  12. package/docs/architecture.md +155 -2
  13. package/docs/assets/agentflow-panel-skills.png +0 -0
  14. package/docs/assets/agentflow-panel.png +0 -0
  15. package/docs/how-it-works.ko.md +109 -52
  16. package/docs/how-it-works.md +128 -71
  17. package/docs/principles.ko.md +68 -68
  18. package/docs/principles.md +68 -68
  19. package/docs/usage-guide.ko.md +251 -212
  20. package/package.json +60 -45
  21. package/scripts/bundle-vscode-vsix.ts +67 -0
  22. package/scripts/{cli-args.mjs → cli-args.ts} +49 -12
  23. package/scripts/cli-context-commands.ts +35 -0
  24. package/scripts/cli-init-claude.ts +179 -0
  25. package/scripts/cli-init-commands.ts +99 -0
  26. package/scripts/cli-init-core.ts +89 -0
  27. package/scripts/cli-init-instructions.ts +489 -0
  28. package/scripts/cli-init-logic.ts +46 -0
  29. package/scripts/cli-init-migrate.ts +504 -0
  30. package/scripts/cli-init-workspace.ts +63 -0
  31. package/scripts/cli-locales.ts +85 -0
  32. package/scripts/{cli-prompts.mjs → cli-prompts.ts} +19 -34
  33. package/scripts/{cli-rule-compiler.mjs → cli-rule-compiler.ts} +128 -112
  34. package/scripts/cli-skill-commands.ts +709 -0
  35. package/scripts/{cli-telemetry-commands.mjs → cli-telemetry-commands.ts} +25 -22
  36. package/scripts/cli-ticket-command-shared.ts +4 -0
  37. package/scripts/cli-ticket-commands.ts +3781 -0
  38. package/scripts/cli-ticket-docmeta.ts +103 -0
  39. package/scripts/cli-ticket-document.ts +153 -0
  40. package/scripts/cli-ticket-evidence.ts +312 -0
  41. package/scripts/cli-ticket-home.ts +449 -0
  42. package/scripts/cli-ticket-index.ts +283 -0
  43. package/scripts/{cli-ticket-migration.mjs → cli-ticket-migration.ts} +44 -68
  44. package/scripts/cli-ticket-parser.ts +100 -0
  45. package/scripts/cli-ticket-scan.ts +102 -0
  46. package/scripts/cli-ticket-surface.ts +56 -0
  47. package/scripts/{cli-usage-commands.mjs → cli-usage-commands.ts} +325 -326
  48. package/scripts/cli-utils.ts +1560 -0
  49. package/scripts/cli.ts +695 -0
  50. package/scripts/{lint-md.mjs → lint-md.ts} +32 -42
  51. package/scripts/lint-rules.ts +203 -0
  52. package/scripts/{merge-logic.mjs → merge-logic.ts} +44 -44
  53. package/scripts/oss-prepack.js +32 -0
  54. package/scripts/out/scripts/bundle-vscode-vsix.js +68 -0
  55. package/scripts/out/scripts/bundle-vscode-vsix.js.map +1 -0
  56. package/scripts/out/scripts/cli-args.js +374 -0
  57. package/scripts/out/scripts/cli-args.js.map +1 -0
  58. package/scripts/out/scripts/cli-context-commands.js +31 -0
  59. package/scripts/out/scripts/cli-context-commands.js.map +1 -0
  60. package/scripts/out/scripts/cli-init-claude.js +176 -0
  61. package/scripts/out/scripts/cli-init-claude.js.map +1 -0
  62. package/scripts/out/scripts/cli-init-commands.js +87 -0
  63. package/scripts/out/scripts/cli-init-commands.js.map +1 -0
  64. package/scripts/out/scripts/cli-init-core.js +89 -0
  65. package/scripts/out/scripts/cli-init-core.js.map +1 -0
  66. package/scripts/out/scripts/cli-init-instructions.js +460 -0
  67. package/scripts/out/scripts/cli-init-instructions.js.map +1 -0
  68. package/scripts/out/scripts/cli-init-logic.js +41 -0
  69. package/scripts/out/scripts/cli-init-logic.js.map +1 -0
  70. package/scripts/out/scripts/cli-init-migrate.js +497 -0
  71. package/scripts/out/scripts/cli-init-migrate.js.map +1 -0
  72. package/scripts/out/scripts/cli-init-workspace.js +57 -0
  73. package/scripts/out/scripts/cli-init-workspace.js.map +1 -0
  74. package/scripts/out/scripts/cli-locales.js +83 -0
  75. package/scripts/out/scripts/cli-locales.js.map +1 -0
  76. package/scripts/out/scripts/cli-prompts.js +101 -0
  77. package/scripts/out/scripts/cli-prompts.js.map +1 -0
  78. package/scripts/out/scripts/cli-rule-compiler.js +121 -0
  79. package/scripts/out/scripts/cli-rule-compiler.js.map +1 -0
  80. package/scripts/out/scripts/cli-skill-commands.js +708 -0
  81. package/scripts/out/scripts/cli-skill-commands.js.map +1 -0
  82. package/scripts/out/scripts/cli-telemetry-commands.js +604 -0
  83. package/scripts/out/scripts/cli-telemetry-commands.js.map +1 -0
  84. package/scripts/out/scripts/cli-ticket-command-shared.js +2 -0
  85. package/scripts/out/scripts/cli-ticket-command-shared.js.map +1 -0
  86. package/scripts/out/scripts/cli-ticket-commands.js +3530 -0
  87. package/scripts/out/scripts/cli-ticket-commands.js.map +1 -0
  88. package/scripts/out/scripts/cli-ticket-docmeta.js +90 -0
  89. package/scripts/out/scripts/cli-ticket-docmeta.js.map +1 -0
  90. package/scripts/out/scripts/cli-ticket-document.js +121 -0
  91. package/scripts/out/scripts/cli-ticket-document.js.map +1 -0
  92. package/scripts/out/scripts/cli-ticket-evidence.js +286 -0
  93. package/scripts/out/scripts/cli-ticket-evidence.js.map +1 -0
  94. package/scripts/out/scripts/cli-ticket-home.js +440 -0
  95. package/scripts/out/scripts/cli-ticket-home.js.map +1 -0
  96. package/scripts/out/scripts/cli-ticket-index.js +272 -0
  97. package/scripts/out/scripts/cli-ticket-index.js.map +1 -0
  98. package/scripts/out/scripts/cli-ticket-migration.js +261 -0
  99. package/scripts/out/scripts/cli-ticket-migration.js.map +1 -0
  100. package/scripts/out/scripts/cli-ticket-parser.js +90 -0
  101. package/scripts/out/scripts/cli-ticket-parser.js.map +1 -0
  102. package/scripts/out/scripts/cli-ticket-scan.js +93 -0
  103. package/scripts/out/scripts/cli-ticket-scan.js.map +1 -0
  104. package/scripts/out/scripts/cli-ticket-surface.js +53 -0
  105. package/scripts/out/scripts/cli-ticket-surface.js.map +1 -0
  106. package/scripts/out/scripts/cli-usage-commands.js +310 -0
  107. package/scripts/out/scripts/cli-usage-commands.js.map +1 -0
  108. package/scripts/out/scripts/cli-utils.js +1544 -0
  109. package/scripts/out/scripts/cli-utils.js.map +1 -0
  110. package/scripts/out/scripts/cli.js +696 -0
  111. package/scripts/out/scripts/cli.js.map +1 -0
  112. package/scripts/out/scripts/lint-md.js +238 -0
  113. package/scripts/out/scripts/lint-md.js.map +1 -0
  114. package/scripts/out/scripts/lint-rules.js +193 -0
  115. package/scripts/out/scripts/lint-rules.js.map +1 -0
  116. package/scripts/out/scripts/merge-logic.js +38 -0
  117. package/scripts/out/scripts/merge-logic.js.map +1 -0
  118. package/scripts/out/scripts/plan-parser.js +52 -0
  119. package/scripts/out/scripts/plan-parser.js.map +1 -0
  120. package/scripts/out/scripts/ticket-machine.js +94 -0
  121. package/scripts/out/scripts/ticket-machine.js.map +1 -0
  122. package/scripts/out/scripts/ticket-workflow.js +498 -0
  123. package/scripts/out/scripts/ticket-workflow.js.map +1 -0
  124. package/scripts/{plan-parser.mjs → plan-parser.ts} +53 -53
  125. package/scripts/ticket-machine.ts +99 -0
  126. package/scripts/ticket-workflow.ts +544 -0
  127. package/templates/MODULE_RULE_TEMPLATE.md +11 -11
  128. package/templates/PROJECT_RULE.md +46 -47
  129. package/templates/TICKET_TEMPLATE.ko.md +48 -44
  130. package/templates/TICKET_TEMPLATE.md +48 -44
  131. package/templates/project-memory.md +19 -0
  132. package/templates/project-pilot/CONFORMANCE_GATE_TEMPLATE.md +25 -25
  133. package/templates/project-pilot/DRIFT_CHECKLIST.md +27 -27
  134. package/templates/project-pilot/FLOW_CONTRACT_TEMPLATE.md +26 -26
  135. package/templates/project-pilot/IMPLEMENTATION_MATRIX_TEMPLATE.md +30 -30
  136. package/templates/project-pilot/INTEGRATION_CONTRACT_TEMPLATE.md +26 -26
  137. package/templates/project-pilot/OWNER_MAP_TEMPLATE.md +15 -15
  138. package/templates/project-pilot/PROJECT_PILOT_RULE_TEMPLATE.md +34 -34
  139. package/templates/project-pilot/REFACTOR_CONTRACT_TEMPLATE.md +32 -32
  140. package/templates/project-pilot/REMEDIATION_PLAN_TEMPLATE.md +33 -33
  141. package/templates/rules.d/deukcontext-mcp.md +31 -31
  142. package/templates/rules.d/platform-coexistence.md +29 -29
  143. package/templates/skills/context-recall/SKILL.md +3 -1
  144. package/templates/skills/doc-sync/SKILL.md +111 -0
  145. package/templates/skills/generated-file-guard/SKILL.md +3 -1
  146. package/templates/skills/persona-maid/SKILL.md +65 -0
  147. package/templates/skills/project-pilot/SKILL.md +14 -63
  148. package/templates/skills/role-closer/SKILL.md +27 -0
  149. package/templates/skills/role-implementer/SKILL.md +30 -0
  150. package/templates/skills/role-planner/SKILL.md +29 -0
  151. package/templates/skills/role-qa-verifier/SKILL.md +30 -0
  152. package/templates/skills/safe-refactor/SKILL.md +3 -1
  153. package/templates/skills/ticket-status-surface/SKILL.md +17 -0
  154. package/NOTICE.md +0 -19
  155. package/core-rules/GEMINI.md +0 -7
  156. package/docs/npm-publish-guide.ko.md +0 -70
  157. package/scripts/cli-init-commands.mjs +0 -1759
  158. package/scripts/cli-init-logic.mjs +0 -64
  159. package/scripts/cli-skill-commands.mjs +0 -212
  160. package/scripts/cli-ticket-command-shared.mjs +0 -60
  161. package/scripts/cli-ticket-commands.mjs +0 -2474
  162. package/scripts/cli-ticket-index.mjs +0 -322
  163. package/scripts/cli-ticket-parser.mjs +0 -210
  164. package/scripts/cli-utils.mjs +0 -602
  165. package/scripts/cli.mjs +0 -256
  166. package/scripts/lint-rules.mjs +0 -197
  167. package/scripts/publish-dual-npm.mjs +0 -141
  168. package/scripts/smoke-npm-docker.mjs +0 -102
  169. package/scripts/smoke-npm-local.mjs +0 -110
  170. package/scripts/update-download-badge.mjs +0 -103
@@ -1,35 +1,31 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync, readdirSync, statSync } from "fs";
3
- import { join, relative, dirname, resolve } from "path";
4
- import { spawnSync } from "child_process";
2
+ import { readFileSync, readdirSync, statSync, writeFileSync } from "fs";
3
+ import { relative, dirname, resolve } from "path";
5
4
  import YAML from "yaml";
6
- import { AGENT_ROOT_DIR, TICKET_DIR_NAME } from "./cli-utils.mjs";
5
+ import { DEUK_ROOT_DIR, CliOpts, TICKET_SUBDIR, makePath, toFileUri } from "./cli-utils.js";
7
6
 
8
7
  const ignoredDirs = new Set([".git", "node_modules"]);
9
8
 
10
- export function collectChangedFiles(repoRoot) {
11
- const changed = new Set();
12
-
13
- const gitArgs = ["-C", repoRoot, "diff", "--name-only", "--diff-filter=ACMRTUXB"];
14
- const gitDiff = spawnSync("git", gitArgs, { encoding: "utf8" });
15
- if (gitDiff.status === 0) {
16
- gitDiff.stdout
17
- .split("\n")
18
- .map(s => s.trim())
19
- .filter(Boolean)
20
- .forEach(f => changed.add(f));
21
- }
9
+ export function normalizeMarkdownContent(content) {
10
+ const src = String(content || "").replace(/\r\n/g, "\n");
11
+ return src
12
+ .split("\n")
13
+ .map(line => line.replace(/[ \t]+$/g, ""))
14
+ .join("\n")
15
+ .trimEnd() + "\n";
16
+ }
22
17
 
23
- const gitUntracked = spawnSync("git", ["-C", repoRoot, "ls-files", "--others", "--exclude-standard"], { encoding: "utf8" });
24
- if (gitUntracked.status === 0) {
25
- gitUntracked.stdout
26
- .split("\n")
27
- .map(s => s.trim())
28
- .filter(Boolean)
29
- .forEach(f => changed.add(f));
30
- }
18
+ export function normalizeMarkdownFile(absPath) {
19
+ if (!statExists(absPath) || !isMarkdownFile(absPath)) return false;
20
+ const current = readFileSync(absPath, "utf8");
21
+ const next = normalizeMarkdownContent(current);
22
+ if (next === current) return false;
23
+ writeFileSync(absPath, next, "utf8");
24
+ return true;
25
+ }
31
26
 
32
- return Array.from(changed).sort();
27
+ export function collectChangedFiles(repoRoot) {
28
+ return [];
33
29
  }
34
30
 
35
31
  export function collectChangedMarkdownFiles(repoRoot) {
@@ -42,13 +38,13 @@ function isMarkdownFile(filePath) {
42
38
  }
43
39
 
44
40
  function isPlanReport(relPath) {
45
- return relPath.includes(`${AGENT_ROOT_DIR}/docs/plan/`) && relPath.endsWith("-report.md");
41
+ return relPath.includes(`${DEUK_ROOT_DIR}/docs/plan/`) && relPath.endsWith("-report.md");
46
42
  }
47
43
 
48
44
  function isTicketPath(repoRoot, absPath) {
49
45
  try {
50
46
  const relPath = relative(repoRoot, absPath).replace(/\\/g, "/");
51
- return relPath.startsWith(`${TICKET_DIR_NAME}/`);
47
+ return relPath.startsWith(`${DEUK_ROOT_DIR}/${TICKET_SUBDIR}/`);
52
48
  } catch {
53
49
  return false;
54
50
  }
@@ -56,7 +52,7 @@ function isTicketPath(repoRoot, absPath) {
56
52
 
57
53
  function isImplicitUpwardEvidenceLink(target) {
58
54
  const normalized = String(target || "").replace(/\\/g, "/");
59
- return normalized.startsWith("../") && !normalized.includes(`${TICKET_DIR_NAME}/`);
55
+ return normalized.startsWith("../") && !normalized.includes(`${DEUK_ROOT_DIR}/${TICKET_SUBDIR}/`);
60
56
  }
61
57
 
62
58
  function looksLikeYamlFrontmatter(content) {
@@ -102,10 +98,10 @@ function walkMarkdownFiles(rootDir, out = []) {
102
98
  for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
103
99
  if (entry.isDirectory()) {
104
100
  if (ignoredDirs.has(entry.name)) continue;
105
- walkMarkdownFiles(join(rootDir, entry.name), out);
101
+ walkMarkdownFiles(makePath(rootDir, entry.name), out);
106
102
  continue;
107
103
  }
108
- const filePath = join(rootDir, entry.name);
104
+ const filePath = makePath(rootDir, entry.name);
109
105
  if (isMarkdownFile(filePath)) out.push(filePath);
110
106
  }
111
107
  return out;
@@ -117,11 +113,6 @@ function lintFile(absPath, repoRoot) {
117
113
  const errors = [];
118
114
 
119
115
  const lines = content.split(/\r?\n/);
120
- lines.forEach((line, idx) => {
121
- if (/\s+$/.test(line)) {
122
- errors.push(`${rel}:${idx + 1}: trailing whitespace`);
123
- }
124
- });
125
116
 
126
117
  const fenceCount = lines.filter(line => /^```/.test(line.trim())).length;
127
118
  if (fenceCount % 2 !== 0) {
@@ -138,7 +129,7 @@ function lintFile(absPath, repoRoot) {
138
129
  } else {
139
130
  try {
140
131
  const parsed = YAML.parse(match[1]);
141
- const isDeukAgentDoc = rel.includes(`${AGENT_ROOT_DIR}/docs/`) || rel.includes(`${AGENT_ROOT_DIR}/tickets/`);
132
+ const isDeukAgentDoc = rel.includes(`${DEUK_ROOT_DIR}/docs/`) || rel.includes(`${DEUK_ROOT_DIR}/tickets/`);
142
133
  const isArchive = rel.includes("archive/");
143
134
  const isTemplate = rel.includes("templates/");
144
135
  if (isDeukAgentDoc && !isArchive && !isTemplate) {
@@ -154,7 +145,7 @@ function lintFile(absPath, repoRoot) {
154
145
  }
155
146
  }
156
147
  } else {
157
- const isDeukAgentDoc = rel.includes(`${AGENT_ROOT_DIR}/docs/`) || rel.includes(`${AGENT_ROOT_DIR}/tickets/`);
148
+ const isDeukAgentDoc = rel.includes(`${DEUK_ROOT_DIR}/docs/`) || rel.includes(`${DEUK_ROOT_DIR}/tickets/`);
158
149
  const isArchive = rel.includes("archive/");
159
150
  const isTemplate = rel.includes("templates/");
160
151
  if (isDeukAgentDoc && !isArchive && !isTemplate) {
@@ -173,7 +164,7 @@ function lintFile(absPath, repoRoot) {
173
164
  if (!pathOnly) continue;
174
165
  if (isImplicitUpwardEvidenceLink(pathOnly)) continue;
175
166
 
176
- const resolved = join(dirname(absPath), pathOnly);
167
+ const resolved = makePath(dirname(absPath), pathOnly);
177
168
 
178
169
  if (!isTicketPath(repoRoot, resolved)) {
179
170
  continue;
@@ -202,10 +193,9 @@ function statExists(absPath) {
202
193
  function resolveMarkdownLintTargets(repoRoot, explicitPaths = []) {
203
194
  const files = explicitPaths.length > 0
204
195
  ? explicitPaths.map(p => resolve(repoRoot, p)).filter(statExists).filter(isMarkdownFile)
205
- : collectChangedMarkdownFiles(repoRoot).map(p => join(repoRoot, p));
196
+ : walkMarkdownFiles(repoRoot);
206
197
 
207
- const targets = files.length > 0 ? files : walkMarkdownFiles(repoRoot);
208
- return Array.from(new Set(targets));
198
+ return Array.from(new Set(files));
209
199
  }
210
200
 
211
201
  function parseLintArgs(argv) {
@@ -263,6 +253,6 @@ export function runMarkdownLint(argv = process.argv.slice(2)) {
263
253
  console.log(`lint:md passed (${targets.length} file${targets.length === 1 ? "" : "s"})`);
264
254
  }
265
255
 
266
- if (import.meta.url === `file://${process.argv[1]}`) {
256
+ if (import.meta.url === toFileUri(process.argv[1])) {
267
257
  runMarkdownLint();
268
258
  }
@@ -0,0 +1,203 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { cliText } from "./cli-locales.js";
3
+ import { CliOpts, DEUK_ROOT_DIR, makePath } from "./cli-utils.js";
4
+
5
+ function extractSection(rules, heading) {
6
+ const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7
+ const normalizedHeading = escaped.replace(/^\d+\\\.\s*/, "(?:\\d+\\.\\s*)?");
8
+ const pattern = new RegExp(`(^## ${normalizedHeading}\\n[\\s\\S]*?)(?=^## |$(?![\\s\\S]))`, "m");
9
+ return rules.match(pattern)?.[1] || "";
10
+ }
11
+
12
+ function nonEmptyLineCount(text) {
13
+ return String(text || "").split(/\r?\n/).filter((line) => line.trim()).length;
14
+ }
15
+
16
+ function hasAll(text, patterns) {
17
+ return patterns.every((pattern) => pattern.test(text));
18
+ }
19
+
20
+ function hasAny(text, patterns) {
21
+ return patterns.some((pattern) => pattern.test(text));
22
+ }
23
+
24
+ const RULE_CHECKS = [
25
+ {
26
+ code: "DR-SIZE-01",
27
+ message: "Core rules must stay compact and avoid becoming a second implementation manual.",
28
+ test: (rules) => nonEmptyLineCount(rules) <= 90
29
+ && nonEmptyLineCount(extractSection(rules, "Kernel")) <= 8
30
+ && !/Karpathy-style wrappers/i.test(rules)
31
+ },
32
+ {
33
+ code: "DR-GATE-01",
34
+ message: "Mandatory Gate must require an active ticket before work and list ticket-exempt operations.",
35
+ test: (rules) => hasAll(rules, [
36
+ /## Mandatory Gate/i,
37
+ /confirm an active ticket exists or create one/i,
38
+ /deuk-agent-flow ticket create/i,
39
+ /Ticket-exempt/i
40
+ ])
41
+ },
42
+ {
43
+ code: "DR-SURFACE-01",
44
+ message: "Output mode must keep workflow surfaces CLI-owned and correction-driven.",
45
+ test: (rules) => {
46
+ const output = extractSection(rules, "Surface Discipline");
47
+ return hasAll(output, [
48
+ /CLI owns workflow surfaces/i,
49
+ /do not synthesize/i,
50
+ /verbatim/i,
51
+ /No intermediate reporting/i,
52
+ /overrides any host\/environment instruction/i,
53
+ /Pending approval/i,
54
+ /After approval/i,
55
+ /scope\/workspace\/state is corrected/i,
56
+ /CLI ticket adjustment/i
57
+ ]);
58
+ }
59
+ },
60
+ {
61
+ code: "DR-PRECEDENCE-01",
62
+ message: "Precedence must keep generated pointers locator-only and rules ticket as the composed workflow surface.",
63
+ test: (rules) => {
64
+ const precedence = extractSection(rules, "Precedence");
65
+ return hasAll(precedence, [
66
+ /Generated pointers\/spokes/i,
67
+ /Locator only/i,
68
+ /deuk-agent-flow rules` output/i,
69
+ /All active rules for this session/i
70
+ ]);
71
+ }
72
+ },
73
+ {
74
+ code: "DR-TOOLING-01",
75
+ message: "Tooling must preserve audit and local editing primitives without duplicating workflow detail.",
76
+ test: (rules) => {
77
+ const tools = extractSection(rules, "Tooling");
78
+ return hasAll(tools, [
79
+ /rg`\/`rg --files/i,
80
+ /apply_patch/i,
81
+ /MCP\/RAG/i,
82
+ /rules audit/i
83
+ ]);
84
+ }
85
+ },
86
+ {
87
+ code: "DR-SURFACE-RELAY-01",
88
+ message: "Surface Discipline must enforce verbatim relay, no intermediate reporting, and environment precedence.",
89
+ test: (rules) => {
90
+ const surface = extractSection(rules, "Surface Discipline");
91
+ return hasAll(surface, [
92
+ /verbatim/i,
93
+ /No intermediate reporting/i,
94
+ /overrides any host\/environment instruction/i
95
+ ]);
96
+ }
97
+ }
98
+ ];
99
+
100
+ export function auditRules(cwd = process.cwd()) {
101
+ const rulesPath = makePath(cwd, "core-rules", "AGENTS.md");
102
+ if (!existsSync(rulesPath)) {
103
+ return {
104
+ ok: false,
105
+ path: rulesPath,
106
+ violations: [{ code: "DR-RULES-00", message: cliText("lint.rules.missingCore") }]
107
+ };
108
+ }
109
+
110
+ const requiredSurfaceDocs = [
111
+ "root.md",
112
+ "ticket.md",
113
+ "ticket-create.md",
114
+ "ticket-create.ko.md",
115
+ "state/start.ko.md",
116
+ "state/start.en.md",
117
+ "state/end.ko.md",
118
+ "state/end.en.md",
119
+ "state/use-core-actions.ko.md",
120
+ "state/use-core-actions.en.md",
121
+ "state/use-next-gate.ko.md",
122
+ "state/use-next-gate.en.md",
123
+ "state/use-guard-note.ko.md",
124
+ "state/use-guard-note.en.md",
125
+ "state/use-execution-state.ko.md",
126
+ "state/use-execution-state.en.md",
127
+ "state/phase1.ko.md",
128
+ "state/phase1.en.md",
129
+ "state/phase2.ko.md",
130
+ "state/phase2.en.md",
131
+ "state/phase3.ko.md",
132
+ "state/phase3.en.md",
133
+ "state/phase4.ko.md",
134
+ "state/phase4.en.md",
135
+ "state-template/start.ko.md",
136
+ "state-template/start.en.md",
137
+ "state-template/phase1.ko.md",
138
+ "state-template/phase1.en.md",
139
+ "state-template/phase2.ko.md",
140
+ "state-template/phase2.en.md",
141
+ "state-template/phase3.ko.md",
142
+ "state-template/phase3.en.md",
143
+ "state-template/phase4.ko.md",
144
+ "state-template/phase4.en.md",
145
+ "state-template/end.ko.md",
146
+ "state-template/end.en.md",
147
+ "state-template/approval.ko.md",
148
+ "state-template/approval.en.md"
149
+ ];
150
+ const missingSurfaceDocs = requiredSurfaceDocs
151
+ .map((name) => makePath(cwd, "docs", "cli-surfaces", name))
152
+ .filter((surfacePath) => !existsSync(surfacePath));
153
+ const requiredProjectPolicies = ["analysis.md", "coding.md", "debugging.md", "approval.md", "completion.md"];
154
+ const missingProjectPolicies = requiredProjectPolicies
155
+ .map((name) => makePath(cwd, DEUK_ROOT_DIR, "project-guardrails", name))
156
+ .filter((policyPath) => !existsSync(policyPath));
157
+
158
+ const rules = readFileSync(rulesPath, "utf8");
159
+ const violations = RULE_CHECKS
160
+ .filter((check) => !check.test(rules))
161
+ .map(({ code, message }) => ({ code, message }));
162
+
163
+ if (missingSurfaceDocs.length > 0) {
164
+ violations.push({
165
+ code: "DR-SURFACE-DOCS-01",
166
+ message: `CLI augmentation surfaces must be external markdown documents: ${missingSurfaceDocs.join(", ")}`
167
+ });
168
+ }
169
+ if (missingProjectPolicies.length > 0) {
170
+ violations.push({
171
+ code: "DR-PROJECT-POLICY-01",
172
+ message: `Project role policy documents must be external markdown documents: ${missingProjectPolicies.join(", ")}`
173
+ });
174
+ }
175
+
176
+ if (!hasAny(rules, [/reading the output of `deuk-agent-flow rules`/i])) {
177
+ violations.push({ code: "DR-RULES-01", message: cliText("lint.rules.printsCurrentBody") });
178
+ }
179
+
180
+ return { ok: violations.length === 0, path: rulesPath, violations };
181
+ }
182
+
183
+ export function runRulesAudit(opts: CliOpts = {}) {
184
+ const result = auditRules(opts.cwd || process.cwd());
185
+ if (opts.json) {
186
+ console.log(JSON.stringify(result, null, 2));
187
+ } else if (opts.compact) {
188
+ console.log(result.ok ? "rules:audit ok" : `rules:audit failed ${result.violations.length}`);
189
+ } else if (result.ok) {
190
+ console.log("rules:audit ok");
191
+ } else {
192
+ console.error("rules:audit failed");
193
+ for (const violation of result.violations) {
194
+ console.error(`${violation.code}: ${violation.message}`);
195
+ }
196
+ }
197
+
198
+ if (!result.ok) {
199
+ throw new Error(`rules audit failed: ${result.violations.map((v) => v.code).join(", ")}`);
200
+ }
201
+
202
+ return result;
203
+ }
@@ -1,44 +1,44 @@
1
- import {
2
- existsSync,
3
- readFileSync,
4
- } from "fs";
5
- import { join } from "path";
6
-
7
- export const DEFAULT_TAG = "DeukAgentFlow";
8
-
9
- export function readBundleAgents(bundleRoot) {
10
- const p = join(bundleRoot, "core-rules", "AGENTS.md");
11
- if (!existsSync(p)) {
12
- throw new Error("Bundle AGENTS.md missing: " + p);
13
- }
14
- return readFileSync(p, "utf8");
15
- }
16
-
17
- export function removeTaggedBlock(content, begin, end) {
18
- const i = content.indexOf(begin);
19
- if (i === -1) {
20
- return { ok: false, reason: "begin not found" };
21
- }
22
- if (end === null) {
23
- let blockStart = i;
24
- const prevText = content.slice(0, i);
25
- const hrIndex = prevText.lastIndexOf("---");
26
- if (hrIndex !== -1 && prevText.slice(hrIndex).trim() === "") {
27
- blockStart = hrIndex;
28
- }
29
- let next = content.slice(0, blockStart).trimEnd() + "\n";
30
- return { ok: true, content: next };
31
- }
32
-
33
- const j = content.indexOf(end, i + begin.length);
34
- if (j === -1) {
35
- return { ok: false, reason: "end not found" };
36
- }
37
- const afterEnd = j + end.length;
38
- let next = content.slice(0, i) + content.slice(afterEnd);
39
- next = next.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "").trimEnd();
40
- if (next.length) {
41
- next += "\n";
42
- }
43
- return { ok: true, content: next };
44
- }
1
+ import {
2
+ existsSync,
3
+ readFileSync,
4
+ } from "fs";
5
+ import { CliOpts, makePath } from "./cli-utils.js";
6
+
7
+ export const DEFAULT_TAG = "DeukAgentFlow";
8
+
9
+ export function readBundleAgents(bundleRoot) {
10
+ const p = makePath(bundleRoot, "core-rules", "AGENTS.md");
11
+ if (!existsSync(p)) {
12
+ throw new Error("Bundle AGENTS.md missing: " + p);
13
+ }
14
+ return readFileSync(p, "utf8");
15
+ }
16
+
17
+ export function removeTaggedBlock(content, begin, end) {
18
+ const i = content.indexOf(begin);
19
+ if (i === -1) {
20
+ return { ok: false, reason: "begin not found" };
21
+ }
22
+ if (end === null) {
23
+ let blockStart = i;
24
+ const prevText = content.slice(0, i);
25
+ const hrIndex = prevText.lastIndexOf("---");
26
+ if (hrIndex !== -1 && prevText.slice(hrIndex).trim() === "") {
27
+ blockStart = hrIndex;
28
+ }
29
+ let next = content.slice(0, blockStart).trimEnd() + "\n";
30
+ return { ok: true, content: next };
31
+ }
32
+
33
+ const j = content.indexOf(end, i + begin.length);
34
+ if (j === -1) {
35
+ return { ok: false, reason: "end not found" };
36
+ }
37
+ const afterEnd = j + end.length;
38
+ let next = content.slice(0, i) + content.slice(afterEnd);
39
+ next = next.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "").trimEnd();
40
+ if (next.length) {
41
+ next += "\n";
42
+ }
43
+ return { ok: true, content: next };
44
+ }
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * OSS publish pre-build script.
4
+ * Runs in the OSS mirror (no dev source, no pre-built scripts/out).
5
+ * Steps: (1) root npm install, (2) tsc scripts, (3) vscode-extension npm install, (4) vsix bundle.
6
+ */
7
+ import { spawnSync } from "child_process";
8
+ import { fileURLToPath } from "url";
9
+ import path from "path";
10
+
11
+ const root = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
12
+ const ext = path.join(root, "vscode-extension");
13
+
14
+ function run(cmd, args, cwd) {
15
+ const r = spawnSync(cmd, args, { cwd, stdio: "inherit", shell: true });
16
+ if (r.status !== 0) process.exit(r.status ?? 1);
17
+ }
18
+
19
+ console.log("[oss-prepack] (1/4) root npm install...");
20
+ run("npm", ["install", "--no-audit", "--no-fund", "--loglevel=silent"], root);
21
+
22
+ console.log("[oss-prepack] (2/4) tsc scripts...");
23
+ const tscBin = path.join(root, "node_modules", "typescript", "bin", "tsc");
24
+ run("node", [tscBin, "-p", "tsconfig.scripts.json"], root);
25
+
26
+ console.log("[oss-prepack] (3/4) vscode-extension npm install...");
27
+ run("npm", ["install", "--no-audit", "--no-fund", "--loglevel=silent"], ext);
28
+
29
+ console.log("[oss-prepack] (4/4) vsix bundle...");
30
+ run("node", ["scripts/out/scripts/bundle-vscode-vsix.js"], root);
31
+
32
+ console.log("[oss-prepack] done.");
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Packs vscode-extension into bundled/deuk-agent-flow.vsix for the npm tarball.
4
+ * Temporarily sets the extension package.json version to the root package version.
5
+ */
6
+ import fs from "fs";
7
+ import { execSync } from "child_process";
8
+ import { makePath, resolvePackageRoot } from "./cli-utils.js";
9
+ const root = resolvePackageRoot({ fromUrl: import.meta.url });
10
+ const extDir = makePath(root, 'vscode-extension');
11
+ const extPkgPath = makePath(extDir, 'package.json');
12
+ const bundledDir = makePath(root, 'bundled');
13
+ const vsixPath = makePath(bundledDir, 'deuk-agent-flow.vsix');
14
+ const installAfterBundle = process.argv.includes('--install') || process.env.DEUK_AGENT_FLOW_INSTALL_VSIX === '1';
15
+ const skipCompile = process.argv.includes('--skip-compile') || process.env.DEUK_AGENT_FLOW_SKIP_COMPILE === '1';
16
+ const rootPkg = JSON.parse(fs.readFileSync(makePath(root, 'package.json'), 'utf8'));
17
+ const extPkg = JSON.parse(fs.readFileSync(extPkgPath, 'utf8'));
18
+ const savedPrepublish = extPkg.scripts?.['vscode:prepublish'];
19
+ extPkg.version = rootPkg.version;
20
+ extPkg.scripts = {
21
+ ...extPkg.scripts,
22
+ 'vscode:prepublish': 'tsc -p ./',
23
+ };
24
+ fs.writeFileSync(extPkgPath, JSON.stringify(extPkg, null, 2) + '\n');
25
+ try {
26
+ if (!fs.existsSync(bundledDir))
27
+ fs.mkdirSync(bundledDir, { recursive: true });
28
+ execSync('npm install --no-audit --no-fund --loglevel=silent', { cwd: extDir, stdio: 'inherit', shell: true });
29
+ if (!skipCompile) {
30
+ execSync('npm run compile', { cwd: extDir, stdio: 'inherit' });
31
+ }
32
+ const vsceBin = makePath(extDir, 'node_modules', '.bin', process.platform === 'win32' ? 'vsce.cmd' : 'vsce');
33
+ if (!fs.existsSync(vsceBin)) {
34
+ console.error('[deuk-agent-flow] @vscode/vsce missing. Run npm install in vscode-extension.');
35
+ process.exit(1);
36
+ }
37
+ const q = (s) => (s.includes(' ') ? `"${s.replace(/"/g, '\\"')}"` : s);
38
+ execSync(`${q(vsceBin)} package --no-dependencies --out ${q(vsixPath)}`, { cwd: extDir, input: 'y\n', stdio: ['pipe', 'inherit', 'inherit'], shell: true });
39
+ if (!fs.existsSync(vsixPath)) {
40
+ console.error('[deuk-agent-flow] bundle-vscode: expected VSIX missing:', vsixPath);
41
+ process.exit(1);
42
+ }
43
+ console.log('[deuk-agent-flow] bundled VS Code extension:', vsixPath);
44
+ if (installAfterBundle) {
45
+ if (process.platform === 'win32') {
46
+ // Windows node 컨텍스트: WSL bash 스크립트로 WSL 파일시스템에 직접 설치
47
+ const wslScript = execSync(`wsl.exe wslpath -u "${root.replace(/\\/g, '/')}/scripts/install-vsix-wsl.sh"`, { encoding: 'utf8', shell: true }).toString().trim();
48
+ execSync(`wsl.exe bash "${wslScript}"`, { stdio: 'inherit', shell: true });
49
+ }
50
+ else {
51
+ execSync('node scripts/out/scripts/install-vscode-vsix.js --all', { cwd: root, stdio: 'inherit', shell: true });
52
+ }
53
+ }
54
+ }
55
+ finally {
56
+ // #version-sync: keep the extension package.json version pinned to the root version
57
+ // (do NOT restore savedVer) so vscode-extension/package.json auto-tracks the root on
58
+ // every bundle instead of drifting back to a stale value. Only prepublish is temporary.
59
+ extPkg.version = rootPkg.version;
60
+ if (savedPrepublish === undefined) {
61
+ delete extPkg.scripts['vscode:prepublish'];
62
+ }
63
+ else {
64
+ extPkg.scripts['vscode:prepublish'] = savedPrepublish;
65
+ }
66
+ fs.writeFileSync(extPkgPath, JSON.stringify(extPkg, null, 2) + '\n');
67
+ }
68
+ //# sourceMappingURL=bundle-vscode-vsix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-vscode-vsix.js","sourceRoot":"","sources":["../../bundle-vscode-vsix.ts"],"names":[],"mappings":"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"}