@planu/cli 0.72.0 → 0.73.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 (255) hide show
  1. package/README.md +1 -1
  2. package/dist/config/license-plans.json +9 -2
  3. package/dist/config/tool-groups.json +5 -1
  4. package/dist/engine/actuals/git-analyzer.js +1 -1
  5. package/dist/engine/actuals/git-analyzer.js.map +1 -1
  6. package/dist/engine/agent-prompt-generator.d.ts +12 -0
  7. package/dist/engine/agent-prompt-generator.d.ts.map +1 -0
  8. package/dist/engine/agent-prompt-generator.js +171 -0
  9. package/dist/engine/agent-prompt-generator.js.map +1 -0
  10. package/dist/engine/ai-tool-detector/index.d.ts +6 -0
  11. package/dist/engine/ai-tool-detector/index.d.ts.map +1 -0
  12. package/dist/engine/ai-tool-detector/index.js +95 -0
  13. package/dist/engine/ai-tool-detector/index.js.map +1 -0
  14. package/dist/engine/ci-generator/planu-steps.d.ts.map +1 -1
  15. package/dist/engine/ci-generator/planu-steps.js +10 -11
  16. package/dist/engine/ci-generator/planu-steps.js.map +1 -1
  17. package/dist/engine/convention-scanner/codebase-scanner.d.ts +7 -0
  18. package/dist/engine/convention-scanner/codebase-scanner.d.ts.map +1 -0
  19. package/dist/engine/convention-scanner/codebase-scanner.js +258 -0
  20. package/dist/engine/convention-scanner/codebase-scanner.js.map +1 -0
  21. package/dist/engine/convention-scanner/convention-parser.d.ts +7 -0
  22. package/dist/engine/convention-scanner/convention-parser.d.ts.map +1 -0
  23. package/dist/engine/convention-scanner/convention-parser.js +195 -0
  24. package/dist/engine/convention-scanner/convention-parser.js.map +1 -0
  25. package/dist/engine/convention-scanner/index.d.ts +3 -0
  26. package/dist/engine/convention-scanner/index.d.ts.map +1 -0
  27. package/dist/engine/convention-scanner/index.js +5 -0
  28. package/dist/engine/convention-scanner/index.js.map +1 -0
  29. package/dist/engine/convention-sync.d.ts +9 -0
  30. package/dist/engine/convention-sync.d.ts.map +1 -0
  31. package/dist/engine/convention-sync.js +156 -0
  32. package/dist/engine/convention-sync.js.map +1 -0
  33. package/dist/engine/doc-generator/portal/portal-regenerator.d.ts +2 -1
  34. package/dist/engine/doc-generator/portal/portal-regenerator.d.ts.map +1 -1
  35. package/dist/engine/doc-generator/portal/portal-regenerator.js +23 -15
  36. package/dist/engine/doc-generator/portal/portal-regenerator.js.map +1 -1
  37. package/dist/engine/feedback/triage.d.ts +16 -0
  38. package/dist/engine/feedback/triage.d.ts.map +1 -0
  39. package/dist/engine/feedback/triage.js +165 -0
  40. package/dist/engine/feedback/triage.js.map +1 -0
  41. package/dist/engine/hooks-reconciler.d.ts +7 -0
  42. package/dist/engine/hooks-reconciler.d.ts.map +1 -0
  43. package/dist/engine/hooks-reconciler.js +214 -0
  44. package/dist/engine/hooks-reconciler.js.map +1 -0
  45. package/dist/engine/platform-registry.d.ts +17 -0
  46. package/dist/engine/platform-registry.d.ts.map +1 -0
  47. package/dist/engine/platform-registry.js +78 -0
  48. package/dist/engine/platform-registry.js.map +1 -0
  49. package/dist/engine/project-health-checker.d.ts +4 -2
  50. package/dist/engine/project-health-checker.d.ts.map +1 -1
  51. package/dist/engine/project-health-checker.js +78 -5
  52. package/dist/engine/project-health-checker.js.map +1 -1
  53. package/dist/engine/rules-generator/index.d.ts +14 -0
  54. package/dist/engine/rules-generator/index.d.ts.map +1 -0
  55. package/dist/engine/rules-generator/index.js +313 -0
  56. package/dist/engine/rules-generator/index.js.map +1 -0
  57. package/dist/engine/rules-reconciler.d.ts +13 -0
  58. package/dist/engine/rules-reconciler.d.ts.map +1 -0
  59. package/dist/engine/rules-reconciler.js +193 -0
  60. package/dist/engine/rules-reconciler.js.map +1 -0
  61. package/dist/engine/skill-generator/detect.d.ts +1 -0
  62. package/dist/engine/skill-generator/detect.d.ts.map +1 -1
  63. package/dist/engine/skill-generator/detect.js +13 -5
  64. package/dist/engine/skill-generator/detect.js.map +1 -1
  65. package/dist/engine/skills/skills-fetcher.d.ts +4 -0
  66. package/dist/engine/skills/skills-fetcher.d.ts.map +1 -0
  67. package/dist/engine/skills/skills-fetcher.js +102 -0
  68. package/dist/engine/skills/skills-fetcher.js.map +1 -0
  69. package/dist/engine/skills-reconciler.d.ts +15 -0
  70. package/dist/engine/skills-reconciler.d.ts.map +1 -0
  71. package/dist/engine/skills-reconciler.js +98 -0
  72. package/dist/engine/skills-reconciler.js.map +1 -0
  73. package/dist/engine/spec-template-cleaner.d.ts +12 -0
  74. package/dist/engine/spec-template-cleaner.d.ts.map +1 -0
  75. package/dist/engine/spec-template-cleaner.js +119 -0
  76. package/dist/engine/spec-template-cleaner.js.map +1 -0
  77. package/dist/engine/validator/analyzer.d.ts +4 -2
  78. package/dist/engine/validator/analyzer.d.ts.map +1 -1
  79. package/dist/engine/validator/analyzer.js +5 -2
  80. package/dist/engine/validator/analyzer.js.map +1 -1
  81. package/dist/engine/validator/deep-code-checker.d.ts +4 -2
  82. package/dist/engine/validator/deep-code-checker.d.ts.map +1 -1
  83. package/dist/engine/validator/deep-code-checker.js +44 -1
  84. package/dist/engine/validator/deep-code-checker.js.map +1 -1
  85. package/dist/engine/validator/extractors.d.ts +8 -1
  86. package/dist/engine/validator/extractors.d.ts.map +1 -1
  87. package/dist/engine/validator/extractors.js +33 -0
  88. package/dist/engine/validator/extractors.js.map +1 -1
  89. package/dist/engine/validator.d.ts.map +1 -1
  90. package/dist/engine/validator.js +13 -2
  91. package/dist/engine/validator.js.map +1 -1
  92. package/dist/engine/workers/schema.d.ts +58 -0
  93. package/dist/engine/workers/schema.d.ts.map +1 -0
  94. package/dist/engine/workers/schema.js +41 -0
  95. package/dist/engine/workers/schema.js.map +1 -0
  96. package/dist/engine/workers/worker-engine.js +1 -1
  97. package/dist/engine/workers/worker-engine.js.map +1 -1
  98. package/dist/index.js +10 -0
  99. package/dist/index.js.map +1 -1
  100. package/dist/storage/convention-baseline.d.ts +20 -0
  101. package/dist/storage/convention-baseline.d.ts.map +1 -0
  102. package/dist/storage/convention-baseline.js +57 -0
  103. package/dist/storage/convention-baseline.js.map +1 -0
  104. package/dist/storage/feedback-remote.d.ts +8 -0
  105. package/dist/storage/feedback-remote.d.ts.map +1 -0
  106. package/dist/storage/feedback-remote.js +27 -0
  107. package/dist/storage/feedback-remote.js.map +1 -0
  108. package/dist/storage/feedback-store.d.ts +27 -0
  109. package/dist/storage/feedback-store.d.ts.map +1 -0
  110. package/dist/storage/feedback-store.js +272 -0
  111. package/dist/storage/feedback-store.js.map +1 -0
  112. package/dist/storage/index.d.ts +1 -0
  113. package/dist/storage/index.d.ts.map +1 -1
  114. package/dist/storage/index.js +1 -0
  115. package/dist/storage/index.js.map +1 -1
  116. package/dist/tools/convention-sync.d.ts +8 -0
  117. package/dist/tools/convention-sync.d.ts.map +1 -0
  118. package/dist/tools/convention-sync.js +77 -0
  119. package/dist/tools/convention-sync.js.map +1 -0
  120. package/dist/tools/create-spec-hu/ac-adapters/convention-adapter.d.ts +9 -0
  121. package/dist/tools/create-spec-hu/ac-adapters/convention-adapter.d.ts.map +1 -0
  122. package/dist/tools/create-spec-hu/ac-adapters/convention-adapter.js +68 -0
  123. package/dist/tools/create-spec-hu/ac-adapters/convention-adapter.js.map +1 -0
  124. package/dist/tools/create-spec-hu/ac-adapters/custom-template-adapter.d.ts +14 -0
  125. package/dist/tools/create-spec-hu/ac-adapters/custom-template-adapter.d.ts.map +1 -0
  126. package/dist/tools/create-spec-hu/ac-adapters/custom-template-adapter.js +60 -0
  127. package/dist/tools/create-spec-hu/ac-adapters/custom-template-adapter.js.map +1 -0
  128. package/dist/tools/create-spec-hu/ac-adapters/index.d.ts +4 -0
  129. package/dist/tools/create-spec-hu/ac-adapters/index.d.ts.map +1 -1
  130. package/dist/tools/create-spec-hu/ac-adapters/index.js +9 -1
  131. package/dist/tools/create-spec-hu/ac-adapters/index.js.map +1 -1
  132. package/dist/tools/create-spec.d.ts.map +1 -1
  133. package/dist/tools/create-spec.js +3 -2
  134. package/dist/tools/create-spec.js.map +1 -1
  135. package/dist/tools/delete-decision.d.ts.map +1 -1
  136. package/dist/tools/delete-decision.js +2 -0
  137. package/dist/tools/delete-decision.js.map +1 -1
  138. package/dist/tools/delete-project.d.ts.map +1 -1
  139. package/dist/tools/delete-project.js +11 -14
  140. package/dist/tools/delete-project.js.map +1 -1
  141. package/dist/tools/delete-spec.d.ts.map +1 -1
  142. package/dist/tools/delete-spec.js +11 -9
  143. package/dist/tools/delete-spec.js.map +1 -1
  144. package/dist/tools/estimate.d.ts.map +1 -1
  145. package/dist/tools/estimate.js +6 -5
  146. package/dist/tools/estimate.js.map +1 -1
  147. package/dist/tools/export-session.d.ts.map +1 -1
  148. package/dist/tools/export-session.js +7 -9
  149. package/dist/tools/export-session.js.map +1 -1
  150. package/dist/tools/feedback-handler.d.ts +5 -0
  151. package/dist/tools/feedback-handler.d.ts.map +1 -0
  152. package/dist/tools/feedback-handler.js +106 -0
  153. package/dist/tools/feedback-handler.js.map +1 -0
  154. package/dist/tools/generate-teammate-prompt.d.ts +8 -0
  155. package/dist/tools/generate-teammate-prompt.d.ts.map +1 -1
  156. package/dist/tools/generate-teammate-prompt.js +33 -0
  157. package/dist/tools/generate-teammate-prompt.js.map +1 -1
  158. package/dist/tools/init-project/handler.d.ts.map +1 -1
  159. package/dist/tools/init-project/handler.js +42 -7
  160. package/dist/tools/init-project/handler.js.map +1 -1
  161. package/dist/tools/init-project/helpers.d.ts.map +1 -1
  162. package/dist/tools/init-project/helpers.js +1 -2
  163. package/dist/tools/init-project/helpers.js.map +1 -1
  164. package/dist/tools/init-project/result-builder.d.ts.map +1 -1
  165. package/dist/tools/init-project/result-builder.js +12 -1
  166. package/dist/tools/init-project/result-builder.js.map +1 -1
  167. package/dist/tools/log-decision.d.ts.map +1 -1
  168. package/dist/tools/log-decision.js +15 -4
  169. package/dist/tools/log-decision.js.map +1 -1
  170. package/dist/tools/manage-trash.d.ts.map +1 -1
  171. package/dist/tools/manage-trash.js +13 -27
  172. package/dist/tools/manage-trash.js.map +1 -1
  173. package/dist/tools/reconcile-hooks.d.ts +7 -0
  174. package/dist/tools/reconcile-hooks.d.ts.map +1 -0
  175. package/dist/tools/reconcile-hooks.js +78 -0
  176. package/dist/tools/reconcile-hooks.js.map +1 -0
  177. package/dist/tools/reconcile-rules.d.ts +7 -0
  178. package/dist/tools/reconcile-rules.d.ts.map +1 -0
  179. package/dist/tools/reconcile-rules.js +86 -0
  180. package/dist/tools/reconcile-rules.js.map +1 -0
  181. package/dist/tools/reconcile-skills.d.ts +8 -0
  182. package/dist/tools/reconcile-skills.d.ts.map +1 -0
  183. package/dist/tools/reconcile-skills.js +70 -0
  184. package/dist/tools/reconcile-skills.js.map +1 -0
  185. package/dist/tools/register-feedback-tools.d.ts +3 -0
  186. package/dist/tools/register-feedback-tools.d.ts.map +1 -0
  187. package/dist/tools/register-feedback-tools.js +65 -0
  188. package/dist/tools/register-feedback-tools.js.map +1 -0
  189. package/dist/tools/register-spec-tools/core-spec-tools.d.ts.map +1 -1
  190. package/dist/tools/register-spec-tools/core-spec-tools.js +10 -4
  191. package/dist/tools/register-spec-tools/core-spec-tools.js.map +1 -1
  192. package/dist/tools/register-team-tools.d.ts.map +1 -1
  193. package/dist/tools/register-team-tools.js +35 -8
  194. package/dist/tools/register-team-tools.js.map +1 -1
  195. package/dist/tools/safe-handler.d.ts.map +1 -1
  196. package/dist/tools/safe-handler.js +20 -2
  197. package/dist/tools/safe-handler.js.map +1 -1
  198. package/dist/tools/schemas/index.d.ts +1 -0
  199. package/dist/tools/schemas/index.d.ts.map +1 -1
  200. package/dist/tools/schemas/index.js +1 -0
  201. package/dist/tools/schemas/index.js.map +1 -1
  202. package/dist/tools/schemas/reconcile-skills-schemas.d.ts +7 -0
  203. package/dist/tools/schemas/reconcile-skills-schemas.d.ts.map +1 -0
  204. package/dist/tools/schemas/reconcile-skills-schemas.js +18 -0
  205. package/dist/tools/schemas/reconcile-skills-schemas.js.map +1 -0
  206. package/dist/tools/schemas/workers-schema.d.ts +1 -56
  207. package/dist/tools/schemas/workers-schema.d.ts.map +1 -1
  208. package/dist/tools/schemas/workers-schema.js +6 -42
  209. package/dist/tools/schemas/workers-schema.js.map +1 -1
  210. package/dist/tools/skill-registry/search.d.ts.map +1 -1
  211. package/dist/tools/skill-registry/search.js +29 -3
  212. package/dist/tools/skill-registry/search.js.map +1 -1
  213. package/dist/tools/suggest-tooling/skills-fetcher.d.ts +1 -3
  214. package/dist/tools/suggest-tooling/skills-fetcher.d.ts.map +1 -1
  215. package/dist/tools/suggest-tooling/skills-fetcher.js +3 -101
  216. package/dist/tools/suggest-tooling/skills-fetcher.js.map +1 -1
  217. package/dist/tools/token-recording.d.ts +16 -0
  218. package/dist/tools/token-recording.d.ts.map +1 -0
  219. package/dist/tools/token-recording.js +47 -0
  220. package/dist/tools/token-recording.js.map +1 -0
  221. package/dist/tools/update-status-convention-gate.d.ts +12 -0
  222. package/dist/tools/update-status-convention-gate.d.ts.map +1 -0
  223. package/dist/tools/update-status-convention-gate.js +159 -0
  224. package/dist/tools/update-status-convention-gate.js.map +1 -0
  225. package/dist/tools/update-status-reconcile.d.ts +7 -0
  226. package/dist/tools/update-status-reconcile.d.ts.map +1 -0
  227. package/dist/tools/update-status-reconcile.js +47 -0
  228. package/dist/tools/update-status-reconcile.js.map +1 -0
  229. package/dist/tools/update-status.d.ts.map +1 -1
  230. package/dist/tools/update-status.js +113 -67
  231. package/dist/tools/update-status.js.map +1 -1
  232. package/dist/tools/validate.d.ts.map +1 -1
  233. package/dist/tools/validate.js +92 -2
  234. package/dist/tools/validate.js.map +1 -1
  235. package/dist/types/ai-tool-rules.d.ts +42 -0
  236. package/dist/types/ai-tool-rules.d.ts.map +1 -0
  237. package/dist/types/ai-tool-rules.js +3 -0
  238. package/dist/types/ai-tool-rules.js.map +1 -0
  239. package/dist/types/conventions.d.ts +155 -0
  240. package/dist/types/conventions.d.ts.map +1 -0
  241. package/dist/types/conventions.js +3 -0
  242. package/dist/types/conventions.js.map +1 -0
  243. package/dist/types/feedback.d.ts +76 -0
  244. package/dist/types/feedback.d.ts.map +1 -0
  245. package/dist/types/feedback.js +3 -0
  246. package/dist/types/feedback.js.map +1 -0
  247. package/dist/types/index.d.ts +3 -0
  248. package/dist/types/index.d.ts.map +1 -1
  249. package/dist/types/index.js +1 -0
  250. package/dist/types/index.js.map +1 -1
  251. package/dist/types/project/planu-config.d.ts +4 -0
  252. package/dist/types/project/planu-config.d.ts.map +1 -1
  253. package/package.json +1 -1
  254. package/src/config/license-plans.json +9 -2
  255. package/src/config/tool-groups.json +5 -1
