codecartographer-pi 0.10.0 → 0.12.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 (71) hide show
  1. package/.codecarto/GUIDE.md +40 -18
  2. package/.codecarto/README.md +3 -0
  3. package/.codecarto/findings/goal-synthesis/README.md +3 -0
  4. package/.codecarto/findings/goal-synthesis-finalize/SKILL.md +30 -0
  5. package/.codecarto/findings/goal-synthesis-propose/SKILL.md +24 -0
  6. package/.codecarto/findings/porting/SKILL.md +7 -0
  7. package/.codecarto/findings/reimplementation-spec/SKILL.md +10 -0
  8. package/.codecarto/findings/spec-merge/README.md +3 -0
  9. package/.codecarto/findings/spec-merge/SKILL.md +23 -0
  10. package/.codecarto/findings/vision-capture/README.md +3 -0
  11. package/.codecarto/findings/vision-capture/SKILL.md +26 -0
  12. package/.codecarto/inputs/vision.md +11 -0
  13. package/.codecarto/templates/architecture-map.md +9 -0
  14. package/.codecarto/templates/behavioral-contracts.md +9 -0
  15. package/.codecarto/templates/defect-report.md +9 -0
  16. package/.codecarto/templates/mechanical-defects.md +9 -0
  17. package/.codecarto/templates/merged-spec.md +58 -0
  18. package/.codecarto/templates/phase-checkpoint.md +41 -0
  19. package/.codecarto/templates/phase-handoff.yaml +22 -0
  20. package/.codecarto/templates/project-plan.md +70 -0
  21. package/.codecarto/templates/proposal.md +43 -0
  22. package/.codecarto/templates/protocols-and-state.md +9 -0
  23. package/.codecarto/templates/reimplementation-spec-opinionated.md +10 -0
  24. package/.codecarto/templates/reimplementation-spec.md +10 -0
  25. package/.codecarto/templates/reverse-engineering-bundle.md +29 -3
  26. package/.codecarto/templates/semantic-defects.md +9 -0
  27. package/.codecarto/templates/vision.md +63 -0
  28. package/.codecarto/workflow/pipeline-architecture-only.yaml +1 -0
  29. package/.codecarto/workflow/pipeline-defect-scan.yaml +2 -0
  30. package/.codecarto/workflow/pipeline-full-with-audit.yaml +8 -3
  31. package/.codecarto/workflow/pipeline-full-with-deep-audit.yaml +9 -5
  32. package/.codecarto/workflow/pipeline-lite.yaml +3 -0
  33. package/.codecarto/workflow/pipeline-synthesis.yaml +105 -0
  34. package/.codecarto/workflow/pipeline.yaml +7 -3
  35. package/.codecarto/workflow/status.yaml +2 -0
  36. package/README.md +89 -7
  37. package/dist/core/completion.d.ts +6 -0
  38. package/dist/core/completion.js +127 -0
  39. package/dist/core/dashboard.js +37 -7
  40. package/dist/core/index.d.ts +2 -0
  41. package/dist/core/index.js +2 -0
  42. package/dist/core/pipeline.js +1 -0
  43. package/dist/core/prompts.d.ts +9 -3
  44. package/dist/core/prompts.js +43 -26
  45. package/dist/core/status.d.ts +7 -1
  46. package/dist/core/status.js +187 -2
  47. package/dist/core/synthesis.d.ts +31 -0
  48. package/dist/core/synthesis.js +140 -0
  49. package/dist/core/types.d.ts +29 -1
  50. package/dist/core/usage.d.ts +11 -0
  51. package/dist/core/usage.js +64 -46
  52. package/dist/core/workspace.d.ts +3 -1
  53. package/dist/core/workspace.js +39 -3
  54. package/dist/core/yaml.js +24 -0
  55. package/dist/extensions/codecarto/agent-rewriter.js +0 -1
  56. package/dist/extensions/codecarto/agent-runner.d.ts +19 -0
  57. package/dist/extensions/codecarto/agent-runner.js +68 -6
  58. package/dist/extensions/codecarto/agent-state.d.ts +3 -0
  59. package/dist/extensions/codecarto/agent-state.js +2 -0
  60. package/dist/extensions/codecarto/agent-summary.d.ts +5 -0
  61. package/dist/extensions/codecarto/agent-summary.js +9 -0
  62. package/dist/extensions/codecarto/agent-widget.js +6 -0
  63. package/dist/extensions/codecarto/auto-runner.d.ts +3 -1
  64. package/dist/extensions/codecarto/auto-runner.js +33 -69
  65. package/dist/extensions/codecarto/dashboard-narrator.js +0 -1
  66. package/dist/extensions/codecarto/index.d.ts +1 -1
  67. package/dist/extensions/codecarto/index.js +153 -12
  68. package/dist/extensions/codecarto/phase-compaction.d.ts +11 -0
  69. package/dist/extensions/codecarto/phase-compaction.js +115 -0
  70. package/dist/mcp-server/server.js +24 -68
  71. package/package.json +4 -3
