@jakkrichm/create-nexus-devflow 2.0.25 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +30 -8
  2. package/dist/bin/create-nexus-devflow.d.ts +22 -1
  3. package/dist/bin/create-nexus-devflow.js +658 -11
  4. package/dist/bin/create-nexus-devflow.js.map +1 -1
  5. package/dist/lib/branch-context.d.ts +39 -0
  6. package/dist/lib/branch-context.js +196 -0
  7. package/dist/lib/branch-context.js.map +1 -0
  8. package/dist/lib/code-graph.d.ts +30 -0
  9. package/dist/lib/code-graph.js +209 -0
  10. package/dist/lib/code-graph.js.map +1 -0
  11. package/dist/lib/command-catalog.d.ts +11 -0
  12. package/dist/lib/command-catalog.js +63 -0
  13. package/dist/lib/command-catalog.js.map +1 -0
  14. package/dist/lib/context-slicer.d.ts +31 -0
  15. package/dist/lib/context-slicer.js +234 -0
  16. package/dist/lib/context-slicer.js.map +1 -0
  17. package/dist/lib/current-work.js +97 -49
  18. package/dist/lib/current-work.js.map +1 -1
  19. package/dist/lib/dashboard-page.d.ts +2 -0
  20. package/dist/lib/dashboard-page.js +285 -0
  21. package/dist/lib/dashboard-page.js.map +1 -0
  22. package/dist/lib/dashboard-snapshot.d.ts +62 -0
  23. package/dist/lib/dashboard-snapshot.js +114 -0
  24. package/dist/lib/dashboard-snapshot.js.map +1 -0
  25. package/dist/lib/dashboard.d.ts +2 -0
  26. package/dist/lib/dashboard.js +398 -8
  27. package/dist/lib/dashboard.js.map +1 -1
  28. package/dist/lib/discoveries.d.ts +19 -0
  29. package/dist/lib/discoveries.js +81 -0
  30. package/dist/lib/discoveries.js.map +1 -0
  31. package/dist/lib/doctor.d.ts +26 -0
  32. package/dist/lib/doctor.js +474 -0
  33. package/dist/lib/doctor.js.map +1 -0
  34. package/dist/lib/drift-reconciler.d.ts +38 -0
  35. package/dist/lib/drift-reconciler.js +155 -0
  36. package/dist/lib/drift-reconciler.js.map +1 -0
  37. package/dist/lib/findings.d.ts +26 -2
  38. package/dist/lib/findings.js +165 -1
  39. package/dist/lib/findings.js.map +1 -1
  40. package/dist/lib/gatekeeper.d.ts +20 -0
  41. package/dist/lib/gatekeeper.js +106 -0
  42. package/dist/lib/gatekeeper.js.map +1 -0
  43. package/dist/lib/git-hooks.d.ts +16 -0
  44. package/dist/lib/git-hooks.js +103 -0
  45. package/dist/lib/git-hooks.js.map +1 -0
  46. package/dist/lib/history.d.ts +6 -1
  47. package/dist/lib/history.js +98 -11
  48. package/dist/lib/history.js.map +1 -1
  49. package/dist/lib/ide-extension.d.ts +38 -0
  50. package/dist/lib/ide-extension.js +61 -0
  51. package/dist/lib/ide-extension.js.map +1 -0
  52. package/dist/lib/ideas.d.ts +26 -0
  53. package/dist/lib/ideas.js +179 -0
  54. package/dist/lib/ideas.js.map +1 -0
  55. package/dist/lib/mcp.d.ts +36 -0
  56. package/dist/lib/mcp.js +653 -0
  57. package/dist/lib/mcp.js.map +1 -0
  58. package/dist/lib/status.d.ts +3 -1
  59. package/dist/lib/status.js +60 -6
  60. package/dist/lib/status.js.map +1 -1
  61. package/dist/lib/swarm-orchestrator.d.ts +31 -0
  62. package/dist/lib/swarm-orchestrator.js +134 -0
  63. package/dist/lib/swarm-orchestrator.js.map +1 -0
  64. package/dist/lib/update.js +2 -2
  65. package/dist/lib/update.js.map +1 -1
  66. package/dist/lib/version-check.d.ts +22 -0
  67. package/dist/lib/version-check.js +59 -0
  68. package/dist/lib/version-check.js.map +1 -0
  69. package/dist/lib/webview-studio.d.ts +8 -0
  70. package/dist/lib/webview-studio.js +463 -0
  71. package/dist/lib/webview-studio.js.map +1 -0
  72. package/dist/lib/workflow-state.d.ts +23 -0
  73. package/dist/lib/workflow-state.js +128 -0
  74. package/dist/lib/workflow-state.js.map +1 -0
  75. package/dist/scripts/prepare-template.js +3 -3
  76. package/package.json +1 -1
  77. package/template/{.claude/skills/00-discover → .agents/skills/00-explore}/SKILL.md +10 -10
  78. package/template/.agents/skills/10-define/SKILL.md +4 -4
  79. package/template/.agents/skills/20-spec/SKILL.md +2 -3
  80. package/template/.agents/skills/30-plan/SKILL.md +2 -3
  81. package/template/.agents/skills/40-execute/SKILL.md +2 -2
  82. package/template/.agents/skills/50-verify/SKILL.md +2 -2
  83. package/template/.agents/skills/60-report/SKILL.md +3 -3
  84. package/template/{.claude/skills/70-release → .agents/skills/70-deliver}/SKILL.md +7 -13
  85. package/template/.agents/skills/adopt/SKILL.md +136 -73
  86. package/template/.agents/skills/audit/SKILL.md +275 -0
  87. package/template/.agents/skills/autopilot/SKILL.md +228 -147
  88. package/template/.agents/skills/brainstorm/SKILL.md +3 -3
  89. package/template/.agents/skills/brief/SKILL.md +74 -51
  90. package/template/.agents/skills/check/SKILL.md +96 -76
  91. package/template/.agents/skills/ci/SKILL.md +140 -61
  92. package/template/.agents/skills/complete/SKILL.md +156 -101
  93. package/template/.agents/skills/convert-any-to-md/SKILL.md +2 -2
  94. package/template/.agents/skills/debug/SKILL.md +124 -49
  95. package/template/.agents/skills/devflow/SKILL.md +16 -10
  96. package/template/.agents/skills/discovery/SKILL.md +166 -0
  97. package/template/.agents/skills/doctor/SKILL.md +188 -72
  98. package/template/.agents/skills/feature/SKILL.md +195 -102
  99. package/template/.agents/skills/fix/SKILL.md +41 -90
  100. package/template/.agents/skills/idea/SKILL.md +3 -3
  101. package/template/.agents/skills/implement/SKILL.md +189 -46
  102. package/template/.agents/skills/onboard/SKILL.md +215 -85
  103. package/template/.agents/skills/overview/SKILL.md +51 -85
  104. package/template/.agents/skills/prototype/SKILL.md +82 -27
  105. package/template/.agents/skills/release/SKILL.md +160 -0
  106. package/template/.agents/skills/report-html/SKILL.md +2 -2
  107. package/template/.agents/skills/rollback/SKILL.md +123 -77
  108. package/template/.agents/skills/status/SKILL.md +109 -0
  109. package/template/.agents/skills/test/SKILL.md +2 -2
  110. package/template/.agents/skills/tests/SKILL.md +126 -0
  111. package/template/.agents/skills/try/SKILL.md +77 -65
  112. package/template/{.agents/skills/00-discover → .claude/skills/00-explore}/SKILL.md +9 -9
  113. package/template/.claude/skills/10-define/SKILL.md +2 -2
  114. package/template/.claude/skills/20-spec/SKILL.md +1 -1
  115. package/template/.claude/skills/30-plan/SKILL.md +1 -1
  116. package/template/.claude/skills/60-report/SKILL.md +1 -1
  117. package/template/{.agents/skills/70-release → .claude/skills/70-deliver}/SKILL.md +6 -12
  118. package/template/.claude/skills/adopt/SKILL.md +2 -2
  119. package/template/.claude/skills/audit/SKILL.md +141 -0
  120. package/template/.claude/skills/autopilot/SKILL.md +74 -52
  121. package/template/.claude/skills/brief/SKILL.md +67 -45
  122. package/template/.claude/skills/ci/SKILL.md +1 -1
  123. package/template/.claude/skills/complete/SKILL.md +1 -1
  124. package/template/.claude/skills/debug/SKILL.md +1 -1
  125. package/template/.claude/skills/devflow/SKILL.md +7 -7
  126. package/template/.claude/skills/discovery/SKILL.md +145 -0
  127. package/template/.claude/skills/doctor/SKILL.md +1 -1
  128. package/template/.claude/skills/feature/SKILL.md +67 -18
  129. package/template/.claude/skills/fix/SKILL.md +1 -1
  130. package/template/.claude/skills/idea/SKILL.md +2 -2
  131. package/template/.claude/skills/onboard/SKILL.md +3 -3
  132. package/template/.claude/skills/overview/SKILL.md +39 -88
  133. package/template/.claude/skills/prototype/SKILL.md +1 -1
  134. package/template/.claude/skills/release/SKILL.md +171 -0
  135. package/template/.claude/skills/rollback/SKILL.md +2 -2
  136. package/template/AGENTS.md +5 -5
  137. package/template/devflow/build-plan.md +62 -0
  138. package/template/devflow/context/ai-interaction.md +4 -4
  139. package/template/devflow/context/coding-standards.md +3 -3
  140. package/template/devflow/context/current-stage.md +1 -1
  141. package/template/devflow/context/findings.md +1 -1
  142. package/template/devflow/history/HISTORY.md +2 -2
  143. package/template/devflow/project-plan.md +79 -0
  144. package/template/devflow/reference/mockup.html +476 -0
  145. package/template/devflow/reference/project-overview-template.md +39 -0
  146. package/template/devflow/reference/running-id-contract.md +24 -2
  147. package/template/devflow/reference/studio.html +504 -0
