codecartographer-pi 0.12.3 → 0.12.4

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.
@@ -78,25 +78,25 @@ export async function runPhasePreflight(state, phase) {
78
78
  if (checks.has("requires-vision-input")) {
79
79
  const visionPath = join(state.workspaceDir, SYNTHESIS_VISION_INPUT_PATH);
80
80
  if (!(await pathExists(visionPath))) {
81
- throw new PhasePreflightError(phase.id, `the vision brief is missing at .codecarto/${SYNTHESIS_VISION_INPUT_PATH}. Create it before starting synthesis.`);
81
+ throw new PhasePreflightError(phase.id, `the vision brief is missing at .codecarto/${SYNTHESIS_VISION_INPUT_PATH}. Create that file and describe your product intent (audience, problem, desired outcome, constraints, non-goals). See .codecarto/templates/vision.md for the expected structure.`);
82
82
  }
83
83
  const rawVision = await readFile(visionPath, "utf8");
84
84
  if (!hasMeaningfulVisionContent(rawVision)) {
85
- throw new PhasePreflightError(phase.id, `the vision brief at .codecarto/${SYNTHESIS_VISION_INPUT_PATH} is still empty. Describe the audience, problem, and desired outcome, then retry.`);
85
+ throw new PhasePreflightError(phase.id, `the vision brief at .codecarto/${SYNTHESIS_VISION_INPUT_PATH} appears to be empty or only contains comments. Write your product intent into that file — at minimum: who the product is for, what problem it solves, and what outcome you want. See .codecarto/templates/vision.md for the full structure.`);
86
86
  }
87
87
  }
88
88
  if (checks.has("requires-library")) {
89
89
  const config = await loadCodecartoConfig(state.workspaceDir);
90
90
  if (!config.library.path) {
91
- throw new PhasePreflightError(phase.id, "no library.path is configured. Set it in ~/.codecarto/config.yaml or .codecarto/workflow/config.yaml.");
91
+ throw new PhasePreflightError(phase.id, "no library.path is configured. Create a library directory with a .codecarto-library marker file, then set library.path in ~/.codecarto/config.yaml or .codecarto/workflow/config.yaml. Example config:\n library:\n path: ~/codecarto-library\n publish_confirm: true");
92
92
  }
93
93
  const marker = await discoverLibrary(config.library.path);
94
94
  if (!marker) {
95
- throw new PhasePreflightError(phase.id, `no CodeCartographer library was found at ${config.library.path} (missing .codecarto-library).`);
95
+ throw new PhasePreflightError(phase.id, `no CodeCartographer library was found at ${config.library.path} (missing .codecarto-library). Create a .codecarto-library marker file in that directory with: {"schema_version": 1, "name": "personal-library", "visibility": "internal", "namespaced": false}`);
96
96
  }
97
97
  const entries = await listEntries(config.library.path);
98
98
  if (entries.length === 0) {
99
- throw new PhasePreflightError(phase.id, `the configured library at ${config.library.path} has no entries. Publish at least one reimplementation spec first.`);
99
+ throw new PhasePreflightError(phase.id, `the configured library at ${config.library.path} has no entries. Run a reverse-engineering pipeline (e.g. /codecarto-init full-with-deep-audit) on a source repository, then use /codecarto-publish to publish at least one reimplementation spec into the library before starting synthesis.`);
100
100
  }
101
101
  result.libraryPath = config.library.path;
102
102
  result.libraryName = marker.name;
@@ -110,13 +110,13 @@ export async function runPhasePreflight(state, phase) {
110
110
  result.confirmedSelections = parseConfirmedProposalSelections(await readFile(proposalPath, "utf8"));
111
111
  result.confirmedEntries = result.confirmedSelections.map((selection) => selection.ref);
112
112
  if (result.confirmedSelections.length === 0) {
113
- throw new PhasePreflightError(phase.id, `no library entries are confirmed in .codecarto/${SYNTHESIS_PROPOSAL_PATH}. Change at least one [ ] checkbox to [x], then retry.`);
113
+ throw new PhasePreflightError(phase.id, `no library entries are confirmed in .codecarto/${SYNTHESIS_PROPOSAL_PATH}. Open that file and change at least one [ ] checkbox to [x] for the entry you want to include, then retry.`);
114
114
  }
115
115
  const available = new Map(result.libraryEntries.map((entry) => [entry.ref, entry]));
116
116
  for (const selection of result.confirmedSelections) {
117
117
  const entry = available.get(selection.ref);
118
118
  if (!entry || !entry.versions.includes(selection.version)) {
119
- throw new PhasePreflightError(phase.id, `confirmed selection ${selection.ref}@v${selection.version} is not present in the configured library. Re-run the proposal phase or correct the checked row.`);
119
+ throw new PhasePreflightError(phase.id, `confirmed selection ${selection.ref}@v${selection.version} is not present in the configured library. Edit .codecarto/${SYNTHESIS_PROPOSAL_PATH} to correct the checked row (change [x] back to [ ] or update the version), or re-run the goal-synthesis-propose phase to regenerate the proposal.`);
120
120
  }
121
121
  selection.specPath = specPathForVersion(result.libraryPath, selection.ref, selection.version);
122
122
  }
@@ -1,4 +1,4 @@
1
- import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
1
+ import { cp, mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
2
  import { basename, join, resolve } from "node:path";
3
3
  import { autoCompletePhase, buildAutoSummary, isPhaseRunning, runAuto, runSinglePhase } from "./auto-runner.js";
4
4
  import { disposeAgentsWidget } from "./agent-widget.js";
@@ -220,10 +220,13 @@ export default function codeCartographerExtension(pi) {
220
220
  if (targetExists) {
221
221
  const sameWorkspace = normalizeForComparison(await canonicalPath(targetWorkspaceDir)) === normalizeForComparison(await canonicalPath(sourceWorkspaceDir));
222
222
  if (!sameWorkspace) {
223
- const overwrite = await ctx.ui.confirm("CodeCartographer already exists", "A .codecarto/ directory already exists in this repository. Overwrite it?");
223
+ const overwrite = await ctx.ui.confirm("CodeCartographer already exists — data will be lost", "A .codecarto/ directory already exists in this repository. Re-initializing will back up the existing workspace to .codecarto-backup-TIMESTAMP/ and create a fresh one. All phase findings, handoffs, usage data, closeouts, and progress will be moved to the backup. Consider /codecarto-open to reattach without resetting. Continue?");
224
224
  if (!overwrite)
225
225
  return;
226
- await rm(targetWorkspaceDir, { recursive: true, force: true });
226
+ const backupDir = join(ctx.cwd, `.codecarto-backup-${new Date().toISOString().replace(/[:.]/g, "-")}`);
227
+ await rename(targetWorkspaceDir, backupDir);
228
+ if (ctx.hasUI)
229
+ ctx.ui.notify(`Backed up existing workspace to ${basename(backupDir)}/`, "info");
227
230
  }
228
231
  }
229
232
  if (!(await pathExists(targetWorkspaceDir))) {
@@ -538,12 +541,12 @@ export default function codeCartographerExtension(pi) {
538
541
  return;
539
542
  const config = await loadCodecartoConfig(state.workspaceDir);
540
543
  if (!config.library.path) {
541
- ctx.ui.notify("No library.path is configured. Set it in ~/.codecarto/config.yaml or .codecarto/workflow/config.yaml.", "error");
544
+ ctx.ui.notify("No library.path is configured. Create a library directory with a .codecarto-library marker, then set library.path in ~/.codecarto/config.yaml or .codecarto/workflow/config.yaml.", "error");
542
545
  return;
543
546
  }
544
547
  const marker = await discoverLibrary(config.library.path);
545
548
  if (!marker) {
546
- ctx.ui.notify(`No CodeCartographer library at ${config.library.path} (missing .codecarto-library).`, "error");
549
+ ctx.ui.notify(`No CodeCartographer library at ${config.library.path} (missing .codecarto-library). Create a .codecarto-library marker file in that directory.`, "error");
547
550
  return;
548
551
  }
549
552
  const phase = resolvePhase(state, "reimplementation-spec");
@@ -13,7 +13,7 @@
13
13
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
14
14
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
15
  import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
16
- import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
16
+ import { cp, mkdir, readFile, rename, writeFile } from "node:fs/promises";
17
17
  import { basename, isAbsolute, join } from "node:path";
18
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 ----------
@@ -77,9 +77,10 @@ export async function handleInit(args) {
77
77
  }
78
78
  if (targetExists && !sameWorkspace) {
79
79
  if (!args.force) {
80
- throw new McpError(ErrorCode.InvalidRequest, `A .codecarto/ directory already exists at ${targetWorkspaceDir}. Pass force: true to overwrite it.`);
80
+ throw new McpError(ErrorCode.InvalidRequest, `A .codecarto/ directory already exists at ${targetWorkspaceDir}. Pass force: true to back it up and reinitialize. Warning: this moves all existing findings, handoffs, usage data, closeouts, and phase progress to a .codecarto-backup-TIMESTAMP/ directory.`);
81
81
  }
82
- await rm(targetWorkspaceDir, { recursive: true, force: true });
82
+ const backupDir = join(cwd, `.codecarto-backup-${new Date().toISOString().replace(/[:.]/g, "-")}`);
83
+ await rename(targetWorkspaceDir, backupDir);
83
84
  }
84
85
  if (!(await pathExists(targetWorkspaceDir))) {
85
86
  await mkdir(cwd, { recursive: true });
@@ -463,7 +464,7 @@ export async function handleLibraryReindex(args) {
463
464
  const TOOLS = [
464
465
  {
465
466
  name: "codecarto_init",
466
- description: "Initialize a CodeCartographer workspace (.codecarto/) in a target repository. Copies the packaged framework template and writes a fresh status.yaml for the chosen pipeline. Errors if .codecarto/ already exists unless force is true.",
467
+ description: "Initialize a CodeCartographer workspace (.codecarto/) in a target repository. Copies the packaged framework template and writes a fresh status.yaml for the chosen pipeline. If .codecarto/ already exists, pass force: true to back up the existing workspace to .codecarto-backup-TIMESTAMP/ and create a fresh one. Warning: backing up moves all existing findings, handoffs, usage data, closeouts, and phase progress to the backup directory.",
467
468
  inputSchema: {
468
469
  type: "object",
469
470
  properties: {
@@ -474,7 +475,7 @@ const TOOLS = [
474
475
  },
475
476
  force: {
476
477
  type: "boolean",
477
- description: "Overwrite an existing .codecarto/ directory if present (default false).",
478
+ description: "Back up and overwrite an existing .codecarto/ directory if present (default false).",
478
479
  },
479
480
  },
480
481
  required: ["cwd"],
@@ -625,7 +626,7 @@ const HANDLERS = {
625
626
  };
626
627
  // ---------- server bootstrap ----------
627
628
  export function buildServer() {
628
- const server = new Server({ name: "codecartographer", version: "0.2.0" }, { capabilities: { tools: {} } });
629
+ const server = new Server({ name: "codecartographer", version: PACKAGE_VERSION }, { capabilities: { tools: {} } });
629
630
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
630
631
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
631
632
  const handler = HANDLERS[request.params.name];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codecartographer-pi",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "mcpName": "io.github.HuginnIndustries/codecartographer",
5
5
  "description": "Evidence-backed reverse engineering and human-gated software planning for Pi and MCP coding agents.",
6
6
  "type": "module",