@@ -15,7 +15,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
15
15
  import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
16
16
  import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
17
17
  import { basename, isAbsolute, join } from "node:path";
18
- import { buildPhasePrompt, buildSkillPrompt, buildThreadLogEntry, buildValidationSummary, canonicalPath, closeoutFileName, createEmptyStatus, dateOnly, DEFAULT_PIPELINE_PATH, deriveSlug, discoverLibrary, ensureCloseoutStub, getNextEligiblePhase, getPipelineLabel, getWorkspaceState, isValidSlug, listEntries, listSkillNames, loadCodecartoConfig, loadYamlFile, normalizeForComparison, normalizeStatus, PACKAGE_VERSION, packagedWorkspaceDir, pathExists, publishEntry, reindex as libraryReindex, resolvePhase, resolvePipelineChoice, stringifySimpleYaml, uniqueStrings, updateStatusAtomically, validatePhaseOutput, } from "../core/index.js";
18
+ import { buildPhasePrompt, buildSkillPrompt, buildValidationSummary, canonicalPath, completeValidatedPhase, createEmptyStatus, DEFAULT_PIPELINE_PATH, deriveSlug, discoverLibrary, getNextEligiblePhase, getPipelineLabel, getWorkspaceState, isValidSlug, listEntries, listSkillNames, loadCodecartoConfig, loadYamlFile, normalizeForComparison, PACKAGE_VERSION, packagedWorkspaceDir, pathExists, PhasePreflightError, publishEntry, reindex as libraryReindex, resolvePhase, resolvePipelineChoice, stringifySimpleYaml, validatePhaseOutput, } from "../core/index.js";
19
19
  // ---------- input helpers ----------