@@ -0,0 +1,155 @@
1
+ import fs from "node:fs/promises";
2
+ import fsSync from "node:fs";
3
+ import path from "node:path";
4
+ import { resolveActiveContextPaths } from "./branch-context.js";
5
+ import { readGitStatus } from "./git-status.js";
6
+ const IGNORED_DRIFT_PATTERNS = [
7
+ /devflow\/context\/current-feature\.md$/i,
8
+ /devflow\/context\/current-stage\.md$/i,
9
+ /devflow\/history\//i,
10
+ /devflow\/runs\//i,
11
+ /devflow\/discoveries\//i,
12
+ /\.gitignore$/i,
13
+ /\.nexus\//i,
14
+ /\.agents\//i,
15
+ /\.claude\//i,
16
+ /node_modules\//i,
17
+ /dist\//i,
18
+ /package-lock\.json$/i
19
+ ];
20
+ /**
21
+ * Normalizes file path to forward slashes relative to workspace root.
22
+ */
23
+ export function normalizeRelativePath(projectRoot, filePath) {
24
+ const relative = path.isAbsolute(filePath)
25
+ ? path.relative(projectRoot, filePath)
26
+ : filePath;
27
+ return relative.replace(/\\/g, "/").replace(/^\.\//, "");
28
+ }
29
+ /**
30
+ * Parses the "Files to Modify/Create" section from a living spec markdown.
31
+ */
32
+ export function parseSpecFilesList(specContent) {
33
+ const files = [];
34
+ const lines = specContent.split("\n");
35
+ let inFilesSection = false;
36
+ for (const line of lines) {
37
+ const trimmed = line.trim();
38
+ if (/Files\s+to\s+Modify\/Create/i.test(trimmed)) {
39
+ inFilesSection = true;
40
+ continue;
41
+ }
42
+ if (inFilesSection) {
43
+ // Exit if next major section, horizontal rule, or next main bold bullet in Plan (e.g. - **Test Decision**:)
44
+ if (/^##+\s+/.test(trimmed) || /^-\s+\*\*[^*]+\*\*:/i.test(trimmed) || trimmed.startsWith("---")) {
45
+ inFilesSection = false;
46
+ continue;
47
+ }
48
+ if (trimmed.startsWith("-") || trimmed.startsWith("*")) {
49
+ // Extract backtick path `path/to/file.ext` or direct path
50
+ const match = trimmed.match(/`([^`]+)`/) || trimmed.match(/^[*-]\s+(?:\[[ x]\]\s+)?([a-zA-Z0-9_./\\-]+\.[a-zA-Z0-9]+)/);
51
+ if (match && match[1]) {
52
+ const clean = match[1].trim().replace(/\\/g, "/");
53
+ // Ensure it looks like a valid file path with extension
54
+ if (/\.[a-zA-Z0-9_-]+$/.test(clean) && !clean.startsWith("http")) {
55
+ files.push(clean);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ return Array.from(new Set(files));
62
+ }
63
+ /**
64
+ * Detects git drift between modified repository files and spec declaration.
65
+ */
66
+ export async function detectGitDrift(projectRoot, explicitBranch) {
67
+ const contextPaths = await resolveActiveContextPaths(projectRoot, explicitBranch);
68
+ const gitStatus = await readGitStatus(projectRoot);
69
+ let specFiles = [];
70
+ let stageRunningId = null;
71
+ if (fsSync.existsSync(contextPaths.featureSpecPath)) {
72
+ const specContent = await fs.readFile(contextPaths.featureSpecPath, "utf8");
73
+ specFiles = parseSpecFilesList(specContent);
74
+ }
75
+ if (fsSync.existsSync(contextPaths.stagePath)) {
76
+ const stageContent = await fs.readFile(contextPaths.stagePath, "utf8");
77
+ const match = stageContent.match(/Active Running ID:\s*`?([a-zA-Z0-9_-]+)`?/i);
78
+ if (match)
79
+ stageRunningId = match[1];
80
+ }
81
+ // Collect git changed files
82
+ const rawGitFiles = [];
83
+ if (gitStatus.available) {
84
+ if (gitStatus.changedFiles && Array.isArray(gitStatus.changedFiles)) {
85
+ rawGitFiles.push(...gitStatus.changedFiles);
86
+ }
87
+ }
88
+ // Filter out ignored/transient files
89
+ const gitModifiedFiles = rawGitFiles
90
+ .map((f) => normalizeRelativePath(projectRoot, f))
91
+ .filter((f) => !IGNORED_DRIFT_PATTERNS.some((p) => p.test(f)));
92
+ const normalizedSpecFiles = specFiles.map((f) => normalizeRelativePath(projectRoot, f));
93
+ const undocumentedFiles = gitModifiedFiles.filter((gf) => !normalizedSpecFiles.some((sf) => sf === gf || gf.endsWith(sf) || sf.endsWith(gf)));
94
+ const phantomFiles = normalizedSpecFiles.filter((sf) => !gitModifiedFiles.some((gf) => gf === sf || gf.endsWith(sf) || sf.endsWith(gf)));
95
+ const matchedFiles = gitModifiedFiles.filter((gf) => normalizedSpecFiles.some((sf) => sf === gf || gf.endsWith(sf) || sf.endsWith(gf)));
96
+ const isStageDrifted = Boolean(gitStatus.branch &&
97
+ stageRunningId &&
98
+ stageRunningId !== "None" &&
99
+ !gitStatus.branch.includes(stageRunningId) &&
100
+ !stageRunningId.includes(gitStatus.branch));
101
+ const hasDrift = undocumentedFiles.length > 0 || isStageDrifted;
102
+ return {
103
+ hasDrift,
104
+ undocumentedFiles,
105
+ phantomFiles,
106
+ matchedFiles,
107
+ gitModifiedFiles,
108
+ specFiles: normalizedSpecFiles,
109
+ stageDrift: {
110
+ isDrifted: isStageDrifted,
111
+ activeBranch: gitStatus.branch || null,
112
+ stageRunningId
113
+ }
114
+ };
115
+ }
116
+ /**
117
+ * Automatically reconciles and synchronizes living spec and stage file.
118
+ */
119
+ export async function reconcileState(projectRoot, options = { autoAddUndocumented: true, healStage: true }) {
120
+ const drift = await detectGitDrift(projectRoot);
121
+ const contextPaths = await resolveActiveContextPaths(projectRoot);
122
+ const addedFiles = [];
123
+ let healedStage = false;
124
+ // 1. Reconcile Undocumented Files into current-feature.md
125
+ if (options.autoAddUndocumented && drift.undocumentedFiles.length > 0 && fsSync.existsSync(contextPaths.featureSpecPath)) {
126
+ const specContent = await fs.readFile(contextPaths.featureSpecPath, "utf8");
127
+ const lines = specContent.split("\n");
128
+ const targetIdx = lines.findIndex((l) => /Files\s+to\s+Modify\/Create/i.test(l));
129
+ if (targetIdx !== -1) {
130
+ const newEntries = drift.undocumentedFiles.map((f) => ` - \`${f}\` (Auto-reconciled from Git changes)`);
131
+ lines.splice(targetIdx + 1, 0, ...newEntries);
132
+ await fs.writeFile(contextPaths.featureSpecPath, lines.join("\n"), "utf8");
133
+ addedFiles.push(...drift.undocumentedFiles);
134
+ }
135
+ }
136
+ // 2. Heal current-stage.md if drifted
137
+ if (options.healStage && drift.stageDrift.isDrifted && drift.stageDrift.activeBranch && fsSync.existsSync(contextPaths.stagePath)) {
138
+ const stageContent = await fs.readFile(contextPaths.stagePath, "utf8");
139
+ const cleanBranch = drift.stageDrift.activeBranch.replace(/^(feature|fix|chore)\//, "");
140
+ const updatedStage = stageContent.replace(/Active Running ID:\s*`?[^`\n]+`?/i, `Active Running ID: \`${cleanBranch}\``);
141
+ await fs.writeFile(contextPaths.stagePath, updatedStage, "utf8");
142
+ healedStage = true;
143
+ }
144
+ const reconciled = addedFiles.length > 0 || healedStage;
145
+ const message = reconciled
146
+ ? `Reconciliation complete: Added ${addedFiles.length} undocumented file(s) to spec, stage healed: ${healedStage}`
147
+ : "No drift detected or nothing to reconcile.";
148
+ return {
149
+ reconciled,
150
+ addedFiles,
151
+ healedStage,
152
+ message
153
+ };
154
+ }
155
+ //# sourceMappingURL=drift-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-reconciler.js","sourceRoot":"","sources":["../../lib/drift-reconciler.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,30 @@ interface FindingsSummary {
21
21
  }
