devflow-kit 3.9.0 → 3.11.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 (168) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/README.md +1 -1
  3. package/dist/agents/code.md +6 -6
  4. package/dist/agents/fix.md +6 -6
  5. package/dist/agents/harden.md +7 -6
  6. package/dist/agents/refactor.md +6 -6
  7. package/dist/cli/commands/ambient.js +10 -2
  8. package/dist/cli/commands/backup-session.js +131 -0
  9. package/dist/cli/commands/compliance-prompts.js +9 -4
  10. package/dist/cli/commands/compliance.js +184 -24
  11. package/dist/cli/commands/curation.js +23 -10
  12. package/dist/cli/commands/gate-level-prompts.js +39 -25
  13. package/dist/cli/commands/gates.js +5 -7
  14. package/dist/cli/commands/init.js +169 -184
  15. package/dist/cli/commands/install-report.js +129 -0
  16. package/dist/cli/commands/legacy-sweep.js +159 -0
  17. package/dist/cli/commands/proxy.js +6 -1
  18. package/dist/cli/commands/rules.js +75 -21
  19. package/dist/cli/commands/skills.js +42 -9
  20. package/dist/cli/commands/tracker.js +9 -3
  21. package/dist/cli/commands/uninstall.js +339 -75
  22. package/dist/commands/bug-analysis.md +69 -120
  23. package/dist/commands/dynamic-build.md +23 -23
  24. package/dist/commands/implement.md +46 -32
  25. package/dist/commands/release.md +1 -1
  26. package/dist/commands/resolve.md +35 -31
  27. package/dist/commands/self-review.md +8 -7
  28. package/dist/compliance-off/agents/git.md +120 -0
  29. package/dist/compliance-off/agents/triage.md +180 -0
  30. package/dist/compliance-off/commands/bug-analysis.md +398 -0
  31. package/dist/compliance-off/commands/code-review.md +520 -0
  32. package/dist/compliance-off/commands/dynamic-build.md +1251 -0
  33. package/dist/compliance-off/commands/dynamic-tickets.md +676 -0
  34. package/dist/compliance-off/commands/implement.md +736 -0
  35. package/dist/compliance-off/commands/plan.md +671 -0
  36. package/dist/compliance-off/commands/release.md +309 -0
  37. package/dist/compliance-off/commands/resolve.md +742 -0
  38. package/dist/compliance-off/skills/git/references/decision-markers.md +17 -0
  39. package/dist/compliance-off/skills/git/references/learn-conventions.md +80 -0
  40. package/dist/compliance-off/skills/git/references/pr/check-ci-status.md +33 -0
  41. package/dist/compliance-off/skills/git/references/pr/check-merge-readiness.md +49 -0
  42. package/dist/compliance-off/skills/git/references/pr/fetch-review-threads.md +52 -0
  43. package/dist/compliance-off/skills/git/references/pr/validate-branch.md +47 -0
  44. package/dist/compliance-off/skills/git/references/tracker/_contract.md +33 -0
  45. package/dist/compliance-off/skills/git/references/tracker/_mcp.md +153 -0
  46. package/dist/compliance-off/skills/git/references/tracker/github/create-release.md +35 -0
  47. package/dist/compliance-off/skills/git/references/tracker/github/ensure-pr-ready.md +100 -0
  48. package/dist/compliance-off/skills/git/references/tracker/github/ensure-traceable-issue.md +74 -0
  49. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issue.md +69 -0
  50. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issues-batch.md +65 -0
  51. package/dist/compliance-off/skills/git/references/tracker/github/gather-release-evidence.md +48 -0
  52. package/dist/compliance-off/skills/git/references/tracker/github/setup-task.md +77 -0
  53. package/dist/compliance-off/skills/git/references/tracker/jira/create-release.md +35 -0
  54. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-pr-ready.md +100 -0
  55. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-traceable-issue.md +61 -0
  56. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issue.md +51 -0
  57. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issues-batch.md +63 -0
  58. package/dist/compliance-off/skills/git/references/tracker/jira/gather-release-evidence.md +47 -0
  59. package/dist/compliance-off/skills/git/references/tracker/jira/setup-task.md +82 -0
  60. package/dist/compliance-off/skills/git/references/tracker/linear/create-release.md +35 -0
  61. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-pr-ready.md +100 -0
  62. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-traceable-issue.md +61 -0
  63. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issue.md +51 -0
  64. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issues-batch.md +63 -0
  65. package/dist/compliance-off/skills/git/references/tracker/linear/gather-release-evidence.md +47 -0
  66. package/dist/compliance-off/skills/git/references/tracker/linear/setup-task.md +83 -0
  67. package/dist/compliance-off/skills/git/references/trust-rule.md +7 -0
  68. package/dist/core/agent-models.js +19 -4
  69. package/dist/core/assets.js +126 -17
  70. package/dist/core/compliance-off-files.js +27 -0
  71. package/dist/core/compliance.js +14 -0
  72. package/dist/core/curation-variants.js +460 -112
  73. package/dist/core/flags.js +2 -2
  74. package/dist/core/fs-atomic.js +5 -1
  75. package/dist/core/installed-variants.js +63 -0
  76. package/dist/core/manifest.js +48 -5
  77. package/dist/core/mds-variants.js +700 -3
  78. package/dist/core/orphan-sweep.js +29 -2
  79. package/dist/core/path-set.js +15 -0
  80. package/dist/core/plugins.js +68 -10
  81. package/dist/core/reference-sweep.js +42 -25
  82. package/dist/core/retired-shipped-names.js +278 -0
  83. package/dist/curation-compliance-off/agents/triage.md +176 -0
  84. package/dist/curation-compliance-off/commands/bug-analysis.md +349 -0
  85. package/dist/curation-compliance-off/commands/code-review.md +481 -0
  86. package/dist/curation-compliance-off/commands/dynamic-build.md +1211 -0
  87. package/dist/curation-compliance-off/commands/dynamic-tickets.md +634 -0
  88. package/dist/curation-compliance-off/commands/implement.md +689 -0
  89. package/dist/curation-compliance-off/commands/plan.md +631 -0
  90. package/dist/curation-compliance-off/commands/release.md +279 -0
  91. package/dist/curation-compliance-off/commands/resolve.md +692 -0
  92. package/dist/curation-off/agents/code.md +6 -6
  93. package/dist/curation-off/agents/fix.md +6 -6
  94. package/dist/curation-off/agents/harden.md +7 -6
  95. package/dist/curation-off/agents/refactor.md +6 -6
  96. package/dist/curation-off/commands/bug-analysis.md +69 -119
  97. package/dist/curation-off/commands/dynamic-build.md +23 -23
  98. package/dist/curation-off/commands/implement.md +46 -32
  99. package/dist/curation-off/commands/release.md +1 -1
  100. package/dist/curation-off/commands/resolve.md +35 -31
  101. package/dist/curation-off/commands/self-review.md +8 -7
  102. package/dist/skills/git/references/pr/resolve-review-threads.md +1 -1
  103. package/dist/targets/claude-code/behavior-install.js +23 -9
  104. package/dist/targets/claude-code/charter-render.js +374 -0
  105. package/dist/targets/claude-code/compliance-install.js +62 -17
  106. package/dist/targets/claude-code/compliance-off-files.js +249 -0
  107. package/dist/targets/claude-code/curation-install.js +632 -117
  108. package/dist/targets/claude-code/folder-swap.js +142 -0
  109. package/dist/targets/claude-code/install-backup.js +780 -0
  110. package/dist/targets/claude-code/installer.js +795 -199
  111. package/dist/targets/claude-code/language-stamp.js +6 -0
  112. package/dist/targets/claude-code/legacy-skill-hashes.js +170 -0
  113. package/dist/targets/claude-code/linked-folder.js +176 -0
  114. package/dist/targets/claude-code/reference-converge.js +131 -0
  115. package/dist/targets/claude-code/rules-folder.js +34 -0
  116. package/dist/targets/claude-code/shipped-set.js +160 -0
  117. package/dist/targets/claude-code/tracker-install.js +21 -8
  118. package/dist/targets/claude-code/tracker-servers.js +20 -6
  119. package/dist/targets/claude-code/workflow-folder-install.js +251 -0
  120. package/dist/variant-axes.json +109 -0
  121. package/package.json +1 -1
  122. package/src/assets/agents/_partials/_code.mds +6 -6
  123. package/src/assets/agents/evaluate.md +1 -1
  124. package/src/assets/agents/git.mds +32 -0
  125. package/src/assets/agents/harden.mds +7 -6
  126. package/src/assets/agents/test.md +21 -12
  127. package/src/assets/agents/triage.mds +2 -0
  128. package/src/assets/agents/validate.md +10 -10
  129. package/src/assets/commands/_partials/_compliance.mds +5 -3
  130. package/src/assets/commands/_partials/_engine.mds +9 -8
  131. package/src/assets/commands/_partials/_publication.mds +10 -1
  132. package/src/assets/commands/bug-analysis.mds +80 -126
  133. package/src/assets/commands/code-review.mds +43 -0
  134. package/src/assets/commands/dynamic-build.mds +109 -15
  135. package/src/assets/commands/dynamic-tickets.mds +13 -0
  136. package/src/assets/commands/implement.mds +145 -33
  137. package/src/assets/commands/plan.mds +19 -0
  138. package/src/assets/commands/release.mds +50 -1
  139. package/src/assets/commands/resolve.mds +217 -32
  140. package/src/assets/commands/self-review.mds +8 -7
  141. package/src/assets/mds/git/_ops.mds +23 -0
  142. package/src/assets/mds/git/_ops_steps.mds +17 -0
  143. package/src/assets/mds/git/_pr.mds +1 -1
  144. package/src/assets/mds/git/_references.mds +6 -0
  145. package/src/assets/mds/tracker/_common.mds +4 -0
  146. package/src/assets/mds/tracker/_github.mds +42 -0
  147. package/src/assets/mds/tracker/_jira.mds +43 -0
  148. package/src/assets/mds/tracker/_linear.mds +43 -0
  149. package/src/assets/rules/quality.md +2 -0
  150. package/src/assets/scripts/ci-wait.cjs +204 -126
  151. package/src/assets/scripts/hooks/assets/implement-installed +1 -0
  152. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +13 -11
  153. package/src/assets/scripts/hooks/preamble +18 -8
  154. package/src/assets/scripts/hooks/session-start-orchestrator +4 -2
  155. package/src/assets/scripts/pr-evidence.cjs +41 -2
  156. package/src/assets/scripts/verify-evidence.cjs +408 -56
  157. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +3 -3
  158. package/src/assets/skills/agent-references/references/commands/plan-levels.md +1 -1
  159. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +6 -2
  160. package/src/assets/skills/agent-references/references/validate/passed-alone.md +7 -7
  161. package/src/assets/skills/docs-framework/SKILL.md +5 -2
  162. package/src/assets/skills/git/SKILL.md +3 -3
  163. package/src/assets/skills/git/references/github-api.md +2 -139
  164. package/src/assets/skills/git/references/github-posting.md +158 -0
  165. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  166. package/src/assets/skills/review-methodology/references/patterns.md +1 -1
  167. package/src/assets/skills/review-methodology/references/report-template.md +1 -2
  168. package/src/assets/skills/testing/SKILL.md +2 -4
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The swap of a folder that devflow owns and that may hold files of the user's: a skill folder the
3
+ * converge replaces. The new folder is built beside the old one and renamed in; the old folder waits
4
+ * in an aside folder while that happens.
5
+ *
6
+ * Nothing here removes a folder with a recursive `rm`. Before the swap, the backup session moves
7
+ * every file devflow did not ship out of the old folder. If any file could not move, the folder is
8
+ * not swapped: the files devflow ships are written into it one by one, and it stays in place. The
9
+ * write comes before any removal, so a copy that fails leaves the old shipped files in the folder;
10
+ * then only the listed entries that the new folder lacks are removed. The same holds when the aside
11
+ * name is taken by a folder that keeps a file. A file at the aside name
12
+ * moves to the backup folder first; if it cannot move, a rename never replaces it, so a folder
13
+ * stays in place and a link makes the swap throw. After
14
+ * a swap, the aside folder is scanned again, because a file can arrive between the first scan and the
15
+ * rename. What the session moves out of it is named, what devflow shipped is removed by the list the
16
+ * scan made, and the folder goes with a plain `rmdir`; a folder that still holds a file stays.
17
+ *
18
+ * This module imports no installer module, so the install and the converge steps can all use it.
19
+ * A swap that cannot finish throws, and the caller reports it.
20
+ */
21
+ import { promises as fs } from 'fs';
22
+ import * as path from 'path';
23
+ import { DEFAULT_ENTRY_CAP, MAX_WALK_DEPTH } from './install-backup.js';
24
+ import { directoryState, unlinkLinkAt } from './linked-folder.js';
25
+ const errorMessage = (err) => (err instanceof Error ? err.message : String(err));
26
+ /**
27
+ * Remove a folder that was displaced from `stoodAt`: scan it as if it still stood there, move what
28
+ * devflow did not ship, remove what it shipped by the session's list, then `rmdir`. A displaced link
29
+ * is unlinked. A folder that still holds a file stays, and the session's record names the file.
30
+ */
31
+ export async function discardDisplacedFolder(backups, aside, stoodAt) {
32
+ const state = await directoryState(aside);
33
+ if (state === 'link') {
34
+ await unlinkLinkAt(aside);
35
+ return;
36
+ }
37
+ if (state !== 'real')
38
+ return;
39
+ await backups.prepass([{ folder: aside, displacedFrom: stoodAt }]);
40
+ await backups.removeListed(aside);
41
+ }
42
+ /**
43
+ * The files and links below `staged` as paths relative to it, with `/` separators. Null when the
44
+ * walk reached its depth or entry bound, because a list that stops early would name too few.
45
+ */
46
+ async function stagedPaths(staged) {
47
+ const found = new Set();
48
+ async function walk(folder, rel, depth) {
49
+ if (depth > MAX_WALK_DEPTH)
50
+ return false;
51
+ const entries = await fs.readdir(folder, { withFileTypes: true });
52
+ for (const entry of entries) {
53
+ const childRel = rel === '' ? entry.name : `${rel}/${entry.name}`;
54
+ if (entry.isDirectory()) {
55
+ if (!(await walk(path.join(folder, entry.name), childRel, depth + 1)))
56
+ return false;
57
+ }
58
+ else {
59
+ found.add(childRel);
60
+ if (found.size > DEFAULT_ENTRY_CAP)
61
+ return false;
62
+ }
63
+ }
64
+ return true;
65
+ }
66
+ return (await walk(staged, '', 0)) ? found : null;
67
+ }
68
+ /**
69
+ * Write the files of `staged` into `target`, then remove what the old folder held and the new one
70
+ * lacks. The write comes first: if the copy fails, the files devflow shipped are still in the old
71
+ * folder. The removal scans `target` again with a filter that leaves every staged path, every kept
72
+ * file and everything below a kept folder alone, so `removeListed` takes only the listed leftovers
73
+ * (retired and sidecar names, `.DS_Store`) and the shipped files that the new release dropped.
74
+ * When the staged list is not complete, nothing is removed.
75
+ */
76
+ async function mergeThenClear(backups, target, staged, mergeInto) {
77
+ const written = await stagedPaths(staged);
78
+ await mergeInto();
79
+ if (written === null)
80
+ return;
81
+ await backups.prepass([{
82
+ folder: target,
83
+ include: (relative, kind) => !(kind !== 'directory' && written.has(relative)) && !backups.isKept(path.join(target, ...relative.split('/'))),
84
+ }]);
85
+ await backups.removeListed(target);
86
+ }
87
+ /**
88
+ * Put `staged` at `target`. See the module comment for the order of the steps.
89
+ *
90
+ * If the rename of `staged` fails, the old folder is renamed back. If that fails too, the old folder
91
+ * stays at `aside` and the error names the path. Throws on a failure that leaves the swap undone.
92
+ */
93
+ export async function swapFolderIn(options) {
94
+ const { backups, target, staged, aside, links, mergeInto } = options;
95
+ // What an earlier, interrupted swap left at the aside name is cleared first, so the rename below has a free name.
96
+ // A file there is not a displaced folder: it moves to the backup folder, because a rename replaces it without a trace.
97
+ await discardDisplacedFolder(backups, aside, target);
98
+ if ((await directoryState(aside)) === 'unusable')
99
+ await backups.moveWhole(aside);
100
+ const asideTaken = (await directoryState(aside)) !== 'absent';
101
+ let state = await directoryState(target);
102
+ if (state === 'unusable') {
103
+ const moved = await backups.moveWhole(target);
104
+ if (moved.status === 'kept') {
105
+ throw new Error(`${target} is not a folder and could not be moved aside (${moved.reason})`);
106
+ }
107
+ state = 'absent';
108
+ }
109
+ if (state === 'real') {
110
+ await backups.prepass([target]);
111
+ if (asideTaken || backups.keptUnder(target).length > 0) {
112
+ await mergeThenClear(backups, target, staged, mergeInto);
113
+ return 'merged';
114
+ }
115
+ }
116
+ if (state === 'link' && asideTaken) {
117
+ throw new Error(`${target} is a link and was not replaced: ${aside} is in the way and could not be moved`);
118
+ }
119
+ const displaced = state !== 'absent';
120
+ if (displaced)
121
+ await fs.rename(target, aside);
122
+ try {
123
+ await fs.rename(staged, target);
124
+ }
125
+ catch (err) {
126
+ if (displaced) {
127
+ try {
128
+ await fs.rename(aside, target);
129
+ }
130
+ catch (restoreErr) {
131
+ throw new Error(`${errorMessage(err)}; the previous folder could not be put back (${errorMessage(restoreErr)}) and is kept at ${aside}`);
132
+ }
133
+ }
134
+ throw err;
135
+ }
136
+ if (state === 'link')
137
+ links.replacedLinks.push(target);
138
+ if (displaced)
139
+ await discardDisplacedFolder(backups, aside, target);
140
+ return 'swapped';
141
+ }
142
+ //# sourceMappingURL=folder-swap.js.map