@dewtech/dare-cli 2.15.0 → 2.17.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 (101) hide show
  1. package/README.md +659 -561
  2. package/dist/__tests__/refine.test.d.ts +2 -0
  3. package/dist/__tests__/refine.test.d.ts.map +1 -0
  4. package/dist/__tests__/refine.test.js +186 -0
  5. package/dist/__tests__/refine.test.js.map +1 -0
  6. package/dist/__tests__/review.test.d.ts +2 -0
  7. package/dist/__tests__/review.test.d.ts.map +1 -0
  8. package/dist/__tests__/review.test.js +242 -0
  9. package/dist/__tests__/review.test.js.map +1 -0
  10. package/dist/__tests__/update.test.d.ts +2 -0
  11. package/dist/__tests__/update.test.d.ts.map +1 -0
  12. package/dist/__tests__/update.test.js +150 -0
  13. package/dist/__tests__/update.test.js.map +1 -0
  14. package/dist/bin/dare.js +6 -0
  15. package/dist/bin/dare.js.map +1 -1
  16. package/dist/commands/dag.d.ts.map +1 -1
  17. package/dist/commands/dag.js +27 -9
  18. package/dist/commands/dag.js.map +1 -1
  19. package/dist/commands/execute.d.ts.map +1 -1
  20. package/dist/commands/execute.js +76 -0
  21. package/dist/commands/execute.js.map +1 -1
  22. package/dist/commands/refine.d.ts +16 -0
  23. package/dist/commands/refine.d.ts.map +1 -0
  24. package/dist/commands/refine.js +167 -0
  25. package/dist/commands/refine.js.map +1 -0
  26. package/dist/commands/review.d.ts +16 -0
  27. package/dist/commands/review.d.ts.map +1 -0
  28. package/dist/commands/review.js +106 -0
  29. package/dist/commands/review.js.map +1 -0
  30. package/dist/commands/update.d.ts +13 -0
  31. package/dist/commands/update.d.ts.map +1 -0
  32. package/dist/commands/update.js +149 -0
  33. package/dist/commands/update.js.map +1 -0
  34. package/dist/types/Refine.types.d.ts +96 -0
  35. package/dist/types/Refine.types.d.ts.map +1 -0
  36. package/dist/types/Refine.types.js +19 -0
  37. package/dist/types/Refine.types.js.map +1 -0
  38. package/dist/types/Review.types.d.ts +86 -0
  39. package/dist/types/Review.types.d.ts.map +1 -0
  40. package/dist/types/Review.types.js +15 -0
  41. package/dist/types/Review.types.js.map +1 -0
  42. package/dist/types/UpdateManifest.types.d.ts +91 -0
  43. package/dist/types/UpdateManifest.types.d.ts.map +1 -0
  44. package/dist/types/UpdateManifest.types.js +13 -0
  45. package/dist/types/UpdateManifest.types.js.map +1 -0
  46. package/dist/utils/ReviewRunner.d.ts +42 -0
  47. package/dist/utils/ReviewRunner.d.ts.map +1 -0
  48. package/dist/utils/ReviewRunner.js +175 -0
  49. package/dist/utils/ReviewRunner.js.map +1 -0
  50. package/dist/utils/UpdateApplier.d.ts +42 -0
  51. package/dist/utils/UpdateApplier.d.ts.map +1 -0
  52. package/dist/utils/UpdateApplier.js +207 -0
  53. package/dist/utils/UpdateApplier.js.map +1 -0
  54. package/dist/utils/UpdateDetector.d.ts +56 -0
  55. package/dist/utils/UpdateDetector.d.ts.map +1 -0
  56. package/dist/utils/UpdateDetector.js +164 -0
  57. package/dist/utils/UpdateDetector.js.map +1 -0
  58. package/dist/utils/complexity-analyzer.d.ts +60 -0
  59. package/dist/utils/complexity-analyzer.d.ts.map +1 -0
  60. package/dist/utils/complexity-analyzer.js +292 -0
  61. package/dist/utils/complexity-analyzer.js.map +1 -0
  62. package/dist/utils/excalidraw-renderer.d.ts +79 -0
  63. package/dist/utils/excalidraw-renderer.d.ts.map +1 -0
  64. package/dist/utils/excalidraw-renderer.js +188 -0
  65. package/dist/utils/excalidraw-renderer.js.map +1 -0
  66. package/dist/utils/excalidraw-renderer.test.d.ts +2 -0
  67. package/dist/utils/excalidraw-renderer.test.d.ts.map +1 -0
  68. package/dist/utils/excalidraw-renderer.test.js +135 -0
  69. package/dist/utils/excalidraw-renderer.test.js.map +1 -0
  70. package/dist/utils/project-generator.d.ts.map +1 -1
  71. package/dist/utils/project-generator.js +21 -2
  72. package/dist/utils/project-generator.js.map +1 -1
  73. package/dist/utils/stack-bootstrap.js +3 -1
  74. package/dist/utils/stack-bootstrap.js.map +1 -1
  75. package/dist/utils/static-analyzer.d.ts +29 -0
  76. package/dist/utils/static-analyzer.d.ts.map +1 -0
  77. package/dist/utils/static-analyzer.js +390 -0
  78. package/dist/utils/static-analyzer.js.map +1 -0
  79. package/dist/utils/version-compare.d.ts +27 -0
  80. package/dist/utils/version-compare.d.ts.map +1 -0
  81. package/dist/utils/version-compare.js +47 -0
  82. package/dist/utils/version-compare.js.map +1 -0
  83. package/package.json +1 -1
  84. package/templates/DARE-dag-example.yaml +280 -0
  85. package/templates/UPDATE-MANIFEST.json +48 -0
  86. package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +180 -36
  87. package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -0
  88. package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -0
  89. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +41 -0
  90. package/templates/ide/antigravity/templates/TASK-SPEC-template.md +45 -4
  91. package/templates/ide/claude/.claude/commands/dare-blueprint.md +56 -0
  92. package/templates/ide/claude/.claude/commands/dare-dag-build.md +41 -0
  93. package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -0
  94. package/templates/ide/claude/.claude/commands/dare-refine.md +145 -0
  95. package/templates/ide/claude/.claude/commands/dare-review.md +113 -0
  96. package/templates/ide/claude/templates/TASK-SPEC-template.md +45 -4
  97. package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +45 -0
  98. package/templates/ide/cursor/.cursor/commands/generate-tasks.md +42 -0
  99. package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -0
  100. package/templates/ide/cursor/.cursor/commands/review-task.md +91 -0
  101. package/templates/ide/cursor/templates/TASK-SPEC-template.md +45 -4
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Orchestrates `dare review`:
3
+ * 1. Resolve the task spec from `DARE/EXECUTION/task-<id>.md` (or other
4
+ * common locations).
5
+ * 2. Discover which files the task touched — by parsing the spec's
6
+ * "ARQUIVOS A CRIAR / MODIFICAR" table, falling back to `git diff`
7
+ * against the merge base when the spec doesn't list files.
8
+ * 3. Run the static analyzer over those files.
9
+ * 4. Optionally merge a `SemanticVerdict` provided by the IDE agent
10
+ * (via `--from-agent <path>`).
11
+ *
12
+ * Pure data manipulation — file I/O happens through `fs-extra` and `child_process`.
13
+ * The CLI command (`commands/review.ts`) wraps this with chalk output.
14
+ */
15
+ import fs from 'fs-extra';
16
+ import path from 'path';
17
+ import { execFileSync } from 'child_process';
18
+ import { runStaticAnalysis } from './static-analyzer.js';
19
+ /** Candidate locations of a task spec, tried in order. */
20
+ function specCandidates(projectRoot, taskId) {
21
+ return [
22
+ path.join(projectRoot, 'DARE', 'EXECUTION', `${taskId}.md`),
23
+ path.join(projectRoot, 'DARE', 'EXECUTION', `task-${taskId}.md`),
24
+ path.join(projectRoot, 'DARE', 'tasks', `${taskId}.md`),
25
+ path.join(projectRoot, 'DARE', `${taskId}.md`),
26
+ ];
27
+ }
28
+ export async function findSpecFile(projectRoot, taskId) {
29
+ for (const candidate of specCandidates(projectRoot, taskId)) {
30
+ if (await fs.pathExists(candidate))
31
+ return candidate;
32
+ }
33
+ return null;
34
+ }
35
+ /**
36
+ * Parse the "ARQUIVOS A CRIAR / MODIFICAR" markdown table from a spec.
37
+ *
38
+ * Expected shape (from `TASK-SPEC-template.md`):
39
+ *
40
+ * | Ação | Caminho | Descrição |
41
+ * |------|---------|-----------|
42
+ * | CRIAR | `src/foo.ts` | ... |
43
+ * | MODIFICAR | `src/bar.ts` | ... |
44
+ *
45
+ * We grab anything in backticks within rows where the first column is
46
+ * CRIAR/MODIFICAR/CREATE/MODIFY/UPDATE. Returns project-relative paths.
47
+ */
48
+ export function parseFilesFromSpec(specMarkdown) {
49
+ const lines = specMarkdown.split(/\r?\n/);
50
+ const out = [];
51
+ const actionRe = /^\|\s*(CRIAR|MODIFICAR|CREATE|MODIFY|UPDATE|TOUCH)\s*\|/i;
52
+ const pathRe = /`([^`]+)`/;
53
+ for (const line of lines) {
54
+ if (!actionRe.test(line))
55
+ continue;
56
+ const m = pathRe.exec(line);
57
+ if (!m)
58
+ continue;
59
+ const filePath = m[1].trim();
60
+ // Filter obvious non-file references (directories, comments).
61
+ if (!filePath || filePath.endsWith('/') || filePath.startsWith('['))
62
+ continue;
63
+ out.push(filePath);
64
+ }
65
+ // De-dupe while preserving order.
66
+ return Array.from(new Set(out));
67
+ }
68
+ /**
69
+ * Fallback: ask git which files diverge from the merge base with the default
70
+ * branch. Returns project-relative paths; on any git error, returns `[]`
71
+ * silently — the caller is expected to surface a friendlier message.
72
+ */
73
+ export function discoverFilesFromGit(projectRoot) {
74
+ try {
75
+ const baseRef = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
76
+ cwd: projectRoot,
77
+ stdio: ['ignore', 'pipe', 'ignore'],
78
+ })
79
+ .toString()
80
+ .trim();
81
+ // Diff vs HEAD~1 if no merge-base is sensible — best-effort.
82
+ const out = execFileSync('git', ['diff', '--name-only', 'HEAD', '--', '.'], { cwd: projectRoot, stdio: ['ignore', 'pipe', 'ignore'] })
83
+ .toString()
84
+ .trim();
85
+ if (!out)
86
+ return [];
87
+ return out
88
+ .split('\n')
89
+ .map((s) => s.trim())
90
+ .filter(Boolean);
91
+ void baseRef; // (silence unused-warning when only diff matters)
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
97
+ /** Build the empty-shell report when there are no files to scan. */
98
+ function emptyReport(taskId) {
99
+ return {
100
+ taskId,
101
+ filesScanned: [],
102
+ reports: [],
103
+ failed: false,
104
+ totals: { errors: 0, warnings: 0, filesWithFindings: 0 },
105
+ };
106
+ }
107
+ /** Read the optional semantic verdict supplied by the IDE agent. */
108
+ async function loadSemanticVerdict(fromAgentPath) {
109
+ if (!(await fs.pathExists(fromAgentPath))) {
110
+ throw new Error(`--from-agent file not found: ${fromAgentPath}`);
111
+ }
112
+ const data = await fs.readJSON(fromAgentPath);
113
+ if (typeof data?.passed !== 'boolean' || !Array.isArray(data?.unmetCriteria)) {
114
+ throw new Error(`Invalid semantic verdict in ${fromAgentPath}: needs { passed: boolean, unmetCriteria: string[] }.`);
115
+ }
116
+ return data;
117
+ }
118
+ /**
119
+ * Main entry point. Resolves files, runs the analyzer, merges semantic input
120
+ * if any, and returns a fully populated `ReviewReport`.
121
+ */
122
+ export async function runReview(taskId, options = {}) {
123
+ const projectRoot = options.projectRoot ?? process.cwd();
124
+ // 1. Resolve file list.
125
+ let files = options.files ?? [];
126
+ if (files.length === 0) {
127
+ const specPath = await findSpecFile(projectRoot, taskId);
128
+ if (specPath) {
129
+ const md = await fs.readFile(specPath, 'utf-8');
130
+ files = parseFilesFromSpec(md);
131
+ }
132
+ }
133
+ if (files.length === 0) {
134
+ // Last-ditch: try git.
135
+ files = discoverFilesFromGit(projectRoot);
136
+ }
137
+ if (files.length === 0) {
138
+ return emptyReport(taskId);
139
+ }
140
+ // 2. Run analyzer.
141
+ const reports = await runStaticAnalysis(projectRoot, files);
142
+ // 3. Aggregate totals.
143
+ let errors = 0;
144
+ let warnings = 0;
145
+ let filesWithFindings = 0;
146
+ for (const r of reports) {
147
+ if (r.violations.length === 0)
148
+ continue;
149
+ filesWithFindings++;
150
+ for (const v of r.violations) {
151
+ if (v.severity === 'error')
152
+ errors++;
153
+ else
154
+ warnings++;
155
+ }
156
+ }
157
+ // 4. Optional semantic merge.
158
+ let semantic;
159
+ if (options.fromAgent) {
160
+ const v = await loadSemanticVerdict(options.fromAgent);
161
+ if (v)
162
+ semantic = v;
163
+ }
164
+ const failedFromStatic = errors > 0 || (Boolean(options.strict) && warnings > 0);
165
+ const failedFromSemantic = semantic ? !semantic.passed : false;
166
+ return {
167
+ taskId,
168
+ filesScanned: files,
169
+ reports,
170
+ failed: failedFromStatic || failedFromSemantic,
171
+ totals: { errors, warnings, filesWithFindings },
172
+ semantic,
173
+ };
174
+ }
175
+ //# sourceMappingURL=ReviewRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReviewRunner.js","sourceRoot":"","sources":["../../src/utils/ReviewRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,0DAA0D;AAC1D,SAAS,cAAc,CAAC,WAAmB,EAAE,MAAc;IACzD,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,KAAK,CAAC;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,MAAM,KAAK,CAAC;QAChE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,KAAK,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,MAAc;IAEd,KAAK,MAAM,SAAS,IAAI,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;QAC5D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,0DAA0D,CAAC;IAC5E,MAAM,MAAM,GAAG,WAAW,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,8DAA8D;QAC9D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC9E,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAED,kCAAkC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE;YACzE,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC;aACC,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,6DAA6D;QAC7D,MAAM,GAAG,GAAG,YAAY,CACtB,KAAK,EACL,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,EAC1C,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAC1D;aACE,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG;aACP,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,OAAO,CAAC,CAAC,kDAAkD;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO;QACL,MAAM;QACN,YAAY,EAAE,EAAE;QAChB,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE;KACzD,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,KAAK,UAAU,mBAAmB,CAChC,aAAqB;IAErB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,gCAAgC,aAAa,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC9C,IAAI,OAAO,IAAI,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CACb,+BAA+B,aAAa,uDAAuD,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,IAAuB,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAc,EACd,UAAyB,EAAE;IAE3B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzD,wBAAwB;IACxB,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,KAAK,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,uBAAuB;QACvB,KAAK,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,mBAAmB;IACnB,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAE5D,uBAAuB;IACvB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACxC,iBAAiB,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO;gBAAE,MAAM,EAAE,CAAC;;gBAChC,QAAQ,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,QAAqC,CAAC;IAC1C,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC;YAAE,QAAQ,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,MAAM,gBAAgB,GACpB,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,kBAAkB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAE/D,OAAO;QACL,MAAM;QACN,YAAY,EAAE,KAAK;QACnB,OAAO;QACP,MAAM,EAAE,gBAAgB,IAAI,kBAAkB;QAC9C,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE;QAC/C,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Applies an `UpdatePlan` to a project on disk.
3
+ *
4
+ * The detector decides *what* would happen; the applier actually writes files,
5
+ * backs up the previous state, prompts on conflicts and runs migrations. Kept
6
+ * separate so unit tests can poke the detector without touching the filesystem.
7
+ */
8
+ import type { ConflictResolution, ManifestChange, ManifestMigration, UpdatePlan } from '../types/UpdateManifest.types.js';
9
+ /** Per-file outcome used to build the final summary. */
10
+ export interface ChangeOutcome {
11
+ change: ManifestChange;
12
+ resolution: ConflictResolution;
13
+ action: 'wrote' | 'deleted' | 'skipped' | 'kept-custom';
14
+ }
15
+ export interface ApplyOptions {
16
+ projectRoot: string;
17
+ /** Backup directory inside the project (defaults to `.dare/backup-<from>`). */
18
+ backupDir?: string;
19
+ /** Skip interactive prompts and always overwrite customizations. Dangerous. */
20
+ force?: boolean;
21
+ /** Print plan but write nothing. */
22
+ dryRun?: boolean;
23
+ /** Default answer for the per-file conflict prompt — `'ask'` is interactive. */
24
+ conflictPolicy?: 'ask' | 'keep' | 'replace';
25
+ }
26
+ /**
27
+ * Snapshot every file the plan touches into `backupDir`, preserving its
28
+ * relative path. Touches only files that currently exist.
29
+ */
30
+ export declare function backupAffectedFiles(plan: UpdatePlan, projectRoot: string, backupDir: string): Promise<number>;
31
+ export interface ApplyResult {
32
+ outcomes: ChangeOutcome[];
33
+ migrationsRan: ManifestMigration[];
34
+ backupPath: string | null;
35
+ backupFilesCount: number;
36
+ }
37
+ /**
38
+ * Execute the plan. Returns a structured result so the command can print a
39
+ * sensible summary at the end.
40
+ */
41
+ export declare function applyPlan(plan: UpdatePlan, options: ApplyOptions): Promise<ApplyResult>;
42
+ //# sourceMappingURL=UpdateApplier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateApplier.d.ts","sourceRoot":"","sources":["../../src/utils/UpdateApplier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,UAAU,EACX,MAAM,kCAAkC,CAAC;AA6B1C,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;CACzD;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAYjB;AA8JD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC,CAgCtB"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Applies an `UpdatePlan` to a project on disk.
3
+ *
4
+ * The detector decides *what* would happen; the applier actually writes files,
5
+ * backs up the previous state, prompts on conflicts and runs migrations. Kept
6
+ * separate so unit tests can poke the detector without touching the filesystem.
7
+ */
8
+ import fs from 'fs-extra';
9
+ import path from 'path';
10
+ import chalk from 'chalk';
11
+ import inquirer from 'inquirer';
12
+ import { fileURLToPath } from 'url';
13
+ import { classifyChange, readProjectConfig } from './UpdateDetector.js';
14
+ /** Where templates ship inside the CLI bundle. */
15
+ function getTemplatesRoot() {
16
+ const here = fileURLToPath(import.meta.url);
17
+ return path.resolve(path.dirname(here), '..', '..', 'templates');
18
+ }
19
+ /** Resolve the template source for a change (defaults to mirroring `path`). */
20
+ function resolveTemplateSource(change) {
21
+ const rel = change.templateSource ?? change.path;
22
+ return path.join(getTemplatesRoot(), rel);
23
+ }
24
+ /** Read the new template content for a non-schema change. */
25
+ async function readNewContent(change) {
26
+ if (change.path.includes('#'))
27
+ return null; // schema-only
28
+ if (change.type === 'removed')
29
+ return null;
30
+ const source = resolveTemplateSource(change);
31
+ if (!(await fs.pathExists(source))) {
32
+ throw new Error(`Template source missing for change "${change.path}" (expected at ${source}). ` +
33
+ `Make sure the manifest's templateSource is correct or that templates/ ships the file.`);
34
+ }
35
+ return fs.readFile(source);
36
+ }
37
+ /**
38
+ * Snapshot every file the plan touches into `backupDir`, preserving its
39
+ * relative path. Touches only files that currently exist.
40
+ */
41
+ export async function backupAffectedFiles(plan, projectRoot, backupDir) {
42
+ let copied = 0;
43
+ for (const change of plan.applicableChanges) {
44
+ if (change.path.includes('#'))
45
+ continue;
46
+ const src = path.join(projectRoot, change.path);
47
+ if (!(await fs.pathExists(src)))
48
+ continue;
49
+ const dest = path.join(backupDir, change.path);
50
+ await fs.ensureDir(path.dirname(dest));
51
+ await fs.copy(src, dest);
52
+ copied++;
53
+ }
54
+ return copied;
55
+ }
56
+ /**
57
+ * Prompt the dev on a customized file. Returns the action to take.
58
+ *
59
+ * Honors `conflictPolicy` to skip the prompt in non-interactive flows
60
+ * (CI, scripted updates) — `'keep'` preserves the local file, `'replace'`
61
+ * overwrites it.
62
+ */
63
+ async function resolveCustomization(change, conflictPolicy) {
64
+ if (conflictPolicy !== 'ask')
65
+ return conflictPolicy;
66
+ const { decision } = (await inquirer.prompt([
67
+ {
68
+ type: 'list',
69
+ name: 'decision',
70
+ message: `Arquivo customizado: ${chalk.yellow(change.path)}\n ${chalk.gray(change.description)}`,
71
+ choices: [
72
+ { name: '🔒 Manter minha versão (recomendado se você editou)', value: 'keep' },
73
+ { name: '⬆️ Substituir pela versão nova do DARE', value: 'replace' },
74
+ ],
75
+ default: 'keep',
76
+ },
77
+ ]));
78
+ return decision;
79
+ }
80
+ async function applyOne(change, projectRoot, conflictPolicy, dryRun) {
81
+ // Schema-only ("dare.config.json#field") — migrations handle these.
82
+ if (change.path.includes('#')) {
83
+ return { change, resolution: 'apply', action: 'skipped' };
84
+ }
85
+ const target = path.join(projectRoot, change.path);
86
+ const newContent = await readNewContent(change);
87
+ const resolution = await classifyChange(projectRoot, change, newContent);
88
+ if (resolution === 'identical') {
89
+ return { change, resolution, action: 'skipped' };
90
+ }
91
+ if (change.type === 'removed') {
92
+ if (!dryRun && (await fs.pathExists(target))) {
93
+ await fs.remove(target);
94
+ }
95
+ return { change, resolution, action: 'deleted' };
96
+ }
97
+ if (resolution === 'customized') {
98
+ const decision = await resolveCustomization(change, conflictPolicy);
99
+ if (decision === 'keep') {
100
+ return { change, resolution, action: 'kept-custom' };
101
+ }
102
+ }
103
+ if (change.type === 'renamed' && change.previousPath) {
104
+ const prev = path.join(projectRoot, change.previousPath);
105
+ if (!dryRun && (await fs.pathExists(prev))) {
106
+ await fs.remove(prev);
107
+ }
108
+ }
109
+ if (newContent && !dryRun) {
110
+ await fs.ensureDir(path.dirname(target));
111
+ await fs.writeFile(target, newContent);
112
+ }
113
+ return { change, resolution, action: 'wrote' };
114
+ }
115
+ /** Run all migrations declared in the plan (post file changes). */
116
+ async function runMigrations(plan, projectRoot, dryRun) {
117
+ const ran = [];
118
+ for (const { release } of plan.pendingReleases) {
119
+ if (!release.migrations)
120
+ continue;
121
+ for (const migration of release.migrations) {
122
+ if (dryRun) {
123
+ ran.push(migration);
124
+ continue;
125
+ }
126
+ await runMigration(migration, projectRoot);
127
+ ran.push(migration);
128
+ }
129
+ }
130
+ return ran;
131
+ }
132
+ /**
133
+ * Built-in migrations. Each `id` maps to a handler — unknown ids are skipped
134
+ * with a warning so an older CLI can still apply a partial update.
135
+ */
136
+ async function runMigration(migration, projectRoot) {
137
+ switch (migration.id) {
138
+ case 'unify-version-field': {
139
+ // Pre-2.17 projects wrote `version: "0.1.0"` (zombie placeholder) and
140
+ // an early prototype briefly used `dareVersion`. Consolidate both into
141
+ // a single `version` field that now tracks the DARE release.
142
+ const configPath = path.join(projectRoot, 'dare.config.json');
143
+ const cfg = (await readProjectConfig(projectRoot));
144
+ const legacyDareVersion = cfg.dareVersion;
145
+ if (legacyDareVersion) {
146
+ cfg.version = legacyDareVersion;
147
+ delete cfg.dareVersion;
148
+ }
149
+ else if (!cfg.version || cfg.version === '0.1.0') {
150
+ cfg.version = '2.16.0';
151
+ }
152
+ await fs.writeJSON(configPath, cfg, { spaces: 2 });
153
+ return;
154
+ }
155
+ case 'add-review-refine-defaults': {
156
+ // Seed the new review/refine objects so dev can see they exist (and
157
+ // edit). Opt-in stance for legacy projects — review.onComplete: false
158
+ // means the gate is silent until the dev flips it.
159
+ const configPath = path.join(projectRoot, 'dare.config.json');
160
+ const cfg = (await readProjectConfig(projectRoot));
161
+ if (!cfg.review) {
162
+ cfg.review = { onComplete: false, strict: false };
163
+ }
164
+ if (!cfg.refine) {
165
+ cfg.refine = { thresholds: { low: 5, med: 12, high: 20 } };
166
+ }
167
+ await fs.writeJSON(configPath, cfg, { spaces: 2 });
168
+ return;
169
+ }
170
+ default:
171
+ console.log(chalk.yellow(` ⚠ Unknown migration "${migration.id}" — skipping (CLI may be outdated).`));
172
+ }
173
+ }
174
+ /** Bump `version` in `dare.config.json` to the plan's target version. */
175
+ async function stampVersion(projectRoot, toVersion) {
176
+ const configPath = path.join(projectRoot, 'dare.config.json');
177
+ const cfg = (await readProjectConfig(projectRoot));
178
+ cfg.version = toVersion;
179
+ cfg.updatedAt = new Date().toISOString();
180
+ await fs.writeJSON(configPath, cfg, { spaces: 2 });
181
+ }
182
+ /**
183
+ * Execute the plan. Returns a structured result so the command can print a
184
+ * sensible summary at the end.
185
+ */
186
+ export async function applyPlan(plan, options) {
187
+ const { projectRoot, backupDir, force = false, dryRun = false, conflictPolicy = force ? 'replace' : 'ask', } = options;
188
+ let backupPath = null;
189
+ let backupFilesCount = 0;
190
+ if (!dryRun) {
191
+ backupPath =
192
+ backupDir ?? path.join(projectRoot, '.dare', `backup-${plan.fromVersion}`);
193
+ await fs.ensureDir(backupPath);
194
+ backupFilesCount = await backupAffectedFiles(plan, projectRoot, backupPath);
195
+ }
196
+ const outcomes = [];
197
+ for (const change of plan.applicableChanges) {
198
+ const outcome = await applyOne(change, projectRoot, conflictPolicy, dryRun);
199
+ outcomes.push(outcome);
200
+ }
201
+ const migrationsRan = await runMigrations(plan, projectRoot, dryRun);
202
+ if (!dryRun) {
203
+ await stampVersion(projectRoot, plan.toVersion);
204
+ }
205
+ return { outcomes, migrationsRan, backupPath, backupFilesCount };
206
+ }
207
+ //# sourceMappingURL=UpdateApplier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateApplier.js","sourceRoot":"","sources":["../../src/utils/UpdateApplier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Detects what `dare update` needs to do for a given project.
3
+ *
4
+ * Pure planning — it never writes to disk. Loads the manifest, reads the
5
+ * project's `dare.config.json`, and produces an `UpdatePlan` the applier can
6
+ * execute (or the dev can simply preview with `--dry-run`).
7
+ */
8
+ import type { ConflictResolution, ManifestChange, UpdateManifest, UpdatePlan } from '../types/UpdateManifest.types.js';
9
+ export declare function loadManifest(): Promise<UpdateManifest>;
10
+ /** Read the current CLI version from the bundled `package.json`. */
11
+ export declare function getCliVersion(): string;
12
+ export interface ProjectConfig {
13
+ ide?: string;
14
+ version?: string;
15
+ [key: string]: unknown;
16
+ }
17
+ /** Baseline assumed for projects with the legacy placeholder or no `version`. */
18
+ export declare const LEGACY_BASELINE_VERSION = "2.16.0";
19
+ /**
20
+ * Resolve the "effective DARE version" of a project, handling the legacy
21
+ * `"0.1.0"` placeholder that was hardcoded by pre-2.17 `dare init`.
22
+ */
23
+ export declare function resolveProjectVersion(cfg: ProjectConfig): {
24
+ version: string;
25
+ isLegacy: boolean;
26
+ };
27
+ /** Load and return `dare.config.json` from the given project root. */
28
+ export declare function readProjectConfig(projectRoot: string): Promise<ProjectConfig>;
29
+ /**
30
+ * Filter a single change against the IDE configured for this project. A change
31
+ * with `appliesTo: ['*']` (or no `appliesTo`) is universal.
32
+ *
33
+ * Hybrid setups (`hybrid` = cursor+antigravity, `claude-hybrid` = claude+cursor)
34
+ * accept changes targeted at any of their member IDEs.
35
+ */
36
+ export declare function changeAppliesToIde(change: ManifestChange, ide: string | undefined): boolean;
37
+ /**
38
+ * Build the update plan: every release between `from` (exclusive) and `to`
39
+ * (inclusive), with its changes filtered down to what applies to this IDE.
40
+ */
41
+ export declare function buildUpdatePlan(manifest: UpdateManifest, fromVersion: string, toVersion: string, ide: string | undefined): UpdatePlan;
42
+ /** SHA-256 hex digest of file content; returns `null` if the file is absent. */
43
+ export declare function hashFile(absPath: string): Promise<string | null>;
44
+ /**
45
+ * Classify what we'd be doing to a single file on disk:
46
+ * - `identical` → new template content already matches what's on disk
47
+ * - `missing` → file absent in the project, safe to create
48
+ * - `apply` → file present and matches `previousHash`, safe to overwrite
49
+ * - `customized` → file present but doesn't match `previousHash`; ask the dev
50
+ *
51
+ * `newContent` is the bytes we'd write; `previousHash` is the manifest's record
52
+ * of what the file looked like in the prior version (optional — without it we
53
+ * can't tell `apply` from `customized` and conservatively return `customized`).
54
+ */
55
+ export declare function classifyChange(projectRoot: string, change: ManifestChange, newContent: Buffer | string | null): Promise<ConflictResolution>;
56
+ //# sourceMappingURL=UpdateDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateDetector.d.ts","sourceRoot":"","sources":["../../src/utils/UpdateDetector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EACV,kBAAkB,EAElB,cAAc,EACd,cAAc,EACd,UAAU,EACX,MAAM,kCAAkC,CAAC;AAiB1C,wBAAsB,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC,CAY5D;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAMA;AAED,sEAAsE;AACtE,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAQnF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAe3F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,UAAU,CA8BZ;AAED,gFAAgF;AAChF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAItE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GACjC,OAAO,CAAC,kBAAkB,CAAC,CA2B7B"}