22
22
  declare const DEVFLOW_FINDINGS_PATH: string;
23
23
  declare function readFindings(projectRoot: string): Promise<FindingsSummary>;
24
+ declare function resolveFinding(projectRoot: string, findingId: string, newStatus?: FindingStatus): Promise<{
25
+ success: boolean;
26
+ message: string;
27
+ previousStatus?: FindingStatus;
28
+ finding?: Finding;
29
+ }>;
30
+ declare function formatFindingsHuman(summary: FindingsSummary, options?: {
31
+ blockersOnly?: boolean;
32
+ color?: boolean;
33
+ }): string;
24
34
  declare function parseFindings(markdown: string): FindingsSummary;
25
- export { DEVFLOW_FINDINGS_PATH, parseFindings, readFindings };
26
- export type { Finding, FindingSeverity, FindingsSummary, FindingStatus, FindingsWarning, FindingsWarningCode };
35
+ interface AddFindingOptions {
36
+ id?: string;
37
+ severity?: FindingSeverity;
38
+ status?: FindingStatus;
39
+ location?: string;
40
+ impact?: string;
41
+ remediation?: string;
42
+ }
43
+ declare function addFinding(projectRoot: string, title: string, options?: AddFindingOptions): Promise<{
44
+ success: boolean;
45
+ message: string;
46
+ finding?: Finding;
47
+ filePath: string;
48
+ }>;
49
+ export { DEVFLOW_FINDINGS_PATH, addFinding, formatFindingsHuman, parseFindings, readFindings, resolveFinding };
50
+ export type { AddFindingOptions, Finding, FindingSeverity, FindingsSummary, FindingStatus, FindingsWarning, FindingsWarningCode };
@@ -1,8 +1,30 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { createStyle } from "./ui.js";
3
4
  const DEVFLOW_FINDINGS_PATH = path.join("devflow", "context", "findings.md");