@@ -0,0 +1,156 @@
1
+ // engine/convention-sync.ts — Convention sync health calculator.
2
+ // Combines rules, skills, hooks and convention scanner scores into a single
3
+ // weighted percentage showing how well the project enforces its own conventions.
4
+ import { reconcileRules } from './rules-reconciler.js';
5
+ import { reconcileSkills } from './skills-reconciler.js';
6
+ import { reconcileHooks } from './hooks-reconciler.js';
7
+ import { parseConventions, scanConventions } from './convention-scanner/index.js';
8
+ // ---------------------------------------------------------------------------
9
+ // Weights (must sum to 1.0)
10
+ // ---------------------------------------------------------------------------
11
+ const WEIGHT_RULES = 0.25;
12
+ const WEIGHT_SKILLS = 0.25;
13
+ const WEIGHT_HOOKS = 0.25;
14
+ const WEIGHT_CONVENTIONS = 0.25;
15
+ // Violation count that maps to 0 conventionHealth (linear scale).
16
+ const MAX_VIOLATIONS_FOR_ZERO = 40;
17
+ // ---------------------------------------------------------------------------
18
+ // Convention health score
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Derive a 0–100 score from raw violation count.
22
+ * 0 violations → 100; MAX_VIOLATIONS_FOR_ZERO+ violations → 0.
23
+ */
24
+ function conventionScoreFromViolations(violationCount) {
25
+ if (violationCount <= 0) {
26
+ return 100;
27
+ }
28
+ const ratio = Math.min(violationCount / MAX_VIOLATIONS_FOR_ZERO, 1);
29
+ return Math.max(0, Math.round((1 - ratio) * 100));
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // Recommendations
33
+ // ---------------------------------------------------------------------------
34
+ function buildAreaSuggestions(rulesHealth, skillsHealth, hooksHealth, conventionHealth) {
35
+ const areas = [
36
+ {
37
+ label: 'rules',
38
+ score: rulesHealth,
39
+ suggestions: [
40
+ 'Run reconcile_rules to auto-generate missing .claude/rules/ files.',
41
+ 'Review stale rules files and remove or update them.',
42
+ ],
43
+ },
44
+ {
45
+ label: 'skills',
46
+ score: skillsHealth,
47
+ suggestions: [
48
+ 'Run reconcile_skills to identify skills your stack recommends.',
49
+ 'Install missing skills with skill_install or remove stale ones.',
50
+ ],
51
+ },
52
+ {
53
+ label: 'hooks',
54
+ score: hooksHealth,
55
+ suggestions: [
56
+ 'Run reconcile_hooks to find missing git hook steps.',
57
+ 'Run configure_hooks to add typecheck, lint, or test steps to hooks.',
58
+ ],
59
+ },
60
+ {
61
+ label: 'conventions',
62
+ score: conventionHealth,
63
+ suggestions: [
64
+ 'Run scan_project to get a detailed list of convention violations.',
65
+ 'Fix critical violations first (architecture imports, naming rules).',
66
+ ],
67
+ },
68
+ ];
69
+ // Sort by ascending score so lowest-scoring areas come first.
70
+ return areas.sort((a, b) => a.score - b.score);
71
+ }
72
+ function pickTopRecommendations(areas, maxItems) {
73
+ const recs = [];
74
+ for (const area of areas) {
75
+ if (area.score < 100) {
76
+ for (const s of area.suggestions) {
77
+ if (recs.length < maxItems) {
78
+ recs.push(s);
79
+ }
80
+ }
81
+ }
82
+ if (recs.length >= maxItems) {
83
+ break;
84
+ }
85
+ }
86
+ return recs;
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Summary string
90
+ // ---------------------------------------------------------------------------
91
+ function buildSummary(overallScore, worstArea) {
92
+ const grade = overallScore >= 90
93
+ ? 'Excellent'
94
+ : overallScore >= 75
95
+ ? 'Good'
96
+ : overallScore >= 50
97
+ ? 'Fair'
98
+ : 'Poor';
99
+ if (!worstArea || overallScore >= 90) {
100
+ return `${grade} (${overallScore}/100) — conventions and enforcement mechanisms are in sync.`;
101
+ }
102
+ return `${grade} (${overallScore}/100) — worst area: ${worstArea.label} (${worstArea.score}/100). Focus here first.`;
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Public API
106
+ // ---------------------------------------------------------------------------
107
+ /**
108
+ * Calculate overall convention sync health by running all four reconcilers
109
+ * in parallel and combining their scores with equal 25% weights.
110
+ *
111
+ * Never throws — returns zero scores on unexpected errors.
112
+ */
113
+ export async function calculateConventionSync(projectPath, knowledge) {
114
+ try {
115
+ const [rulesResult, skillsResult, hooksResult] = await Promise.all([
116
+ Promise.resolve(reconcileRules(projectPath)),
117
+ reconcileSkills(projectPath, knowledge),
118
+ Promise.resolve(reconcileHooks(projectPath)),
119
+ ]);
120
+ const rules = parseConventions(projectPath);
121
+ const violations = scanConventions(projectPath, rules);
122
+ const rulesHealth = rulesResult.healthScore;
123
+ const skillsHealth = skillsResult.healthScore;
124
+ const hooksHealth = hooksResult.healthScore;
125
+ const conventionHealth = conventionScoreFromViolations(violations.length);
126
+ const overallScore = Math.round(rulesHealth * WEIGHT_RULES +
127
+ skillsHealth * WEIGHT_SKILLS +
128
+ hooksHealth * WEIGHT_HOOKS +
129
+ conventionHealth * WEIGHT_CONVENTIONS);
130
+ const areas = buildAreaSuggestions(rulesHealth, skillsHealth, hooksHealth, conventionHealth);
131
+ const worstArea = areas[0];
132
+ const summary = buildSummary(overallScore, worstArea);
133
+ const recommendations = pickTopRecommendations(areas, 4);
134
+ return {
135
+ overallScore,
136
+ rulesHealth,
137
+ skillsHealth,
138
+ hooksHealth,
139
+ conventionHealth,
140
+ summary,
141
+ recommendations,
142
+ };
143
+ }
144
+ catch {
145
+ return {
146
+ overallScore: 0,
147
+ rulesHealth: 0,
148
+ skillsHealth: 0,
149
+ hooksHealth: 0,
150
+ conventionHealth: 0,
151
+ summary: 'Error: could not calculate convention sync health.',
152
+ recommendations: ['Ensure the project has been initialised with init_project.'],
153
+ };
154
+ }
155
+ }
156
+ //# sourceMappingURL=convention-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convention-sync.js","sourceRoot":"","sources":["../../src/engine/convention-sync.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,12 @@
1
1
  import type { StoreType } from '../../../types/portal.js';
2
2
  /**
3
3
  * Schedule a debounced regeneration (500 ms window).
4
- * Multiple calls within the window are coalesced.
4
+ * Multiple calls within the window are coalesced per project.
5
5
  */
6
6
  export declare function scheduleRegeneration(projectPath: string, changedStores: StoreType[]): void;
7
7
  /**
8
8
  * Immediately regenerate all portal pages affected by the given store changes.
9
+ * Creates planu/ directory if it does not exist.
9
10
  * Returns the list of page keys that were successfully written.
10
11
  * Never throws.
11
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"portal-regenerator.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/portal/portal-regenerator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAOtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,IAAI,CAiB1F;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,EAAE,GACzB,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBnB"}
1
+ {"version":3,"file":"portal-regenerator.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/portal/portal-regenerator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAOtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,IAAI,CAuB1F;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,EAAE,GACzB,OAAO,CAAC,MAAM,EAAE,CAAC,CA0BnB"}
@@ -1,40 +1,48 @@
1
1
  // Planu — Portal regenerator: auto-regen pages when stores change (SPEC-146)
2
- import { existsSync } from 'node:fs';
3
- import { writeFile } from 'node:fs/promises';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
4
3
  import { join } from 'node:path';
5
4
  import { hashProjectPath } from '../../../storage/base-store.js';
6
5
  import { getAffectedPages } from './dirty-flag-map.js';
7
- // Debounce state (module-level, intentionally mutable)
8
- let debounceTimer = null;
9
- const pendingStores = new Set();
6
+ // Debounce state keyed by projectPath to avoid cross-project interference
7
+ const debounceTimers = new Map();
8
+ const pendingStoresPerProject = new Map();
10
9
  /**
11
10
  * Schedule a debounced regeneration (500 ms window).
12
- * Multiple calls within the window are coalesced.
11
+ * Multiple calls within the window are coalesced per project.
13
12
  */
14
13
  export function scheduleRegeneration(projectPath, changedStores) {
14
+ const pending = pendingStoresPerProject.get(projectPath) ?? new Set();
15
15
  for (const s of changedStores) {
16
- pendingStores.add(s);
16
+ pending.add(s);
17
17
  }
18
- if (debounceTimer) {
19
- clearTimeout(debounceTimer);
18
+ pendingStoresPerProject.set(projectPath, pending);
19
+ const existing = debounceTimers.get(projectPath);
20
+ if (existing) {
21
+ clearTimeout(existing);
20
22
  }
21
- debounceTimer = setTimeout(() => {
22
- const stores = [...pendingStores];
23
- pendingStores.clear();
24
- debounceTimer = null;
23
+ const timer = setTimeout(() => {
24
+ const stores = [...pending];
25
+ pendingStoresPerProject.delete(projectPath);
26
+ debounceTimers.delete(projectPath);
25
27
  regeneratePages(projectPath, stores).catch((err) => {
26
- console.error('[Planu] Portal regeneration failed:', err);
28
+ const message = err instanceof Error ? err.message : String(err);
29
+ console.error('[Planu] Portal regeneration failed for', projectPath, ':', message);
27
30
  });
28
31
  }, 500);
32
+ debounceTimers.set(projectPath, timer);
29
33
  }
30
34
  /**
31
35
  * Immediately regenerate all portal pages affected by the given store changes.
36
+ * Creates planu/ directory if it does not exist.
32
37
  * Returns the list of page keys that were successfully written.
33
38
  * Never throws.
34
39
  */
35
40
  export async function regeneratePages(projectPath, changedStores) {
36
41
  const planuDir = join(projectPath, 'planu');
37
- if (!existsSync(planuDir)) {
42
+ try {
43
+ await mkdir(planuDir, { recursive: true });
44
+ }
45
+ catch {
38
46
  return [];
39
47
  }
40
48
  const pages = getAffectedPages(changedStores);
@@ -1 +1 @@
1
- {"version":3,"file":"portal-regenerator.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/portal/portal-regenerator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"portal-regenerator.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/portal/portal-regenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { FeedbackEntry, TriageGroup } from '../../types/index.js';
2
+ /**
3
+ * Compute a similarity score between two strings using Jaccard index on word sets.
4
+ * Stop words are excluded. Returns a value in [0, 1].
5
+ */
6
+ export declare function similarityScore(a: string, b: string): number;
7
+ /**
8
+ * Group similar pending feedback entries into triage groups.
9
+ * Two entries are grouped if their title similarity exceeds the threshold (default 0.5).
10
+ */
11
+ export declare function triageFeedback(entries: FeedbackEntry[], threshold?: number): TriageGroup[];
12
+ /**
13
+ * Format a list of triage groups as a markdown report.
14
+ */
15
+ export declare function formatTriageReport(groups: TriageGroup[]): string;
16
+ //# sourceMappingURL=triage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../../src/engine/feedback/triage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA+CnE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAc5D;AAgBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,SAAS,SAAM,GAAG,WAAW,EAAE,CAoCvF;AAoCD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CA2ChE"}
@@ -0,0 +1,165 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Stop words excluded from similarity calculation
3
+ // ---------------------------------------------------------------------------
4
+ const STOP_WORDS = new Set([
5
+ 'the',
6
+ 'a',
7
+ 'an',
8
+ 'is',
9
+ 'are',
10
+ 'was',
11
+ 'were',
12
+ 'it',
13
+ 'its',
14
+ 'in',
15
+ 'on',
16
+ 'at',
17
+ 'to',
18
+ 'for',
19
+ 'of',
20
+ 'and',
21
+ 'or',
22
+ 'but',
23
+ 'not',
24
+ 'with',
25
+ 'this',
26
+ 'that',
27
+ 'i',
28
+ 'we',
29
+ 'my',
30
+ 'our',
31
+ 'does',
32
+ 'do',
33
+ 'can',
34
+ 'cannot',
35
+ 'could',
36
+ 'should',
37
+ 'when',
38
+ 'if',
39
+ ]);
40
+ // ---------------------------------------------------------------------------
41
+ // Public: Similarity score (Jaccard word overlap)
42
+ // ---------------------------------------------------------------------------
43
+ /**
44
+ * Compute a similarity score between two strings using Jaccard index on word sets.
45
+ * Stop words are excluded. Returns a value in [0, 1].
46
+ */
47
+ export function similarityScore(a, b) {
48
+ const tokensA = tokenize(a);
49
+ const tokensB = tokenize(b);
50
+ if (tokensA.size === 0 && tokensB.size === 0) {
51
+ return 1;
52
+ }
53
+ if (tokensA.size === 0 || tokensB.size === 0) {
54
+ return 0;
55
+ }
56
+ const intersection = [...tokensA].filter((w) => tokensB.has(w)).length;
57
+ const union = new Set([...tokensA, ...tokensB]).size;
58
+ return union === 0 ? 0 : intersection / union;
59
+ }
60
+ function tokenize(text) {
61
+ return new Set(text
62
+ .toLowerCase()
63
+ .replace(/[^a-z0-9\s]/g, ' ')
64
+ .split(/\s+/)
65
+ .filter((w) => w.length > 1 && !STOP_WORDS.has(w)));
66
+ }
67
+ // ---------------------------------------------------------------------------
68
+ // Public: Group pending feedback by similarity
69
+ // ---------------------------------------------------------------------------
70
+ /**
71
+ * Group similar pending feedback entries into triage groups.
72
+ * Two entries are grouped if their title similarity exceeds the threshold (default 0.5).
73
+ */
74
+ export function triageFeedback(entries, threshold = 0.5) {
75
+ const pending = entries.filter((e) => e.status === 'pending');
76
+ const visited = new Set();
77
+ const groups = [];
78
+ for (const entry of pending) {
79
+ if (visited.has(entry.id)) {
80
+ continue;
81
+ }
82
+ visited.add(entry.id);
83
+ const similar = [];
84
+ for (const other of pending) {
85
+ if (visited.has(other.id)) {
86
+ continue;
87
+ }
88
+ if (similarityScore(entry.title, other.title) > threshold) {
89
+ similar.push(other);
90
+ visited.add(other.id);
91
+ }
92
+ }
93
+ const totalCount = 1 + similar.length;
94
+ const suggestedAction = determineSuggestedAction(totalCount, entry);
95
+ const suggestedSpecTitle = suggestedAction !== 'dismiss' ? buildSpecTitle(entry, similar) : undefined;
96
+ groups.push({
97
+ representative: entry,
98
+ similar,
99
+ suggestedAction,
100
+ suggestedSpecTitle,
101
+ });
102
+ }
103
+ return groups;
104
+ }
105
+ function determineSuggestedAction(count, entry) {
106
+ if (count >= 3) {
107
+ return 'create_spec';
108
+ }
109
+ if (count >= 2 || entry.specId) {
110
+ return 'merge_with_existing';
111
+ }
112
+ return 'dismiss';
113
+ }
114
+ function buildSpecTitle(representative, similar) {
115
+ // Use the most-voted entry's title as the base if votes differ
116
+ const all = [representative, ...similar];
117
+ const topVoted = all.reduce((best, e) => ((e.votes ?? 0) > (best.votes ?? 0) ? e : best), representative);
118
+ return topVoted.title;
119
+ }
120
+ // ---------------------------------------------------------------------------
121
+ // Public: Format triage report as markdown
122
+ // ---------------------------------------------------------------------------
123
+ const TYPE_EMOJI = {
124
+ bug: 'Bug',
125
+ feature: 'Feature',
126
+ suggestion: 'Suggestion',
127
+ dx: 'DX',
128
+ };
129
+ /**
130
+ * Format a list of triage groups as a markdown report.
131
+ */
132
+ export function formatTriageReport(groups) {
133
+ if (groups.length === 0) {
134
+ return '# Feedback Triage\n\nNo pending feedback to triage.';
135
+ }
136
+ const priority = groups.filter((g) => g.suggestedAction === 'create_spec' || 1 + g.similar.length >= 3);
137
+ const individual = groups.filter((g) => g.suggestedAction !== 'create_spec' && 1 + g.similar.length < 3);
138
+ const lines = ['# Feedback Triage', ''];
139
+ if (priority.length > 0) {
140
+ lines.push('## Priority Groups (3+ similar)', '');
141
+ for (const group of priority) {
142
+ const total = 1 + group.similar.length;
143
+ const ids = [group.representative.id, ...group.similar.map((s) => s.id)].join(', ');
144
+ lines.push(`### "${group.representative.title}" (${total} reports)`);
145
+ lines.push(`- Reports: ${ids}`);
146
+ if (group.suggestedSpecTitle) {
147
+ lines.push(`- Suggested: Create spec — "${group.suggestedSpecTitle}"`);
148
+ }
149
+ lines.push('');
150
+ }
151
+ }
152
+ if (individual.length > 0) {
153
+ lines.push('## Individual Items', '');
154
+ lines.push('| ID | Type | Title | Action |');
155
+ lines.push('|----|------|-------|--------|');
156
+ for (const group of individual) {
157
+ const e = group.representative;
158
+ const typeLabel = TYPE_EMOJI[e.type] ?? e.type;
159
+ lines.push(`| ${e.id} | ${typeLabel} | ${e.title} | ${group.suggestedAction.replace(/_/g, ' ')} |`);
160
+ }
161
+ lines.push('');
162
+ }
163
+ return lines.join('\n');
164
+ }
165
+ //# sourceMappingURL=triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.js","sourceRoot":"","sources":["../../../src/engine/feedback/triage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { HooksReconciliation } from '../types/index.js';
2
+ /**
3
+ * Analyse git hooks against detected project capabilities and report drift.
4
+ * Never throws — returns a zero-score result on unexpected errors.
5
+ */
6
+ export declare function reconcileHooks(projectPath: string): HooksReconciliation;
7
+ //# sourceMappingURL=hooks-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-reconciler.d.ts","sourceRoot":"","sources":["../../src/engine/hooks-reconciler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,mBAAmB,EAIpB,MAAM,mBAAmB,CAAC;AAyN3B;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CA8CvE"}