continuous-improvement 3.0.0 → 3.8.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 (126) hide show
  1. package/.claude-plugin/marketplace.json +78 -0
  2. package/CHANGELOG.md +210 -0
  3. package/LICENSE +21 -21
  4. package/QUICKSTART.md +101 -81
  5. package/README.md +224 -198
  6. package/SKILL.md +87 -9
  7. package/action.yml +33 -0
  8. package/bin/analyze.sh +161 -153
  9. package/bin/backfill.mjs +172 -0
  10. package/bin/check-docs-substrings.mjs +333 -0
  11. package/bin/check-everything-mirror.mjs +145 -0
  12. package/bin/check-routing-targets.mjs +151 -0
  13. package/bin/check-skill-law-tag.mjs +128 -0
  14. package/bin/check-skill-mirror.mjs +119 -0
  15. package/bin/check-skill-tiers.mjs +116 -0
  16. package/bin/check-third-party-shape.mjs +202 -0
  17. package/bin/generate-plugin-manifests.mjs +169 -0
  18. package/bin/harvest-friction.mjs +279 -0
  19. package/bin/hook-stats.mjs +258 -0
  20. package/bin/install.mjs +418 -456
  21. package/bin/lint-transcript.mjs +239 -0
  22. package/bin/mcp-server.mjs +842 -499
  23. package/bin/observe.mjs +148 -0
  24. package/bin/pre-commit-block-strays.sh +49 -0
  25. package/bin/refresh-third-party.mjs +416 -0
  26. package/bin/unified-cli.mjs +533 -0
  27. package/commands/continuous-improvement.md +115 -74
  28. package/commands/dashboard.md +56 -0
  29. package/commands/discipline.md +51 -0
  30. package/commands/harvest.md +76 -0
  31. package/commands/learn-eval.md +117 -0
  32. package/commands/planning-with-files.md +66 -0
  33. package/commands/proceed-with-the-recommendation.md +62 -0
  34. package/commands/ralph.md +103 -0
  35. package/commands/release-train.md +81 -0
  36. package/commands/seven-laws.md +16 -0
  37. package/commands/superpowers.md +153 -0
  38. package/commands/swarm.md +101 -0
  39. package/commands/workspace-surface-audit.md +77 -0
  40. package/hooks/observe.sh +172 -134
  41. package/hooks/session.sh +106 -106
  42. package/hooks/three-section-close.mjs +181 -0
  43. package/instinct-packs/go.json +58 -0
  44. package/instinct-packs/meta.json +16 -0
  45. package/instinct-packs/python.json +58 -0
  46. package/instinct-packs/react.json +58 -0
  47. package/lib/cli-anything.mjs +401 -0
  48. package/lib/compound-engineering.mjs +831 -0
  49. package/lib/observe-event.mjs +128 -0
  50. package/lib/plugin-metadata.mjs +432 -0
  51. package/lib/pm-marketplace.mjs +61 -0
  52. package/lib/pm-skills.mjs +1274 -0
  53. package/lib/resolve-home-dir.mjs +43 -0
  54. package/lib/skill-tiers.mjs +137 -0
  55. package/lib/unified-plugin.mjs +924 -0
  56. package/llms.txt +68 -0
  57. package/package.json +38 -15
  58. package/plugins/beginner.json +17 -6
  59. package/plugins/continuous-improvement/.claude-plugin/marketplace.json +20 -0
  60. package/plugins/continuous-improvement/.claude-plugin/plugin.json +26 -0
  61. package/plugins/continuous-improvement/LICENSE +21 -0
  62. package/plugins/continuous-improvement/README.md +56 -0
  63. package/plugins/continuous-improvement/bin/backfill.mjs +172 -0
  64. package/plugins/continuous-improvement/bin/mcp-server.mjs +886 -0
  65. package/plugins/continuous-improvement/bin/observe.mjs +148 -0
  66. package/plugins/continuous-improvement/commands/continuous-improvement.md +115 -0
  67. package/plugins/continuous-improvement/commands/dashboard.md +56 -0
  68. package/plugins/continuous-improvement/commands/discipline.md +51 -0
  69. package/plugins/continuous-improvement/commands/harvest.md +76 -0
  70. package/plugins/continuous-improvement/commands/learn-eval.md +117 -0
  71. package/plugins/continuous-improvement/commands/planning-with-files.md +66 -0
  72. package/plugins/continuous-improvement/commands/proceed-with-the-recommendation.md +62 -0
  73. package/plugins/continuous-improvement/commands/ralph.md +103 -0
  74. package/plugins/continuous-improvement/commands/release-train.md +81 -0
  75. package/plugins/continuous-improvement/commands/seven-laws.md +16 -0
  76. package/plugins/continuous-improvement/commands/superpowers.md +153 -0
  77. package/plugins/continuous-improvement/commands/swarm.md +101 -0
  78. package/plugins/continuous-improvement/commands/workspace-surface-audit.md +77 -0
  79. package/plugins/continuous-improvement/hooks/hooks.json +60 -0
  80. package/plugins/continuous-improvement/hooks/observe.sh +172 -0
  81. package/plugins/continuous-improvement/hooks/session.sh +106 -0
  82. package/plugins/continuous-improvement/hooks/three-section-close.mjs +181 -0
  83. package/plugins/continuous-improvement/instinct-packs/go.json +58 -0
  84. package/plugins/continuous-improvement/instinct-packs/meta.json +16 -0
  85. package/plugins/continuous-improvement/instinct-packs/python.json +58 -0
  86. package/plugins/continuous-improvement/instinct-packs/react.json +58 -0
  87. package/plugins/continuous-improvement/lib/observe-event.mjs +128 -0
  88. package/plugins/continuous-improvement/lib/plugin-metadata.mjs +432 -0
  89. package/plugins/continuous-improvement/lib/resolve-home-dir.mjs +43 -0
  90. package/plugins/continuous-improvement/skills/README.md +34 -0
  91. package/plugins/continuous-improvement/skills/continuous-improvement/SKILL.md +249 -0
  92. package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +131 -0
  93. package/plugins/continuous-improvement/skills/gateguard/SKILL.md +155 -0
  94. package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +108 -0
  95. package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +454 -0
  96. package/plugins/continuous-improvement/skills/ralph/SKILL.md +221 -0
  97. package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +76 -0
  98. package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +104 -0
  99. package/plugins/continuous-improvement/skills/superpowers/SKILL.md +212 -0
  100. package/plugins/continuous-improvement/skills/tdd-workflow/SKILL.md +411 -0
  101. package/plugins/continuous-improvement/skills/token-budget-advisor/SKILL.md +136 -0
  102. package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +192 -0
  103. package/plugins/continuous-improvement/skills/wild-risa-balance/SKILL.md +191 -0
  104. package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +147 -0
  105. package/plugins/continuous-improvement/templates/planning-with-files/findings.md +8 -0
  106. package/plugins/continuous-improvement/templates/planning-with-files/progress.md +7 -0
  107. package/plugins/continuous-improvement/templates/planning-with-files/task_plan.md +23 -0
  108. package/plugins/expert.json +34 -5
  109. package/skills/README.md +79 -0
  110. package/skills/deploy-receipt.md +131 -0
  111. package/skills/gateguard.md +155 -0
  112. package/skills/para-memory-files.md +108 -0
  113. package/skills/proceed-with-the-recommendation.md +454 -0
  114. package/skills/ralph.md +221 -0
  115. package/skills/safety-guard.md +76 -0
  116. package/skills/strategic-compact.md +104 -0
  117. package/skills/superpowers.md +212 -0
  118. package/skills/tdd-workflow.md +411 -0
  119. package/skills/token-budget-advisor.md +136 -0
  120. package/skills/verification-loop.md +192 -0
  121. package/skills/wild-risa-balance.md +191 -0
  122. package/skills/workspace-surface-audit.md +147 -0
  123. package/templates/planning-with-files/findings.md +8 -0
  124. package/templates/planning-with-files/progress.md +7 -0
  125. package/templates/planning-with-files/task_plan.md +23 -0
  126. package/templates/verify-ladder.example.json +47 -0