4
5
  const BLUEPRINT_FINDINGS_PATH = path.join("blueprint", "context", "findings.md");
5
6
  const FINDING_PATTERN = /^###\s+(\S+)\s+\[(P[0-3])\]\s+(unverified|open|fixed|closed|accepted|invalid)\s+-\s+(.+?)\s*$/i;
7
+ async function getFindingsFilePath(projectRoot) {
8
+ const devflowPath = path.join(projectRoot, DEVFLOW_FINDINGS_PATH);
9
+ const blueprintPath = path.join(projectRoot, BLUEPRINT_FINDINGS_PATH);
10
+ try {
11
+ const stats = await fs.lstat(devflowPath);
12
+ if (stats.isFile())
13
+ return devflowPath;
14
+ }
15
+ catch {
16
+ // try fallback
17
+ }
18
+ try {
19
+ const stats = await fs.lstat(blueprintPath);
20
+ if (stats.isFile())
21
+ return blueprintPath;
22
+ }
23
+ catch {
24
+ // not found
25
+ }
26
+ return null;
27
+ }
6
28
  async function readFindings(projectRoot) {
7
29
  let findingsPath = path.join(projectRoot, DEVFLOW_FINDINGS_PATH);
8
30
  try {
@@ -43,6 +65,84 @@ async function readFindings(projectRoot) {
43
65
  throw error;
44
66
  }
45
67
  }
68
+ async function resolveFinding(projectRoot, findingId, newStatus = "closed") {
69
+ const filePath = await getFindingsFilePath(projectRoot);
70
+ if (!filePath) {
71
+ return {
72
+ success: false,
73
+ message: `Findings file not found in ${projectRoot}`
74
+ };
75
+ }
76
+ const content = await fs.readFile(filePath, "utf8");
77
+ const lines = content.split(/\r?\n/);
78
+ let targetIndex = -1;
79
+ let previousStatus;
80
+ let updatedFinding;
81
+ for (let i = 0; i < lines.length; i++) {
82
+ const line = lines[i];
83
+ const match = line.match(FINDING_PATTERN);
84
+ if (match && match[1]?.toLowerCase() === findingId.toLowerCase()) {
85
+ targetIndex = i;
86
+ const id = match[1];
87
+ const severity = (match[2] || "").toUpperCase();
88
+ previousStatus = (match[3] || "").toLowerCase();
89
+ const title = (match[4] || "").trim();
90
+ lines[i] = `### ${id} [${severity}] ${newStatus} - ${title}`;
91
+ updatedFinding = {
92
+ id,
93
+ severity,
94
+ status: newStatus,
95
+ title,
96
+ line: i + 1
97
+ };
98
+ break;
99
+ }
100
+ }
101
+ if (targetIndex === -1 || !updatedFinding) {
102
+ return {
103
+ success: false,
104
+ message: `Finding with ID '${findingId}' not found in ${filePath}`
105
+ };
106
+ }
107
+ await fs.writeFile(filePath, lines.join("\n"), "utf8");
108
+ return {
109
+ success: true,
110
+ message: `Finding ${updatedFinding.id} status updated from '${previousStatus}' to '${newStatus}'`,
111
+ previousStatus,
112
+ finding: updatedFinding
113
+ };
114
+ }
115
+ function formatFindingsHuman(summary, options = {}) {
116
+ const style = createStyle(options.color);
117
+ const lines = [];
118
+ const items = options.blockersOnly ? summary.blockers : summary.items;
119
+ const headerTitle = options.blockersOnly
120
+ ? `Findings Blockers (${summary.blockers.length} active P0/P1)`
121
+ : `Findings Ledger (${summary.total} total, ${summary.blockers.length} blockers)`;
122
+ lines.push(style.bold(headerTitle));
123
+ lines.push("");
124
+ if (items.length === 0) {
125
+ lines.push(style.dim(options.blockersOnly
126
+ ? " No active P0/P1 blockers! Ready for delivery."
127
+ : " No findings recorded in devflow/context/findings.md"));
128
+ }
129
+ else {
130
+ for (const finding of items) {
131
+ const isBlocker = (finding.severity === "P0" || finding.severity === "P1") &&
132
+ (finding.status === "open" || finding.status === "fixed");
133
+ const sevFormatted = isBlocker
134
+ ? style.bold(style.red(`[${finding.severity}]`))
135
+ : style.yellow(`[${finding.severity}]`);
136
+ const statusFormatted = finding.status === "closed" || finding.status === "accepted"
137
+ ? style.green(finding.status)
138
+ : finding.status === "fixed"
139
+ ? style.cyan(finding.status)
140
+ : style.yellow(finding.status);
141
+ lines.push(` ${style.bold(style.cyan(finding.id))} ${sevFormatted} ${statusFormatted} - ${finding.title}`);
142
+ }
143
+ }
144
+ return lines.join("\n").trimEnd();
145
+ }
46
146
  function parseFindings(markdown) {
47
147
  const items = [];
48
148
  let malformed = false;
@@ -106,5 +206,69 @@ function getErrorCode(error) {
106
206
  ? error.code
107
207
  : undefined;
108
208
  }
109
- export { DEVFLOW_FINDINGS_PATH, parseFindings, readFindings };
209
+ async function addFinding(projectRoot, title, options = {}) {
210
+ let filePath = await getFindingsFilePath(projectRoot);
211
+ let content = "";
212
+ if (!filePath) {
213
+ filePath = path.join(projectRoot, DEVFLOW_FINDINGS_PATH);
214
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
215
+ content = `# Findings Ledger\n\n> Durable record of audit findings, security issues, and code quality items.\n> Active P0 and P1 findings in \`open\` or \`fixed\` status block delivery and releases.\n\n`;
216
+ }
217
+ else {
218
+ content = await fs.readFile(filePath, "utf8");
219
+ }
220
+ const existing = parseFindings(content);
221
+ const severity = options.severity || "P2";
222
+ const status = options.status || "open";
223
+ let id = options.id?.trim();
224
+ if (!id) {
225
+ let maxNum = 0;
226
+ for (const item of existing.items) {
227
+ const numMatch = item.id.match(/\d+$/);
228
+ if (numMatch) {
229
+ const n = parseInt(numMatch[0], 10);
230
+ if (!isNaN(n) && n > maxNum) {
231
+ maxNum = n;
232
+ }
233
+ }
234
+ }
235
+ const nextSeq = String(maxNum + 1).padStart(3, "0");
236
+ id = `FIND-${nextSeq}`;
237
+ }
238
+ const cleanTitle = title.trim();
239
+ const entryLines = [];
240
+ entryLines.push(`### ${id} [${severity}] ${status} - ${cleanTitle}`);
241
+ if (options.location) {
242
+ entryLines.push(`- **Location**: \`${options.location}\``);
243
+ }
244
+ if (options.impact) {
245
+ entryLines.push(`- **Impact**: ${options.impact}`);
246
+ }
247
+ if (options.remediation) {
248
+ entryLines.push(`- **Remediation**: ${options.remediation}`);
249
+ }
250
+ const newEntry = entryLines.join("\n") + "\n";
251
+ let updatedContent = content.trimEnd();
252
+ if (updatedContent.length > 0) {
253
+ updatedContent += "\n\n" + newEntry;
254
+ }
255
+ else {
256
+ updatedContent = newEntry;
257
+ }
258
+ await fs.writeFile(filePath, updatedContent, "utf8");
259
+ const finding = {
260
+ id,
261
+ severity,
262
+ status,
263
+ title: cleanTitle,
264
+ line: updatedContent.split(/\r?\n/).length
265
+ };
266
+ return {
267
+ success: true,
268
+ message: `Added finding ${id} [${severity}] ${status} to ${filePath}`,
269
+ finding,
270
+ filePath
271
+ };
272
+ }
273
+ export { DEVFLOW_FINDINGS_PATH, addFinding, formatFindingsHuman, parseFindings, readFindings, resolveFinding };
110
274
  //# sourceMappingURL=findings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"findings.js","sourceRoot":"","sources":["../../lib/findings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"findings.js","sourceRoot":"","sources":["../../lib/findings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface GateOptions {
2
+ strict?: boolean;
3
+ allowUnverified?: boolean;
4
+ color?: boolean;
5
+ }
6
+ export interface GateReport {
7
+ passed: boolean;
8
+ exitCode: 0 | 1;
9
+ strict: boolean;
10
+ completionState: string;
11
+ violations: string[];
12
+ warnings: string[];
13
+ findingsBlockers: number;
14
+ remainingTasks: number;
15
+ summary: string;
16
+ }
17
+ export declare function evaluateGate(projectRoot: string, options?: GateOptions): Promise<GateReport>;
18
+ export declare function formatGateReport(report: GateReport, options?: {
19
+ color?: boolean;
20
+ }): string;
@@ -0,0 +1,106 @@
1
+ import { readProjectStatus } from "./status.js";
2
+ import { detectGitDrift } from "./drift-reconciler.js";
3
+ import { createStyle } from "./ui.js";
4
+ export async function evaluateGate(projectRoot, options = {}) {
5
+ const status = await readProjectStatus(projectRoot);
6
+ const violations = [];
7
+ const warnings = [];
8
+ // Check 1: Active Findings Blockers (P0 / P1 in open or fixed status)
9
+ const blockers = status.findings.blockers || [];
10
+ for (const blocker of blockers) {
11
+ violations.push(`Finding ${blocker.id} [${blocker.severity}] (${blocker.status}): ${blocker.title}`);
12
+ }
13
+ // Check 1.1: Non-blocker findings warnings (P2 / P3 in open status)
14
+ const nonBlockers = (status.findings.active || []).filter((item) => (item.severity === "P2" || item.severity === "P3") && (item.status === "open" || item.status === "unverified"));
15
+ for (const item of nonBlockers) {
16
+ warnings.push(`Advisory Finding ${item.id} [${item.severity}] (${item.status}): ${item.title}`);
17
+ }
18
+ // Check 1.2: Status / findings warnings
19
+ for (const w of status.warnings || []) {
20
+ warnings.push(`Warning (${w.code}): ${w.message}`);
21
+ }
22
+ // Check 2: Uncompleted tasks in Living Spec
23
+ const remaining = status.currentWork.remaining;
24
+ if (status.currentWork.state === "active" && remaining > 0) {
25
+ violations.push(`Living spec '${status.currentWork.runId || "active"}' has ${remaining} uncompleted task(s)`);
26
+ }
27
+ // Check 3: Strict mode verification check
28
+ if (options.strict && status.currentWork.state === "active") {
29
+ if (status.completion.state === "needs_verification" || status.completion.state === "blocked") {
30
+ violations.push(`Living spec '${status.currentWork.runId || "active"}' is unverified (run /check before delivery)`);
31
+ }
32
+ }
33
+ // Check 4: Git drift advisory check
34
+ try {
35
+ const drift = await detectGitDrift(projectRoot);
36
+ if (drift.hasDrift && drift.undocumentedFiles.length > 0) {
37
+ warnings.push(`Warning (git_drift): ${drift.undocumentedFiles.length} file(s) modified in git without being listed in living spec.`);
38
+ }
39
+ }
40
+ catch { }
41
+ const passed = violations.length === 0;
42
+ const exitCode = passed ? 0 : 1;
43
+ let summary = "";
44
+ if (passed) {
45
+ summary =
46
+ status.currentWork.state === "idle"
47
+ ? "Quality Gate Passed: Workspace is clean with 0 blockers."
48
+ : "Quality Gate Passed: Active run satisfies all gatekeeper criteria.";
49
+ }
50
+ else {
51
+ summary = `Quality Gate Failed: ${violations.length} blocker(s) detected.`;
52
+ }
53
+ return {
54
+ passed,
55
+ exitCode,
56
+ strict: options.strict === true,
57
+ completionState: status.completion.state,
58
+ violations,
59
+ warnings,
60
+ findingsBlockers: blockers.length,
61
+ remainingTasks: remaining,
62
+ summary
63
+ };
64
+ }
65
+ export function formatGateReport(report, options = {}) {
66
+ const style = createStyle(options.color);
67
+ const lines = [];
68
+ const modeBadge = report.strict ? style.yellow("[Strict Mode]") : style.dim("[Standard Mode]");
69
+ const header = report.passed
70
+ ? style.bold(style.green(`✔ DevFlow Quality Gate PASSED ${modeBadge}`))
71
+ : style.bold(style.red(`✖ DevFlow Quality Gate BLOCKED ${modeBadge}`));
72
+ lines.push(header);
73
+ lines.push(` ${style.dim(report.summary)}`);
74
+ lines.push("");
75
+ if (report.violations.length > 0) {
76
+ lines.push(style.bold(style.red("Violations:")));
77
+ for (const v of report.violations) {
78
+ lines.push(` - ${style.red("✖")} ${v}`);
79
+ }
80
+ lines.push("");
81
+ }
82
+ if (report.warnings.length > 0) {
83
+ lines.push(style.bold(style.yellow("Warnings / Advisories:")));
84
+ for (const w of report.warnings) {
85
+ lines.push(` - ${style.yellow("⚠")} ${style.dim(w)}`);
86
+ }
87
+ lines.push("");
88
+ }
89
+ if (report.violations.length > 0) {
90
+ lines.push(style.yellow("Suggested Actions:"));
91
+ if (report.findingsBlockers > 0) {
92
+ lines.push(` - Resolve blockers: ${style.bold("nexus-devflow findings --blockers")}`);
93
+ }
94
+ if (report.remainingTasks > 0) {
95
+ lines.push(` - Complete tasks: ${style.bold("/implement")}`);
96
+ }
97
+ if (report.completionState === "needs_verification" || report.strict) {
98
+ lines.push(` - Verify living spec: ${style.bold("/check")}`);
99
+ }
100
+ }
101
+ else {
102
+ lines.push(style.green(" All quality gates passed. Safe to merge and commit."));
103
+ }
104
+ return lines.join("\n").trimEnd();
105
+ }
106
+ //# sourceMappingURL=gatekeeper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gatekeeper.js","sourceRoot":"","sources":["../../lib/gatekeeper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type GitHookType = "pre-commit" | "pre-push";
2
+ export interface HookInstallResult {
3
+ success: boolean;
4
+ hookType: GitHookType;
5
+ path: string;
6
+ message: string;
7
+ }
8
+ export interface HookUninstallResult {
9
+ success: boolean;
10
+ removed: string[];
11
+ message: string;
12
+ }
13
+ export declare function installGitHook(projectRoot: string, hookType?: GitHookType, options?: {
14
+ strict?: boolean;
15
+ }): Promise<HookInstallResult>;
16
+ export declare function uninstallGitHooks(projectRoot: string): Promise<HookUninstallResult>;