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.
package/dist/core/synthesis.js
CHANGED
|
@@ -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
|
|
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}
|
|
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.
|
|
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.
|
|
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}.
|
|
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.
|
|
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,
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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,
|
|
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
|
|
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
|
-
|
|
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.
|
|
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: "
|
|
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:
|
|
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
|
+
"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",
|