20
20
  async function validateCwd(cwd) {
21
21
  if (typeof cwd !== "string" || !cwd.trim()) {
@@ -46,6 +46,17 @@ function textResult(text, structured) {
46
46
  result.structuredContent = structured;
47
47
  return result;
48
48
  }
49
+ async function buildMcpPhasePrompt(state, phase, forced) {
50
+ try {
51
+ return await buildPhasePrompt(state, phase, forced);
52
+ }
53
+ catch (error) {
54
+ if (error instanceof PhasePreflightError) {
55
+ throw new McpError(ErrorCode.InvalidRequest, error.message);
56
+ }
57
+ throw error;
58
+ }
59
+ }
49
60
  // ---------- handlers ----------
50
61
  export async function handleInit(args) {
51
62
  const cwd = await validateCwd(args.cwd);
@@ -101,12 +112,16 @@ export async function handleStatus(args) {
101
112
  const completed = state.pipeline.phase_order.filter((id) => state.status.phases[id]?.status === "complete").length;
102
113
  const totalCarryForward = Object.values(state.status.phases).reduce((sum, phase) => sum + (phase.carry_forward?.length ?? 0), 0);
103
114
  const currentOpenQuestions = currentPhase === "complete" ? 0 : state.status.phases[currentPhase]?.open_questions.length ?? 0;
115
+ const terminalOpenQuestions = Object.values(state.status.phases).reduce((sum, phase) => sum + (phase.open_questions?.length ?? 0), 0);
116
+ const postPipelinePending = state.status.post_pipeline.filter((entry) => entry.status !== "resolved").length;
104
117
  const summary = [
105
118
  `Phase: ${currentPhase}`,
119
+ `Pipeline state: ${currentPhase === "complete" ? "complete" : "in progress"}`,
106
120
  `Pipeline: ${getPipelineLabel(state.status.pipeline)} (${state.status.pipeline})`,
107
121
  `Progress: ${completed}/${state.pipeline.phase_order.length} complete`,
108
- `Open questions (current phase): ${currentOpenQuestions}`,
109
- `Carry-forward (all phases): ${totalCarryForward}`,
122
+ `Open questions (terminal unresolved): ${terminalOpenQuestions}`,
123
+ `Carry-forward (pipeline phases): ${totalCarryForward}`,
124
+ `Post-pipeline work: ${postPipelinePending} pending`,
110
125
  `Next: ${state.status.next_actions[0] ?? (nextPhase ? `Begin ${nextPhase.id}` : "All phases complete.")}`,
111
126
  ].join("\n");
112
127
  return textResult(summary, {
@@ -116,7 +131,9 @@ export async function handleStatus(args) {
116
131
  completed,
117
132
  total: state.pipeline.phase_order.length,
118
133
  openQuestionsCurrentPhase: currentOpenQuestions,
134
+ openQuestionsTerminal: terminalOpenQuestions,
119
135
  carryForwardTotal: totalCarryForward,
136
+ postPipelinePending,
120
137
  nextActions: state.status.next_actions,
121
138
  });
122
139
  }
@@ -129,7 +146,7 @@ export async function handleNext(args) {
129
146
  complete: true,
130
147
  });
131
148
  }
132
- const prompt = await buildPhasePrompt(state, phase, false);
149
+ const prompt = await buildMcpPhasePrompt(state, phase, false);
133
150
  return textResult(prompt, { phase: phase.id, forced: false });
134
151
  }
135
152
  export async function handlePhase(args) {
@@ -142,7 +159,7 @@ export async function handlePhase(args) {
142
159
  if (!phase) {
143
160
  throw new McpError(ErrorCode.InvalidParams, `Unknown phase: ${args.phase}`);
144
161
  }
145
- const prompt = await buildPhasePrompt(state, phase, true);
162
+ const prompt = await buildMcpPhasePrompt(state, phase, true);
146
163
  return textResult(prompt, { phase: phase.id, forced: true });
147
164
  }
148
165
  export async function handleValidate(args) {
@@ -172,70 +189,9 @@ export async function handleComplete(args) {
172
189
  if (validation.overall === "FAIL" || validation.overall === "MISSING") {
173
190
  throw new McpError(ErrorCode.InvalidRequest, `Cannot complete ${validation.phaseId}: validation is ${validation.overall}.\n${buildValidationSummary(validation).join("\n")}`);
174
191
  }
175
- const completionTimestamp = new Date().toISOString();
176
- const updatedState = await updateStatusAtomically(cwd, (lockedState) => {
177
- const phase = resolvePhase(lockedState, validation.phaseId);
178
- if (!phase?.primary_output) {
179
- throw new Error(`Phase ${validation.phaseId} is missing primary_output.`);
180
- }
181
- const nextStatus = normalizeStatus(lockedState.status, lockedState.pipeline, lockedState.status.pipeline, lockedState.cwd);
182
- const existingPhase = nextStatus.phases[validation.phaseId] ?? {
183
- status: "pending",
184
- owner_notes: [],
185
- outputs_present: [],
186
- open_questions: [],
187
- carry_forward: [],
188
- };
189
- const gapEntries = validation.rows
190
- .filter((row) => row.result.toUpperCase().includes("PARTIAL"))
191
- .map((row) => ({
192
- kind: "needs-maintainer-decision",
193
- description: row.criterion || "Partial validation gap",
194
- deferred_reason: row.evidence || "Marked PARTIAL by validation",
195
- }));
196
- const mergedOpenQuestions = [...existingPhase.open_questions];
197
- for (const candidate of gapEntries) {
198
- const dupe = mergedOpenQuestions.some((entry) => entry.description === candidate.description && entry.deferred_reason === candidate.deferred_reason);
199
- if (!dupe)
200
- mergedOpenQuestions.push(candidate);
201
- }
202
- nextStatus.phases[validation.phaseId] = {
203
- status: "complete",
204
- owner_notes: uniqueStrings([
205
- ...existingPhase.owner_notes,
206
- `Completed via codecarto_complete on ${completionTimestamp}.`,
207
- `Primary output: .codecarto/${validation.primaryOutput}`,
208
- `Validation: ${validation.overall}`,
209
- ]).slice(-3),
210
- outputs_present: uniqueStrings([...existingPhase.outputs_present, validation.primaryOutput]),
211
- open_questions: mergedOpenQuestions,
212
- carry_forward: existingPhase.carry_forward ?? [],
213
- };
214
- nextStatus.last_updated = completionTimestamp;
215
- const updatedWorkspaceState = {
216
- ...lockedState,
217
- status: nextStatus,
218
- };
219
- const nextEligible = getNextEligiblePhase(updatedWorkspaceState);
220
- nextStatus.current_phase = nextEligible?.id ?? "complete";
221
- nextStatus.next_actions = nextEligible
222
- ? [`Begin ${nextEligible.id} phase by producing ${nextEligible.primary_output ?? `findings/${nextEligible.id}/`}`]
223
- : ["All phases complete. Review findings, open questions, and downstream implementation notes."];
224
- return {
225
- state: { ...updatedWorkspaceState, status: nextStatus },
226
- threadLogEntry: buildThreadLogEntry(validation.phaseId, validation, completionTimestamp),
227
- };
192
+ const { updatedState, closeoutNotice } = await completeValidatedPhase(cwd, validation, "codecarto_complete").catch((error) => {
193
+ throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : String(error));
228
194
  });
229
- let closeoutNotice;
230
- try {
231
- const created = await ensureCloseoutStub(updatedState.workspaceDir, validation.phaseId, completionTimestamp);
232
- if (created) {
233
- closeoutNotice = `Closeout stub created: .codecarto/closeouts/${closeoutFileName(dateOnly(completionTimestamp), validation.phaseId)} (fill it in)`;
234
- }
235
- }
236
- catch (error) {
237
- closeoutNotice = `Closeout stub not created: ${error instanceof Error ? error.message : String(error)}`;
238
- }
239
195
  const lines = [
240
196
  `Marked ${validation.phaseId} complete (validation: ${validation.overall}).`,
241
197
  `Next phase: ${updatedState.status.current_phase}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codecartographer-pi",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "CodeCartographer packaged for Pi as an extension-driven workflow wrapper.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -37,13 +37,14 @@
37
37
  "build": "tsc",
38
38
  "prepublishOnly": "npm run build",
39
39
  "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test tests/*.test.mjs",
40
- "smoke": "node scripts/smoke-mcp.mjs"
40
+ "smoke": "node scripts/smoke-mcp.mjs",
41
+ "demo:synthesis": "npm run build && node scripts/create-synthesis-demo.mjs"
41
42
  },
42
43
  "dependencies": {
43
44
  "@modelcontextprotocol/sdk": "^1.29.0"
44
45
  },
45
46
  "peerDependencies": {
46
- "@earendil-works/pi-coding-agent": "~0.74.0",
47
+ "@earendil-works/pi-coding-agent": "^0.80.10",
47
48
  "@sinclair/typebox": "*"
48
49
  },
49
50
  "pi": {