@@ -0,0 +1,924 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Unified Continuous-Improvement Plugin.
4
+ *
5
+ * Combines CLI-Anything, Compound Engineering, and PM-Skills into a single
6
+ * workflow that follows the 7 Laws of AI Agent Discipline.
7
+ */
8
+ import { mkdir, writeFile } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ import CLIAnything from "./cli-anything.mjs";
11
+ import CompoundEngineering from "./compound-engineering.mjs";
12
+ import PMSkills from "./pm-skills.mjs";
13
+ const DEFAULT_OPTIONS = {
14
+ workspace: "./ci-workspace",
15
+ verbose: false,
16
+ };
17
+ function getErrorMessage(error) {
18
+ return error instanceof Error ? error.message : String(error);
19
+ }
20
+ function clamp(value, min, max) {
21
+ return Math.max(min, Math.min(max, value));
22
+ }
23
+ function roundTo(value, decimals = 2) {
24
+ const factor = 10 ** decimals;
25
+ return Math.round(value * factor) / factor;
26
+ }
27
+ function parseMinutes(value) {
28
+ if (!value) {
29
+ return 0;
30
+ }
31
+ const normalized = value.toLowerCase();
32
+ const hourMatch = normalized.match(/(\d+)\s*hour/);
33
+ if (hourMatch) {
34
+ return Number.parseInt(hourMatch[1] ?? "0", 10) * 60;
35
+ }
36
+ const minuteMatch = normalized.match(/(\d+)\s*minute/);
37
+ if (minuteMatch) {
38
+ return Number.parseInt(minuteMatch[1] ?? "0", 10);
39
+ }
40
+ return 0;
41
+ }
42
+ function formatMinutes(totalMinutes) {
43
+ const minutes = Math.max(0, Math.round(totalMinutes));
44
+ const hours = Math.floor(minutes / 60);
45
+ const remainingMinutes = minutes % 60;
46
+ if (hours === 0) {
47
+ return `${minutes} minutes`;
48
+ }
49
+ if (remainingMinutes === 0) {
50
+ return hours === 1 ? "1 hour" : `${hours} hours`;
51
+ }
52
+ return `${hours}h ${remainingMinutes}m`;
53
+ }
54
+ export default class UnifiedContinuousImprovement {
55
+ options;
56
+ cliAnything;
57
+ compoundEngineering;
58
+ pmSkills;
59
+ currentSession = null;
60
+ projectContext = {};
61
+ constructor(options = {}) {
62
+ this.options = { ...DEFAULT_OPTIONS, ...options };
63
+ this.cliAnything = new CLIAnything({
64
+ outputDir: join(this.options.workspace, "generated-clis"),
65
+ verbose: this.options.verbose,
66
+ });
67
+ this.compoundEngineering = new CompoundEngineering({
68
+ workspace: join(this.options.workspace, "compound"),
69
+ learningsPath: join(this.options.workspace, "learnings.json"),
70
+ verbose: this.options.verbose,
71
+ });
72
+ this.pmSkills = new PMSkills({
73
+ workspace: join(this.options.workspace, "pm-skills"),
74
+ verbose: this.options.verbose,
75
+ });
76
+ }
77
+ async initializeProject(projectInfo) {
78
+ this.log(`🚀 Initializing project: ${projectInfo.name}`);
79
+ await this.ensureWorkspace();
80
+ const context = {
81
+ ...projectInfo,
82
+ initializedAt: new Date().toISOString(),
83
+ phases: {
84
+ research: { status: "pending", startedAt: null },
85
+ planning: { status: "pending", startedAt: null },
86
+ execution: { status: "pending", startedAt: null },
87
+ review: { status: "pending", startedAt: null },
88
+ },
89
+ };
90
+ this.projectContext = context;
91
+ this.log(`📊 Running initial product analysis...`);
92
+ const pmAnalysis = await this.pmSkills.runProductAnalysis({
93
+ product: projectInfo.product ?? {},
94
+ industry: projectInfo.industry ?? "",
95
+ targetMarket: projectInfo.targetMarket ?? {},
96
+ });
97
+ context.pmAnalysis = pmAnalysis;
98
+ this.log(`🔧 Starting compound engineering session...`);
99
+ this.currentSession = await this.compoundEngineering.startSession(projectInfo.name, projectInfo.objective ?? "Build and improve the product");
100
+ context.sessionId = this.currentSession.id;
101
+ await this.saveProjectContext();
102
+ this.log(`✅ Project initialized successfully`);
103
+ return {
104
+ projectId: context.name,
105
+ sessionId: this.currentSession.id,
106
+ pmAnalysis: pmAnalysis.summary,
107
+ nextSteps: this.getNextSteps("research"),
108
+ };
109
+ }
110
+ async executeResearchPhase(additionalContext = {}) {
111
+ const context = this.requireContext();
112
+ if (!this.currentSession) {
113
+ throw new Error("No active session. Call initializeProject() first.");
114
+ }
115
+ this.log(`🔍 Starting research phase...`);
116
+ context.phases.research.status = "active";
117
+ context.phases.research.startedAt = new Date().toISOString();
118
+ const pmAnalysis = context.pmAnalysis;
119
+ const brainstormResults = await this.compoundEngineering.brainstorm({
120
+ ...(pmAnalysis ?? {}),
121
+ ...additionalContext,
122
+ });
123
+ const keyInsights = this.extractKeyInsights(pmAnalysis);
124
+ let cliGeneration = null;
125
+ if (typeof additionalContext.repositoryPath === "string") {
126
+ this.log(`🛠️ Generating CLI for repository...`);
127
+ try {
128
+ cliGeneration = await this.cliAnything.generateCLI(additionalContext.repositoryPath);
129
+ }
130
+ catch {
131
+ cliGeneration = null;
132
+ }
133
+ }
134
+ const researchResults = {
135
+ brainstorm: brainstormResults,
136
+ pmInsights: keyInsights,
137
+ cliTools: cliGeneration,
138
+ recommendations: this.generateResearchRecommendations(brainstormResults, keyInsights),
139
+ completedAt: new Date().toISOString(),
140
+ };
141
+ context.researchResults = researchResults;
142
+ context.phases.research.status = "completed";
143
+ await this.saveProjectContext();
144
+ this.log(`✅ Research phase completed`);
145
+ return { ...researchResults, nextSteps: this.getNextSteps("planning") };
146
+ }
147
+ async executePlanningPhase(preferences = {}) {
148
+ const context = this.requireContext();
149
+ if (!this.currentSession || !context.researchResults) {
150
+ throw new Error("Research phase must be completed first.");
151
+ }
152
+ this.log(`📋 Starting planning phase...`);
153
+ context.phases.planning.status = "active";
154
+ context.phases.planning.startedAt = new Date().toISOString();
155
+ const plan = await this.compoundEngineering.plan(context.researchResults.brainstorm, {
156
+ ...preferences,
157
+ pmInsights: context.researchResults.pmInsights,
158
+ availableTools: context.researchResults.cliTools,
159
+ });
160
+ const pmResults = context.pmAnalysis?.results ?? {};
161
+ const gtmSkill = pmResults.gtmStrategy;
162
+ const roadmapSkill = pmResults.productRoadmap;
163
+ const metricsSkill = pmResults.metricsDefinition;
164
+ const gtmStrategy = gtmSkill && !("error" in gtmSkill) ? gtmSkill : null;
165
+ const roadmap = roadmapSkill && !("error" in roadmapSkill) ? roadmapSkill : null;
166
+ const metrics = metricsSkill && !("error" in metricsSkill)
167
+ ? metricsSkill
168
+ : undefined;
169
+ const planningResults = {
170
+ corePlan: plan,
171
+ gtmStrategy,
172
+ roadmap,
173
+ metrics,
174
+ integratedTimeline: this.createIntegratedTimeline(plan, gtmStrategy, roadmap),
175
+ risks: this.aggregateRisks(plan, gtmStrategy, roadmap),
176
+ completedAt: new Date().toISOString(),
177
+ };
178
+ context.planningResults = planningResults;
179
+ context.phases.planning.status = "completed";
180
+ await this.saveProjectContext();
181
+ this.log(`✅ Planning phase completed`);
182
+ return { ...planningResults, nextSteps: this.getNextSteps("execution") };
183
+ }
184
+ async executeWorkingPhase(progressCallback = null) {
185
+ const context = this.requireContext();
186
+ if (!this.currentSession || !context.planningResults) {
187
+ throw new Error("Planning phase must be completed first.");
188
+ }
189
+ this.log(`🔧 Starting execution phase...`);
190
+ context.phases.execution.status = "active";
191
+ context.phases.execution.startedAt = new Date().toISOString();
192
+ const workResults = await this.compoundEngineering.work(context.planningResults.corePlan, progressCallback);
193
+ let toolExecution = null;
194
+ if (context.researchResults?.cliTools) {
195
+ toolExecution = this.executeGeneratedTools(context.researchResults.cliTools, workResults);
196
+ }
197
+ const executionResults = {
198
+ coreWork: workResults,
199
+ toolExecution,
200
+ metrics: this.trackExecutionMetrics(workResults),
201
+ issues: workResults.issues,
202
+ solutions: workResults.solutions,
203
+ completedAt: new Date().toISOString(),
204
+ };
205
+ context.executionResults = executionResults;
206
+ context.phases.execution.status = "completed";
207
+ await this.saveProjectContext();
208
+ this.log(`✅ Execution phase completed`);
209
+ return { ...executionResults, nextSteps: this.getNextSteps("review") };
210
+ }
211
+ async executeReviewPhase(criteria = null) {
212
+ const context = this.requireContext();
213
+ if (!this.currentSession || !context.executionResults) {
214
+ throw new Error("Execution phase must be completed first.");
215
+ }
216
+ this.log(`🔍 Starting review phase...`);
217
+ context.phases.review.status = "active";
218
+ context.phases.review.startedAt = new Date().toISOString();
219
+ const coreReview = await this.compoundEngineering.review(context.executionResults.coreWork, criteria);
220
+ const performanceReview = this.conductPerformanceReview(context.executionResults, context.planningResults?.metrics);
221
+ const processImprovements = this.analyzeProcessImprovements();
222
+ const comprehensiveReport = this.generateComprehensiveReport();
223
+ const reviewResults = {
224
+ coreReview,
225
+ performanceReview,
226
+ processImprovements,
227
+ comprehensiveReport,
228
+ learnings: coreReview.learnings,
229
+ recommendations: this.aggregateRecommendations(coreReview, performanceReview, processImprovements),
230
+ completedAt: new Date().toISOString(),
231
+ };
232
+ context.reviewResults = reviewResults;
233
+ context.phases.review.status = "completed";
234
+ context.completedAt = new Date().toISOString();
235
+ await this.saveProjectContext();
236
+ this.log(`✅ Review phase completed`);
237
+ return reviewResults;
238
+ }
239
+ async executeCompleteWorkflow(projectInfo, options = {}) {
240
+ this.log(`🚀 Starting complete continuous improvement workflow...`);
241
+ const init = await this.initializeProject(projectInfo);
242
+ const research = await this.executeResearchPhase(options.researchContext ?? {});
243
+ const planning = await this.executePlanningPhase(options.planningPreferences ?? {});
244
+ const execution = await this.executeWorkingPhase(options.progressCallback ?? null);
245
+ const review = await this.executeReviewPhase(options.reviewCriteria);
246
+ const sessionId = this.currentSession?.id ?? "";
247
+ this.log(`🎉 Complete workflow finished successfully`);
248
+ return {
249
+ project: projectInfo.name,
250
+ sessionId,
251
+ phases: {
252
+ initialization: init,
253
+ research,
254
+ planning,
255
+ execution,
256
+ review,
257
+ },
258
+ summary: this.generateWorkflowSummary(),
259
+ completedAt: new Date().toISOString(),
260
+ };
261
+ }
262
+ async getProjectStatus() {
263
+ const context = this.projectContext;
264
+ if (!context.name) {
265
+ return { status: "No active project" };
266
+ }
267
+ return {
268
+ project: context.name,
269
+ sessionId: this.currentSession?.id,
270
+ currentPhase: this.getCurrentPhase(),
271
+ phaseStatus: context.phases,
272
+ progress: this.calculateProgress(),
273
+ nextSteps: this.getNextSteps(this.getCurrentPhase()),
274
+ };
275
+ }
276
+ async ensureWorkspace() {
277
+ try {
278
+ await mkdir(this.options.workspace, { recursive: true });
279
+ }
280
+ catch {
281
+ // Directory may already exist.
282
+ }
283
+ }
284
+ async saveProjectContext() {
285
+ const contextPath = join(this.options.workspace, "project-context.json");
286
+ await writeFile(contextPath, JSON.stringify(this.projectContext, null, 2));
287
+ }
288
+ extractKeyInsights(pmAnalysis) {
289
+ const insights = [];
290
+ if (!pmAnalysis)
291
+ return insights;
292
+ if (pmAnalysis.summary?.keyInsights) {
293
+ insights.push(...pmAnalysis.summary.keyInsights);
294
+ }
295
+ for (const result of Object.values(pmAnalysis.results)) {
296
+ if ("error" in result)
297
+ continue;
298
+ const resultInsights = result.insights;
299
+ if (Array.isArray(resultInsights)) {
300
+ insights.push(...resultInsights);
301
+ }
302
+ }
303
+ return insights.slice(0, 10);
304
+ }
305
+ generateResearchRecommendations(brainstormResults, pmInsights) {
306
+ return [
307
+ ...brainstormResults.ideas.slice(0, 3).map((idea) => {
308
+ const label = typeof idea === "string" ? idea : idea.description ?? "idea";
309
+ return `Explore: ${label}`;
310
+ }),
311
+ ...pmInsights.slice(0, 3).map((insight) => `Consider: ${insight}`),
312
+ ];
313
+ }
314
+ createIntegratedTimeline(corePlan, gtmStrategy, roadmap) {
315
+ return {
316
+ phases: {
317
+ development: corePlan.timeline ?? {},
318
+ marketing: this.pickObject(gtmStrategy, ["timeline"]) ?? {},
319
+ product: this.pickObject(roadmap, ["roadmap", "timeline"]) ?? {},
320
+ },
321
+ dependencies: this.extractDependencies(corePlan, gtmStrategy, roadmap),
322
+ milestones: this.extractMilestones(corePlan, gtmStrategy, roadmap),
323
+ };
324
+ }
325
+ aggregateRisks(corePlan, gtmStrategy, roadmap) {
326
+ const risks = [];
327
+ if (Array.isArray(corePlan.risks))
328
+ risks.push(...corePlan.risks);
329
+ const gtmRisks = this.pickArray(gtmStrategy, ["strategy", "risks"]);
330
+ if (gtmRisks)
331
+ risks.push(...gtmRisks);
332
+ const roadmapRisks = this.pickArray(roadmap, ["roadmap", "risks"]);
333
+ if (roadmapRisks)
334
+ risks.push(...roadmapRisks);
335
+ return [...new Set(risks)];
336
+ }
337
+ executeGeneratedTools(cliTools, workResults) {
338
+ const integrationPoints = this.identifyIntegrationPoints(cliTools, workResults);
339
+ return {
340
+ toolsGenerated: cliTools.commands?.length ?? 0,
341
+ executionStatus: (cliTools.commands?.length ?? 0) === 0
342
+ ? "no-tools-generated"
343
+ : integrationPoints.length > 0
344
+ ? "integration-ready"
345
+ : "generated",
346
+ integrationPoints,
347
+ };
348
+ }
349
+ identifyIntegrationPoints(cliTools, workResults) {
350
+ const integrationPoints = new Set();
351
+ for (const command of cliTools.commands ?? []) {
352
+ switch (command.category) {
353
+ case "build":
354
+ integrationPoints.add("build automation");
355
+ break;
356
+ case "testing":
357
+ case "quality":
358
+ integrationPoints.add("testing automation");
359
+ break;
360
+ case "deployment":
361
+ integrationPoints.add("deployment automation");
362
+ break;
363
+ case "development":
364
+ case "lifecycle":
365
+ case "core":
366
+ integrationPoints.add("developer workflow");
367
+ break;
368
+ case "setup":
369
+ integrationPoints.add("environment setup");
370
+ break;
371
+ default:
372
+ break;
373
+ }
374
+ }
375
+ for (const step of workResults.steps) {
376
+ const description = step.step.toLowerCase();
377
+ if (description.includes("verify") || description.includes("test")) {
378
+ integrationPoints.add("testing automation");
379
+ }
380
+ if (description.includes("build")) {
381
+ integrationPoints.add("build automation");
382
+ }
383
+ if (description.includes("deploy")) {
384
+ integrationPoints.add("deployment automation");
385
+ }
386
+ if (description.includes("document")) {
387
+ integrationPoints.add("documentation workflow");
388
+ }
389
+ }
390
+ if (integrationPoints.size === 0 && workResults.steps.length > 0) {
391
+ integrationPoints.add("developer workflow");
392
+ }
393
+ return Array.from(integrationPoints);
394
+ }
395
+ trackExecutionMetrics(workResults) {
396
+ return {
397
+ stepsCompleted: workResults.steps.filter((s) => s.status === "completed").length,
398
+ issuesResolved: workResults.solutions.length,
399
+ timeSpent: this.calculateTimeSpent(workResults),
400
+ qualityScore: this.calculateQualityScore(workResults),
401
+ };
402
+ }
403
+ conductPerformanceReview(executionResults, plannedMetrics) {
404
+ const variance = this.calculateMetricVariance(executionResults.metrics, plannedMetrics?.metrics);
405
+ const performanceScore = this.calculatePerformanceScore(executionResults.metrics, variance);
406
+ return {
407
+ actualMetrics: executionResults.metrics,
408
+ plannedMetrics: plannedMetrics?.metrics,
409
+ variance,
410
+ performanceScore,
411
+ recommendations: this.buildPerformanceRecommendations(executionResults.metrics, variance),
412
+ };
413
+ }
414
+ analyzeProcessImprovements() {
415
+ return {
416
+ processEfficiencies: this.identifyProcessEfficiencies(),
417
+ bottleneckAnalysis: this.analyzeBottlenecks(),
418
+ improvementOpportunities: this.identifyImprovementOpportunities(),
419
+ automationPotential: this.assessAutomationPotential(),
420
+ };
421
+ }
422
+ generateComprehensiveReport() {
423
+ return {
424
+ executiveSummary: this.createExecutiveSummary(),
425
+ detailedAnalysis: this.createDetailedAnalysis(),
426
+ recommendations: this.createStrategicRecommendations(),
427
+ nextPhasePlanning: this.planNextPhase(),
428
+ appendices: this.createAppendices(),
429
+ };
430
+ }
431
+ aggregateRecommendations(coreReview, performanceReview, processImprovements) {
432
+ const recommendations = [];
433
+ const coreRecs = coreReview.review.recommendations;
434
+ if (Array.isArray(coreRecs))
435
+ recommendations.push(...coreRecs);
436
+ const perfRecs = performanceReview.recommendations;
437
+ if (Array.isArray(perfRecs))
438
+ recommendations.push(...perfRecs);
439
+ const improvementOps = processImprovements.improvementOpportunities;
440
+ if (Array.isArray(improvementOps))
441
+ recommendations.push(...improvementOps);
442
+ return [...new Set(recommendations)];
443
+ }
444
+ getCurrentPhase() {
445
+ const phases = this.projectContext.phases;
446
+ if (!phases)
447
+ return "completed";
448
+ for (const [phase, data] of Object.entries(phases)) {
449
+ if (data.status === "active")
450
+ return phase;
451
+ if (data.status === "pending")
452
+ return phase;
453
+ }
454
+ return "completed";
455
+ }
456
+ calculateProgress() {
457
+ const phases = this.projectContext.phases ?? {};
458
+ const entries = Object.values(phases);
459
+ const totalPhases = entries.length;
460
+ const completedPhases = entries.filter((p) => p.status === "completed").length;
461
+ return {
462
+ completed: completedPhases,
463
+ total: totalPhases,
464
+ percentage: totalPhases === 0 ? 0 : Math.round((completedPhases / totalPhases) * 100),
465
+ };
466
+ }
467
+ getNextSteps(currentPhase) {
468
+ const stepMap = {
469
+ research: ["Execute brainstorming", "Generate CLI tools", "Analyze market insights"],
470
+ planning: ["Create detailed project plan", "Define GTM strategy", "Establish metrics"],
471
+ execution: ["Implement core features", "Use generated tools", "Track progress"],
472
+ review: ["Conduct comprehensive review", "Document learnings", "Plan improvements"],
473
+ completed: [
474
+ "Start new iteration",
475
+ "Apply learnings to next project",
476
+ "Begin next phase",
477
+ ],
478
+ };
479
+ return stepMap[currentPhase] ?? ["Initialize project"];
480
+ }
481
+ extractDependencies(corePlan, gtmStrategy, roadmap) {
482
+ const dependencies = new Set();
483
+ for (let i = 1; i < corePlan.steps.length; i++) {
484
+ const current = corePlan.steps[i]?.description;
485
+ const previous = corePlan.steps[i - 1]?.description;
486
+ if (current && previous) {
487
+ dependencies.add(`${current} depends on ${previous}`);
488
+ }
489
+ }
490
+ const roadmapDependencies = this.pickArray(roadmap, ["roadmap", "dependencies"]);
491
+ if (roadmapDependencies) {
492
+ for (const dependency of roadmapDependencies) {
493
+ if (typeof dependency === "string") {
494
+ dependencies.add(dependency);
495
+ }
496
+ }
497
+ }
498
+ const launchPhases = this.pickArray(gtmStrategy, ["strategy", "launch", "phases"]);
499
+ if (launchPhases) {
500
+ for (let i = 1; i < launchPhases.length; i++) {
501
+ const previous = this.pickString(launchPhases[i - 1], ["phase"]);
502
+ const current = this.pickString(launchPhases[i], ["phase"]);
503
+ if (previous && current) {
504
+ dependencies.add(`Launch phase "${current}" follows "${previous}"`);
505
+ }
506
+ }
507
+ }
508
+ return Array.from(dependencies);
509
+ }
510
+ extractMilestones(corePlan, gtmStrategy, roadmap) {
511
+ const milestones = new Map();
512
+ corePlan.steps.forEach((step, index) => {
513
+ milestones.set(step.description, {
514
+ name: step.description,
515
+ source: "core-plan",
516
+ order: index + 1,
517
+ eta: step.estimatedTime ?? null,
518
+ });
519
+ });
520
+ const roadmapInitiatives = this.pickArray(roadmap, ["roadmap", "initiatives"]);
521
+ if (roadmapInitiatives) {
522
+ for (const initiative of roadmapInitiatives) {
523
+ const name = this.pickString(initiative, ["name"]);
524
+ if (!name)
525
+ continue;
526
+ milestones.set(name, {
527
+ name,
528
+ source: "roadmap",
529
+ timeline: this.pickString(initiative, ["timeline"]),
530
+ priority: this.pickString(initiative, ["priority"]),
531
+ });
532
+ }
533
+ }
534
+ const launchPhases = this.pickArray(gtmStrategy, ["strategy", "launch", "phases"]);
535
+ if (launchPhases) {
536
+ for (const phase of launchPhases) {
537
+ const name = this.pickString(phase, ["phase"]);
538
+ if (!name)
539
+ continue;
540
+ milestones.set(name, {
541
+ name,
542
+ source: "gtm-launch",
543
+ duration: this.pickString(phase, ["duration"]),
544
+ });
545
+ }
546
+ }
547
+ return Array.from(milestones.values());
548
+ }
549
+ calculateTimeSpent(workResults) {
550
+ let totalMinutes = 0;
551
+ for (const step of workResults.steps) {
552
+ const actualMinutes = this.durationBetween(step.startTime, step.endTime);
553
+ totalMinutes += actualMinutes > 0 ? actualMinutes : this.estimateStepMinutes(step.step);
554
+ }
555
+ if (totalMinutes === 0 && workResults.steps.length > 0) {
556
+ totalMinutes = workResults.steps.length * 15;
557
+ }
558
+ return formatMinutes(totalMinutes);
559
+ }
560
+ calculateQualityScore(workResults) {
561
+ const totalSteps = Math.max(workResults.steps.length, 1);
562
+ const completedSteps = workResults.steps.filter((step) => step.status === "completed").length;
563
+ const failedSteps = workResults.steps.filter((step) => step.status === "failed").length;
564
+ const unresolvedIssues = Math.max(0, workResults.issues.length - workResults.solutions.length);
565
+ const completionRatio = completedSteps / totalSteps;
566
+ const resolutionRatio = Math.min(workResults.solutions.length, workResults.issues.length || 1) /
567
+ totalSteps;
568
+ const score = 0.45 +
569
+ completionRatio * 0.35 +
570
+ resolutionRatio * 0.15 -
571
+ (failedSteps / totalSteps) * 0.2 -
572
+ (unresolvedIssues / totalSteps) * 0.1;
573
+ return roundTo(clamp(score, 0, 1));
574
+ }
575
+ calculateMetricVariance(actualMetrics, plannedMetrics) {
576
+ const actualMetricKeys = Object.keys(actualMetrics);
577
+ const plannedMetricGroups = plannedMetrics && typeof plannedMetrics === "object" && !Array.isArray(plannedMetrics)
578
+ ? Object.keys(plannedMetrics)
579
+ : [];
580
+ const coverageRatio = plannedMetricGroups.length === 0
581
+ ? 1
582
+ : roundTo(clamp(actualMetricKeys.length / plannedMetricGroups.length, 0, 1));
583
+ return {
584
+ actualMetricKeys,
585
+ plannedMetricGroups,
586
+ coverageRatio,
587
+ missingMetricGroups: plannedMetricGroups.slice(actualMetricKeys.length),
588
+ };
589
+ }
590
+ calculatePerformanceScore(actualMetrics, variance) {
591
+ const coverageRatio = typeof variance.coverageRatio === "number" ? variance.coverageRatio : 0.5;
592
+ const deliveryBonus = actualMetrics.stepsCompleted > 0 ? 0.1 : 0;
593
+ return roundTo(clamp(actualMetrics.qualityScore * 0.6 + coverageRatio * 0.3 + deliveryBonus, 0, 1));
594
+ }
595
+ identifyProcessEfficiencies() {
596
+ const context = this.projectContext;
597
+ const efficiencies = [];
598
+ if (context.researchResults?.pmInsights.length) {
599
+ efficiencies.push(`Research captured ${context.researchResults.pmInsights.length} PM insight(s) before planning`);
600
+ }
601
+ if (context.planningResults?.corePlan.steps.length) {
602
+ efficiencies.push(`Planning broke the work into ${context.planningResults.corePlan.steps.length} executable step(s)`);
603
+ }
604
+ if (context.executionResults?.solutions.length) {
605
+ efficiencies.push(`Execution resolved ${context.executionResults.solutions.length} issue(s) during delivery`);
606
+ }
607
+ if (context.reviewResults?.learnings.length) {
608
+ efficiencies.push(`Review captured ${context.reviewResults.learnings.length} reusable learning(s)`);
609
+ }
610
+ return efficiencies;
611
+ }
612
+ analyzeBottlenecks() {
613
+ const context = this.projectContext;
614
+ const bottlenecks = [];
615
+ if (context.executionResults &&
616
+ context.executionResults.issues.length > context.executionResults.solutions.length) {
617
+ bottlenecks.push("Execution surfaced more issues than documented solutions");
618
+ }
619
+ if (!context.researchResults?.cliTools && context.executionResults?.coreWork.steps.length) {
620
+ bottlenecks.push("No generated CLI integration was available during execution");
621
+ }
622
+ if (context.reviewResults &&
623
+ context.reviewResults.recommendations.length === 0) {
624
+ bottlenecks.push("Review phase closed without concrete follow-up recommendations");
625
+ }
626
+ return bottlenecks.length > 0
627
+ ? bottlenecks
628
+ : ["No material workflow bottlenecks detected from the recorded state"];
629
+ }
630
+ identifyImprovementOpportunities() {
631
+ const context = this.projectContext;
632
+ const opportunities = new Set();
633
+ for (const risk of context.planningResults?.risks ?? []) {
634
+ opportunities.add(`Mitigate planning risk: ${risk}`);
635
+ }
636
+ for (const improvement of context.reviewResults?.coreReview.review.improvements ?? []) {
637
+ opportunities.add(improvement);
638
+ }
639
+ for (const recommendation of context.reviewResults?.recommendations ?? []) {
640
+ opportunities.add(recommendation);
641
+ }
642
+ if (!context.researchResults?.cliTools) {
643
+ opportunities.add("Generate repo-aware CLI tooling for repetitive workflow steps");
644
+ }
645
+ return Array.from(opportunities).slice(0, 6);
646
+ }
647
+ assessAutomationPotential() {
648
+ const context = this.projectContext;
649
+ const toolCount = context.researchResults?.cliTools?.commands.length ?? 0;
650
+ const integrationCount = context.executionResults?.toolExecution?.integrationPoints.length ?? 0;
651
+ if (toolCount >= 5 || integrationCount >= 3) {
652
+ return "high";
653
+ }
654
+ if (toolCount > 0 || integrationCount > 0 || (context.executionResults?.coreWork.steps.length ?? 0) >= 4) {
655
+ return "medium";
656
+ }
657
+ return "low";
658
+ }
659
+ createExecutiveSummary() {
660
+ const context = this.projectContext;
661
+ if (!context.name) {
662
+ return "No active project context is available.";
663
+ }
664
+ const progress = this.calculateProgress();
665
+ const issues = context.executionResults?.issues.length ?? 0;
666
+ const learnings = context.reviewResults?.learnings.length ?? 0;
667
+ return `${context.name} reached ${progress.completed}/${progress.total} workflow phases (${progress.percentage}%) with ${issues} tracked issue(s) and ${learnings} captured learning(s).`;
668
+ }
669
+ createDetailedAnalysis() {
670
+ const context = this.projectContext;
671
+ return {
672
+ project: context.name ?? null,
673
+ objective: context.objective ?? null,
674
+ currentPhase: this.getCurrentPhase(),
675
+ progress: this.calculateProgress(),
676
+ phaseStatus: context.phases ?? {},
677
+ research: {
678
+ pmInsights: context.researchResults?.pmInsights.length ?? 0,
679
+ recommendations: context.researchResults?.recommendations.length ?? 0,
680
+ generatedCliCommands: context.researchResults?.cliTools?.commands.length ?? 0,
681
+ },
682
+ planning: {
683
+ steps: context.planningResults?.corePlan.steps.length ?? 0,
684
+ risks: context.planningResults?.risks.length ?? 0,
685
+ milestones: context.planningResults?.integratedTimeline.milestones.length ?? 0,
686
+ },
687
+ execution: {
688
+ metrics: context.executionResults?.metrics ?? null,
689
+ issues: context.executionResults?.issues.length ?? 0,
690
+ solutions: context.executionResults?.solutions.length ?? 0,
691
+ },
692
+ review: {
693
+ overallScore: context.reviewResults?.coreReview.review.overallScore ?? null,
694
+ recommendations: context.reviewResults?.recommendations.length ?? 0,
695
+ },
696
+ };
697
+ }
698
+ createStrategicRecommendations() {
699
+ const context = this.projectContext;
700
+ const recommendations = new Set();
701
+ for (const nextStep of this.getNextSteps(this.getCurrentPhase())) {
702
+ recommendations.add(nextStep);
703
+ }
704
+ for (const recommendation of context.reviewResults?.recommendations ?? []) {
705
+ recommendations.add(recommendation);
706
+ }
707
+ for (const risk of context.planningResults?.risks.slice(0, 3) ?? []) {
708
+ recommendations.add(`Reduce delivery risk: ${risk}`);
709
+ }
710
+ return Array.from(recommendations).slice(0, 6);
711
+ }
712
+ planNextPhase() {
713
+ const currentPhase = this.getCurrentPhase();
714
+ const strategicRecommendations = this.createStrategicRecommendations();
715
+ if (currentPhase === "completed") {
716
+ return strategicRecommendations[0] ?? "Start the next iteration from review learnings.";
717
+ }
718
+ const nextStep = this.getNextSteps(currentPhase)[0];
719
+ return nextStep
720
+ ? `Continue by prioritizing: ${nextStep}`
721
+ : "Continue with the next queued workflow phase.";
722
+ }
723
+ createAppendices() {
724
+ const context = this.projectContext;
725
+ return {
726
+ sessionId: context.sessionId ?? null,
727
+ cliOutputPath: context.researchResults?.cliTools?.outputPath ?? null,
728
+ topRisks: context.planningResults?.risks.slice(0, 5) ?? [],
729
+ learnings: context.reviewResults?.learnings.slice(0, 5).map((learning) => ({
730
+ summary: learning.summary,
731
+ confidence: learning.confidence,
732
+ category: learning.category,
733
+ })) ?? [],
734
+ };
735
+ }
736
+ generateWorkflowSummary() {
737
+ const context = this.projectContext;
738
+ if (!context.name) {
739
+ return "No workflow has been started.";
740
+ }
741
+ const progress = this.calculateProgress();
742
+ const issues = context.executionResults?.issues.length ?? 0;
743
+ const recommendations = context.reviewResults?.recommendations.length ?? 0;
744
+ const learnings = context.reviewResults?.learnings.length ?? 0;
745
+ return `${context.name}: ${progress.completed}/${progress.total} phases completed, ${issues} issue(s) tracked, ${recommendations} recommendation(s) generated, ${learnings} learning(s) captured.`;
746
+ }
747
+ buildPerformanceRecommendations(actualMetrics, variance) {
748
+ const recommendations = [];
749
+ const coverageRatio = typeof variance.coverageRatio === "number" ? variance.coverageRatio : 1;
750
+ const missingGroups = Array.isArray(variance.missingMetricGroups)
751
+ ? variance.missingMetricGroups
752
+ : [];
753
+ if (actualMetrics.qualityScore < 0.75) {
754
+ recommendations.push("Improve verification depth to raise execution quality");
755
+ }
756
+ if (coverageRatio < 0.75) {
757
+ recommendations.push("Align execution metrics more closely with planned measurement areas");
758
+ }
759
+ if (missingGroups.length > 0) {
760
+ recommendations.push(`Fill metric gaps for: ${missingGroups.slice(0, 2).join(", ")}`);
761
+ }
762
+ return recommendations;
763
+ }
764
+ durationBetween(startTime, endTime) {
765
+ if (!endTime) {
766
+ return 0;
767
+ }
768
+ const start = new Date(startTime).getTime();
769
+ const end = new Date(endTime).getTime();
770
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) {
771
+ return 0;
772
+ }
773
+ return Math.max(1, Math.round((end - start) / 60000));
774
+ }
775
+ estimateStepMinutes(step) {
776
+ const normalized = step.toLowerCase();
777
+ if (normalized.includes("implement") || normalized.includes("build"))
778
+ return 45;
779
+ if (normalized.includes("verify") ||
780
+ normalized.includes("test") ||
781
+ normalized.includes("validate")) {
782
+ return 20;
783
+ }
784
+ if (normalized.includes("document") || normalized.includes("review"))
785
+ return 15;
786
+ return 30;
787
+ }
788
+ log(message) {
789
+ if (this.options.verbose) {
790
+ console.log(`[Unified-CI] ${message}`);
791
+ }
792
+ }
793
+ requireContext() {
794
+ const context = this.projectContext;
795
+ if (!context || !context.phases) {
796
+ throw new Error("No active session. Call initializeProject() first.");
797
+ }
798
+ return context;
799
+ }
800
+ pickObject(source, path) {
801
+ let current = source;
802
+ for (const key of path) {
803
+ if (!current || typeof current !== "object")
804
+ return null;
805
+ current = current[key];
806
+ }
807
+ if (current && typeof current === "object" && !Array.isArray(current)) {
808
+ return current;
809
+ }
810
+ return null;
811
+ }
812
+ pickArray(source, path) {
813
+ let current = source;
814
+ for (const key of path) {
815
+ if (!current || typeof current !== "object")
816
+ return null;
817
+ current = current[key];
818
+ }
819
+ return Array.isArray(current) ? current : null;
820
+ }
821
+ pickString(source, path) {
822
+ let current = source;
823
+ for (const key of path) {
824
+ if (!current || typeof current !== "object")
825
+ return null;
826
+ current = current[key];
827
+ }
828
+ return typeof current === "string" ? current : null;
829
+ }
830
+ }
831
+ if (import.meta.url === `file://${process.argv[1]}`) {
832
+ const [, , command, ...args] = process.argv;
833
+ if (!command || command === "--help" || command === "-h") {
834
+ console.log(`
835
+ Usage: unified-plugin <command> [options]
836
+
837
+ Commands:
838
+ init <project-name> <objective> Initialize new project
839
+ research Execute research phase
840
+ planning Execute planning phase
841
+ execution Execute execution phase
842
+ review Execute review phase
843
+ workflow <project-name> <objective> Run complete workflow
844
+ status Show project status
845
+
846
+ Options:
847
+ --workspace <dir> Workspace directory (default: ./ci-workspace)
848
+ --verbose Enable verbose logging
849
+ --repo <path> Repository path for CLI generation
850
+ `);
851
+ process.exit(0);
852
+ }
853
+ const options = {};
854
+ for (let i = 0; i < args.length; i++) {
855
+ const flag = args[i];
856
+ if (flag === "--workspace" && args[i + 1]) {
857
+ options.workspace = args[i + 1];
858
+ i++;
859
+ }
860
+ else if (flag === "--verbose") {
861
+ options.verbose = true;
862
+ }
863
+ else if (flag === "--repo" && args[i + 1]) {
864
+ options.repositoryPath = args[i + 1];
865
+ i++;
866
+ }
867
+ }
868
+ const unifiedPlugin = new UnifiedContinuousImprovement(options);
869
+ switch (command) {
870
+ case "init":
871
+ if (args.length < 2) {
872
+ console.error("Error: Project name and objective required");
873
+ process.exit(1);
874
+ }
875
+ unifiedPlugin
876
+ .initializeProject({ name: args[0], objective: args.slice(1).join(" ") })
877
+ .then((result) => {
878
+ console.log(`✅ Project initialized: ${result.projectId}`);
879
+ console.log(`📊 Session: ${result.sessionId}`);
880
+ })
881
+ .catch((error) => {
882
+ console.error(`❌ Error: ${getErrorMessage(error)}`);
883
+ process.exit(1);
884
+ });
885
+ break;
886
+ case "workflow":
887
+ if (args.length < 2) {
888
+ console.error("Error: Project name and objective required");
889
+ process.exit(1);
890
+ }
891
+ unifiedPlugin
892
+ .executeCompleteWorkflow({ name: args[0], objective: args.slice(1).join(" ") }, options.repositoryPath ? { researchContext: { repositoryPath: options.repositoryPath } } : {})
893
+ .then((result) => {
894
+ console.log(`🎉 Workflow completed for: ${result.project}`);
895
+ console.log(`📊 Session: ${result.sessionId}`);
896
+ })
897
+ .catch((error) => {
898
+ console.error(`❌ Error: ${getErrorMessage(error)}`);
899
+ process.exit(1);
900
+ });
901
+ break;
902
+ case "status":
903
+ unifiedPlugin
904
+ .getProjectStatus()
905
+ .then((status) => {
906
+ console.log("📊 Project Status:");
907
+ console.log(JSON.stringify(status, null, 2));
908
+ })
909
+ .catch((error) => {
910
+ console.error(`❌ Error: ${getErrorMessage(error)}`);
911
+ process.exit(1);
912
+ });
913
+ break;
914
+ case "research":
915
+ case "planning":
916
+ case "execution":
917
+ case "review":
918
+ console.log(`⚠️ Phase execution requires prior initialization. Use 'init' or 'workflow' commands.`);
919
+ break;
920
+ default:
921
+ console.error(`Unknown command: ${command}`);
922
+ process.exit(1);
923
+ }
924
+ }