mancode 0.5.1 → 0.5.3
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/README.en.md +286 -325
- package/README.md +239 -281
- package/dist/{chunk-SOZ5OUAG.js → chunk-2JOKDC3X.js} +6 -2
- package/dist/chunk-2JOKDC3X.js.map +1 -0
- package/dist/cli.js +990 -629
- package/dist/cli.js.map +1 -1
- package/dist/{v3-adapter-CRSQO3XW.js → v3-adapter-DBVEX5H5.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-SOZ5OUAG.js.map +0 -1
- /package/dist/{v3-adapter-CRSQO3XW.js.map → v3-adapter-DBVEX5H5.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -134,7 +134,7 @@ import {
|
|
|
134
134
|
stageV3AdapterUpgradeFiles,
|
|
135
135
|
v3AdapterTargetPath,
|
|
136
136
|
v3AdapterVersionsFromStatuses
|
|
137
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-2JOKDC3X.js";
|
|
138
138
|
|
|
139
139
|
// src/cli.ts
|
|
140
140
|
import { Option, program } from "commander";
|
|
@@ -9883,7 +9883,7 @@ async function activateLegacyMigration(input) {
|
|
|
9883
9883
|
for (const action of payload.actions.filter(
|
|
9884
9884
|
(action2) => action2.kind === "v3_adapter_file"
|
|
9885
9885
|
)) {
|
|
9886
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
9886
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-DBVEX5H5.js");
|
|
9887
9887
|
await applyV3AdapterFilePlan2(root, action);
|
|
9888
9888
|
}
|
|
9889
9889
|
journal = await completeActivationStep(
|
|
@@ -13739,7 +13739,7 @@ async function upgradeV3Adapters(input) {
|
|
|
13739
13739
|
if (unfinished.length > 0) {
|
|
13740
13740
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
13741
13741
|
}
|
|
13742
|
-
const actualVersions = await import("./v3-adapter-
|
|
13742
|
+
const actualVersions = await import("./v3-adapter-DBVEX5H5.js").then(
|
|
13743
13743
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
13744
13744
|
root,
|
|
13745
13745
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -14341,6 +14341,7 @@ var SCOUT_AGENT = {
|
|
|
14341
14341
|
- \u53EA\u5217\u5BF9\u5B9E\u65BD\u6709\u7528\u7684\u4FE1\u606F
|
|
14342
14342
|
- \u627E\u5230\u98CE\u9669\u70B9\u8981\u6807\u6CE8\uFF08\u26A0\uFE0F\uFF09
|
|
14343
14343
|
- \u4E0D\u786E\u5B9A\u7684\u8981\u660E\u8BF4\uFF0C\u4E0D\u731C
|
|
14344
|
+
- \u5B58\u5728 \`.mancode/shared/context/glossary.json\` \u65F6\uFF0C\u62A5\u544A\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u672F\u8BED\uFF1B\u53D1\u73B0\u65B0\u7684\u9AD8\u9891\u9886\u57DF\u8BCD\u53EF\u5728\u62A5\u544A\u4E2D\u5217\u4E3A\u5EFA\u8BAE\u8BCD\u6761\uFF08\u4EC5\u5EFA\u8BAE\uFF0C\u4E0D\u5199\u5165\u672F\u8BED\u8868\uFF09
|
|
14344
14345
|
- \u5F15\u7528\u6587\u4EF6\u7528 \`path:line\` \u683C\u5F0F\uFF0C\u8BA9 Head Coach \u4E00\u79D2\u8DF3\u8FC7\u53BB
|
|
14345
14346
|
|
|
14346
14347
|
## \u4F60\u4E0D\u662F\u51B3\u7B56\u8005
|
|
@@ -14453,7 +14454,7 @@ var PLAN_COACH_AGENT = {
|
|
|
14453
14454
|
tools: ["Read", "Grep", "Glob"],
|
|
14454
14455
|
body: `\u4F60\u662F mancode \u6559\u7EC3\u7EC4\u7684 Plan Coach\uFF08\u8BA1\u5212\u6559\u7EC3\uFF09\u3002
|
|
14455
14456
|
|
|
14456
|
-
\u4F60\u7684\u804C\u8D23\uFF1A\u5148\u68C0\u67E5\u9700\u6C42\u662F\u5426\u8DB3\u591F\u652F\u6491\u8BA1\u5212\uFF0C\u518D\u5728\u7528\u6237\u786E\u8BA4\u524D\u628A Scout Report\u3001\u7ED3\u6784\u5316 requirements \u548C\u56E2\u961F\u4E0A\u4E0B\u6587\u6574\u7406\u6210\u53EF\u6267\u884C plan\u3002
|
|
14457
|
+
\u4F60\u7684\u804C\u8D23\uFF1A\u5148\u68C0\u67E5\u9700\u6C42\u662F\u5426\u8DB3\u591F\u652F\u6491\u8BA1\u5212\uFF0C\u518D\u5728\u7528\u6237\u786E\u8BA4\u524D\u628A Scout Report\u3001\u7ED3\u6784\u5316 requirements \u548C\u56E2\u961F\u4E0A\u4E0B\u6587\u6574\u7406\u6210\u53EF\u6267\u884C plan\u3002\u5B58\u5728 \`.mancode/shared/context/glossary.json\` \u65F6\uFF0C\u8BA1\u5212\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u672F\u8BED\uFF1B\u53D1\u73B0\u65B0\u7684\u9AD8\u9891\u9886\u57DF\u8BCD\u53EF\u5728\u8BA1\u5212\u4E2D\u5217\u4E3A\u5EFA\u8BAE\u8BCD\u6761\uFF08\u4EC5\u5EFA\u8BAE\uFF0C\u4E0D\u5199\u5165\u672F\u8BED\u8868\uFF09\u3002
|
|
14457
14458
|
|
|
14458
14459
|
## \u786C\u7EA6\u675F
|
|
14459
14460
|
|
|
@@ -15321,7 +15322,7 @@ var MAN_SKILL = {
|
|
|
15321
15322
|
|
|
15322
15323
|
### Step 1: Scout \u8C03\u7814
|
|
15323
15324
|
|
|
15324
|
-
\u8C03\u7528 \`scout\`\uFF0C\u5199 \`scout-report.md\`\u3002\u62A5\u544A\u5FC5\u987B\u5305\u542B\u201C**\u4E0D\u786E\u5B9A\u7684\u5730\u65B9**\u201D\uFF0C\u5E76\u6309\u53EF\u9A8C\u8BC1\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1B\u5B57\u6BB5\u4E0D\u76F8\u5173\u6216\u65E0\u6CD5\u9A8C\u8BC1\u65F6\u53EF\u4EE5\u7701\u7565\uFF0C\u4E0D\u80FD\u7F16\u9020\u3002Current Behavior Evidence \u81F3\u5C11\u6709\u4E00\u4E2A\u53EF\u590D\u73B0\u89C2\u5BDF\u548C\u4ED3\u5E93\u8DEF\u5F84\u3001\u6D4B\u8BD5\u6216\u547D\u4EE4\u8BC1\u636E\uFF1Bowner \u5199\u7F6E\u4FE1\u5EA6\u4E0E\u51B2\u7A81\uFF1Bsource of truth \u533A\u5206 authority \u548C derived copy\uFF1B\u517C\u5BB9\u5F71\u54CD\u8986\u76D6\u65E7 workflow\u3001legacy fixture\u3001transport\u3001\u8FC1\u79FB\u548C rollback\u3002\u8FD0\u884C \`mancode workflow update <taskId> --step 2\`\u3002
|
|
15325
|
+
\u5148\u8BFB \`.mancode/shared/context/glossary.json\`\uFF08\u82E5\u5B58\u5728\uFF09\uFF0C\u8C03\u7814\u3001\u62A5\u544A\u4E0E\u540E\u7EED\u6C9F\u901A\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u5DF2\u786E\u8BA4\u672F\u8BED\u3002\u8C03\u7528 \`scout\`\uFF0C\u5199 \`scout-report.md\`\u3002\u62A5\u544A\u5FC5\u987B\u5305\u542B\u201C**\u4E0D\u786E\u5B9A\u7684\u5730\u65B9**\u201D\uFF0C\u5E76\u6309\u53EF\u9A8C\u8BC1\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1B\u5B57\u6BB5\u4E0D\u76F8\u5173\u6216\u65E0\u6CD5\u9A8C\u8BC1\u65F6\u53EF\u4EE5\u7701\u7565\uFF0C\u4E0D\u80FD\u7F16\u9020\u3002Current Behavior Evidence \u81F3\u5C11\u6709\u4E00\u4E2A\u53EF\u590D\u73B0\u89C2\u5BDF\u548C\u4ED3\u5E93\u8DEF\u5F84\u3001\u6D4B\u8BD5\u6216\u547D\u4EE4\u8BC1\u636E\uFF1Bowner \u5199\u7F6E\u4FE1\u5EA6\u4E0E\u51B2\u7A81\uFF1Bsource of truth \u533A\u5206 authority \u548C derived copy\uFF1B\u517C\u5BB9\u5F71\u54CD\u8986\u76D6\u65E7 workflow\u3001legacy fixture\u3001transport\u3001\u8FC1\u79FB\u548C rollback\u3002\u8FD0\u884C \`mancode workflow update <taskId> --step 2\`\u3002
|
|
15325
15326
|
|
|
15326
15327
|
### Step 2: \u9700\u6C42\u6F84\u6E05
|
|
15327
15328
|
|
|
@@ -15388,7 +15389,7 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
|
|
|
15388
15389
|
2. remediation \u4F1A\u4F7F\u65E7\u9A8C\u8BC1\u6574\u6279\u5931\u6548\u3002\u5728 Step 9 \u91CD\u8DD1\u5168\u90E8 required \u9A8C\u6536\uFF0C\u5E76\u901A\u8FC7 verify record/require-manual/confirm-manual \u91CD\u65B0\u767B\u8BB0\u8BC1\u636E\uFF1B\u672A\u91CD\u65B0\u5168\u90E8\u901A\u8FC7\u4E0D\u80FD completed\u3002\u4E0D\u91CD\u65B0\u8FD0\u884C\u5DF2\u5B8C\u6210\u7684 reviewer\u3002\u4FEE\u590D\u82E5\u5F15\u5165\u65B0\u7684\u9AD8\u98CE\u9669\u9762\u5219\u6807\u8BB0 blocked\uFF0C\u4E0D\u80FD\u5F00\u542F\u65E0\u754C review \u5FAA\u73AF\u3002
|
|
15389
15390
|
3. \u5199 \`summary.md\`\uFF1A\u6539\u52A8\u3001\u65B0\u5EFA\u3001\u590D\u7528\u3001\u9A8C\u8BC1\u3001\u5BA1\u67E5\u6DF1\u5EA6\u3001findings \u5904\u7F6E\u3001\u8DF3\u8FC7\u6B65\u9AA4\u548C\u6B8B\u4F59\u98CE\u9669\u3002
|
|
15390
15391
|
4. CLI \u786E\u8BA4\u6240\u9700\u5BA1\u67E5\u9886\u57DF\u5B8C\u6210\u4E14 blocker \u6E05\u96F6\u540E\u624D\u5199 \`completed\`\uFF1B\u5426\u5219\u7528 \`--status blocked --blocking-reason "<\u539F\u56E0>"\`\u3002
|
|
15391
|
-
5. \u5173\u952E\u51B3\u7B56 appendTeamDecision \u5230 \`decisions.md\`\uFF0C\u66F4\u65B0 Active Plans\u3002
|
|
15392
|
+
5. \u5173\u952E\u51B3\u7B56 appendTeamDecision \u5230 \`decisions.md\`\uFF0C\u66F4\u65B0 Active Plans\u3002\u53D1\u73B0\u65B0\u7684\u9AD8\u9891\u9886\u57DF\u8BCD\u65F6\u5411\u7528\u6237\u63D0\u8BAE\uFF0C\u7ECF\u7528\u6237\u786E\u8BA4\u540E\u7528 \`mancode context glossary add\` \u767B\u8BB0\uFF0C\u4E0D\u5F97\u672A\u7ECF\u786E\u8BA4\u5199\u5165\u672F\u8BED\u8868\u3002
|
|
15392
15393
|
6. worktree \u5408\u5E76\u524D\u53D6\u5F97\u7528\u6237\u786E\u8BA4\uFF1B\u7EC8\u6001\u5199\u5165\u6210\u529F\u540E state \u56DE solo \u5E76\u6E05\u7A7A workflow \u6307\u9488\u3002
|
|
15393
15394
|
|
|
15394
15395
|
\u4EFB\u4F55 step/status/outcome/planVersion \u53D8\u5316\u90FD\u5FC5\u987B\u7ECF\u8FC7 workflow CLI\uFF1BCLI \u62D2\u7EDD\u65F6\u4FDD\u7559\u5F53\u524D state \u5E76\u62A5\u544A\u539F\u56E0\uFF0C\u4E0D\u53EF\u7ED5\u8FC7\u6821\u9A8C\u76F4\u63A5\u6539 metadata.json\u3002
|
|
@@ -15615,7 +15616,7 @@ var MANSOLO_SKILL = {
|
|
|
15615
15616
|
description: "Switch back to solo mode. Clears the current workflow state and returns to lightweight daily-practice mode.",
|
|
15616
15617
|
body: `# mancode \xB7 /mansolo (Back to Practice)
|
|
15617
15618
|
|
|
15618
|
-
\u7528\u6237\u7528 \`/mansolo\` \u89E6\u53D1\u4F60\u3002\u8FD9\u662F**\u5207\u56DE solo \u6A21\u5F0F**\u7684\u547D\u4EE4\u3002
|
|
15619
|
+
\u7528\u6237\u7528 \`/mansolo\` \u89E6\u53D1\u4F60\u3002\u8FD9\u662F**\u5207\u56DE solo \u6A21\u5F0F**\u7684\u547D\u4EE4\u3002\u5B58\u5728 \`.mancode/shared/context/glossary.json\` \u65F6\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u672F\u8BED\u3002
|
|
15619
15620
|
|
|
15620
15621
|
## \u4F60\u8981\u505A\u7684
|
|
15621
15622
|
|
|
@@ -15673,7 +15674,7 @@ var MANTEAM_SKILL = {
|
|
|
15673
15674
|
description: "Team workflow for shared repositories. Adds contributor context, coordination notes, commit discipline, and hand-off summaries to the full /man flow.",
|
|
15674
15675
|
body: `# mancode \xB7 /manteam (Team Game)
|
|
15675
15676
|
|
|
15676
|
-
\u7528\u6237\u7528 \`/manteam <task>\` \u89E6\u53D1\u4F60\u3002\u8FD9\u662F\u591A\u4EBA\u534F\u4F5C\u7248\u7684\u5B8C\u6574\u5DE5\u4F5C\u6D41\uFF1A\u5148\u7406\u89E3\u56E2\u961F\u4E0A\u4E0B\u6587\uFF0C\u518D\u6309 /man \u7684 9 \u6B65\u6D41\u7A0B\u63A8\u8FDB\u3002
|
|
15677
|
+
\u7528\u6237\u7528 \`/manteam <task>\` \u89E6\u53D1\u4F60\u3002\u8FD9\u662F\u591A\u4EBA\u534F\u4F5C\u7248\u7684\u5B8C\u6574\u5DE5\u4F5C\u6D41\uFF1A\u5148\u7406\u89E3\u56E2\u961F\u4E0A\u4E0B\u6587\uFF0C\u518D\u6309 /man \u7684 9 \u6B65\u6D41\u7A0B\u63A8\u8FDB\u3002\u5B58\u5728 \`.mancode/shared/context/glossary.json\` \u65F6\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u672F\u8BED\u3002
|
|
15677
15678
|
|
|
15678
15679
|
\u7528 \`mancode workflow create manteam "<task>" --json\` \u521B\u5EFA workflow\uFF0C\u5E76\u5C06 state \u6307\u5411\u8FD4\u56DE\u7684 taskId\u3002\u540E\u7EED step/status/planVersion/skippedSteps \u5168\u90E8\u4F7F\u7528 \`mancode workflow update\`\uFF1B\u4E0D\u5F97\u76F4\u63A5\u6539 metadata.json\u3002\u82E5\u5DF2\u6709 active workflow\uFF0C\u5148\u8BA9\u7528\u6237\u9009\u62E9\u6062\u590D\u6216\u653E\u5F03\uFF0C\u4E0D\u80FD\u6E05\u7A7A\u65E7\u6307\u9488\u3002
|
|
15679
15680
|
|
|
@@ -18122,7 +18123,7 @@ function commandClient(value) {
|
|
|
18122
18123
|
}
|
|
18123
18124
|
function printV3Result(json, result2) {
|
|
18124
18125
|
if (json) {
|
|
18125
|
-
console.log(JSON.stringify(result2
|
|
18126
|
+
console.log(JSON.stringify(result2));
|
|
18126
18127
|
} else {
|
|
18127
18128
|
console.log(JSON.stringify(result2, null, 2));
|
|
18128
18129
|
}
|
|
@@ -18131,7 +18132,7 @@ function printV3Result(json, result2) {
|
|
|
18131
18132
|
function printV3Error(json, code, message, exitCode = EXIT_V3_BLOCKED) {
|
|
18132
18133
|
const result2 = { schemaVersion: 1, error: { code, message } };
|
|
18133
18134
|
if (json) {
|
|
18134
|
-
console.log(JSON.stringify(result2
|
|
18135
|
+
console.log(JSON.stringify(result2));
|
|
18135
18136
|
} else {
|
|
18136
18137
|
console.error(`\u2717 ${code}`);
|
|
18137
18138
|
console.error(` ${message}`);
|
|
@@ -18235,9 +18236,263 @@ function selectUpgradePlatforms(options) {
|
|
|
18235
18236
|
return options.all === true ? [...V3_ADAPTER_PLATFORMS] : selectStatusPlatforms(options.platform);
|
|
18236
18237
|
}
|
|
18237
18238
|
|
|
18238
|
-
// src/context/
|
|
18239
|
-
import {
|
|
18239
|
+
// src/context/glossary.ts
|
|
18240
|
+
import { mkdir as mkdir27, readFile as readFile30, rename as rename9, rm as rm14, writeFile as writeFile33 } from "fs/promises";
|
|
18240
18241
|
import path37 from "path";
|
|
18242
|
+
var GLOSSARY_TERM_MAX_LENGTH = 64;
|
|
18243
|
+
var GLOSSARY_DEFINITION_MAX_LENGTH = 500;
|
|
18244
|
+
var GLOSSARY_MAX_ENTRIES = 200;
|
|
18245
|
+
var GLOSSARY_LOCK_KEY = "glossary:project";
|
|
18246
|
+
function emptyProjectGlossary() {
|
|
18247
|
+
return { schemaVersion: 1, revision: 0, entries: [] };
|
|
18248
|
+
}
|
|
18249
|
+
function parseProjectGlossary(value) {
|
|
18250
|
+
assertRecord(value, "project glossary");
|
|
18251
|
+
assertKnownKeys(
|
|
18252
|
+
value,
|
|
18253
|
+
["schemaVersion", "revision", "entries"],
|
|
18254
|
+
"project glossary"
|
|
18255
|
+
);
|
|
18256
|
+
if (value.schemaVersion !== 1) {
|
|
18257
|
+
throw new Error("project glossary schemaVersion must be 1");
|
|
18258
|
+
}
|
|
18259
|
+
const revision = value.revision;
|
|
18260
|
+
if (typeof revision !== "number" || !Number.isSafeInteger(revision) || revision < 0) {
|
|
18261
|
+
throw new Error("project glossary revision must be a non-negative integer");
|
|
18262
|
+
}
|
|
18263
|
+
if (!Array.isArray(value.entries)) {
|
|
18264
|
+
throw new Error("project glossary entries must be an array");
|
|
18265
|
+
}
|
|
18266
|
+
if (value.entries.length > GLOSSARY_MAX_ENTRIES) {
|
|
18267
|
+
throw new Error("MANCODE_GLOSSARY_ENTRY_LIMIT_EXCEEDED");
|
|
18268
|
+
}
|
|
18269
|
+
const entries = value.entries.map((entry) => parseGlossaryEntry(entry));
|
|
18270
|
+
assertGlobalTermUniqueness(entries);
|
|
18271
|
+
return { schemaVersion: 1, revision, entries };
|
|
18272
|
+
}
|
|
18273
|
+
function parseGlossaryEntry(value) {
|
|
18274
|
+
assertRecord(value, "glossary entry");
|
|
18275
|
+
assertKnownKeys(
|
|
18276
|
+
value,
|
|
18277
|
+
["term", "definition", "aliases", "sourceTaskRef", "confirmedAt"],
|
|
18278
|
+
"glossary entry"
|
|
18279
|
+
);
|
|
18280
|
+
const term = parseGlossaryText(
|
|
18281
|
+
value.term,
|
|
18282
|
+
"glossary term",
|
|
18283
|
+
GLOSSARY_TERM_MAX_LENGTH
|
|
18284
|
+
);
|
|
18285
|
+
const definition2 = parseGlossaryText(
|
|
18286
|
+
value.definition,
|
|
18287
|
+
"glossary definition",
|
|
18288
|
+
GLOSSARY_DEFINITION_MAX_LENGTH
|
|
18289
|
+
);
|
|
18290
|
+
if (!Array.isArray(value.aliases)) {
|
|
18291
|
+
throw new Error("glossary entry aliases must be an array");
|
|
18292
|
+
}
|
|
18293
|
+
const aliases = value.aliases.map(
|
|
18294
|
+
(alias) => parseGlossaryText(alias, "glossary alias", GLOSSARY_TERM_MAX_LENGTH)
|
|
18295
|
+
);
|
|
18296
|
+
const localKeys = /* @__PURE__ */ new Set([termKey(term)]);
|
|
18297
|
+
for (const alias of aliases) {
|
|
18298
|
+
const key = termKey(alias);
|
|
18299
|
+
if (localKeys.has(key)) {
|
|
18300
|
+
throw new Error(`MANCODE_GLOSSARY_TERM_CONFLICT: ${alias}`);
|
|
18301
|
+
}
|
|
18302
|
+
localKeys.add(key);
|
|
18303
|
+
}
|
|
18304
|
+
const sourceTaskRef = value.sourceTaskRef === null ? null : parseTaskRefValue(value.sourceTaskRef);
|
|
18305
|
+
if (sourceTaskRef?.namespace === "local") {
|
|
18306
|
+
throw new Error("MANCODE_GLOSSARY_LOCAL_TASK_FORBIDDEN");
|
|
18307
|
+
}
|
|
18308
|
+
return {
|
|
18309
|
+
term,
|
|
18310
|
+
definition: definition2,
|
|
18311
|
+
aliases,
|
|
18312
|
+
sourceTaskRef,
|
|
18313
|
+
confirmedAt: parseTimestamp12(value.confirmedAt, "glossary confirmedAt")
|
|
18314
|
+
};
|
|
18315
|
+
}
|
|
18316
|
+
function projectGlossaryPath(projectRoot) {
|
|
18317
|
+
return path37.join(
|
|
18318
|
+
path37.resolve(projectRoot),
|
|
18319
|
+
".mancode",
|
|
18320
|
+
"shared",
|
|
18321
|
+
"context",
|
|
18322
|
+
"glossary.json"
|
|
18323
|
+
);
|
|
18324
|
+
}
|
|
18325
|
+
async function readProjectGlossary(projectRoot) {
|
|
18326
|
+
try {
|
|
18327
|
+
return parseProjectGlossary(
|
|
18328
|
+
JSON.parse(await readFile30(projectGlossaryPath(projectRoot), "utf8"))
|
|
18329
|
+
);
|
|
18330
|
+
} catch (error) {
|
|
18331
|
+
if (isNotFound20(error)) return emptyProjectGlossary();
|
|
18332
|
+
if (error instanceof SyntaxError) {
|
|
18333
|
+
throw new Error(
|
|
18334
|
+
"MANCODE_CONTEXT_ENTITY_CORRUPT: shared/context/glossary.json"
|
|
18335
|
+
);
|
|
18336
|
+
}
|
|
18337
|
+
throw error;
|
|
18338
|
+
}
|
|
18339
|
+
}
|
|
18340
|
+
function findGlossaryEntry(glossary, term) {
|
|
18341
|
+
const key = termKey(term);
|
|
18342
|
+
return glossary.entries.find(
|
|
18343
|
+
(entry) => termKey(entry.term) === key || entry.aliases.some((alias) => termKey(alias) === key)
|
|
18344
|
+
) ?? null;
|
|
18345
|
+
}
|
|
18346
|
+
async function addGlossaryEntry(projectRoot, store, expectedRevision, input) {
|
|
18347
|
+
return mutateProjectGlossary(
|
|
18348
|
+
projectRoot,
|
|
18349
|
+
store,
|
|
18350
|
+
expectedRevision,
|
|
18351
|
+
(glossary) => {
|
|
18352
|
+
if (findGlossaryEntry(glossary, input.term) !== null) {
|
|
18353
|
+
throw new Error(`MANCODE_GLOSSARY_TERM_EXISTS: ${input.term}`);
|
|
18354
|
+
}
|
|
18355
|
+
if (glossary.entries.length >= GLOSSARY_MAX_ENTRIES) {
|
|
18356
|
+
throw new Error("MANCODE_GLOSSARY_ENTRY_LIMIT_EXCEEDED");
|
|
18357
|
+
}
|
|
18358
|
+
return [
|
|
18359
|
+
...glossary.entries,
|
|
18360
|
+
{
|
|
18361
|
+
term: input.term,
|
|
18362
|
+
definition: input.definition,
|
|
18363
|
+
aliases: input.aliases ?? [],
|
|
18364
|
+
sourceTaskRef: input.sourceTaskRef ?? null,
|
|
18365
|
+
confirmedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
18366
|
+
}
|
|
18367
|
+
];
|
|
18368
|
+
}
|
|
18369
|
+
);
|
|
18370
|
+
}
|
|
18371
|
+
async function updateGlossaryEntry(projectRoot, store, expectedRevision, input) {
|
|
18372
|
+
return mutateProjectGlossary(
|
|
18373
|
+
projectRoot,
|
|
18374
|
+
store,
|
|
18375
|
+
expectedRevision,
|
|
18376
|
+
(glossary) => {
|
|
18377
|
+
const key = termKey(input.term);
|
|
18378
|
+
const index = glossary.entries.findIndex(
|
|
18379
|
+
(entry) => termKey(entry.term) === key
|
|
18380
|
+
);
|
|
18381
|
+
if (index === -1) {
|
|
18382
|
+
throw new Error(`MANCODE_GLOSSARY_TERM_NOT_FOUND: ${input.term}`);
|
|
18383
|
+
}
|
|
18384
|
+
const previous = glossary.entries[index];
|
|
18385
|
+
const next = {
|
|
18386
|
+
term: previous.term,
|
|
18387
|
+
definition: input.definition ?? previous.definition,
|
|
18388
|
+
aliases: input.aliases ?? previous.aliases,
|
|
18389
|
+
sourceTaskRef: input.sourceTaskRef === void 0 ? previous.sourceTaskRef : input.sourceTaskRef,
|
|
18390
|
+
confirmedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
18391
|
+
};
|
|
18392
|
+
return glossary.entries.map(
|
|
18393
|
+
(entry, position) => position === index ? next : entry
|
|
18394
|
+
);
|
|
18395
|
+
}
|
|
18396
|
+
);
|
|
18397
|
+
}
|
|
18398
|
+
async function removeGlossaryEntry(projectRoot, store, expectedRevision, term) {
|
|
18399
|
+
return mutateProjectGlossary(
|
|
18400
|
+
projectRoot,
|
|
18401
|
+
store,
|
|
18402
|
+
expectedRevision,
|
|
18403
|
+
(glossary) => {
|
|
18404
|
+
const key = termKey(term);
|
|
18405
|
+
const remaining = glossary.entries.filter(
|
|
18406
|
+
(entry) => termKey(entry.term) !== key
|
|
18407
|
+
);
|
|
18408
|
+
if (remaining.length === glossary.entries.length) {
|
|
18409
|
+
throw new Error(`MANCODE_GLOSSARY_TERM_NOT_FOUND: ${term}`);
|
|
18410
|
+
}
|
|
18411
|
+
return remaining;
|
|
18412
|
+
}
|
|
18413
|
+
);
|
|
18414
|
+
}
|
|
18415
|
+
async function mutateProjectGlossary(projectRoot, store, expectedRevision, mutate) {
|
|
18416
|
+
if (!Number.isSafeInteger(expectedRevision) || expectedRevision < 0) {
|
|
18417
|
+
throw new Error(
|
|
18418
|
+
"MANCODE_GLOSSARY_EXPECTED_REVISION_INVALID: expected revision must be a non-negative integer"
|
|
18419
|
+
);
|
|
18420
|
+
}
|
|
18421
|
+
const lock = await acquireLocalLock(store, {
|
|
18422
|
+
operationId: createUlid(),
|
|
18423
|
+
entityLockKey: GLOSSARY_LOCK_KEY
|
|
18424
|
+
});
|
|
18425
|
+
try {
|
|
18426
|
+
const current = await readProjectGlossary(projectRoot);
|
|
18427
|
+
if (current.revision !== expectedRevision) {
|
|
18428
|
+
throw new Error(
|
|
18429
|
+
`MANCODE_GLOSSARY_REVISION_CONFLICT: expected ${expectedRevision}, found ${current.revision}`
|
|
18430
|
+
);
|
|
18431
|
+
}
|
|
18432
|
+
const next = parseProjectGlossary({
|
|
18433
|
+
schemaVersion: 1,
|
|
18434
|
+
revision: current.revision + 1,
|
|
18435
|
+
entries: mutate(current)
|
|
18436
|
+
});
|
|
18437
|
+
await writeGlossaryFile(projectRoot, next);
|
|
18438
|
+
return next;
|
|
18439
|
+
} finally {
|
|
18440
|
+
await lock.release().catch(() => void 0);
|
|
18441
|
+
}
|
|
18442
|
+
}
|
|
18443
|
+
async function writeGlossaryFile(projectRoot, glossary) {
|
|
18444
|
+
const target = projectGlossaryPath(projectRoot);
|
|
18445
|
+
await mkdir27(path37.dirname(target), { recursive: true });
|
|
18446
|
+
const temporary = path37.join(
|
|
18447
|
+
path37.dirname(target),
|
|
18448
|
+
`.${path37.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
18449
|
+
);
|
|
18450
|
+
try {
|
|
18451
|
+
await writeFile33(temporary, `${JSON.stringify(glossary, null, 2)}
|
|
18452
|
+
`, {
|
|
18453
|
+
encoding: "utf8",
|
|
18454
|
+
flag: "wx"
|
|
18455
|
+
});
|
|
18456
|
+
await rename9(temporary, target);
|
|
18457
|
+
} finally {
|
|
18458
|
+
await rm14(temporary, { force: true }).catch(() => void 0);
|
|
18459
|
+
}
|
|
18460
|
+
}
|
|
18461
|
+
function assertGlobalTermUniqueness(entries) {
|
|
18462
|
+
const keys = /* @__PURE__ */ new Set();
|
|
18463
|
+
for (const entry of entries) {
|
|
18464
|
+
for (const candidate of [entry.term, ...entry.aliases]) {
|
|
18465
|
+
const key = termKey(candidate);
|
|
18466
|
+
if (keys.has(key)) {
|
|
18467
|
+
throw new Error(`MANCODE_GLOSSARY_TERM_CONFLICT: ${candidate}`);
|
|
18468
|
+
}
|
|
18469
|
+
keys.add(key);
|
|
18470
|
+
}
|
|
18471
|
+
}
|
|
18472
|
+
}
|
|
18473
|
+
function termKey(value) {
|
|
18474
|
+
return value.trim().toLowerCase();
|
|
18475
|
+
}
|
|
18476
|
+
function parseGlossaryText(value, label, maxLength) {
|
|
18477
|
+
if (typeof value !== "string" || !value.trim() || value.includes("\0") || value.length > maxLength) {
|
|
18478
|
+
throw new Error(`${label} is invalid`);
|
|
18479
|
+
}
|
|
18480
|
+
assertSharedTextSafe(value, label);
|
|
18481
|
+
return value;
|
|
18482
|
+
}
|
|
18483
|
+
function parseTimestamp12(value, label) {
|
|
18484
|
+
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
18485
|
+
throw new Error(`${label} must be an ISO timestamp`);
|
|
18486
|
+
}
|
|
18487
|
+
return value;
|
|
18488
|
+
}
|
|
18489
|
+
function isNotFound20(error) {
|
|
18490
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
18491
|
+
}
|
|
18492
|
+
|
|
18493
|
+
// src/context/publish-promote.ts
|
|
18494
|
+
import { lstat as lstat12, mkdir as mkdir28, rename as rename10, rm as rm15, writeFile as writeFile34 } from "fs/promises";
|
|
18495
|
+
import path38 from "path";
|
|
18241
18496
|
|
|
18242
18497
|
// src/context/task-mutation.ts
|
|
18243
18498
|
function markTaskReviewStale(previous, operationId, updatedAt) {
|
|
@@ -18969,15 +19224,15 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
18969
19224
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
18970
19225
|
const parent = await ensureSafeTaskParent2(projectRoot, destinationTaskRef);
|
|
18971
19226
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
18972
|
-
const staging =
|
|
19227
|
+
const staging = path38.join(
|
|
18973
19228
|
parent,
|
|
18974
19229
|
`.${destinationTaskRef.taskId}.${operationId}.staging`
|
|
18975
19230
|
);
|
|
18976
19231
|
await assertPathAbsent(staging, "MANCODE_PROMOTION_STAGING_CONFLICT");
|
|
18977
|
-
await
|
|
19232
|
+
await mkdir28(staging);
|
|
18978
19233
|
try {
|
|
18979
19234
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
18980
|
-
await
|
|
19235
|
+
await writeFile34(path38.join(staging, fileName), content, {
|
|
18981
19236
|
encoding: "utf8",
|
|
18982
19237
|
flag: "wx"
|
|
18983
19238
|
});
|
|
@@ -18985,7 +19240,7 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
18985
19240
|
await assertSafeDirectory3(staging);
|
|
18986
19241
|
return staging;
|
|
18987
19242
|
} catch (error) {
|
|
18988
|
-
await
|
|
19243
|
+
await rm15(staging, { recursive: true, force: true });
|
|
18989
19244
|
throw error;
|
|
18990
19245
|
}
|
|
18991
19246
|
}
|
|
@@ -18993,11 +19248,11 @@ async function ensureSafeTaskParent2(projectRoot, taskRef) {
|
|
|
18993
19248
|
await assertSafeDirectory3(projectRoot);
|
|
18994
19249
|
let current = projectRoot;
|
|
18995
19250
|
for (const segment of [".mancode", taskRef.namespace, "workflows"]) {
|
|
18996
|
-
current =
|
|
19251
|
+
current = path38.join(current, segment);
|
|
18997
19252
|
const existing = await lstatOrNull2(current);
|
|
18998
19253
|
if (existing === null) {
|
|
18999
19254
|
try {
|
|
19000
|
-
await
|
|
19255
|
+
await mkdir28(current);
|
|
19001
19256
|
continue;
|
|
19002
19257
|
} catch (error) {
|
|
19003
19258
|
if (!isAlreadyExists16(error)) throw error;
|
|
@@ -19014,7 +19269,7 @@ async function publishStagedDestination(projectRoot, destinationTaskRef, staging
|
|
|
19014
19269
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
19015
19270
|
await assertSafeDirectory3(staging);
|
|
19016
19271
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
19017
|
-
await
|
|
19272
|
+
await rename10(staging, target);
|
|
19018
19273
|
await assertSafeDirectory3(target);
|
|
19019
19274
|
}
|
|
19020
19275
|
async function assertDestinationAbsent(projectRoot, destinationHomeStore, destinationTaskRef) {
|
|
@@ -19169,7 +19424,7 @@ async function handlePromotionFailure(source, primaryStore, journal, stagingDire
|
|
|
19169
19424
|
} catch {
|
|
19170
19425
|
} finally {
|
|
19171
19426
|
if (stagingDirectory !== null) {
|
|
19172
|
-
await
|
|
19427
|
+
await rm15(stagingDirectory, { recursive: true, force: true });
|
|
19173
19428
|
}
|
|
19174
19429
|
}
|
|
19175
19430
|
}
|
|
@@ -19178,41 +19433,41 @@ async function renewPromotionLocks(source) {
|
|
|
19178
19433
|
}
|
|
19179
19434
|
async function writePromotionQuarantine(projectRoot, operationId, candidate, contents) {
|
|
19180
19435
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
19181
|
-
const parent =
|
|
19182
|
-
await
|
|
19436
|
+
const parent = path38.dirname(directory);
|
|
19437
|
+
await mkdir28(parent, { recursive: true });
|
|
19183
19438
|
await assertSafeDirectory3(parent);
|
|
19184
19439
|
await assertPathAbsent(directory, "MANCODE_PROMOTION_QUARANTINE_CONFLICT");
|
|
19185
|
-
await
|
|
19440
|
+
await mkdir28(directory);
|
|
19186
19441
|
try {
|
|
19187
|
-
await
|
|
19188
|
-
|
|
19442
|
+
await writeFile34(
|
|
19443
|
+
path38.join(directory, "candidate.json"),
|
|
19189
19444
|
serializeTaskAuthority(candidate),
|
|
19190
19445
|
{ encoding: "utf8", flag: "wx" }
|
|
19191
19446
|
);
|
|
19192
19447
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
19193
|
-
await
|
|
19448
|
+
await writeFile34(path38.join(directory, fileName), content, {
|
|
19194
19449
|
encoding: "utf8",
|
|
19195
19450
|
flag: "wx"
|
|
19196
19451
|
});
|
|
19197
19452
|
}
|
|
19198
19453
|
} catch (error) {
|
|
19199
|
-
await
|
|
19454
|
+
await rm15(directory, { recursive: true, force: true });
|
|
19200
19455
|
throw error;
|
|
19201
19456
|
}
|
|
19202
19457
|
}
|
|
19203
19458
|
async function rewritePromotionQuarantine(projectRoot, operationId, candidate) {
|
|
19204
19459
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
19205
19460
|
await assertSafeDirectory3(directory);
|
|
19206
|
-
const target =
|
|
19207
|
-
const temporary =
|
|
19461
|
+
const target = path38.join(directory, "candidate.json");
|
|
19462
|
+
const temporary = path38.join(
|
|
19208
19463
|
directory,
|
|
19209
19464
|
`.candidate.${process.pid}.${Date.now()}.tmp`
|
|
19210
19465
|
);
|
|
19211
|
-
await
|
|
19466
|
+
await writeFile34(temporary, serializeTaskAuthority(candidate), {
|
|
19212
19467
|
encoding: "utf8",
|
|
19213
19468
|
flag: "wx"
|
|
19214
19469
|
});
|
|
19215
|
-
await
|
|
19470
|
+
await rename10(temporary, target);
|
|
19216
19471
|
}
|
|
19217
19472
|
function completeOperationStep2(steps, stepId) {
|
|
19218
19473
|
const index = steps.findIndex((step) => step.id === stepId);
|
|
@@ -19254,11 +19509,11 @@ async function lstatOrNull2(target) {
|
|
|
19254
19509
|
try {
|
|
19255
19510
|
return await lstat12(target);
|
|
19256
19511
|
} catch (error) {
|
|
19257
|
-
if (
|
|
19512
|
+
if (isNotFound21(error)) return null;
|
|
19258
19513
|
throw error;
|
|
19259
19514
|
}
|
|
19260
19515
|
}
|
|
19261
|
-
function
|
|
19516
|
+
function isNotFound21(error) {
|
|
19262
19517
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
19263
19518
|
}
|
|
19264
19519
|
function isAlreadyExists16(error) {
|
|
@@ -20026,7 +20281,7 @@ function compareUtf89(left, right) {
|
|
|
20026
20281
|
|
|
20027
20282
|
// src/context/task-head-reconcile.ts
|
|
20028
20283
|
import { execFile as execFileCallback4 } from "child_process";
|
|
20029
|
-
import
|
|
20284
|
+
import path40 from "path";
|
|
20030
20285
|
import { promisify as promisify4 } from "util";
|
|
20031
20286
|
|
|
20032
20287
|
// src/team/conflicts.ts
|
|
@@ -20226,9 +20481,9 @@ function unique(values) {
|
|
|
20226
20481
|
|
|
20227
20482
|
// src/team/git-ref-transport.ts
|
|
20228
20483
|
import { execFile as execFileCallback3 } from "child_process";
|
|
20229
|
-
import { mkdtemp, rm as
|
|
20484
|
+
import { mkdtemp, rm as rm16, writeFile as writeFile35 } from "fs/promises";
|
|
20230
20485
|
import { tmpdir } from "os";
|
|
20231
|
-
import
|
|
20486
|
+
import path39 from "path";
|
|
20232
20487
|
import { promisify as promisify3 } from "util";
|
|
20233
20488
|
var execFile3 = promisify3(execFileCallback3);
|
|
20234
20489
|
var TEAM_REF = "refs/mancode/team";
|
|
@@ -20251,7 +20506,7 @@ async function resolveGitRefRemoteIdentityHash(projectRoot, remote) {
|
|
|
20251
20506
|
}
|
|
20252
20507
|
let configured = remote;
|
|
20253
20508
|
try {
|
|
20254
|
-
const output = await runGit2(
|
|
20509
|
+
const output = await runGit2(path39.resolve(projectRoot), [
|
|
20255
20510
|
"remote",
|
|
20256
20511
|
"get-url",
|
|
20257
20512
|
"--all",
|
|
@@ -20301,7 +20556,7 @@ var GitRefTeamManifestStore = class {
|
|
|
20301
20556
|
"git-ref configRevision"
|
|
20302
20557
|
);
|
|
20303
20558
|
parseOptionalDigest(options.configDigest, "git-ref configDigest");
|
|
20304
|
-
this.projectRoot =
|
|
20559
|
+
this.projectRoot = path39.resolve(options.projectRoot);
|
|
20305
20560
|
this.remote = options.remote;
|
|
20306
20561
|
this.workspaceId = options.workspaceId;
|
|
20307
20562
|
this.expectedHeader = {
|
|
@@ -21023,7 +21278,7 @@ function parseGitRefTeamManifest(value) {
|
|
|
21023
21278
|
parseGitRefRemoteMutationReceipt
|
|
21024
21279
|
).sort(compareReceipts),
|
|
21025
21280
|
lastMutation: normalized.lastMutation === null ? null : parseGitRefRemoteMutationReceipt(normalized.lastMutation),
|
|
21026
|
-
updatedAt:
|
|
21281
|
+
updatedAt: parseTimestamp13(
|
|
21027
21282
|
normalized.updatedAt,
|
|
21028
21283
|
"git-ref team manifest updatedAt"
|
|
21029
21284
|
)
|
|
@@ -21078,7 +21333,7 @@ function parseGitRefOwnershipFence(value) {
|
|
|
21078
21333
|
"git-ref ownership fence remoteRevision"
|
|
21079
21334
|
),
|
|
21080
21335
|
lastOperationId: value.lastOperationId,
|
|
21081
|
-
updatedAt:
|
|
21336
|
+
updatedAt: parseTimestamp13(
|
|
21082
21337
|
value.updatedAt,
|
|
21083
21338
|
"git-ref ownership fence updatedAt"
|
|
21084
21339
|
)
|
|
@@ -21141,7 +21396,7 @@ function parseGitRefTaskBundle(value) {
|
|
|
21141
21396
|
value.bundleDigest,
|
|
21142
21397
|
"git-ref task bundle bundleDigest"
|
|
21143
21398
|
),
|
|
21144
|
-
createdAt:
|
|
21399
|
+
createdAt: parseTimestamp13(value.createdAt, "git-ref task bundle createdAt")
|
|
21145
21400
|
};
|
|
21146
21401
|
assertTaskBundleConsistency(bundle);
|
|
21147
21402
|
const { bundleDigest: _digest, ...body } = bundle;
|
|
@@ -21197,7 +21452,7 @@ function parseGitRefRemoteMutationReceipt(value) {
|
|
|
21197
21452
|
),
|
|
21198
21453
|
ownershipEpoch,
|
|
21199
21454
|
entityDigests: parseReceiptEntityDigests(value.entityDigests),
|
|
21200
|
-
committedAt:
|
|
21455
|
+
committedAt: parseTimestamp13(
|
|
21201
21456
|
value.committedAt,
|
|
21202
21457
|
"git-ref mutation receipt committedAt"
|
|
21203
21458
|
)
|
|
@@ -21231,7 +21486,7 @@ function parseGitRefAuthorityTombstone(value) {
|
|
|
21231
21486
|
"git-ref authority tombstone successorEpoch"
|
|
21232
21487
|
),
|
|
21233
21488
|
operationId: value.operationId,
|
|
21234
|
-
tombstonedAt:
|
|
21489
|
+
tombstonedAt: parseTimestamp13(
|
|
21235
21490
|
value.tombstonedAt,
|
|
21236
21491
|
"git-ref authority tombstone tombstonedAt"
|
|
21237
21492
|
)
|
|
@@ -21265,7 +21520,7 @@ function parseGitRefAuthorityFreeze(value) {
|
|
|
21265
21520
|
"git-ref authority freeze successorEpoch"
|
|
21266
21521
|
),
|
|
21267
21522
|
operationId: value.operationId,
|
|
21268
|
-
frozenAt:
|
|
21523
|
+
frozenAt: parseTimestamp13(
|
|
21269
21524
|
value.frozenAt,
|
|
21270
21525
|
"git-ref authority freeze frozenAt"
|
|
21271
21526
|
)
|
|
@@ -22007,17 +22262,17 @@ function upsertActorProfile(profiles, profile) {
|
|
|
22007
22262
|
}
|
|
22008
22263
|
async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
22009
22264
|
const temporaryDirectory = await mkdtemp(
|
|
22010
|
-
|
|
22265
|
+
path39.join(tmpdir(), "mancode-git-ref-")
|
|
22011
22266
|
);
|
|
22012
|
-
const manifestPath =
|
|
22013
|
-
const indexPath =
|
|
22267
|
+
const manifestPath = path39.join(temporaryDirectory, "manifest.json");
|
|
22268
|
+
const indexPath = path39.join(temporaryDirectory, "index");
|
|
22014
22269
|
try {
|
|
22015
22270
|
const serialized = `${JSON.stringify(manifest, null, 2)}
|
|
22016
22271
|
`;
|
|
22017
22272
|
if (Buffer.byteLength(serialized, "utf8") > MAX_MANIFEST_BYTES) {
|
|
22018
22273
|
throw new Error("MANCODE_TRANSPORT_MANIFEST_TOO_LARGE");
|
|
22019
22274
|
}
|
|
22020
|
-
await
|
|
22275
|
+
await writeFile35(manifestPath, serialized);
|
|
22021
22276
|
const blob = (await runGit2(projectRoot, ["hash-object", "-w", manifestPath])).trim();
|
|
22022
22277
|
const environment = { ...process.env, GIT_INDEX_FILE: indexPath };
|
|
22023
22278
|
await runGit2(projectRoot, ["read-tree", "--empty"], environment);
|
|
@@ -22049,7 +22304,7 @@ async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
|
22049
22304
|
commitEnvironment
|
|
22050
22305
|
)).trim();
|
|
22051
22306
|
} finally {
|
|
22052
|
-
await
|
|
22307
|
+
await rm16(temporaryDirectory, { recursive: true, force: true });
|
|
22053
22308
|
}
|
|
22054
22309
|
}
|
|
22055
22310
|
async function pushWithLease(projectRoot, remote, expectedCommit, commit3) {
|
|
@@ -22131,7 +22386,7 @@ function normalizeRemoteIdentity(projectRoot, value) {
|
|
|
22131
22386
|
url.pathname = url.pathname.replace(/\/+$/g, "");
|
|
22132
22387
|
return url.toString();
|
|
22133
22388
|
} catch {
|
|
22134
|
-
return
|
|
22389
|
+
return path39.resolve(projectRoot, value).replaceAll("\\", "/");
|
|
22135
22390
|
}
|
|
22136
22391
|
}
|
|
22137
22392
|
function parseBundleCodeRef(value) {
|
|
@@ -22203,7 +22458,7 @@ function parseVersion(value, label) {
|
|
|
22203
22458
|
}
|
|
22204
22459
|
return value;
|
|
22205
22460
|
}
|
|
22206
|
-
function
|
|
22461
|
+
function parseTimestamp13(value, label) {
|
|
22207
22462
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
22208
22463
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
22209
22464
|
}
|
|
@@ -22505,8 +22760,8 @@ function injectAfterReconcileStep(stepId) {
|
|
|
22505
22760
|
throwIfOperationCrashInjected("task_head_reconcile", stepId);
|
|
22506
22761
|
}
|
|
22507
22762
|
async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
22508
|
-
const relativeTaskRoot =
|
|
22509
|
-
if (!relativeTaskRoot ||
|
|
22763
|
+
const relativeTaskRoot = path40.relative(projectRoot, taskRoot2);
|
|
22764
|
+
if (!relativeTaskRoot || path40.isAbsolute(relativeTaskRoot) || relativeTaskRoot.split(path40.sep).some((part) => part === "..")) {
|
|
22510
22765
|
throw new Error("MANCODE_TASK_UNAVAILABLE");
|
|
22511
22766
|
}
|
|
22512
22767
|
const authorityFiles = [
|
|
@@ -22514,7 +22769,7 @@ async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
|
22514
22769
|
"requirements.json",
|
|
22515
22770
|
"review-ledger.json",
|
|
22516
22771
|
"verification-ledger.json"
|
|
22517
|
-
].map((file) =>
|
|
22772
|
+
].map((file) => path40.join(relativeTaskRoot, file));
|
|
22518
22773
|
try {
|
|
22519
22774
|
await execFile4("git", ["rev-parse", "--verify", "HEAD^{commit}"], {
|
|
22520
22775
|
cwd: projectRoot,
|
|
@@ -22738,12 +22993,12 @@ var BETA_PLATFORMS = [
|
|
|
22738
22993
|
];
|
|
22739
22994
|
|
|
22740
22995
|
// src/runtime/retention.ts
|
|
22741
|
-
import { lstat as lstat13, readFile as
|
|
22742
|
-
import
|
|
22996
|
+
import { lstat as lstat13, readFile as readFile31, readdir as readdir14, rm as rm17 } from "fs/promises";
|
|
22997
|
+
import path41 from "path";
|
|
22743
22998
|
var TERMINAL_JOURNAL_RETENTION_DAYS = 30;
|
|
22744
22999
|
var RETAINED_NON_MILESTONE_CHECKPOINTS = 10;
|
|
22745
23000
|
async function planContextCompaction(input) {
|
|
22746
|
-
const root =
|
|
23001
|
+
const root = path41.resolve(input.projectRoot);
|
|
22747
23002
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
22748
23003
|
const store = new V3ContextStore(root);
|
|
22749
23004
|
const [project, runtime] = await Promise.all([
|
|
@@ -22816,7 +23071,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22816
23071
|
if (taskRef.namespace !== "shared") continue;
|
|
22817
23072
|
const task = await store.readTaskSnapshot(taskRef);
|
|
22818
23073
|
if (!isTerminalTaskStatus(task.metadata.status)) continue;
|
|
22819
|
-
const directory =
|
|
23074
|
+
const directory = path41.join(
|
|
22820
23075
|
root,
|
|
22821
23076
|
".mancode",
|
|
22822
23077
|
"local",
|
|
@@ -22825,7 +23080,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22825
23080
|
"artifacts"
|
|
22826
23081
|
);
|
|
22827
23082
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
22828
|
-
const target =
|
|
23083
|
+
const target = path41.join(directory, entry);
|
|
22829
23084
|
const metadata = await regularFileMetadataOrNull(target);
|
|
22830
23085
|
if (metadata === null || metadata.mtimeMs >= threshold) continue;
|
|
22831
23086
|
candidates.push({
|
|
@@ -22842,7 +23097,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22842
23097
|
}
|
|
22843
23098
|
async function planLocalCacheRetention(root, localCacheDays, now) {
|
|
22844
23099
|
const threshold = now.getTime() - localCacheDays * 864e5;
|
|
22845
|
-
const directory =
|
|
23100
|
+
const directory = path41.join(root, ".mancode", "local", "cache");
|
|
22846
23101
|
const candidates = [];
|
|
22847
23102
|
for (const target of await listRegularFilesRecursively(directory)) {
|
|
22848
23103
|
const metadata = await regularFileMetadataOrNull(target);
|
|
@@ -22905,7 +23160,7 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
22905
23160
|
}
|
|
22906
23161
|
candidates.push({
|
|
22907
23162
|
kind: "checkpoint",
|
|
22908
|
-
target:
|
|
23163
|
+
target: path41.join(
|
|
22909
23164
|
task.location.taskRoot,
|
|
22910
23165
|
"checkpoints",
|
|
22911
23166
|
`${checkpoint.checkpointId}.json`
|
|
@@ -22919,13 +23174,13 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
22919
23174
|
return { candidates, skippedReferencedCheckpoints };
|
|
22920
23175
|
}
|
|
22921
23176
|
async function planCompletedSessionRetention(root, completedSessionDays, now, protectedSessionIds) {
|
|
22922
|
-
const directory =
|
|
23177
|
+
const directory = path41.join(root, ".mancode", "local", "sessions");
|
|
22923
23178
|
const entries = await readDirectoryOrEmpty(directory);
|
|
22924
23179
|
const threshold = now.getTime() - completedSessionDays * 864e5;
|
|
22925
23180
|
const candidates = [];
|
|
22926
23181
|
for (const entry of entries) {
|
|
22927
23182
|
if (!entry.endsWith(".json")) continue;
|
|
22928
|
-
const target =
|
|
23183
|
+
const target = path41.join(directory, entry);
|
|
22929
23184
|
const session = parseSessionState(
|
|
22930
23185
|
JSON.parse(await readRegularFile(target))
|
|
22931
23186
|
);
|
|
@@ -22951,7 +23206,7 @@ async function planOperationRetention(stores, now) {
|
|
|
22951
23206
|
const entries = await readDirectoryOrEmpty(directory);
|
|
22952
23207
|
for (const entry of entries) {
|
|
22953
23208
|
if (!entry.endsWith(".json")) continue;
|
|
22954
|
-
const target =
|
|
23209
|
+
const target = path41.join(directory, entry);
|
|
22955
23210
|
const journal = parseOperationJournal(
|
|
22956
23211
|
JSON.parse(await readRegularFile(target))
|
|
22957
23212
|
);
|
|
@@ -23030,7 +23285,7 @@ function isTerminalTaskStatus(status2) {
|
|
|
23030
23285
|
async function listTaskRefs(root) {
|
|
23031
23286
|
const refs = [];
|
|
23032
23287
|
for (const namespace of ["local", "shared"]) {
|
|
23033
|
-
const directory =
|
|
23288
|
+
const directory = path41.join(root, ".mancode", namespace, "workflows");
|
|
23034
23289
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23035
23290
|
if (!/^[0-9A-HJKMNP-TV-Z]{26}$/.test(entry)) continue;
|
|
23036
23291
|
refs.push({ namespace, taskId: entry });
|
|
@@ -23043,12 +23298,12 @@ async function listTaskRefs(root) {
|
|
|
23043
23298
|
);
|
|
23044
23299
|
}
|
|
23045
23300
|
async function listTaskCheckpoints(taskRoot2, taskRef) {
|
|
23046
|
-
const directory =
|
|
23301
|
+
const directory = path41.join(taskRoot2, "checkpoints");
|
|
23047
23302
|
const checkpoints = [];
|
|
23048
23303
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23049
23304
|
if (!entry.endsWith(".json")) continue;
|
|
23050
23305
|
const checkpoint = parseCheckpoint(
|
|
23051
|
-
JSON.parse(await readRegularFile(
|
|
23306
|
+
JSON.parse(await readRegularFile(path41.join(directory, entry)))
|
|
23052
23307
|
);
|
|
23053
23308
|
if (!sameTaskRef(checkpoint.taskRef, taskRef) || entry !== `${checkpoint.checkpointId}.json`) {
|
|
23054
23309
|
throw new Error("MANCODE_RETENTION_CHECKPOINT_CORRUPT");
|
|
@@ -23080,14 +23335,14 @@ async function readDirectoryOrEmpty(directory) {
|
|
|
23080
23335
|
(left, right) => Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"))
|
|
23081
23336
|
);
|
|
23082
23337
|
} catch (error) {
|
|
23083
|
-
if (
|
|
23338
|
+
if (isNotFound22(error)) return [];
|
|
23084
23339
|
throw error;
|
|
23085
23340
|
}
|
|
23086
23341
|
}
|
|
23087
23342
|
async function listRegularFilesRecursively(directory) {
|
|
23088
23343
|
const files = [];
|
|
23089
23344
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23090
|
-
const target =
|
|
23345
|
+
const target = path41.join(directory, entry);
|
|
23091
23346
|
const metadata = await lstatOrNull3(target);
|
|
23092
23347
|
if (metadata === null) continue;
|
|
23093
23348
|
if (metadata.isSymbolicLink()) {
|
|
@@ -23110,7 +23365,7 @@ async function readRegularFile(target) {
|
|
|
23110
23365
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23111
23366
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
23112
23367
|
}
|
|
23113
|
-
const content = await
|
|
23368
|
+
const content = await readFile31(target, "utf8");
|
|
23114
23369
|
const after = await lstat13(target);
|
|
23115
23370
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23116
23371
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
@@ -23119,14 +23374,14 @@ async function readRegularFile(target) {
|
|
|
23119
23374
|
}
|
|
23120
23375
|
async function removeRegularFile(target) {
|
|
23121
23376
|
await readRegularFile(target);
|
|
23122
|
-
await
|
|
23377
|
+
await rm17(target);
|
|
23123
23378
|
}
|
|
23124
23379
|
async function regularFileExists(target) {
|
|
23125
23380
|
try {
|
|
23126
23381
|
await readRegularFile(target);
|
|
23127
23382
|
return true;
|
|
23128
23383
|
} catch (error) {
|
|
23129
|
-
if (
|
|
23384
|
+
if (isNotFound22(error)) return false;
|
|
23130
23385
|
throw error;
|
|
23131
23386
|
}
|
|
23132
23387
|
}
|
|
@@ -23142,17 +23397,17 @@ async function lstatOrNull3(target) {
|
|
|
23142
23397
|
try {
|
|
23143
23398
|
return await lstat13(target);
|
|
23144
23399
|
} catch (error) {
|
|
23145
|
-
if (
|
|
23400
|
+
if (isNotFound22(error)) return null;
|
|
23146
23401
|
throw error;
|
|
23147
23402
|
}
|
|
23148
23403
|
}
|
|
23149
|
-
function
|
|
23404
|
+
function isNotFound22(error) {
|
|
23150
23405
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23151
23406
|
}
|
|
23152
23407
|
|
|
23153
23408
|
// src/team/git-ref-cache.ts
|
|
23154
|
-
import { lstat as lstat14, mkdir as
|
|
23155
|
-
import
|
|
23409
|
+
import { lstat as lstat14, mkdir as mkdir29, readFile as readFile32, writeFile as writeFile36 } from "fs/promises";
|
|
23410
|
+
import path42 from "path";
|
|
23156
23411
|
var DEFAULT_GIT_REF_FRESHNESS_TTL_MS = 5 * 60 * 1e3;
|
|
23157
23412
|
async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
23158
23413
|
const remote = gitRefRemote(config);
|
|
@@ -23168,11 +23423,11 @@ async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
|
23168
23423
|
});
|
|
23169
23424
|
const directory = await ensureSafeCacheDirectory(projectRoot);
|
|
23170
23425
|
const target = gitRefCachePath(projectRoot);
|
|
23171
|
-
const temporary =
|
|
23426
|
+
const temporary = path42.join(
|
|
23172
23427
|
directory,
|
|
23173
23428
|
`.snapshot.${process.pid}.${Date.now()}.tmp`
|
|
23174
23429
|
);
|
|
23175
|
-
await
|
|
23430
|
+
await writeFile36(temporary, `${JSON.stringify(cache, null, 2)}
|
|
23176
23431
|
`, {
|
|
23177
23432
|
encoding: "utf8",
|
|
23178
23433
|
flag: "wx"
|
|
@@ -23190,7 +23445,7 @@ async function readGitRefTeamCache(projectRoot, config) {
|
|
|
23190
23445
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
23191
23446
|
}
|
|
23192
23447
|
const cache = parseGitRefTeamCache(
|
|
23193
|
-
JSON.parse(await
|
|
23448
|
+
JSON.parse(await readFile32(target, "utf8"))
|
|
23194
23449
|
);
|
|
23195
23450
|
const after = await lstat14(target);
|
|
23196
23451
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -23201,7 +23456,7 @@ async function readGitRefTeamCache(projectRoot, config) {
|
|
|
23201
23456
|
}
|
|
23202
23457
|
return cache;
|
|
23203
23458
|
} catch (error) {
|
|
23204
|
-
if (
|
|
23459
|
+
if (isNotFound23(error)) return null;
|
|
23205
23460
|
if (error instanceof SyntaxError) {
|
|
23206
23461
|
throw new Error("MANCODE_TRANSPORT_CACHE_CORRUPT");
|
|
23207
23462
|
}
|
|
@@ -23262,7 +23517,7 @@ function parseGitRefTeamCache(value) {
|
|
|
23262
23517
|
value.transportEpoch,
|
|
23263
23518
|
"git-ref cache transportEpoch"
|
|
23264
23519
|
);
|
|
23265
|
-
const fetchedAt =
|
|
23520
|
+
const fetchedAt = parseTimestamp14(value.fetchedAt, "git-ref cache fetchedAt");
|
|
23266
23521
|
const commit3 = parseCommitOrNull(value.commit);
|
|
23267
23522
|
const receipt = parseReceiptOrNull(value.receipt);
|
|
23268
23523
|
const manifest = value.manifest === null ? null : parseGitRefTeamManifest(value.manifest);
|
|
@@ -23284,11 +23539,11 @@ function parseGitRefTeamCache(value) {
|
|
|
23284
23539
|
};
|
|
23285
23540
|
}
|
|
23286
23541
|
function gitRefCachePath(projectRoot) {
|
|
23287
|
-
return
|
|
23542
|
+
return path42.join(gitRefCacheDirectory(projectRoot), "snapshot.json");
|
|
23288
23543
|
}
|
|
23289
23544
|
function gitRefCacheDirectory(projectRoot) {
|
|
23290
|
-
return
|
|
23291
|
-
|
|
23545
|
+
return path42.join(
|
|
23546
|
+
path42.resolve(projectRoot),
|
|
23292
23547
|
".mancode",
|
|
23293
23548
|
"local",
|
|
23294
23549
|
"cache",
|
|
@@ -23313,7 +23568,7 @@ function parsePositiveInteger4(value, label) {
|
|
|
23313
23568
|
}
|
|
23314
23569
|
return value;
|
|
23315
23570
|
}
|
|
23316
|
-
function
|
|
23571
|
+
function parseTimestamp14(value, label) {
|
|
23317
23572
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
23318
23573
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
23319
23574
|
}
|
|
@@ -23334,12 +23589,12 @@ function parseReceiptOrNull(value) {
|
|
|
23334
23589
|
return value;
|
|
23335
23590
|
}
|
|
23336
23591
|
async function ensureSafeCacheDirectory(projectRoot) {
|
|
23337
|
-
const root =
|
|
23592
|
+
const root = path42.resolve(projectRoot);
|
|
23338
23593
|
let current = root;
|
|
23339
23594
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23340
|
-
current =
|
|
23595
|
+
current = path42.join(current, segment);
|
|
23341
23596
|
try {
|
|
23342
|
-
await
|
|
23597
|
+
await mkdir29(current);
|
|
23343
23598
|
} catch (error) {
|
|
23344
23599
|
if (!isAlreadyExists17(error)) throw error;
|
|
23345
23600
|
}
|
|
@@ -23348,9 +23603,9 @@ async function ensureSafeCacheDirectory(projectRoot) {
|
|
|
23348
23603
|
return current;
|
|
23349
23604
|
}
|
|
23350
23605
|
async function assertSafeCacheDirectory(projectRoot) {
|
|
23351
|
-
let current =
|
|
23606
|
+
let current = path42.resolve(projectRoot);
|
|
23352
23607
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23353
|
-
current =
|
|
23608
|
+
current = path42.join(current, segment);
|
|
23354
23609
|
await assertDirectoryNotLinked(current);
|
|
23355
23610
|
}
|
|
23356
23611
|
}
|
|
@@ -23360,7 +23615,7 @@ async function assertDirectoryNotLinked(directory) {
|
|
|
23360
23615
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
23361
23616
|
}
|
|
23362
23617
|
}
|
|
23363
|
-
function
|
|
23618
|
+
function isNotFound23(error) {
|
|
23364
23619
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23365
23620
|
}
|
|
23366
23621
|
function isAlreadyExists17(error) {
|
|
@@ -23368,24 +23623,24 @@ function isAlreadyExists17(error) {
|
|
|
23368
23623
|
}
|
|
23369
23624
|
|
|
23370
23625
|
// src/team/git-ref-workflow-repair.ts
|
|
23371
|
-
import { lstat as lstat18, mkdir as
|
|
23372
|
-
import
|
|
23626
|
+
import { lstat as lstat18, mkdir as mkdir33, readFile as readFile36, readdir as readdir17, writeFile as writeFile40 } from "fs/promises";
|
|
23627
|
+
import path46 from "path";
|
|
23373
23628
|
|
|
23374
23629
|
// src/team/git-ref-materialization.ts
|
|
23375
23630
|
import {
|
|
23376
23631
|
lstat as lstat17,
|
|
23377
|
-
mkdir as
|
|
23378
|
-
readFile as
|
|
23632
|
+
mkdir as mkdir32,
|
|
23633
|
+
readFile as readFile35,
|
|
23379
23634
|
readdir as readdir16,
|
|
23380
23635
|
unlink as unlink2,
|
|
23381
|
-
writeFile as
|
|
23636
|
+
writeFile as writeFile39
|
|
23382
23637
|
} from "fs/promises";
|
|
23383
|
-
import
|
|
23638
|
+
import path45 from "path";
|
|
23384
23639
|
|
|
23385
23640
|
// src/team/git-ref-bundle.ts
|
|
23386
23641
|
import { execFile as execFileCallback5 } from "child_process";
|
|
23387
|
-
import { lstat as lstat15, mkdir as
|
|
23388
|
-
import
|
|
23642
|
+
import { lstat as lstat15, mkdir as mkdir30, readFile as readFile33, readdir as readdir15, writeFile as writeFile37 } from "fs/promises";
|
|
23643
|
+
import path43 from "path";
|
|
23389
23644
|
import { promisify as promisify5 } from "util";
|
|
23390
23645
|
var execFile5 = promisify5(execFileCallback5);
|
|
23391
23646
|
function createGitRefTaskBundle(input) {
|
|
@@ -23448,7 +23703,7 @@ async function assertGitRefBundleCodeReachable(projectRoot, bundle) {
|
|
|
23448
23703
|
"git",
|
|
23449
23704
|
["cat-file", "-e", `${parsed.codeRef.head}^{commit}`],
|
|
23450
23705
|
{
|
|
23451
|
-
cwd:
|
|
23706
|
+
cwd: path43.resolve(projectRoot),
|
|
23452
23707
|
windowsHide: true
|
|
23453
23708
|
}
|
|
23454
23709
|
);
|
|
@@ -23461,8 +23716,8 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23461
23716
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23462
23717
|
}
|
|
23463
23718
|
const parsed = parseGitRefTaskBundle(bundle);
|
|
23464
|
-
const directory =
|
|
23465
|
-
|
|
23719
|
+
const directory = path43.join(
|
|
23720
|
+
path43.resolve(projectRoot),
|
|
23466
23721
|
".mancode",
|
|
23467
23722
|
"local",
|
|
23468
23723
|
"quarantine",
|
|
@@ -23478,9 +23733,9 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23478
23733
|
parsed.taskRef.taskId,
|
|
23479
23734
|
String(remoteRevision)
|
|
23480
23735
|
]);
|
|
23481
|
-
const target =
|
|
23736
|
+
const target = path43.join(directory, `${parsed.bundleDigest.slice(7)}.json`);
|
|
23482
23737
|
try {
|
|
23483
|
-
await
|
|
23738
|
+
await writeFile37(target, `${JSON.stringify(parsed, null, 2)}
|
|
23484
23739
|
`, {
|
|
23485
23740
|
encoding: "utf8",
|
|
23486
23741
|
flag: "wx"
|
|
@@ -23495,8 +23750,8 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23495
23750
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23496
23751
|
}
|
|
23497
23752
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23498
|
-
const directory =
|
|
23499
|
-
|
|
23753
|
+
const directory = path43.join(
|
|
23754
|
+
path43.resolve(projectRoot),
|
|
23500
23755
|
".mancode",
|
|
23501
23756
|
"local",
|
|
23502
23757
|
"quarantine",
|
|
@@ -23516,19 +23771,19 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23516
23771
|
]);
|
|
23517
23772
|
entries = await readdir15(directory);
|
|
23518
23773
|
} catch (error) {
|
|
23519
|
-
if (
|
|
23774
|
+
if (isNotFound24(error)) return null;
|
|
23520
23775
|
throw error;
|
|
23521
23776
|
}
|
|
23522
23777
|
const matches = [];
|
|
23523
23778
|
for (const entry of entries.sort()) {
|
|
23524
23779
|
if (!/^[a-f0-9]{64}\.json$/.test(entry)) continue;
|
|
23525
|
-
const target =
|
|
23780
|
+
const target = path43.join(directory, entry);
|
|
23526
23781
|
const before = await lstat15(target);
|
|
23527
23782
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23528
23783
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23529
23784
|
}
|
|
23530
23785
|
const bundle = parseGitRefTaskBundle(
|
|
23531
|
-
JSON.parse(await
|
|
23786
|
+
JSON.parse(await readFile33(target, "utf8"))
|
|
23532
23787
|
);
|
|
23533
23788
|
const after = await lstat15(target);
|
|
23534
23789
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -23559,11 +23814,11 @@ function parseCodeRef(value) {
|
|
|
23559
23814
|
return { branch: value.branch, head: value.head };
|
|
23560
23815
|
}
|
|
23561
23816
|
async function ensureFixedDirectory(projectRoot, segments) {
|
|
23562
|
-
let current =
|
|
23817
|
+
let current = path43.resolve(projectRoot);
|
|
23563
23818
|
for (const segment of segments) {
|
|
23564
|
-
current =
|
|
23819
|
+
current = path43.join(current, segment);
|
|
23565
23820
|
try {
|
|
23566
|
-
await
|
|
23821
|
+
await mkdir30(current);
|
|
23567
23822
|
} catch (error) {
|
|
23568
23823
|
if (!isAlreadyExists18(error)) throw error;
|
|
23569
23824
|
}
|
|
@@ -23574,9 +23829,9 @@ async function ensureFixedDirectory(projectRoot, segments) {
|
|
|
23574
23829
|
}
|
|
23575
23830
|
}
|
|
23576
23831
|
async function assertFixedDirectory(projectRoot, segments) {
|
|
23577
|
-
let current =
|
|
23832
|
+
let current = path43.resolve(projectRoot);
|
|
23578
23833
|
for (const segment of segments) {
|
|
23579
|
-
current =
|
|
23834
|
+
current = path43.join(current, segment);
|
|
23580
23835
|
const entry = await lstat15(current);
|
|
23581
23836
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23582
23837
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -23586,13 +23841,13 @@ async function assertFixedDirectory(projectRoot, segments) {
|
|
|
23586
23841
|
function isAlreadyExists18(error) {
|
|
23587
23842
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
23588
23843
|
}
|
|
23589
|
-
function
|
|
23844
|
+
function isNotFound24(error) {
|
|
23590
23845
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23591
23846
|
}
|
|
23592
23847
|
|
|
23593
23848
|
// src/team/git-ref-task-base.ts
|
|
23594
|
-
import { lstat as lstat16, mkdir as
|
|
23595
|
-
import
|
|
23849
|
+
import { lstat as lstat16, mkdir as mkdir31, readFile as readFile34, writeFile as writeFile38 } from "fs/promises";
|
|
23850
|
+
import path44 from "path";
|
|
23596
23851
|
async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
23597
23852
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23598
23853
|
const runtime = await readProjectRuntimeContext(projectRoot);
|
|
@@ -23604,7 +23859,7 @@ async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
|
23604
23859
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23605
23860
|
}
|
|
23606
23861
|
const state = parseGitRefTaskRemoteBase(
|
|
23607
|
-
JSON.parse(await
|
|
23862
|
+
JSON.parse(await readFile34(target, "utf8"))
|
|
23608
23863
|
);
|
|
23609
23864
|
const after = await lstat16(target);
|
|
23610
23865
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -23615,7 +23870,7 @@ async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
|
23615
23870
|
}
|
|
23616
23871
|
return state;
|
|
23617
23872
|
} catch (error) {
|
|
23618
|
-
if (
|
|
23873
|
+
if (isNotFound25(error)) return null;
|
|
23619
23874
|
if (error instanceof SyntaxError) {
|
|
23620
23875
|
throw new Error("MANCODE_TRANSPORT_CACHE_CORRUPT");
|
|
23621
23876
|
}
|
|
@@ -23635,11 +23890,11 @@ async function recordGitRefTaskRemoteBase(projectRoot, remoteRevision, bundle) {
|
|
|
23635
23890
|
});
|
|
23636
23891
|
const directory = await ensureRemoteBaseDirectory(projectRoot);
|
|
23637
23892
|
const target = remoteBasePath(projectRoot, parsedBundle.taskRef);
|
|
23638
|
-
const temporary =
|
|
23893
|
+
const temporary = path44.join(
|
|
23639
23894
|
directory,
|
|
23640
23895
|
`.${parsedBundle.taskRef.taskId}.${process.pid}.${Date.now()}.tmp`
|
|
23641
23896
|
);
|
|
23642
|
-
await
|
|
23897
|
+
await writeFile38(temporary, `${JSON.stringify(state, null, 2)}
|
|
23643
23898
|
`, {
|
|
23644
23899
|
encoding: "utf8",
|
|
23645
23900
|
flag: "wx"
|
|
@@ -23672,7 +23927,7 @@ function parseGitRefTaskRemoteBase(value) {
|
|
|
23672
23927
|
};
|
|
23673
23928
|
}
|
|
23674
23929
|
async function ensureRemoteBaseDirectory(projectRoot) {
|
|
23675
|
-
let current =
|
|
23930
|
+
let current = path44.resolve(projectRoot);
|
|
23676
23931
|
for (const segment of [
|
|
23677
23932
|
".mancode",
|
|
23678
23933
|
"local",
|
|
@@ -23680,9 +23935,9 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
23680
23935
|
"git-ref",
|
|
23681
23936
|
"remote-bases"
|
|
23682
23937
|
]) {
|
|
23683
|
-
current =
|
|
23938
|
+
current = path44.join(current, segment);
|
|
23684
23939
|
try {
|
|
23685
|
-
await
|
|
23940
|
+
await mkdir31(current);
|
|
23686
23941
|
} catch (error) {
|
|
23687
23942
|
if (!isAlreadyExists19(error)) throw error;
|
|
23688
23943
|
}
|
|
@@ -23694,7 +23949,7 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
23694
23949
|
return current;
|
|
23695
23950
|
}
|
|
23696
23951
|
async function assertRemoteBaseDirectory(projectRoot) {
|
|
23697
|
-
let current =
|
|
23952
|
+
let current = path44.resolve(projectRoot);
|
|
23698
23953
|
for (const segment of [
|
|
23699
23954
|
".mancode",
|
|
23700
23955
|
"local",
|
|
@@ -23702,7 +23957,7 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
23702
23957
|
"git-ref",
|
|
23703
23958
|
"remote-bases"
|
|
23704
23959
|
]) {
|
|
23705
|
-
current =
|
|
23960
|
+
current = path44.join(current, segment);
|
|
23706
23961
|
const entry = await lstat16(current);
|
|
23707
23962
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23708
23963
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -23711,8 +23966,8 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
23711
23966
|
}
|
|
23712
23967
|
function remoteBasePath(projectRoot, taskRef) {
|
|
23713
23968
|
const parsed = parseTaskRefValue(taskRef);
|
|
23714
|
-
return
|
|
23715
|
-
|
|
23969
|
+
return path44.join(
|
|
23970
|
+
path44.resolve(projectRoot),
|
|
23716
23971
|
".mancode",
|
|
23717
23972
|
"local",
|
|
23718
23973
|
"cache",
|
|
@@ -23730,13 +23985,13 @@ function positiveInteger2(value) {
|
|
|
23730
23985
|
function isAlreadyExists19(error) {
|
|
23731
23986
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
23732
23987
|
}
|
|
23733
|
-
function
|
|
23988
|
+
function isNotFound25(error) {
|
|
23734
23989
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23735
23990
|
}
|
|
23736
23991
|
|
|
23737
23992
|
// src/team/git-ref-materialization.ts
|
|
23738
23993
|
async function materializeGitRefTaskBundle(input) {
|
|
23739
|
-
const projectRoot =
|
|
23994
|
+
const projectRoot = path45.resolve(input.projectRoot);
|
|
23740
23995
|
const remoteRevision = positiveInteger3(
|
|
23741
23996
|
input.remoteRevision,
|
|
23742
23997
|
"git-ref materialization remoteRevision"
|
|
@@ -24042,7 +24297,7 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
24042
24297
|
const target = safeTaskPath(taskRoot2, relativePath2);
|
|
24043
24298
|
await ensureSafeDirectory(
|
|
24044
24299
|
taskRoot2,
|
|
24045
|
-
|
|
24300
|
+
path45.dirname(relativePath2).split(path45.sep)
|
|
24046
24301
|
);
|
|
24047
24302
|
const current = await readSafeFileOrNull(target);
|
|
24048
24303
|
if (contentMatches(relativePath2, current, targetContent)) return;
|
|
@@ -24052,11 +24307,11 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
24052
24307
|
if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath2 !== "summary.md") {
|
|
24053
24308
|
throw new Error("MANCODE_SPLIT_BRAIN");
|
|
24054
24309
|
}
|
|
24055
|
-
const temporary =
|
|
24056
|
-
|
|
24057
|
-
`.${
|
|
24310
|
+
const temporary = path45.join(
|
|
24311
|
+
path45.dirname(target),
|
|
24312
|
+
`.${path45.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
24058
24313
|
);
|
|
24059
|
-
await
|
|
24314
|
+
await writeFile39(temporary, targetContent, { encoding: "utf8", flag: "wx" });
|
|
24060
24315
|
await replaceFileAtomically(temporary, target);
|
|
24061
24316
|
}
|
|
24062
24317
|
function contentMatches(relativePath2, current, expected) {
|
|
@@ -24110,27 +24365,27 @@ async function readSafeFileOrNull(target) {
|
|
|
24110
24365
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
24111
24366
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24112
24367
|
}
|
|
24113
|
-
const content = await
|
|
24368
|
+
const content = await readFile35(target, "utf8");
|
|
24114
24369
|
const after = await lstat17(target);
|
|
24115
24370
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
24116
24371
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24117
24372
|
}
|
|
24118
24373
|
return content;
|
|
24119
24374
|
} catch (error) {
|
|
24120
|
-
if (
|
|
24375
|
+
if (isNotFound26(error)) return null;
|
|
24121
24376
|
throw error;
|
|
24122
24377
|
}
|
|
24123
24378
|
}
|
|
24124
24379
|
async function ensureSafeDirectory(root, segments) {
|
|
24125
|
-
let current =
|
|
24380
|
+
let current = path45.resolve(root);
|
|
24126
24381
|
for (const segment of segments) {
|
|
24127
24382
|
if (!segment || segment === ".") continue;
|
|
24128
24383
|
if (segment === ".." || segment.includes("/") || segment.includes("\\")) {
|
|
24129
24384
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24130
24385
|
}
|
|
24131
|
-
current =
|
|
24386
|
+
current = path45.join(current, segment);
|
|
24132
24387
|
try {
|
|
24133
|
-
await
|
|
24388
|
+
await mkdir32(current);
|
|
24134
24389
|
} catch (error) {
|
|
24135
24390
|
if (!isAlreadyExists20(error)) throw error;
|
|
24136
24391
|
}
|
|
@@ -24141,9 +24396,9 @@ async function ensureSafeDirectory(root, segments) {
|
|
|
24141
24396
|
}
|
|
24142
24397
|
}
|
|
24143
24398
|
function safeTaskPath(taskRoot2, relativePath2) {
|
|
24144
|
-
const target =
|
|
24145
|
-
const relative =
|
|
24146
|
-
if (!relative || relative.startsWith("..") ||
|
|
24399
|
+
const target = path45.resolve(taskRoot2, relativePath2);
|
|
24400
|
+
const relative = path45.relative(taskRoot2, target);
|
|
24401
|
+
if (!relative || relative.startsWith("..") || path45.isAbsolute(relative)) {
|
|
24147
24402
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24148
24403
|
}
|
|
24149
24404
|
return target;
|
|
@@ -24155,7 +24410,7 @@ async function createJournal(projectRoot, journal) {
|
|
|
24155
24410
|
"journals",
|
|
24156
24411
|
"git-ref-materialize"
|
|
24157
24412
|
]);
|
|
24158
|
-
await
|
|
24413
|
+
await writeFile39(
|
|
24159
24414
|
journalPath(projectRoot, journal.operationId),
|
|
24160
24415
|
serialize11(journal),
|
|
24161
24416
|
{
|
|
@@ -24166,11 +24421,11 @@ async function createJournal(projectRoot, journal) {
|
|
|
24166
24421
|
}
|
|
24167
24422
|
async function replaceJournal(projectRoot, journal) {
|
|
24168
24423
|
const target = journalPath(projectRoot, journal.operationId);
|
|
24169
|
-
const temporary =
|
|
24170
|
-
|
|
24424
|
+
const temporary = path45.join(
|
|
24425
|
+
path45.dirname(target),
|
|
24171
24426
|
`.${journal.operationId}.${process.pid}.${Date.now()}.tmp`
|
|
24172
24427
|
);
|
|
24173
|
-
await
|
|
24428
|
+
await writeFile39(temporary, serialize11(journal), {
|
|
24174
24429
|
encoding: "utf8",
|
|
24175
24430
|
flag: "wx"
|
|
24176
24431
|
});
|
|
@@ -24178,7 +24433,7 @@ async function replaceJournal(projectRoot, journal) {
|
|
|
24178
24433
|
}
|
|
24179
24434
|
async function readJournal(target) {
|
|
24180
24435
|
try {
|
|
24181
|
-
const raw = JSON.parse(await
|
|
24436
|
+
const raw = JSON.parse(await readFile35(target, "utf8"));
|
|
24182
24437
|
return parseJournal(raw);
|
|
24183
24438
|
} catch (error) {
|
|
24184
24439
|
if (error instanceof SyntaxError) {
|
|
@@ -24193,13 +24448,13 @@ async function listJournals(projectRoot) {
|
|
|
24193
24448
|
try {
|
|
24194
24449
|
entries = await readdir16(directory);
|
|
24195
24450
|
} catch (error) {
|
|
24196
|
-
if (
|
|
24451
|
+
if (isNotFound26(error)) return [];
|
|
24197
24452
|
throw error;
|
|
24198
24453
|
}
|
|
24199
24454
|
const journals = [];
|
|
24200
24455
|
for (const entry of entries.sort()) {
|
|
24201
24456
|
if (!entry.endsWith(".json")) continue;
|
|
24202
|
-
journals.push(await readJournal(
|
|
24457
|
+
journals.push(await readJournal(path45.join(directory, entry)));
|
|
24203
24458
|
}
|
|
24204
24459
|
return journals;
|
|
24205
24460
|
}
|
|
@@ -24265,8 +24520,8 @@ function result(status2, bundle, localJournalPath, taskHeadFence) {
|
|
|
24265
24520
|
};
|
|
24266
24521
|
}
|
|
24267
24522
|
function journalDirectory(projectRoot) {
|
|
24268
|
-
return
|
|
24269
|
-
|
|
24523
|
+
return path45.join(
|
|
24524
|
+
path45.resolve(projectRoot),
|
|
24270
24525
|
".mancode",
|
|
24271
24526
|
"local",
|
|
24272
24527
|
"journals",
|
|
@@ -24275,7 +24530,7 @@ function journalDirectory(projectRoot) {
|
|
|
24275
24530
|
}
|
|
24276
24531
|
function journalPath(projectRoot, operationId) {
|
|
24277
24532
|
assertUlid(operationId, "git-ref materialization operationId");
|
|
24278
|
-
return
|
|
24533
|
+
return path45.join(journalDirectory(projectRoot), `${operationId}.json`);
|
|
24279
24534
|
}
|
|
24280
24535
|
function serialize11(value) {
|
|
24281
24536
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -24298,20 +24553,20 @@ async function pathExists3(target) {
|
|
|
24298
24553
|
await lstat17(target);
|
|
24299
24554
|
return true;
|
|
24300
24555
|
} catch (error) {
|
|
24301
|
-
if (
|
|
24556
|
+
if (isNotFound26(error)) return false;
|
|
24302
24557
|
throw error;
|
|
24303
24558
|
}
|
|
24304
24559
|
}
|
|
24305
24560
|
function isAlreadyExists20(error) {
|
|
24306
24561
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
24307
24562
|
}
|
|
24308
|
-
function
|
|
24563
|
+
function isNotFound26(error) {
|
|
24309
24564
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
24310
24565
|
}
|
|
24311
24566
|
|
|
24312
24567
|
// src/team/git-ref-workflow-repair.ts
|
|
24313
24568
|
async function prepareGitRefWorkflowRepair(input) {
|
|
24314
|
-
const root =
|
|
24569
|
+
const root = path46.resolve(input.projectRoot);
|
|
24315
24570
|
const prepared2 = parsePrepared(input.prepared);
|
|
24316
24571
|
const pendingMetadata = parseWorkflowMetadata(input.pendingMetadata);
|
|
24317
24572
|
assertPendingMetadata2(prepared2, pendingMetadata);
|
|
@@ -24346,7 +24601,7 @@ async function prepareGitRefWorkflowRepair(input) {
|
|
|
24346
24601
|
}
|
|
24347
24602
|
async function recoverGitRefWorkflowRepair(projectRoot, operationId, transportReceipt = null, options = {}) {
|
|
24348
24603
|
assertUlid(operationId, "git-ref workflow repair operationId");
|
|
24349
|
-
const root =
|
|
24604
|
+
const root = path46.resolve(projectRoot);
|
|
24350
24605
|
let journal = await requireJournal(root, operationId);
|
|
24351
24606
|
await assertRecoveryAuthorized(root, journal, options);
|
|
24352
24607
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
@@ -24713,7 +24968,7 @@ async function createJournal2(projectRoot, journal) {
|
|
|
24713
24968
|
await ensureJournalDirectory(projectRoot);
|
|
24714
24969
|
const target = gitRefWorkflowRepairJournalPath(projectRoot, journal.operationId);
|
|
24715
24970
|
try {
|
|
24716
|
-
await
|
|
24971
|
+
await writeFile40(target, serialize12(journal), {
|
|
24717
24972
|
encoding: "utf8",
|
|
24718
24973
|
flag: "wx"
|
|
24719
24974
|
});
|
|
@@ -24734,10 +24989,10 @@ async function replaceJournal2(projectRoot, journal) {
|
|
|
24734
24989
|
async function requireJournal(projectRoot, operationId) {
|
|
24735
24990
|
try {
|
|
24736
24991
|
return parseJournal2(
|
|
24737
|
-
JSON.parse(await
|
|
24992
|
+
JSON.parse(await readFile36(gitRefWorkflowRepairJournalPath(projectRoot, operationId), "utf8"))
|
|
24738
24993
|
);
|
|
24739
24994
|
} catch (error) {
|
|
24740
|
-
if (error instanceof SyntaxError ||
|
|
24995
|
+
if (error instanceof SyntaxError || isNotFound27(error)) {
|
|
24741
24996
|
throw new Error("MANCODE_REMOTE_WORKFLOW_REPAIR_JOURNAL_NOT_FOUND");
|
|
24742
24997
|
}
|
|
24743
24998
|
throw error;
|
|
@@ -24753,14 +25008,14 @@ function metadataFromBundle(bundle) {
|
|
|
24753
25008
|
return parseWorkflowMetadata(artifact2.content);
|
|
24754
25009
|
}
|
|
24755
25010
|
function metadataPath2(projectRoot, taskRef) {
|
|
24756
|
-
return
|
|
25011
|
+
return path46.join(taskRootPath(projectRoot, taskRef), "metadata.json");
|
|
24757
25012
|
}
|
|
24758
25013
|
async function readSafeFile(target) {
|
|
24759
25014
|
const before = await lstat18(target);
|
|
24760
25015
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
24761
25016
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24762
25017
|
}
|
|
24763
|
-
const content = await
|
|
25018
|
+
const content = await readFile36(target, "utf8");
|
|
24764
25019
|
const after = await lstat18(target);
|
|
24765
25020
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
24766
25021
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -24768,19 +25023,19 @@ async function readSafeFile(target) {
|
|
|
24768
25023
|
return content;
|
|
24769
25024
|
}
|
|
24770
25025
|
async function atomicWrite(target, content) {
|
|
24771
|
-
const temporary =
|
|
24772
|
-
|
|
24773
|
-
`.${
|
|
25026
|
+
const temporary = path46.join(
|
|
25027
|
+
path46.dirname(target),
|
|
25028
|
+
`.${path46.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
24774
25029
|
);
|
|
24775
|
-
await
|
|
25030
|
+
await writeFile40(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
24776
25031
|
await replaceFileAtomically(temporary, target);
|
|
24777
25032
|
}
|
|
24778
25033
|
async function ensureJournalDirectory(projectRoot) {
|
|
24779
|
-
let current =
|
|
25034
|
+
let current = path46.resolve(projectRoot);
|
|
24780
25035
|
for (const segment of [".mancode", "local", "journals", "git-ref-workflow"]) {
|
|
24781
|
-
current =
|
|
25036
|
+
current = path46.join(current, segment);
|
|
24782
25037
|
try {
|
|
24783
|
-
await
|
|
25038
|
+
await mkdir33(current);
|
|
24784
25039
|
} catch (error) {
|
|
24785
25040
|
if (!isAlreadyExists21(error)) throw error;
|
|
24786
25041
|
}
|
|
@@ -24812,7 +25067,7 @@ function serialize12(value) {
|
|
|
24812
25067
|
function isAlreadyExists21(error) {
|
|
24813
25068
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
24814
25069
|
}
|
|
24815
|
-
function
|
|
25070
|
+
function isNotFound27(error) {
|
|
24816
25071
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
24817
25072
|
}
|
|
24818
25073
|
|
|
@@ -25416,6 +25671,106 @@ async function contextReconcileTaskHead(rootDir, task, options) {
|
|
|
25416
25671
|
);
|
|
25417
25672
|
}
|
|
25418
25673
|
}
|
|
25674
|
+
async function contextGlossary(rootDir, action, options) {
|
|
25675
|
+
if (action !== "list" && action !== "add" && action !== "update" && action !== "remove") {
|
|
25676
|
+
return printV3Error(
|
|
25677
|
+
options.json,
|
|
25678
|
+
"MANCODE_GLOSSARY_ACTION_INVALID",
|
|
25679
|
+
"Use: context glossary <list|add|update|remove>.",
|
|
25680
|
+
EXIT_V3_INVALID_ARGUMENT
|
|
25681
|
+
);
|
|
25682
|
+
}
|
|
25683
|
+
if (action === "list") {
|
|
25684
|
+
try {
|
|
25685
|
+
const project = await readV3CommandProject(rootDir);
|
|
25686
|
+
const glossary = await readProjectGlossary(project.projectRoot);
|
|
25687
|
+
return printV3Result(options.json, { schemaVersion: 1, glossary });
|
|
25688
|
+
} catch (error) {
|
|
25689
|
+
return printV3Error(
|
|
25690
|
+
options.json,
|
|
25691
|
+
v3ErrorCode(error, "MANCODE_GLOSSARY_LIST_FAILED"),
|
|
25692
|
+
error instanceof Error ? error.message : "Unable to read the project glossary."
|
|
25693
|
+
);
|
|
25694
|
+
}
|
|
25695
|
+
}
|
|
25696
|
+
if (options.term === void 0) {
|
|
25697
|
+
return printV3Error(
|
|
25698
|
+
options.json,
|
|
25699
|
+
"MANCODE_GLOSSARY_TERM_REQUIRED",
|
|
25700
|
+
`context glossary ${action} requires --term <term>.`,
|
|
25701
|
+
EXIT_V3_INVALID_ARGUMENT
|
|
25702
|
+
);
|
|
25703
|
+
}
|
|
25704
|
+
const expectedRevision = parseGlossaryExpectedRevision(
|
|
25705
|
+
options.expectedRevision
|
|
25706
|
+
);
|
|
25707
|
+
if (expectedRevision === null) {
|
|
25708
|
+
return printV3Error(
|
|
25709
|
+
options.json,
|
|
25710
|
+
"MANCODE_GLOSSARY_EXPECTED_REVISION_REQUIRED",
|
|
25711
|
+
"context glossary mutations require --expected-revision <n> (0 for an empty glossary).",
|
|
25712
|
+
EXIT_V3_INVALID_ARGUMENT
|
|
25713
|
+
);
|
|
25714
|
+
}
|
|
25715
|
+
if (action === "add" && options.definition === void 0) {
|
|
25716
|
+
return printV3Error(
|
|
25717
|
+
options.json,
|
|
25718
|
+
"MANCODE_GLOSSARY_DEFINITION_REQUIRED",
|
|
25719
|
+
"context glossary add requires --definition <text>.",
|
|
25720
|
+
EXIT_V3_INVALID_ARGUMENT
|
|
25721
|
+
);
|
|
25722
|
+
}
|
|
25723
|
+
if (action === "update" && options.definition === void 0 && (options.alias === void 0 || options.alias.length === 0) && options.task === void 0) {
|
|
25724
|
+
return printV3Error(
|
|
25725
|
+
options.json,
|
|
25726
|
+
"MANCODE_GLOSSARY_UPDATE_EMPTY",
|
|
25727
|
+
"context glossary update requires --definition, --alias, or --task.",
|
|
25728
|
+
EXIT_V3_INVALID_ARGUMENT
|
|
25729
|
+
);
|
|
25730
|
+
}
|
|
25731
|
+
try {
|
|
25732
|
+
const project = await readV3CommandProject(rootDir);
|
|
25733
|
+
await resolveV3CommandSession(project, options);
|
|
25734
|
+
const store = resolveCoordinationEntityHomeStore(
|
|
25735
|
+
project.runtime.entityHomeStoreContext
|
|
25736
|
+
);
|
|
25737
|
+
const sourceTaskRef = options.task === void 0 ? void 0 : parseTaskRef(options.task);
|
|
25738
|
+
const aliases = options.alias === void 0 || options.alias.length === 0 ? void 0 : options.alias;
|
|
25739
|
+
const glossary = action === "add" ? await addGlossaryEntry(project.projectRoot, store, expectedRevision, {
|
|
25740
|
+
term: options.term,
|
|
25741
|
+
definition: options.definition,
|
|
25742
|
+
...aliases === void 0 ? {} : { aliases },
|
|
25743
|
+
...sourceTaskRef === void 0 ? {} : { sourceTaskRef }
|
|
25744
|
+
}) : action === "update" ? await updateGlossaryEntry(
|
|
25745
|
+
project.projectRoot,
|
|
25746
|
+
store,
|
|
25747
|
+
expectedRevision,
|
|
25748
|
+
{
|
|
25749
|
+
term: options.term,
|
|
25750
|
+
...options.definition === void 0 ? {} : { definition: options.definition },
|
|
25751
|
+
...aliases === void 0 ? {} : { aliases },
|
|
25752
|
+
...sourceTaskRef === void 0 ? {} : { sourceTaskRef }
|
|
25753
|
+
}
|
|
25754
|
+
) : await removeGlossaryEntry(
|
|
25755
|
+
project.projectRoot,
|
|
25756
|
+
store,
|
|
25757
|
+
expectedRevision,
|
|
25758
|
+
options.term
|
|
25759
|
+
);
|
|
25760
|
+
return printV3Result(options.json, { schemaVersion: 1, glossary });
|
|
25761
|
+
} catch (error) {
|
|
25762
|
+
return printV3Error(
|
|
25763
|
+
options.json,
|
|
25764
|
+
v3ErrorCode(error, "MANCODE_GLOSSARY_MUTATION_FAILED"),
|
|
25765
|
+
error instanceof Error ? error.message : "Unable to change the project glossary."
|
|
25766
|
+
);
|
|
25767
|
+
}
|
|
25768
|
+
}
|
|
25769
|
+
function parseGlossaryExpectedRevision(value) {
|
|
25770
|
+
if (value === void 0 || !/^(0|[1-9][0-9]*)$/.test(value)) return null;
|
|
25771
|
+
const parsed = Number(value);
|
|
25772
|
+
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
25773
|
+
}
|
|
25419
25774
|
async function resolveContext(project, session, request) {
|
|
25420
25775
|
const resolver = new ContextResolver({
|
|
25421
25776
|
projectRoot: project.projectRoot,
|
|
@@ -25522,20 +25877,20 @@ function parseExpectedRevision2(value) {
|
|
|
25522
25877
|
}
|
|
25523
25878
|
|
|
25524
25879
|
// src/commands/design.ts
|
|
25525
|
-
import { readFile as
|
|
25526
|
-
import
|
|
25880
|
+
import { readFile as readFile38, stat as stat4 } from "fs/promises";
|
|
25881
|
+
import path48 from "path";
|
|
25527
25882
|
import process2 from "process";
|
|
25528
25883
|
|
|
25529
25884
|
// src/context/design-policy.ts
|
|
25530
25885
|
import {
|
|
25531
25886
|
lstat as lstat19,
|
|
25532
|
-
mkdir as
|
|
25533
|
-
readFile as
|
|
25887
|
+
mkdir as mkdir34,
|
|
25888
|
+
readFile as readFile37,
|
|
25534
25889
|
realpath as realpath2,
|
|
25535
|
-
rm as
|
|
25536
|
-
writeFile as
|
|
25890
|
+
rm as rm18,
|
|
25891
|
+
writeFile as writeFile41
|
|
25537
25892
|
} from "fs/promises";
|
|
25538
|
-
import
|
|
25893
|
+
import path47 from "path";
|
|
25539
25894
|
var DEFAULT_DESIGN_POLICY = {
|
|
25540
25895
|
schemaVersion: 1,
|
|
25541
25896
|
revision: 0,
|
|
@@ -25549,8 +25904,8 @@ var DEFAULT_DESIGN_POLICY = {
|
|
|
25549
25904
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
25550
25905
|
};
|
|
25551
25906
|
function designPolicyPath(projectRoot) {
|
|
25552
|
-
return
|
|
25553
|
-
|
|
25907
|
+
return path47.join(
|
|
25908
|
+
path47.resolve(projectRoot),
|
|
25554
25909
|
".mancode",
|
|
25555
25910
|
"shared",
|
|
25556
25911
|
"context",
|
|
@@ -25621,10 +25976,10 @@ function parseDesignPolicy(value) {
|
|
|
25621
25976
|
async function readDesignPolicy(projectRoot) {
|
|
25622
25977
|
try {
|
|
25623
25978
|
return parseDesignPolicy(
|
|
25624
|
-
JSON.parse(await
|
|
25979
|
+
JSON.parse(await readFile37(designPolicyPath(projectRoot), "utf8"))
|
|
25625
25980
|
);
|
|
25626
25981
|
} catch (error) {
|
|
25627
|
-
if (
|
|
25982
|
+
if (isNotFound28(error)) return null;
|
|
25628
25983
|
if (error instanceof SyntaxError) {
|
|
25629
25984
|
throw new Error(
|
|
25630
25985
|
"MANCODE_CONTEXT_ENTITY_CORRUPT: shared/context/design-policy.json"
|
|
@@ -25638,7 +25993,7 @@ async function configureDesignPolicy(input) {
|
|
|
25638
25993
|
const operationId = input.operationId ?? createUlid();
|
|
25639
25994
|
assertUlid(operationId, "design policy operationId");
|
|
25640
25995
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
25641
|
-
const root =
|
|
25996
|
+
const root = path47.resolve(input.projectRoot);
|
|
25642
25997
|
const runtime = await readProjectRuntimeContext(root);
|
|
25643
25998
|
const store = resolveCoordinationEntityHomeStore(
|
|
25644
25999
|
runtime.entityHomeStoreContext
|
|
@@ -25693,12 +26048,12 @@ function isDesignBrowserValidation(value) {
|
|
|
25693
26048
|
}
|
|
25694
26049
|
async function writeDesignPolicy(projectRoot, policy) {
|
|
25695
26050
|
const target = designPolicyPath(projectRoot);
|
|
25696
|
-
await
|
|
25697
|
-
const temporary =
|
|
25698
|
-
|
|
25699
|
-
`.${
|
|
26051
|
+
await mkdir34(path47.dirname(target), { recursive: true });
|
|
26052
|
+
const temporary = path47.join(
|
|
26053
|
+
path47.dirname(target),
|
|
26054
|
+
`.${path47.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
25700
26055
|
);
|
|
25701
|
-
await
|
|
26056
|
+
await writeFile41(temporary, `${JSON.stringify(policy, null, 2)}
|
|
25702
26057
|
`, {
|
|
25703
26058
|
encoding: "utf8",
|
|
25704
26059
|
flag: "wx"
|
|
@@ -25706,17 +26061,17 @@ async function writeDesignPolicy(projectRoot, policy) {
|
|
|
25706
26061
|
try {
|
|
25707
26062
|
await replaceFileAtomically(temporary, target);
|
|
25708
26063
|
} finally {
|
|
25709
|
-
await
|
|
26064
|
+
await rm18(temporary, { force: true }).catch(() => void 0);
|
|
25710
26065
|
}
|
|
25711
26066
|
}
|
|
25712
26067
|
async function assertDesignPolicyPathSafe(projectRoot) {
|
|
25713
|
-
const root =
|
|
26068
|
+
const root = path47.resolve(projectRoot);
|
|
25714
26069
|
const policyPath = designPolicyPath(root);
|
|
25715
|
-
const contextDir =
|
|
26070
|
+
const contextDir = path47.dirname(policyPath);
|
|
25716
26071
|
try {
|
|
25717
26072
|
for (const directory of [
|
|
25718
|
-
|
|
25719
|
-
|
|
26073
|
+
path47.join(root, ".mancode"),
|
|
26074
|
+
path47.join(root, ".mancode", "shared"),
|
|
25720
26075
|
contextDir
|
|
25721
26076
|
]) {
|
|
25722
26077
|
const info = await lstat19(directory);
|
|
@@ -25728,8 +26083,8 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
25728
26083
|
realpath2(root),
|
|
25729
26084
|
realpath2(contextDir)
|
|
25730
26085
|
]);
|
|
25731
|
-
const relative =
|
|
25732
|
-
if (
|
|
26086
|
+
const relative = path47.relative(resolvedRoot, resolvedContextDir);
|
|
26087
|
+
if (path47.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path47.sep}`)) {
|
|
25733
26088
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
25734
26089
|
}
|
|
25735
26090
|
try {
|
|
@@ -25738,7 +26093,7 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
25738
26093
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
25739
26094
|
}
|
|
25740
26095
|
} catch (error) {
|
|
25741
|
-
if (!
|
|
26096
|
+
if (!isNotFound28(error)) throw error;
|
|
25742
26097
|
}
|
|
25743
26098
|
} catch (error) {
|
|
25744
26099
|
if (error instanceof Error && error.message === "MANCODE_DESIGN_POLICY_PATH_UNSAFE") {
|
|
@@ -25755,7 +26110,7 @@ function assertNonNegativeRevision(value) {
|
|
|
25755
26110
|
function isPositiveInteger(value) {
|
|
25756
26111
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
25757
26112
|
}
|
|
25758
|
-
function
|
|
26113
|
+
function isNotFound28(error) {
|
|
25759
26114
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
25760
26115
|
}
|
|
25761
26116
|
|
|
@@ -25972,8 +26327,8 @@ async function readProfile(rootDir, kind) {
|
|
|
25972
26327
|
}
|
|
25973
26328
|
try {
|
|
25974
26329
|
return JSON.parse(
|
|
25975
|
-
await
|
|
25976
|
-
|
|
26330
|
+
await readFile38(
|
|
26331
|
+
path48.join(rootDir, ".mancode", "project-profile.json"),
|
|
25977
26332
|
"utf8"
|
|
25978
26333
|
)
|
|
25979
26334
|
);
|
|
@@ -25982,9 +26337,9 @@ async function readProfile(rootDir, kind) {
|
|
|
25982
26337
|
}
|
|
25983
26338
|
}
|
|
25984
26339
|
async function readStyleSummary(rootDir, kind) {
|
|
25985
|
-
const cachePath = kind === "continuity" ?
|
|
26340
|
+
const cachePath = kind === "continuity" ? path48.join(rootDir, ".mancode", "local", "cache", "style-tokens.json") : path48.join(rootDir, ".mancode", "aesthetics", "style-tokens.json");
|
|
25986
26341
|
try {
|
|
25987
|
-
const raw = JSON.parse(await
|
|
26342
|
+
const raw = JSON.parse(await readFile38(cachePath, "utf8"));
|
|
25988
26343
|
return sanitizeStyleSummary(rootDir, raw);
|
|
25989
26344
|
} catch {
|
|
25990
26345
|
return emptyStyleSummary();
|
|
@@ -26023,7 +26378,7 @@ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
|
|
|
26023
26378
|
const scannedAt = Date.parse(lastScanned);
|
|
26024
26379
|
for (const file of sourceFiles) {
|
|
26025
26380
|
try {
|
|
26026
|
-
const info = await stat4(
|
|
26381
|
+
const info = await stat4(path48.resolve(rootDir, scopeRoot, file));
|
|
26027
26382
|
if (info.mtimeMs > scannedAt) return "stale";
|
|
26028
26383
|
} catch {
|
|
26029
26384
|
return "stale";
|
|
@@ -26093,10 +26448,10 @@ function emptyStyleSummary() {
|
|
|
26093
26448
|
};
|
|
26094
26449
|
}
|
|
26095
26450
|
async function initializedKind(rootDir) {
|
|
26096
|
-
if (await exists(
|
|
26451
|
+
if (await exists(path48.join(rootDir, ".mancode", "schema.json"))) {
|
|
26097
26452
|
return "continuity";
|
|
26098
26453
|
}
|
|
26099
|
-
if (await exists(
|
|
26454
|
+
if (await exists(path48.join(rootDir, ".mancode", "state.json")))
|
|
26100
26455
|
return "legacy";
|
|
26101
26456
|
return null;
|
|
26102
26457
|
}
|
|
@@ -26161,7 +26516,7 @@ function safeShortText(value) {
|
|
|
26161
26516
|
return typeof value === "string" && value.length <= 100 && /^[A-Za-z0-9@/_. -]+$/.test(value) ? value : null;
|
|
26162
26517
|
}
|
|
26163
26518
|
function isSafeRelativeFile(value) {
|
|
26164
|
-
return value.length <= 240 && !
|
|
26519
|
+
return value.length <= 240 && !path48.isAbsolute(value) && !value.includes("\0") && value.split(/[\\/]/).every((part) => part !== "" && part !== "." && part !== "..");
|
|
26165
26520
|
}
|
|
26166
26521
|
function parseNonNegativeInteger2(value) {
|
|
26167
26522
|
if (value === void 0 || !/^\d+$/.test(value)) return null;
|
|
@@ -26169,7 +26524,7 @@ function parseNonNegativeInteger2(value) {
|
|
|
26169
26524
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
26170
26525
|
}
|
|
26171
26526
|
function relativePath(rootDir, target) {
|
|
26172
|
-
return
|
|
26527
|
+
return path48.relative(path48.resolve(rootDir), target).split(path48.sep).join("/");
|
|
26173
26528
|
}
|
|
26174
26529
|
function isRecord6(value) {
|
|
26175
26530
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -26201,12 +26556,12 @@ function errorCode3(error, fallback) {
|
|
|
26201
26556
|
// src/commands/init.ts
|
|
26202
26557
|
import { promises as fs4 } from "fs";
|
|
26203
26558
|
import os from "os";
|
|
26204
|
-
import
|
|
26559
|
+
import path54 from "path";
|
|
26205
26560
|
import process6 from "process";
|
|
26206
26561
|
|
|
26207
26562
|
// src/installers/platform-status.ts
|
|
26208
26563
|
import { promises as fs } from "fs";
|
|
26209
|
-
import
|
|
26564
|
+
import path49 from "path";
|
|
26210
26565
|
async function checkPlatformStatus(rootDir, platform, installed) {
|
|
26211
26566
|
const readiness = await checkPlatformReadiness(rootDir, platform);
|
|
26212
26567
|
return {
|
|
@@ -26223,13 +26578,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26223
26578
|
if (platform === "claude-code") {
|
|
26224
26579
|
const [hasSoloSkill, registered, hasHookFiles] = await Promise.all([
|
|
26225
26580
|
fileMatches(
|
|
26226
|
-
|
|
26581
|
+
path49.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
|
|
26227
26582
|
(content) => isGeneratedClaudeSkill(content, "solo")
|
|
26228
26583
|
),
|
|
26229
26584
|
claudeHooksRegistered(rootDir),
|
|
26230
26585
|
pathsExist([
|
|
26231
|
-
|
|
26232
|
-
|
|
26586
|
+
path49.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
|
|
26587
|
+
path49.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
26233
26588
|
])
|
|
26234
26589
|
]);
|
|
26235
26590
|
const present = hasSoloSkill && registered && hasHookFiles;
|
|
@@ -26245,7 +26600,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26245
26600
|
if (platform === "cursor") {
|
|
26246
26601
|
const hasCoreRules = await allManagedSkills(
|
|
26247
26602
|
MANCODE_CURSOR_CORE_RULE_FILES.map(
|
|
26248
|
-
(file) =>
|
|
26603
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
26249
26604
|
),
|
|
26250
26605
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26251
26606
|
);
|
|
@@ -26260,13 +26615,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26260
26615
|
const [hasRules, hasCommands] = await Promise.all([
|
|
26261
26616
|
allManagedSkills(
|
|
26262
26617
|
MANCODE_CURSOR_RULE_FILES.map(
|
|
26263
|
-
(file) =>
|
|
26618
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
26264
26619
|
),
|
|
26265
26620
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26266
26621
|
),
|
|
26267
26622
|
allManagedSkills(
|
|
26268
26623
|
MODE_NAMES.map(
|
|
26269
|
-
(mode) =>
|
|
26624
|
+
(mode) => path49.join(rootDir, ".cursor", "commands", `${mode}.md`)
|
|
26270
26625
|
),
|
|
26271
26626
|
[MODE_FILE_MANAGED_MARKER]
|
|
26272
26627
|
)
|
|
@@ -26279,7 +26634,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26279
26634
|
};
|
|
26280
26635
|
}
|
|
26281
26636
|
if (platform === "codex") {
|
|
26282
|
-
const hasBlock2 = await fileHasManagedBlock(
|
|
26637
|
+
const hasBlock2 = await fileHasManagedBlock(path49.join(rootDir, "AGENTS.md"));
|
|
26283
26638
|
if (!hasBlock2) {
|
|
26284
26639
|
return {
|
|
26285
26640
|
present: false,
|
|
@@ -26296,9 +26651,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26296
26651
|
readyDetail: "managed block present"
|
|
26297
26652
|
};
|
|
26298
26653
|
}
|
|
26299
|
-
const skillsDir =
|
|
26654
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26300
26655
|
const hasSkills = await allManagedSkills(
|
|
26301
|
-
MODE_NAMES.map((mode) =>
|
|
26656
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26302
26657
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26303
26658
|
);
|
|
26304
26659
|
return {
|
|
@@ -26310,7 +26665,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26310
26665
|
}
|
|
26311
26666
|
if (platform === "zcode") {
|
|
26312
26667
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26313
|
-
|
|
26668
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26314
26669
|
ZCODE_MANCODE_START_MARKER,
|
|
26315
26670
|
ZCODE_MANCODE_END_MARKER
|
|
26316
26671
|
);
|
|
@@ -26330,9 +26685,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26330
26685
|
readyDetail: "managed block present"
|
|
26331
26686
|
};
|
|
26332
26687
|
}
|
|
26333
|
-
const skillsDir =
|
|
26688
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26334
26689
|
const hasSkills = await allManagedSkills(
|
|
26335
|
-
MODE_NAMES.map((mode) =>
|
|
26690
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26336
26691
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26337
26692
|
);
|
|
26338
26693
|
return {
|
|
@@ -26344,7 +26699,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26344
26699
|
}
|
|
26345
26700
|
if (platform === "kimi-code") {
|
|
26346
26701
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26347
|
-
|
|
26702
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26348
26703
|
KIMI_MANCODE_START_MARKER,
|
|
26349
26704
|
KIMI_MANCODE_END_MARKER
|
|
26350
26705
|
);
|
|
@@ -26364,9 +26719,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26364
26719
|
readyDetail: "managed block present"
|
|
26365
26720
|
};
|
|
26366
26721
|
}
|
|
26367
|
-
const skillsDir =
|
|
26722
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26368
26723
|
const hasSkills = await allManagedSkills(
|
|
26369
|
-
MODE_NAMES.map((mode) =>
|
|
26724
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26370
26725
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26371
26726
|
);
|
|
26372
26727
|
return {
|
|
@@ -26378,7 +26733,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26378
26733
|
}
|
|
26379
26734
|
if (platform === "qoder") {
|
|
26380
26735
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26381
|
-
|
|
26736
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26382
26737
|
QODER_MANCODE_START_MARKER,
|
|
26383
26738
|
QODER_MANCODE_END_MARKER
|
|
26384
26739
|
);
|
|
@@ -26398,9 +26753,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26398
26753
|
readyDetail: "managed block present"
|
|
26399
26754
|
};
|
|
26400
26755
|
}
|
|
26401
|
-
const commandsDir =
|
|
26756
|
+
const commandsDir = path49.join(rootDir, ".qoder", "commands");
|
|
26402
26757
|
const hasCommands = await allManagedSkills(
|
|
26403
|
-
MODE_NAMES.map((mode) =>
|
|
26758
|
+
MODE_NAMES.map((mode) => path49.join(commandsDir, `${mode}.md`)),
|
|
26404
26759
|
[MODE_FILE_MANAGED_MARKER]
|
|
26405
26760
|
);
|
|
26406
26761
|
return {
|
|
@@ -26411,7 +26766,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26411
26766
|
};
|
|
26412
26767
|
}
|
|
26413
26768
|
const hasBlock = await fileHasManagedBlock(
|
|
26414
|
-
|
|
26769
|
+
path49.join(rootDir, ".github", "copilot-instructions.md")
|
|
26415
26770
|
);
|
|
26416
26771
|
if (!hasBlock) {
|
|
26417
26772
|
return {
|
|
@@ -26422,9 +26777,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26422
26777
|
};
|
|
26423
26778
|
}
|
|
26424
26779
|
if (!await isPlatformMinimal(rootDir, "copilot")) {
|
|
26425
|
-
const promptsDir =
|
|
26780
|
+
const promptsDir = path49.join(rootDir, ".github", "prompts");
|
|
26426
26781
|
const hasPrompts = await allManagedSkills(
|
|
26427
|
-
MODE_NAMES.map((mode) =>
|
|
26782
|
+
MODE_NAMES.map((mode) => path49.join(promptsDir, `${mode}.prompt.md`)),
|
|
26428
26783
|
[MODE_FILE_MANAGED_MARKER]
|
|
26429
26784
|
);
|
|
26430
26785
|
return {
|
|
@@ -26457,13 +26812,13 @@ async function allManagedSkills(paths, markers) {
|
|
|
26457
26812
|
async function claudeFullContentReady(rootDir) {
|
|
26458
26813
|
const skillChecks = MVP2_SKILLS.map(
|
|
26459
26814
|
(skill) => fileMatches(
|
|
26460
|
-
|
|
26815
|
+
path49.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
|
|
26461
26816
|
(content) => isGeneratedClaudeSkill(content, skill.name)
|
|
26462
26817
|
)
|
|
26463
26818
|
);
|
|
26464
26819
|
const agentChecks = ALL_AGENTS.map(
|
|
26465
26820
|
(agent) => fileMatches(
|
|
26466
|
-
|
|
26821
|
+
path49.join(rootDir, ".claude", "agents", `${agent.name}.md`),
|
|
26467
26822
|
(content) => isGeneratedClaudeAgent(content, agent.name)
|
|
26468
26823
|
)
|
|
26469
26824
|
);
|
|
@@ -26491,7 +26846,7 @@ async function fileHasAnyMarker(filePath, needles) {
|
|
|
26491
26846
|
async function isPlatformMinimal(rootDir, platform) {
|
|
26492
26847
|
try {
|
|
26493
26848
|
const raw = await fs.readFile(
|
|
26494
|
-
|
|
26849
|
+
path49.join(rootDir, ".mancode", "config.json"),
|
|
26495
26850
|
"utf-8"
|
|
26496
26851
|
);
|
|
26497
26852
|
const config = JSON.parse(raw);
|
|
@@ -26513,7 +26868,7 @@ async function fileHasManagedBlock(filePath, startMarker = DEFAULT_MANCODE_START
|
|
|
26513
26868
|
async function claudeHooksRegistered(rootDir) {
|
|
26514
26869
|
try {
|
|
26515
26870
|
const raw = await fs.readFile(
|
|
26516
|
-
|
|
26871
|
+
path49.join(rootDir, ".claude", "settings.json"),
|
|
26517
26872
|
"utf-8"
|
|
26518
26873
|
);
|
|
26519
26874
|
const settings = JSON.parse(raw);
|
|
@@ -26556,7 +26911,7 @@ function isRecord7(value) {
|
|
|
26556
26911
|
// src/system/detect-team.ts
|
|
26557
26912
|
import { execFile as execFile6 } from "child_process";
|
|
26558
26913
|
import { access as access2 } from "fs/promises";
|
|
26559
|
-
import
|
|
26914
|
+
import path50 from "path";
|
|
26560
26915
|
import process3 from "process";
|
|
26561
26916
|
import { promisify as promisify6 } from "util";
|
|
26562
26917
|
var execFileAsync = promisify6(execFile6);
|
|
@@ -26666,7 +27021,7 @@ async function anyPathExists(projectRoot, candidates) {
|
|
|
26666
27021
|
const results = await Promise.all(
|
|
26667
27022
|
candidates.map(async (candidate) => {
|
|
26668
27023
|
try {
|
|
26669
|
-
await access2(
|
|
27024
|
+
await access2(path50.join(projectRoot, candidate));
|
|
26670
27025
|
return true;
|
|
26671
27026
|
} catch {
|
|
26672
27027
|
return false;
|
|
@@ -26707,7 +27062,7 @@ async function detectSystemDeps(env = process4.env) {
|
|
|
26707
27062
|
// src/system/init-onboarding.ts
|
|
26708
27063
|
import { execFileSync } from "child_process";
|
|
26709
27064
|
import { promises as fs2 } from "fs";
|
|
26710
|
-
import
|
|
27065
|
+
import path51 from "path";
|
|
26711
27066
|
import process5 from "process";
|
|
26712
27067
|
import { stdin, stdout } from "process";
|
|
26713
27068
|
import { createInterface } from "readline/promises";
|
|
@@ -26812,7 +27167,7 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
26812
27167
|
hints.add("copilot");
|
|
26813
27168
|
const exists2 = async (relative) => {
|
|
26814
27169
|
try {
|
|
26815
|
-
await fs2.access(
|
|
27170
|
+
await fs2.access(path51.join(rootDir, relative));
|
|
26816
27171
|
return true;
|
|
26817
27172
|
} catch {
|
|
26818
27173
|
return false;
|
|
@@ -26889,7 +27244,7 @@ function createTerminalPrompter() {
|
|
|
26889
27244
|
|
|
26890
27245
|
// src/system/scan-aesthetics.ts
|
|
26891
27246
|
import { promises as fs3 } from "fs";
|
|
26892
|
-
import
|
|
27247
|
+
import path52 from "path";
|
|
26893
27248
|
var MAX_COMPONENT_SCAN_DEPTH = 12;
|
|
26894
27249
|
var MAX_COMPONENT_FILES = 2e3;
|
|
26895
27250
|
async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
@@ -26925,7 +27280,7 @@ async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
|
26925
27280
|
} else if (await hasTailwindDep(projectRoot) || uiLibrary) {
|
|
26926
27281
|
matchLevel = "low";
|
|
26927
27282
|
}
|
|
26928
|
-
if (uiLibrary && await pathExists5(
|
|
27283
|
+
if (uiLibrary && await pathExists5(path52.join(projectRoot, "package.json"))) {
|
|
26929
27284
|
sourceFiles.push("package.json");
|
|
26930
27285
|
}
|
|
26931
27286
|
sourceFiles.push(...cssScan.sourceFiles);
|
|
@@ -26951,7 +27306,7 @@ async function findTailwindConfig(projectRoot) {
|
|
|
26951
27306
|
"tailwind.config.mjs"
|
|
26952
27307
|
];
|
|
26953
27308
|
for (const name of candidates) {
|
|
26954
|
-
const absPath =
|
|
27309
|
+
const absPath = path52.join(projectRoot, name);
|
|
26955
27310
|
if (await pathExists5(absPath)) {
|
|
26956
27311
|
return { absPath, relPath: name };
|
|
26957
27312
|
}
|
|
@@ -27178,7 +27533,7 @@ async function scanComponents(projectRoot) {
|
|
|
27178
27533
|
const names = /* @__PURE__ */ new Set();
|
|
27179
27534
|
let visitedFiles = 0;
|
|
27180
27535
|
for (const relRoot of roots) {
|
|
27181
|
-
const absRoot =
|
|
27536
|
+
const absRoot = path52.join(projectRoot, relRoot);
|
|
27182
27537
|
if (!await pathExists5(absRoot)) continue;
|
|
27183
27538
|
visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);
|
|
27184
27539
|
if (visitedFiles >= MAX_COMPONENT_FILES) break;
|
|
@@ -27198,7 +27553,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
27198
27553
|
}
|
|
27199
27554
|
for (const entry of entries) {
|
|
27200
27555
|
if (fileCount >= MAX_COMPONENT_FILES) return fileCount;
|
|
27201
|
-
const abs =
|
|
27556
|
+
const abs = path52.join(dir, entry);
|
|
27202
27557
|
let info;
|
|
27203
27558
|
try {
|
|
27204
27559
|
info = await fs3.lstat(abs);
|
|
@@ -27219,7 +27574,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
27219
27574
|
""
|
|
27220
27575
|
);
|
|
27221
27576
|
if (base === "index") {
|
|
27222
|
-
base =
|
|
27577
|
+
base = path52.basename(dir);
|
|
27223
27578
|
}
|
|
27224
27579
|
if (base.startsWith(".")) continue;
|
|
27225
27580
|
const componentName = toPascalCase(base);
|
|
@@ -27241,7 +27596,7 @@ async function scanCssVariables(projectRoot) {
|
|
|
27241
27596
|
const variables = {};
|
|
27242
27597
|
const sourceFiles = [];
|
|
27243
27598
|
for (const relPath of candidates) {
|
|
27244
|
-
const absPath =
|
|
27599
|
+
const absPath = path52.join(projectRoot, relPath);
|
|
27245
27600
|
if (!await pathExists5(absPath)) continue;
|
|
27246
27601
|
const content = await fs3.readFile(absPath, "utf-8");
|
|
27247
27602
|
const found = extractCssVariables(content);
|
|
@@ -27287,7 +27642,7 @@ function toPascalCase(value) {
|
|
|
27287
27642
|
async function hasTailwindDep(projectRoot) {
|
|
27288
27643
|
try {
|
|
27289
27644
|
const raw = await fs3.readFile(
|
|
27290
|
-
|
|
27645
|
+
path52.join(projectRoot, "package.json"),
|
|
27291
27646
|
"utf-8"
|
|
27292
27647
|
);
|
|
27293
27648
|
const pkg = JSON.parse(raw);
|
|
@@ -27313,14 +27668,14 @@ async function pathExists5(p) {
|
|
|
27313
27668
|
// src/context/greenfield-init.ts
|
|
27314
27669
|
import {
|
|
27315
27670
|
lstat as lstat20,
|
|
27316
|
-
mkdir as
|
|
27317
|
-
readFile as
|
|
27318
|
-
rename as
|
|
27319
|
-
rm as
|
|
27320
|
-
writeFile as
|
|
27671
|
+
mkdir as mkdir35,
|
|
27672
|
+
readFile as readFile39,
|
|
27673
|
+
rename as rename11,
|
|
27674
|
+
rm as rm19,
|
|
27675
|
+
writeFile as writeFile42
|
|
27321
27676
|
} from "fs/promises";
|
|
27322
|
-
import
|
|
27323
|
-
var JOURNAL_RELATIVE_DIRECTORY =
|
|
27677
|
+
import path53 from "path";
|
|
27678
|
+
var JOURNAL_RELATIVE_DIRECTORY = path53.join(
|
|
27324
27679
|
"local",
|
|
27325
27680
|
"runtime",
|
|
27326
27681
|
"initialization"
|
|
@@ -27343,7 +27698,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27343
27698
|
normalized.operationId
|
|
27344
27699
|
);
|
|
27345
27700
|
try {
|
|
27346
|
-
await
|
|
27701
|
+
await mkdir35(stagingRoot);
|
|
27347
27702
|
} catch (error) {
|
|
27348
27703
|
if (isAlreadyExists22(error)) {
|
|
27349
27704
|
throw new Error("MANCODE_GREENFIELD_STAGING_EXISTS");
|
|
@@ -27369,7 +27724,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27369
27724
|
operationId: normalized.operationId,
|
|
27370
27725
|
workspaceId: normalized.workspaceId,
|
|
27371
27726
|
state: "staged",
|
|
27372
|
-
stagingDirectoryName:
|
|
27727
|
+
stagingDirectoryName: path53.basename(stagingRoot),
|
|
27373
27728
|
targetDirectoryName: ".mancode",
|
|
27374
27729
|
manifestDigest: digestCanonicalJson(manifest),
|
|
27375
27730
|
configDigest: digestCanonicalJson(config),
|
|
@@ -27400,7 +27755,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27400
27755
|
return journal;
|
|
27401
27756
|
}
|
|
27402
27757
|
async function publishGreenfieldInitialization(input) {
|
|
27403
|
-
const root =
|
|
27758
|
+
const root = path53.resolve(input.projectRoot);
|
|
27404
27759
|
assertUlid(input.operationId, "greenfield operationId");
|
|
27405
27760
|
const stagingRoot = greenfieldStagingPath(root, input.operationId);
|
|
27406
27761
|
const targetRoot = greenfieldTargetPath(root);
|
|
@@ -27418,7 +27773,7 @@ async function publishGreenfieldInitialization(input) {
|
|
|
27418
27773
|
if (await lstatOrNull4(targetRoot) !== null) {
|
|
27419
27774
|
throw new Error("MANCODE_V3_TARGET_EXISTS");
|
|
27420
27775
|
}
|
|
27421
|
-
await
|
|
27776
|
+
await rename11(stagingRoot, targetRoot);
|
|
27422
27777
|
throwIfOperationCrashInjected("greenfield_initialize", "publish-v3-root");
|
|
27423
27778
|
return finishPublishedInitialization(
|
|
27424
27779
|
{ ...input, projectRoot: root },
|
|
@@ -27435,10 +27790,10 @@ async function initializeGreenfield(input, publication) {
|
|
|
27435
27790
|
}
|
|
27436
27791
|
function greenfieldStagingPath(projectRoot, operationId) {
|
|
27437
27792
|
assertUlid(operationId, "greenfield operationId");
|
|
27438
|
-
return
|
|
27793
|
+
return path53.join(path53.resolve(projectRoot), `.mancode.init-${operationId}`);
|
|
27439
27794
|
}
|
|
27440
27795
|
function greenfieldTargetPath(projectRoot) {
|
|
27441
|
-
return
|
|
27796
|
+
return path53.join(path53.resolve(projectRoot), ".mancode");
|
|
27442
27797
|
}
|
|
27443
27798
|
function parseGreenfieldInitializationJournal(value) {
|
|
27444
27799
|
assertRecord(value, "greenfield initialization journal");
|
|
@@ -27509,8 +27864,8 @@ function parseGreenfieldInitializationJournal(value) {
|
|
|
27509
27864
|
),
|
|
27510
27865
|
adapterPlans: parseAdapterPlans(value.adapterPlans),
|
|
27511
27866
|
bindingRegistered: value.bindingRegistered,
|
|
27512
|
-
createdAt:
|
|
27513
|
-
updatedAt:
|
|
27867
|
+
createdAt: parseTimestamp15(value.createdAt, "createdAt"),
|
|
27868
|
+
updatedAt: parseTimestamp15(value.updatedAt, "updatedAt")
|
|
27514
27869
|
};
|
|
27515
27870
|
}
|
|
27516
27871
|
async function finishPublishedInitialization(input, stagedJournal) {
|
|
@@ -27574,7 +27929,7 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
27574
27929
|
activatedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
27575
27930
|
};
|
|
27576
27931
|
assertSchemaManifestTransition(manifest, activeManifest);
|
|
27577
|
-
await writeJson(
|
|
27932
|
+
await writeJson(path53.join(targetRoot, "schema.json"), activeManifest);
|
|
27578
27933
|
throwIfOperationCrashInjected(
|
|
27579
27934
|
"greenfield_initialize",
|
|
27580
27935
|
"activate-v3-manifest"
|
|
@@ -27590,46 +27945,46 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
27590
27945
|
}
|
|
27591
27946
|
async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, projectFacts, journal) {
|
|
27592
27947
|
await Promise.all([
|
|
27593
|
-
|
|
27594
|
-
|
|
27948
|
+
mkdir35(path53.join(stagingRoot, "shared", "context"), { recursive: true }),
|
|
27949
|
+
mkdir35(path53.join(stagingRoot, "shared", "memory", "decisions"), {
|
|
27595
27950
|
recursive: true
|
|
27596
27951
|
}),
|
|
27597
|
-
|
|
27952
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "actors"), {
|
|
27598
27953
|
recursive: true
|
|
27599
27954
|
}),
|
|
27600
|
-
|
|
27955
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "handoffs"), {
|
|
27601
27956
|
recursive: true
|
|
27602
27957
|
}),
|
|
27603
|
-
|
|
27958
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "events"), {
|
|
27604
27959
|
recursive: true
|
|
27605
27960
|
}),
|
|
27606
|
-
|
|
27961
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "transport"), {
|
|
27607
27962
|
recursive: true
|
|
27608
27963
|
}),
|
|
27609
|
-
|
|
27610
|
-
|
|
27964
|
+
mkdir35(path53.join(stagingRoot, "local", "sessions"), { recursive: true }),
|
|
27965
|
+
mkdir35(path53.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
|
|
27611
27966
|
recursive: true
|
|
27612
27967
|
}),
|
|
27613
|
-
|
|
27614
|
-
|
|
27615
|
-
|
|
27616
|
-
|
|
27617
|
-
|
|
27618
|
-
|
|
27968
|
+
mkdir35(path53.join(stagingRoot, "local", "workflows"), { recursive: true }),
|
|
27969
|
+
mkdir35(path53.join(stagingRoot, "local", "overlays"), { recursive: true }),
|
|
27970
|
+
mkdir35(path53.join(stagingRoot, "local", "quarantine"), { recursive: true }),
|
|
27971
|
+
mkdir35(path53.join(stagingRoot, "local", "publish"), { recursive: true }),
|
|
27972
|
+
mkdir35(path53.join(stagingRoot, "local", "cache"), { recursive: true }),
|
|
27973
|
+
mkdir35(path53.join(stagingRoot, "runtime", "non-git", journal.workspaceId), {
|
|
27619
27974
|
recursive: true
|
|
27620
27975
|
})
|
|
27621
27976
|
]);
|
|
27622
27977
|
await Promise.all([
|
|
27623
|
-
writeJson(
|
|
27624
|
-
writeJson(
|
|
27625
|
-
writeJson(
|
|
27978
|
+
writeJson(path53.join(stagingRoot, "schema.json"), manifest),
|
|
27979
|
+
writeJson(path53.join(stagingRoot, "shared", "config.json"), config),
|
|
27980
|
+
writeJson(path53.join(stagingRoot, "shared", "team", "policy.json"), policy),
|
|
27626
27981
|
writeJson(
|
|
27627
|
-
|
|
27982
|
+
path53.join(stagingRoot, "shared", "context", "project.json"),
|
|
27628
27983
|
projectFacts
|
|
27629
27984
|
),
|
|
27630
27985
|
writeJson(journalPath2(stagingRoot, journal.operationId), journal),
|
|
27631
|
-
|
|
27632
|
-
|
|
27986
|
+
writeFile42(
|
|
27987
|
+
path53.join(stagingRoot, ".gitignore"),
|
|
27633
27988
|
`${V3_IGNORE.join("\n")}
|
|
27634
27989
|
`,
|
|
27635
27990
|
{ encoding: "utf8", flag: "wx" }
|
|
@@ -27638,14 +27993,14 @@ async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, proj
|
|
|
27638
27993
|
}
|
|
27639
27994
|
async function readGreenfieldJournal(root, operationId) {
|
|
27640
27995
|
try {
|
|
27641
|
-
const raw = await
|
|
27996
|
+
const raw = await readFile39(journalPath2(root, operationId), "utf8");
|
|
27642
27997
|
const journal = parseGreenfieldInitializationJournal(JSON.parse(raw));
|
|
27643
27998
|
if (journal.operationId !== operationId) {
|
|
27644
27999
|
throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
|
|
27645
28000
|
}
|
|
27646
28001
|
return journal;
|
|
27647
28002
|
} catch (error) {
|
|
27648
|
-
if (error instanceof SyntaxError ||
|
|
28003
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27649
28004
|
throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
|
|
27650
28005
|
}
|
|
27651
28006
|
throw error;
|
|
@@ -27654,10 +28009,10 @@ async function readGreenfieldJournal(root, operationId) {
|
|
|
27654
28009
|
async function readManifest(root) {
|
|
27655
28010
|
try {
|
|
27656
28011
|
return parseSchemaManifest(
|
|
27657
|
-
JSON.parse(await
|
|
28012
|
+
JSON.parse(await readFile39(path53.join(root, "schema.json"), "utf8"))
|
|
27658
28013
|
);
|
|
27659
28014
|
} catch (error) {
|
|
27660
|
-
if (error instanceof SyntaxError ||
|
|
28015
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27661
28016
|
throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
|
|
27662
28017
|
}
|
|
27663
28018
|
throw error;
|
|
@@ -27692,7 +28047,7 @@ async function readConfig(root) {
|
|
|
27692
28047
|
try {
|
|
27693
28048
|
config = parseProjectConfig(
|
|
27694
28049
|
JSON.parse(
|
|
27695
|
-
await
|
|
28050
|
+
await readFile39(path53.join(root, "shared", "config.json"), "utf8")
|
|
27696
28051
|
)
|
|
27697
28052
|
);
|
|
27698
28053
|
} catch (error) {
|
|
@@ -27708,8 +28063,8 @@ async function readPolicy(root) {
|
|
|
27708
28063
|
try {
|
|
27709
28064
|
policy = parseTeamPolicy(
|
|
27710
28065
|
JSON.parse(
|
|
27711
|
-
await
|
|
27712
|
-
|
|
28066
|
+
await readFile39(
|
|
28067
|
+
path53.join(root, "shared", "team", "policy.json"),
|
|
27713
28068
|
"utf8"
|
|
27714
28069
|
)
|
|
27715
28070
|
)
|
|
@@ -27726,14 +28081,14 @@ async function readProjectFactsAt(root) {
|
|
|
27726
28081
|
try {
|
|
27727
28082
|
return parseProjectFacts(
|
|
27728
28083
|
JSON.parse(
|
|
27729
|
-
await
|
|
27730
|
-
|
|
28084
|
+
await readFile39(
|
|
28085
|
+
path53.join(root, "shared", "context", "project.json"),
|
|
27731
28086
|
"utf8"
|
|
27732
28087
|
)
|
|
27733
28088
|
)
|
|
27734
28089
|
);
|
|
27735
28090
|
} catch (error) {
|
|
27736
|
-
if (error instanceof SyntaxError ||
|
|
28091
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27737
28092
|
throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
|
|
27738
28093
|
}
|
|
27739
28094
|
throw error;
|
|
@@ -27766,7 +28121,7 @@ function normalizeInput(input) {
|
|
|
27766
28121
|
parseSchemaManifest(manifest);
|
|
27767
28122
|
return {
|
|
27768
28123
|
...input,
|
|
27769
|
-
projectRoot:
|
|
28124
|
+
projectRoot: path53.resolve(input.projectRoot),
|
|
27770
28125
|
projectConfig: config,
|
|
27771
28126
|
teamPolicy: policy,
|
|
27772
28127
|
projectFacts: input.projectFacts === void 0 ? void 0 : parseProjectFacts(input.projectFacts)
|
|
@@ -27864,21 +28219,21 @@ function initializationProjectFacts(input, now) {
|
|
|
27864
28219
|
}
|
|
27865
28220
|
function journalPath2(root, operationId) {
|
|
27866
28221
|
assertUlid(operationId, "greenfield operationId");
|
|
27867
|
-
return
|
|
28222
|
+
return path53.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
|
|
27868
28223
|
}
|
|
27869
28224
|
async function writeJson(target, value) {
|
|
27870
|
-
const directory =
|
|
27871
|
-
await
|
|
27872
|
-
const temporary =
|
|
28225
|
+
const directory = path53.dirname(target);
|
|
28226
|
+
await mkdir35(directory, { recursive: true });
|
|
28227
|
+
const temporary = path53.join(
|
|
27873
28228
|
directory,
|
|
27874
|
-
`.${
|
|
28229
|
+
`.${path53.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
27875
28230
|
);
|
|
27876
|
-
await
|
|
28231
|
+
await writeFile42(temporary, `${JSON.stringify(value, null, 2)}
|
|
27877
28232
|
`, {
|
|
27878
28233
|
encoding: "utf8",
|
|
27879
28234
|
flag: "wx"
|
|
27880
28235
|
});
|
|
27881
|
-
await
|
|
28236
|
+
await rename11(temporary, target);
|
|
27882
28237
|
}
|
|
27883
28238
|
function parseDigest6(value, label) {
|
|
27884
28239
|
if (typeof value !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value)) {
|
|
@@ -27886,7 +28241,7 @@ function parseDigest6(value, label) {
|
|
|
27886
28241
|
}
|
|
27887
28242
|
return value;
|
|
27888
28243
|
}
|
|
27889
|
-
function
|
|
28244
|
+
function parseTimestamp15(value, label) {
|
|
27890
28245
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
27891
28246
|
throw new Error(`greenfield initialization journal ${label} is invalid`);
|
|
27892
28247
|
}
|
|
@@ -27899,11 +28254,11 @@ async function lstatOrNull4(target) {
|
|
|
27899
28254
|
try {
|
|
27900
28255
|
return await lstat20(target);
|
|
27901
28256
|
} catch (error) {
|
|
27902
|
-
if (
|
|
28257
|
+
if (isNotFound29(error)) return null;
|
|
27903
28258
|
throw error;
|
|
27904
28259
|
}
|
|
27905
28260
|
}
|
|
27906
|
-
function
|
|
28261
|
+
function isNotFound29(error) {
|
|
27907
28262
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
27908
28263
|
}
|
|
27909
28264
|
function isAlreadyExists22(error) {
|
|
@@ -27991,9 +28346,9 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27991
28346
|
return EXIT_INIT_FAILED;
|
|
27992
28347
|
}
|
|
27993
28348
|
const authority = resolveInitAuthority(options);
|
|
27994
|
-
const mancodeDir =
|
|
27995
|
-
const stateFile =
|
|
27996
|
-
const v3SchemaFile =
|
|
28349
|
+
const mancodeDir = path54.join(rootDir, ".mancode");
|
|
28350
|
+
const stateFile = path54.join(mancodeDir, "state.json");
|
|
28351
|
+
const v3SchemaFile = path54.join(mancodeDir, "schema.json");
|
|
27997
28352
|
const wasInitialized = await pathExists6(stateFile);
|
|
27998
28353
|
let mutationSnapshots = [];
|
|
27999
28354
|
let directorySnapshots = [];
|
|
@@ -28061,7 +28416,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28061
28416
|
}
|
|
28062
28417
|
return initializeV3(rootDir, options);
|
|
28063
28418
|
}
|
|
28064
|
-
const isGitRepo = await pathExists6(
|
|
28419
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
28065
28420
|
const hasManifest = await hasProjectManifest(rootDir);
|
|
28066
28421
|
let isGenericProject = false;
|
|
28067
28422
|
if (!isGitRepo && !hasManifest) {
|
|
@@ -28179,8 +28534,8 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28179
28534
|
const managedFiles = getInitManagedFilePaths(rootDir, selectedPlatforms);
|
|
28180
28535
|
mutationSnapshots = await snapshotFiles(managedFiles);
|
|
28181
28536
|
directorySnapshots = await snapshotDirectories(managedFiles, [
|
|
28182
|
-
|
|
28183
|
-
|
|
28537
|
+
path54.join(mancodeDir, "workflows"),
|
|
28538
|
+
path54.join(mancodeDir, "preseason-reports")
|
|
28184
28539
|
]);
|
|
28185
28540
|
const team = await detectTeamStatus(rootDir);
|
|
28186
28541
|
const platformMinimal = Object.fromEntries(
|
|
@@ -28241,7 +28596,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28241
28596
|
`;
|
|
28242
28597
|
await fs4.writeFile(stateFile, stateContent, "utf-8");
|
|
28243
28598
|
await fs4.writeFile(
|
|
28244
|
-
|
|
28599
|
+
path54.join(mancodeDir, "project-profile.json"),
|
|
28245
28600
|
`${JSON.stringify(profile, null, 2)}
|
|
28246
28601
|
`,
|
|
28247
28602
|
"utf-8"
|
|
@@ -28278,7 +28633,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28278
28633
|
)
|
|
28279
28634
|
);
|
|
28280
28635
|
const tokens = await scanAesthetics(rootDir, uiLibrary);
|
|
28281
|
-
const tokensPath =
|
|
28636
|
+
const tokensPath = path54.join(
|
|
28282
28637
|
mancodeDir,
|
|
28283
28638
|
"aesthetics",
|
|
28284
28639
|
"style-tokens.json"
|
|
@@ -28442,7 +28797,7 @@ async function initializeV3(rootDir, options) {
|
|
|
28442
28797
|
);
|
|
28443
28798
|
return EXIT_INIT_FAILED;
|
|
28444
28799
|
}
|
|
28445
|
-
const schemaPath =
|
|
28800
|
+
const schemaPath = path54.join(rootDir, ".mancode", "schema.json");
|
|
28446
28801
|
let existingV3 = false;
|
|
28447
28802
|
let registeredAdapters = /* @__PURE__ */ new Set();
|
|
28448
28803
|
if (await pathExists6(schemaPath)) {
|
|
@@ -28545,7 +28900,7 @@ function printV3InitError(error) {
|
|
|
28545
28900
|
}
|
|
28546
28901
|
}
|
|
28547
28902
|
async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms) {
|
|
28548
|
-
const configPath =
|
|
28903
|
+
const configPath = path54.join(mancodeDir, "config.json");
|
|
28549
28904
|
let config = {};
|
|
28550
28905
|
try {
|
|
28551
28906
|
config = JSON.parse(await fs4.readFile(configPath, "utf-8"));
|
|
@@ -28578,7 +28933,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
|
|
|
28578
28933
|
async function readExistingInitPreferences(mancodeDir) {
|
|
28579
28934
|
try {
|
|
28580
28935
|
const config = JSON.parse(
|
|
28581
|
-
await fs4.readFile(
|
|
28936
|
+
await fs4.readFile(path54.join(mancodeDir, "config.json"), "utf-8")
|
|
28582
28937
|
);
|
|
28583
28938
|
const preferences = {
|
|
28584
28939
|
platforms: Array.isArray(config.platforms) ? config.platforms.filter(
|
|
@@ -28644,13 +28999,13 @@ async function selectInitPlatforms(input) {
|
|
|
28644
28999
|
}
|
|
28645
29000
|
async function hasProjectManifest(rootDir) {
|
|
28646
29001
|
for (const name of PROJECT_MANIFESTS) {
|
|
28647
|
-
if (await pathExists6(
|
|
29002
|
+
if (await pathExists6(path54.join(rootDir, name))) return true;
|
|
28648
29003
|
}
|
|
28649
29004
|
return false;
|
|
28650
29005
|
}
|
|
28651
29006
|
async function canInitializeGenericProject(rootDir) {
|
|
28652
|
-
const resolved =
|
|
28653
|
-
if (resolved ===
|
|
29007
|
+
const resolved = path54.resolve(rootDir);
|
|
29008
|
+
if (resolved === path54.parse(resolved).root || resolved === path54.resolve(os.homedir())) {
|
|
28654
29009
|
return { ok: false, reason: "unsafe" };
|
|
28655
29010
|
}
|
|
28656
29011
|
try {
|
|
@@ -28664,11 +29019,11 @@ async function canInitializeGenericProject(rootDir) {
|
|
|
28664
29019
|
}
|
|
28665
29020
|
}
|
|
28666
29021
|
async function validateV3CliProjectBoundary(rootDir, options, locale, legacyInitialized) {
|
|
28667
|
-
const isGitRepo = await pathExists6(
|
|
29022
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
28668
29023
|
const hasManifest = await hasProjectManifest(rootDir);
|
|
28669
29024
|
if (isGitRepo || hasManifest) return null;
|
|
28670
29025
|
const v3Initialized = await pathExists6(
|
|
28671
|
-
|
|
29026
|
+
path54.join(rootDir, ".mancode", "schema.json")
|
|
28672
29027
|
);
|
|
28673
29028
|
const legacyAuthorityPresent = legacyInitialized || (await scanLegacyAuthority(rootDir)).authorityPresent;
|
|
28674
29029
|
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
@@ -28803,7 +29158,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
28803
29158
|
files.push(`.github/prompts/${mode}.prompt.md`);
|
|
28804
29159
|
}
|
|
28805
29160
|
}
|
|
28806
|
-
return [...new Set(files.map((file) =>
|
|
29161
|
+
return [...new Set(files.map((file) => path54.join(rootDir, file)))];
|
|
28807
29162
|
}
|
|
28808
29163
|
async function snapshotFiles(filePaths) {
|
|
28809
29164
|
return Promise.all(
|
|
@@ -28822,10 +29177,10 @@ async function snapshotFiles(filePaths) {
|
|
|
28822
29177
|
async function snapshotDirectories(filePaths, additionalDirectories = []) {
|
|
28823
29178
|
const directories = new Set(additionalDirectories);
|
|
28824
29179
|
for (const filePath of filePaths) {
|
|
28825
|
-
let current =
|
|
28826
|
-
while (current !==
|
|
29180
|
+
let current = path54.dirname(filePath);
|
|
29181
|
+
while (current !== path54.dirname(current)) {
|
|
28827
29182
|
directories.add(current);
|
|
28828
|
-
current =
|
|
29183
|
+
current = path54.dirname(current);
|
|
28829
29184
|
}
|
|
28830
29185
|
}
|
|
28831
29186
|
return Promise.all(
|
|
@@ -28841,7 +29196,7 @@ async function restoreFiles(snapshots) {
|
|
|
28841
29196
|
await fs4.rm(snapshot.filePath, { force: true });
|
|
28842
29197
|
continue;
|
|
28843
29198
|
}
|
|
28844
|
-
await fs4.mkdir(
|
|
29199
|
+
await fs4.mkdir(path54.dirname(snapshot.filePath), { recursive: true });
|
|
28845
29200
|
await fs4.writeFile(snapshot.filePath, snapshot.content, "utf-8");
|
|
28846
29201
|
}
|
|
28847
29202
|
}
|
|
@@ -28918,15 +29273,15 @@ async function pathExists6(p) {
|
|
|
28918
29273
|
|
|
28919
29274
|
// src/commands/install.ts
|
|
28920
29275
|
import { promises as fs5 } from "fs";
|
|
28921
|
-
import
|
|
29276
|
+
import path55 from "path";
|
|
28922
29277
|
import process7 from "process";
|
|
28923
29278
|
var EXIT_OK3 = 0;
|
|
28924
29279
|
var EXIT_NOT_INITIALIZED2 = 1;
|
|
28925
29280
|
var EXIT_UNSUPPORTED_PLATFORM = 2;
|
|
28926
29281
|
var EXIT_INSTALL_FAILED = 3;
|
|
28927
29282
|
async function install(rootDir = process7.cwd(), platform = "claude-code", options = {}) {
|
|
28928
|
-
const stateFile =
|
|
28929
|
-
const v3SchemaFile =
|
|
29283
|
+
const stateFile = path55.join(rootDir, ".mancode", "state.json");
|
|
29284
|
+
const v3SchemaFile = path55.join(rootDir, ".mancode", "schema.json");
|
|
28930
29285
|
if (await pathExists7(v3SchemaFile)) {
|
|
28931
29286
|
return installV3(rootDir, platform, options);
|
|
28932
29287
|
}
|
|
@@ -29087,7 +29442,7 @@ function printUnsupportedPlatform(platform) {
|
|
|
29087
29442
|
}
|
|
29088
29443
|
}
|
|
29089
29444
|
async function readConfig2(rootDir) {
|
|
29090
|
-
const configPath =
|
|
29445
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
29091
29446
|
try {
|
|
29092
29447
|
const raw = await fs5.readFile(configPath, "utf-8");
|
|
29093
29448
|
return { config: JSON.parse(raw), valid: true };
|
|
@@ -29102,7 +29457,7 @@ function isNodeError7(err) {
|
|
|
29102
29457
|
return err instanceof Error && "code" in err;
|
|
29103
29458
|
}
|
|
29104
29459
|
async function updateConfig(rootDir, config) {
|
|
29105
|
-
const configPath =
|
|
29460
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
29106
29461
|
const content = `${JSON.stringify(config, null, 2)}
|
|
29107
29462
|
`;
|
|
29108
29463
|
await fs5.writeFile(configPath, content, "utf-8");
|
|
@@ -29138,7 +29493,7 @@ function readConfiguredMinimal(value, platform) {
|
|
|
29138
29493
|
async function readStatePlatform(rootDir) {
|
|
29139
29494
|
try {
|
|
29140
29495
|
const raw = await fs5.readFile(
|
|
29141
|
-
|
|
29496
|
+
path55.join(rootDir, ".mancode", "state.json"),
|
|
29142
29497
|
"utf-8"
|
|
29143
29498
|
);
|
|
29144
29499
|
const state = JSON.parse(raw);
|
|
@@ -29161,11 +29516,11 @@ function isRecord9(value) {
|
|
|
29161
29516
|
|
|
29162
29517
|
// src/commands/list-platforms.ts
|
|
29163
29518
|
import { promises as fs6 } from "fs";
|
|
29164
|
-
import
|
|
29519
|
+
import path56 from "path";
|
|
29165
29520
|
import process8 from "process";
|
|
29166
29521
|
var EXIT_OK4 = 0;
|
|
29167
29522
|
async function listPlatforms(rootDir = process8.cwd()) {
|
|
29168
|
-
if (await pathExists8(
|
|
29523
|
+
if (await pathExists8(path56.join(rootDir, ".mancode", "schema.json"))) {
|
|
29169
29524
|
return listV3Platforms(rootDir);
|
|
29170
29525
|
}
|
|
29171
29526
|
const installed = new Set(await readInstalledPlatforms(rootDir));
|
|
@@ -29201,7 +29556,7 @@ async function listV3Platforms(rootDir) {
|
|
|
29201
29556
|
async function readInstalledPlatforms(rootDir) {
|
|
29202
29557
|
try {
|
|
29203
29558
|
const raw = await fs6.readFile(
|
|
29204
|
-
|
|
29559
|
+
path56.join(rootDir, ".mancode", "config.json"),
|
|
29205
29560
|
"utf-8"
|
|
29206
29561
|
);
|
|
29207
29562
|
const config = JSON.parse(raw);
|
|
@@ -29233,8 +29588,8 @@ function describePlatform(platform) {
|
|
|
29233
29588
|
}
|
|
29234
29589
|
|
|
29235
29590
|
// src/commands/manps.ts
|
|
29236
|
-
import { access as access4, readFile as
|
|
29237
|
-
import
|
|
29591
|
+
import { access as access4, readFile as readFile41 } from "fs/promises";
|
|
29592
|
+
import path58 from "path";
|
|
29238
29593
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
29239
29594
|
|
|
29240
29595
|
// src/system/preseason.ts
|
|
@@ -29244,13 +29599,13 @@ import { existsSync, readFileSync } from "fs";
|
|
|
29244
29599
|
import {
|
|
29245
29600
|
access as access3,
|
|
29246
29601
|
lstat as lstat21,
|
|
29247
|
-
mkdir as
|
|
29248
|
-
readFile as
|
|
29602
|
+
mkdir as mkdir36,
|
|
29603
|
+
readFile as readFile40,
|
|
29249
29604
|
readdir as readdir18,
|
|
29250
|
-
rename as
|
|
29251
|
-
writeFile as
|
|
29605
|
+
rename as rename12,
|
|
29606
|
+
writeFile as writeFile43
|
|
29252
29607
|
} from "fs/promises";
|
|
29253
|
-
import
|
|
29608
|
+
import path57 from "path";
|
|
29254
29609
|
var PRESEASON_AREAS = [
|
|
29255
29610
|
"all",
|
|
29256
29611
|
"deps",
|
|
@@ -29330,10 +29685,10 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29330
29685
|
const needsFiles = normalizedArea === "all" || normalizedArea === "dead-code" || normalizedArea === "config";
|
|
29331
29686
|
const files = needsFiles ? await listProjectFiles(projectRoot) : [];
|
|
29332
29687
|
const issues = (await scanArea(projectRoot, normalizedArea, pkg, files)).slice(0, 20);
|
|
29333
|
-
const storageRoot = options.storageRoot ??
|
|
29334
|
-
const reportDir =
|
|
29335
|
-
await
|
|
29336
|
-
const issueDbPath =
|
|
29688
|
+
const storageRoot = options.storageRoot ?? path57.join(projectRoot, ".mancode");
|
|
29689
|
+
const reportDir = path57.join(storageRoot, "preseason-reports");
|
|
29690
|
+
await mkdir36(reportDir, { recursive: true });
|
|
29691
|
+
const issueDbPath = path57.join(storageRoot, "preseason-issues.json");
|
|
29337
29692
|
const reportPath = await allocateReportPath(
|
|
29338
29693
|
reportDir,
|
|
29339
29694
|
`${generatedAt.replace(/[:.]/g, "-")}-${normalizedArea}`
|
|
@@ -29347,9 +29702,9 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29347
29702
|
issueDbPath
|
|
29348
29703
|
};
|
|
29349
29704
|
const database = await buildIssueDatabase(projectRoot, report);
|
|
29350
|
-
await
|
|
29351
|
-
await
|
|
29352
|
-
|
|
29705
|
+
await writeFile43(reportPath, renderPreseasonReport(report), "utf-8");
|
|
29706
|
+
await writeFile43(
|
|
29707
|
+
path57.join(storageRoot, "preseason-report.md"),
|
|
29353
29708
|
renderPreseasonReport(report),
|
|
29354
29709
|
"utf-8"
|
|
29355
29710
|
);
|
|
@@ -29357,7 +29712,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29357
29712
|
return report;
|
|
29358
29713
|
}
|
|
29359
29714
|
async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
29360
|
-
const issueDbPath = options.issueDbPath ??
|
|
29715
|
+
const issueDbPath = options.issueDbPath ?? path57.join(projectRoot, ".mancode", "preseason-issues.json");
|
|
29361
29716
|
const database = await readIssueDatabase(issueDbPath);
|
|
29362
29717
|
const keys = new Set(issues.map((issue) => issueKey(issue)));
|
|
29363
29718
|
const targets = database.issues.filter(
|
|
@@ -29435,7 +29790,7 @@ async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
|
29435
29790
|
write2(" Decision: skipped.");
|
|
29436
29791
|
}
|
|
29437
29792
|
database.updatedAt = now;
|
|
29438
|
-
await
|
|
29793
|
+
await writeFile43(
|
|
29439
29794
|
issueDbPath,
|
|
29440
29795
|
`${JSON.stringify(database, null, 2)}
|
|
29441
29796
|
`,
|
|
@@ -29467,7 +29822,7 @@ async function scanArea(projectRoot, area, pkg, files) {
|
|
|
29467
29822
|
async function allocateReportPath(reportDir, baseName) {
|
|
29468
29823
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
29469
29824
|
const suffix = attempt === 0 ? "" : `-${attempt + 1}`;
|
|
29470
|
-
const candidate =
|
|
29825
|
+
const candidate = path57.join(reportDir, `${baseName}${suffix}.md`);
|
|
29471
29826
|
if (!existsSync(candidate)) return candidate;
|
|
29472
29827
|
}
|
|
29473
29828
|
throw new Error(`unable to allocate preseason report path: ${baseName}`);
|
|
@@ -29516,8 +29871,8 @@ async function walk(root, current, results, depth) {
|
|
|
29516
29871
|
}
|
|
29517
29872
|
for (const entry of entries) {
|
|
29518
29873
|
if (IGNORE_DIRS.has(entry)) continue;
|
|
29519
|
-
const abs =
|
|
29520
|
-
const rel =
|
|
29874
|
+
const abs = path57.join(current, entry);
|
|
29875
|
+
const rel = path57.relative(root, abs);
|
|
29521
29876
|
let info;
|
|
29522
29877
|
try {
|
|
29523
29878
|
info = await lstat21(abs);
|
|
@@ -29527,7 +29882,7 @@ async function walk(root, current, results, depth) {
|
|
|
29527
29882
|
if (info.isSymbolicLink()) continue;
|
|
29528
29883
|
if (info.isDirectory()) {
|
|
29529
29884
|
await walk(root, abs, results, depth + 1);
|
|
29530
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
29885
|
+
} else if (SOURCE_EXTENSIONS.has(path57.extname(entry)) || entry === "package.json") {
|
|
29531
29886
|
results.push(rel);
|
|
29532
29887
|
if (results.length >= MAX_PROJECT_FILES) return;
|
|
29533
29888
|
}
|
|
@@ -29535,7 +29890,7 @@ async function walk(root, current, results, depth) {
|
|
|
29535
29890
|
}
|
|
29536
29891
|
async function readPackageJson(projectRoot) {
|
|
29537
29892
|
try {
|
|
29538
|
-
const raw = await
|
|
29893
|
+
const raw = await readFile40(path57.join(projectRoot, "package.json"), "utf-8");
|
|
29539
29894
|
return JSON.parse(raw);
|
|
29540
29895
|
} catch {
|
|
29541
29896
|
return null;
|
|
@@ -29628,7 +29983,7 @@ function scanTodos(projectRoot, files) {
|
|
|
29628
29983
|
const matches = [];
|
|
29629
29984
|
for (const file of files) {
|
|
29630
29985
|
if (matches.length >= 7) break;
|
|
29631
|
-
const abs =
|
|
29986
|
+
const abs = path57.join(projectRoot, file);
|
|
29632
29987
|
matches.push(...readTodoIssues(abs, file, matches.length));
|
|
29633
29988
|
}
|
|
29634
29989
|
return matches.slice(0, 7);
|
|
@@ -29669,7 +30024,7 @@ function scanTestGaps(files) {
|
|
|
29669
30024
|
if (sourceFiles.length === 0) return [];
|
|
29670
30025
|
const tests = new Set(files.filter((file) => file.startsWith("tests/")));
|
|
29671
30026
|
const missing = sourceFiles.filter((file) => {
|
|
29672
|
-
const base =
|
|
30027
|
+
const base = path57.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
29673
30028
|
return !Array.from(tests).some((test) => test.includes(base));
|
|
29674
30029
|
}).slice(0, 4);
|
|
29675
30030
|
return missing.map((file, index) => ({
|
|
@@ -29678,13 +30033,13 @@ function scanTestGaps(files) {
|
|
|
29678
30033
|
type: "tests",
|
|
29679
30034
|
title: "Core source file has no obvious test",
|
|
29680
30035
|
file,
|
|
29681
|
-
detail: `No matching test file was found for ${
|
|
30036
|
+
detail: `No matching test file was found for ${path57.basename(file)}.`,
|
|
29682
30037
|
recommendation: "Add focused coverage for the public behavior or document why this module is exercised indirectly."
|
|
29683
30038
|
}));
|
|
29684
30039
|
}
|
|
29685
30040
|
function scanConfig(projectRoot, files) {
|
|
29686
30041
|
const issues = [];
|
|
29687
|
-
if (!files.includes(".gitignore") && !pathExistsSync(
|
|
30042
|
+
if (!files.includes(".gitignore") && !pathExistsSync(path57.join(projectRoot, ".gitignore"))) {
|
|
29688
30043
|
issues.push({
|
|
29689
30044
|
id: "config-gitignore",
|
|
29690
30045
|
severity: "P1",
|
|
@@ -29695,7 +30050,7 @@ function scanConfig(projectRoot, files) {
|
|
|
29695
30050
|
recommendation: "Add a .gitignore that excludes dependencies, build output, coverage, and local env files."
|
|
29696
30051
|
});
|
|
29697
30052
|
}
|
|
29698
|
-
if (!files.includes(".editorconfig") && !pathExistsSync(
|
|
30053
|
+
if (!files.includes(".editorconfig") && !pathExistsSync(path57.join(projectRoot, ".editorconfig"))) {
|
|
29699
30054
|
issues.push({
|
|
29700
30055
|
id: "config-editorconfig",
|
|
29701
30056
|
severity: "P2",
|
|
@@ -29714,7 +30069,7 @@ function scanAestheticDrift(projectRoot, files, pkg) {
|
|
|
29714
30069
|
for (const file of frontendFiles) {
|
|
29715
30070
|
let content;
|
|
29716
30071
|
try {
|
|
29717
|
-
content = readFileSyncSafe(
|
|
30072
|
+
content = readFileSyncSafe(path57.join(projectRoot, file));
|
|
29718
30073
|
} catch {
|
|
29719
30074
|
continue;
|
|
29720
30075
|
}
|
|
@@ -29765,7 +30120,7 @@ function detectedIconSystems(pkg) {
|
|
|
29765
30120
|
return systems.filter(([, pattern]) => packages.some((name) => pattern.test(name))).map(([name]) => name);
|
|
29766
30121
|
}
|
|
29767
30122
|
async function scanArchitecture(projectRoot) {
|
|
29768
|
-
const localBinary =
|
|
30123
|
+
const localBinary = path57.join(
|
|
29769
30124
|
projectRoot,
|
|
29770
30125
|
"node_modules",
|
|
29771
30126
|
".bin",
|
|
@@ -29813,7 +30168,7 @@ async function hasDependencyCruiserConfig(projectRoot) {
|
|
|
29813
30168
|
"dependency-cruiser.config.mjs"
|
|
29814
30169
|
];
|
|
29815
30170
|
const results = await Promise.all(
|
|
29816
|
-
files.map((file) => pathExists9(
|
|
30171
|
+
files.map((file) => pathExists9(path57.join(projectRoot, file)))
|
|
29817
30172
|
);
|
|
29818
30173
|
return results.some(Boolean);
|
|
29819
30174
|
}
|
|
@@ -29919,9 +30274,9 @@ function inferCommands(pkg) {
|
|
|
29919
30274
|
return ["lint", "test", "build"].filter((name) => scripts[name]).map((name) => `npm run ${name}`);
|
|
29920
30275
|
}
|
|
29921
30276
|
async function buildIssueDatabase(projectRoot, report) {
|
|
29922
|
-
const reportRef =
|
|
30277
|
+
const reportRef = path57.relative(projectRoot, report.reportPath);
|
|
29923
30278
|
const run = {
|
|
29924
|
-
id:
|
|
30279
|
+
id: path57.basename(report.reportPath, ".md"),
|
|
29925
30280
|
generatedAt: report.generatedAt,
|
|
29926
30281
|
area: report.area,
|
|
29927
30282
|
reportPath: reportRef,
|
|
@@ -29963,7 +30318,7 @@ async function buildIssueDatabase(projectRoot, report) {
|
|
|
29963
30318
|
async function readIssueDatabase(issueDbPath) {
|
|
29964
30319
|
let raw;
|
|
29965
30320
|
try {
|
|
29966
|
-
raw = await
|
|
30321
|
+
raw = await readFile40(issueDbPath, "utf-8");
|
|
29967
30322
|
} catch (err) {
|
|
29968
30323
|
if (isNodeError8(err) && err.code === "ENOENT") {
|
|
29969
30324
|
return emptyIssueDatabase();
|
|
@@ -29984,9 +30339,9 @@ async function readIssueDatabase(issueDbPath) {
|
|
|
29984
30339
|
}
|
|
29985
30340
|
async function writeJsonAtomic3(file, value) {
|
|
29986
30341
|
const tmp = `${file}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
29987
|
-
await
|
|
30342
|
+
await writeFile43(tmp, `${JSON.stringify(value, null, 2)}
|
|
29988
30343
|
`, "utf-8");
|
|
29989
|
-
await
|
|
30344
|
+
await rename12(tmp, file);
|
|
29990
30345
|
}
|
|
29991
30346
|
function emptyIssueDatabase() {
|
|
29992
30347
|
return {
|
|
@@ -30027,20 +30382,20 @@ function compareIssueRecords(a, b) {
|
|
|
30027
30382
|
}
|
|
30028
30383
|
async function applySafeRemediation(projectRoot, issue) {
|
|
30029
30384
|
if (issue.id === "config-gitignore" && issue.file === ".gitignore") {
|
|
30030
|
-
const gitignorePath =
|
|
30385
|
+
const gitignorePath = path57.join(projectRoot, ".gitignore");
|
|
30031
30386
|
if (pathExistsSync(gitignorePath)) {
|
|
30032
30387
|
return { applied: false };
|
|
30033
30388
|
}
|
|
30034
|
-
await
|
|
30389
|
+
await writeFile43(gitignorePath, `${DEFAULT_GITIGNORE}
|
|
30035
30390
|
`, "utf-8");
|
|
30036
30391
|
return { applied: true, action: "created .gitignore" };
|
|
30037
30392
|
}
|
|
30038
30393
|
if (issue.id === "config-editorconfig" && issue.file === ".editorconfig") {
|
|
30039
|
-
const editorconfigPath =
|
|
30394
|
+
const editorconfigPath = path57.join(projectRoot, ".editorconfig");
|
|
30040
30395
|
if (pathExistsSync(editorconfigPath)) {
|
|
30041
30396
|
return { applied: false };
|
|
30042
30397
|
}
|
|
30043
|
-
await
|
|
30398
|
+
await writeFile43(editorconfigPath, `${DEFAULT_EDITORCONFIG}
|
|
30044
30399
|
`, "utf-8");
|
|
30045
30400
|
return { applied: true, action: "created .editorconfig" };
|
|
30046
30401
|
}
|
|
@@ -30076,10 +30431,10 @@ async function inferSafePackageScript(projectRoot, scriptName) {
|
|
|
30076
30431
|
}
|
|
30077
30432
|
}
|
|
30078
30433
|
async function addPackageScript(projectRoot, scriptName, script) {
|
|
30079
|
-
const packagePath =
|
|
30434
|
+
const packagePath = path57.join(projectRoot, "package.json");
|
|
30080
30435
|
let pkg;
|
|
30081
30436
|
try {
|
|
30082
|
-
pkg = JSON.parse(await
|
|
30437
|
+
pkg = JSON.parse(await readFile40(packagePath, "utf-8"));
|
|
30083
30438
|
} catch {
|
|
30084
30439
|
return false;
|
|
30085
30440
|
}
|
|
@@ -30089,7 +30444,7 @@ async function addPackageScript(projectRoot, scriptName, script) {
|
|
|
30089
30444
|
...scripts,
|
|
30090
30445
|
[scriptName]: script
|
|
30091
30446
|
};
|
|
30092
|
-
await
|
|
30447
|
+
await writeFile43(packagePath, `${JSON.stringify(pkg, null, 2)}
|
|
30093
30448
|
`, "utf-8");
|
|
30094
30449
|
return true;
|
|
30095
30450
|
}
|
|
@@ -30189,7 +30544,7 @@ var EXIT_NOT_INITIALIZED3 = 1;
|
|
|
30189
30544
|
var EXIT_SCAN_FAILED = 2;
|
|
30190
30545
|
var EXIT_INVALID_ARG = 3;
|
|
30191
30546
|
async function manps(rootDir, area = "all", options = {}) {
|
|
30192
|
-
const v3SchemaPath =
|
|
30547
|
+
const v3SchemaPath = path58.join(rootDir, ".mancode", "schema.json");
|
|
30193
30548
|
const v3Activation = await readV3ActivationState(v3SchemaPath);
|
|
30194
30549
|
if (v3Activation !== null && v3Activation !== "v3_active" && v3Activation !== "dual_read") {
|
|
30195
30550
|
const message = `manps is unavailable while mancode activation is ${v3Activation}`;
|
|
@@ -30202,7 +30557,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30202
30557
|
return EXIT_SCAN_FAILED;
|
|
30203
30558
|
}
|
|
30204
30559
|
const v3Initialized = v3Activation === "v3_active";
|
|
30205
|
-
const initialized = v3Initialized || await pathExists10(
|
|
30560
|
+
const initialized = v3Initialized || await pathExists10(path58.join(rootDir, ".mancode", "state.json"));
|
|
30206
30561
|
if (!initialized) {
|
|
30207
30562
|
if (options.json) {
|
|
30208
30563
|
console.log(JSON.stringify({ error: "not initialized" }, null, 2));
|
|
@@ -30215,7 +30570,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30215
30570
|
let report;
|
|
30216
30571
|
try {
|
|
30217
30572
|
report = await runPreseasonScan(rootDir, area, {
|
|
30218
|
-
storageRoot: v3Initialized ?
|
|
30573
|
+
storageRoot: v3Initialized ? path58.join(rootDir, ".mancode", "local") : void 0
|
|
30219
30574
|
});
|
|
30220
30575
|
} catch (err) {
|
|
30221
30576
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -30284,8 +30639,8 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30284
30639
|
console.log(
|
|
30285
30640
|
`Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`
|
|
30286
30641
|
);
|
|
30287
|
-
console.log(`Report: ${
|
|
30288
|
-
console.log(`Issue DB: ${
|
|
30642
|
+
console.log(`Report: ${path58.relative(rootDir, report.reportPath)}`);
|
|
30643
|
+
console.log(`Issue DB: ${path58.relative(rootDir, report.issueDbPath)}`);
|
|
30289
30644
|
if (report.issues.length > 0) {
|
|
30290
30645
|
console.log("");
|
|
30291
30646
|
for (const issue of report.issues.slice(0, 7)) {
|
|
@@ -30301,7 +30656,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30301
30656
|
console.log(` Skipped: ${remediation.skipped}`);
|
|
30302
30657
|
console.log(` Fixed: ${remediation.fixed}`);
|
|
30303
30658
|
console.log(
|
|
30304
|
-
` Issue DB: ${
|
|
30659
|
+
` Issue DB: ${path58.relative(rootDir, remediation.issueDbPath)}`
|
|
30305
30660
|
);
|
|
30306
30661
|
}
|
|
30307
30662
|
return EXIT_OK5;
|
|
@@ -30362,7 +30717,7 @@ async function readV3ActivationState(schemaPath) {
|
|
|
30362
30717
|
if (!await pathExists10(schemaPath)) return null;
|
|
30363
30718
|
try {
|
|
30364
30719
|
const manifest = parseSchemaManifest(
|
|
30365
|
-
JSON.parse(await
|
|
30720
|
+
JSON.parse(await readFile41(schemaPath, "utf8"))
|
|
30366
30721
|
);
|
|
30367
30722
|
return manifest.activationState;
|
|
30368
30723
|
} catch {
|
|
@@ -30371,8 +30726,8 @@ async function readV3ActivationState(schemaPath) {
|
|
|
30371
30726
|
}
|
|
30372
30727
|
|
|
30373
30728
|
// src/commands/migrate.ts
|
|
30374
|
-
import { readFile as
|
|
30375
|
-
import
|
|
30729
|
+
import { readFile as readFile42 } from "fs/promises";
|
|
30730
|
+
import path59 from "path";
|
|
30376
30731
|
var EXIT_OK6 = 0;
|
|
30377
30732
|
var EXIT_INVALID_ARG2 = 2;
|
|
30378
30733
|
var EXIT_MIGRATION_BLOCKED = 3;
|
|
@@ -30498,14 +30853,14 @@ async function readScopeFile(rootDir, file) {
|
|
|
30498
30853
|
if (!file.trim() || file.includes("\0")) {
|
|
30499
30854
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30500
30855
|
}
|
|
30501
|
-
const resolved =
|
|
30502
|
-
const relative =
|
|
30503
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
30856
|
+
const resolved = path59.resolve(rootDir, file);
|
|
30857
|
+
const relative = path59.relative(path59.resolve(rootDir), resolved);
|
|
30858
|
+
if (relative === ".." || relative.startsWith(`..${path59.sep}`) || path59.isAbsolute(relative)) {
|
|
30504
30859
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30505
30860
|
}
|
|
30506
30861
|
try {
|
|
30507
30862
|
return JSON.parse(
|
|
30508
|
-
await
|
|
30863
|
+
await readFile42(resolved, "utf8")
|
|
30509
30864
|
);
|
|
30510
30865
|
} catch (error) {
|
|
30511
30866
|
if (error instanceof SyntaxError) {
|
|
@@ -30605,12 +30960,12 @@ async function runOperationMutation(rootDir, operationId, options, mode) {
|
|
|
30605
30960
|
}
|
|
30606
30961
|
|
|
30607
30962
|
// src/context/project-policy-upgrade.ts
|
|
30608
|
-
import { lstat as lstat22, mkdir as
|
|
30609
|
-
import
|
|
30963
|
+
import { lstat as lstat22, mkdir as mkdir37, readFile as readFile43, rm as rm20, writeFile as writeFile44 } from "fs/promises";
|
|
30964
|
+
import path60 from "path";
|
|
30610
30965
|
var UPGRADE_OPERATION = "project_policy_upgrade";
|
|
30611
30966
|
async function dryRunProjectPolicyUpgrade(input) {
|
|
30612
30967
|
assertPolicyVersion(input.policyVersion);
|
|
30613
|
-
const root =
|
|
30968
|
+
const root = path60.resolve(input.projectRoot);
|
|
30614
30969
|
const project = await new V3ContextStore(root).readProjectSnapshot();
|
|
30615
30970
|
const beforeDigest = digestManifest(project.manifest);
|
|
30616
30971
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -30654,7 +31009,7 @@ async function dryRunProjectPolicyUpgrade(input) {
|
|
|
30654
31009
|
async function upgradeProjectPolicy(input) {
|
|
30655
31010
|
assertPolicyVersion(input.policyVersion);
|
|
30656
31011
|
assertUlid(input.sessionId, "project policy upgrade sessionId");
|
|
30657
|
-
const root =
|
|
31012
|
+
const root = path60.resolve(input.projectRoot);
|
|
30658
31013
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
30659
31014
|
const operationId = input.operationId;
|
|
30660
31015
|
if (operationId === void 0) {
|
|
@@ -30908,24 +31263,24 @@ function buildV2Manifest(manifest, operationId) {
|
|
|
30908
31263
|
return candidate;
|
|
30909
31264
|
}
|
|
30910
31265
|
async function readSchemaContent(root) {
|
|
30911
|
-
return
|
|
31266
|
+
return readFile43(path60.join(root, ".mancode", "schema.json"), "utf8");
|
|
30912
31267
|
}
|
|
30913
31268
|
async function writeSchemaContent(root, operationId, content) {
|
|
30914
|
-
const directory =
|
|
30915
|
-
const target =
|
|
31269
|
+
const directory = path60.join(root, ".mancode");
|
|
31270
|
+
const target = path60.join(directory, "schema.json");
|
|
30916
31271
|
const stat5 = await lstat22(target);
|
|
30917
31272
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
30918
31273
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
30919
31274
|
}
|
|
30920
|
-
const temporary =
|
|
31275
|
+
const temporary = path60.join(
|
|
30921
31276
|
directory,
|
|
30922
31277
|
`.schema.json.${operationId}.${process.pid}.tmp`
|
|
30923
31278
|
);
|
|
30924
|
-
await
|
|
31279
|
+
await writeFile44(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
30925
31280
|
try {
|
|
30926
31281
|
await replaceFileAtomically(temporary, target);
|
|
30927
31282
|
} catch (error) {
|
|
30928
|
-
await
|
|
31283
|
+
await rm20(temporary, { force: true });
|
|
30929
31284
|
throw error;
|
|
30930
31285
|
}
|
|
30931
31286
|
}
|
|
@@ -30993,15 +31348,15 @@ async function releaseLocks3(locks) {
|
|
|
30993
31348
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
30994
31349
|
}
|
|
30995
31350
|
function projectUpgradePreviewRoot(root, operationId) {
|
|
30996
|
-
return
|
|
31351
|
+
return path60.join(root, ".mancode", "staging", "project-upgrade", operationId);
|
|
30997
31352
|
}
|
|
30998
31353
|
async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
30999
31354
|
const directory = projectUpgradePreviewRoot(root, receipt.operationId);
|
|
31000
|
-
const receiptPath =
|
|
31001
|
-
const manifestPath =
|
|
31002
|
-
await
|
|
31355
|
+
const receiptPath = path60.join(directory, "preview.json");
|
|
31356
|
+
const manifestPath = path60.join(directory, "schema.json");
|
|
31357
|
+
await mkdir37(path60.dirname(directory), { recursive: true });
|
|
31003
31358
|
try {
|
|
31004
|
-
await
|
|
31359
|
+
await mkdir37(directory);
|
|
31005
31360
|
} catch (error) {
|
|
31006
31361
|
if (isAlreadyExists23(error)) {
|
|
31007
31362
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_EXISTS");
|
|
@@ -31009,25 +31364,25 @@ async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
|
31009
31364
|
throw error;
|
|
31010
31365
|
}
|
|
31011
31366
|
try {
|
|
31012
|
-
await
|
|
31367
|
+
await writeFile44(receiptPath, `${JSON.stringify(receipt, null, 2)}
|
|
31013
31368
|
`, {
|
|
31014
31369
|
encoding: "utf8",
|
|
31015
31370
|
flag: "wx"
|
|
31016
31371
|
});
|
|
31017
|
-
await
|
|
31372
|
+
await writeFile44(manifestPath, manifestContent, {
|
|
31018
31373
|
encoding: "utf8",
|
|
31019
31374
|
flag: "wx"
|
|
31020
31375
|
});
|
|
31021
31376
|
} catch (error) {
|
|
31022
|
-
await
|
|
31377
|
+
await rm20(directory, { recursive: true, force: true });
|
|
31023
31378
|
throw error;
|
|
31024
31379
|
}
|
|
31025
31380
|
}
|
|
31026
31381
|
async function assertProjectPolicyUpgradePreview(root, operationId, project) {
|
|
31027
31382
|
const directory = projectUpgradePreviewRoot(root, operationId);
|
|
31028
31383
|
const [receiptContent, manifestContent] = await Promise.all([
|
|
31029
|
-
readSafePreviewFile(
|
|
31030
|
-
readSafePreviewFile(
|
|
31384
|
+
readSafePreviewFile(path60.join(directory, "preview.json")),
|
|
31385
|
+
readSafePreviewFile(path60.join(directory, "schema.json"))
|
|
31031
31386
|
]);
|
|
31032
31387
|
let receipt;
|
|
31033
31388
|
try {
|
|
@@ -31054,9 +31409,9 @@ async function readSafePreviewFile(target) {
|
|
|
31054
31409
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
31055
31410
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_INVALID");
|
|
31056
31411
|
}
|
|
31057
|
-
return
|
|
31412
|
+
return readFile43(target, "utf8");
|
|
31058
31413
|
} catch (error) {
|
|
31059
|
-
if (
|
|
31414
|
+
if (isNotFound30(error)) {
|
|
31060
31415
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_REQUIRED");
|
|
31061
31416
|
}
|
|
31062
31417
|
throw error;
|
|
@@ -31089,7 +31444,7 @@ function parseProjectPolicyUpgradePreviewReceipt(value) {
|
|
|
31089
31444
|
createdAt: record.createdAt
|
|
31090
31445
|
};
|
|
31091
31446
|
}
|
|
31092
|
-
function
|
|
31447
|
+
function isNotFound30(error) {
|
|
31093
31448
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
31094
31449
|
}
|
|
31095
31450
|
function isAlreadyExists23(error) {
|
|
@@ -31143,16 +31498,16 @@ async function projectUpgrade(rootDir, options) {
|
|
|
31143
31498
|
// src/commands/refresh-project.ts
|
|
31144
31499
|
import { randomUUID } from "crypto";
|
|
31145
31500
|
import { promises as fs7 } from "fs";
|
|
31146
|
-
import
|
|
31501
|
+
import path61 from "path";
|
|
31147
31502
|
import process9 from "process";
|
|
31148
31503
|
var EXIT_OK7 = 0;
|
|
31149
31504
|
var EXIT_NOT_INITIALIZED4 = 1;
|
|
31150
31505
|
var EXIT_CORRUPT_STATE = 2;
|
|
31151
31506
|
var EXIT_REFRESH_FAILED = 3;
|
|
31152
31507
|
async function refreshProject(rootDir = process9.cwd()) {
|
|
31153
|
-
const mancodeDir =
|
|
31154
|
-
const statePath =
|
|
31155
|
-
if (await pathExists11(
|
|
31508
|
+
const mancodeDir = path61.join(rootDir, ".mancode");
|
|
31509
|
+
const statePath = path61.join(mancodeDir, "state.json");
|
|
31510
|
+
if (await pathExists11(path61.join(mancodeDir, "schema.json"))) {
|
|
31156
31511
|
return refreshV3Project(rootDir);
|
|
31157
31512
|
}
|
|
31158
31513
|
if (!await pathExists11(statePath)) {
|
|
@@ -31171,12 +31526,12 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
31171
31526
|
const [profile, team, hasGit, hasManifest] = await Promise.all([
|
|
31172
31527
|
detectProjectProfile(rootDir),
|
|
31173
31528
|
detectTeamStatus(rootDir),
|
|
31174
|
-
pathExists11(
|
|
31529
|
+
pathExists11(path61.join(rootDir, ".git")),
|
|
31175
31530
|
hasProjectManifest2(rootDir)
|
|
31176
31531
|
]);
|
|
31177
31532
|
const uiLibrary = primaryUiLibrary(profile);
|
|
31178
31533
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
31179
|
-
const config = await readJson2(
|
|
31534
|
+
const config = await readJson2(path61.join(mancodeDir, "config.json"));
|
|
31180
31535
|
const configuredTeam = config.forceTeamMode === true ? true : config.teamMode === "on" ? true : config.teamMode === "off" ? false : team.isTeam;
|
|
31181
31536
|
const nextState = {
|
|
31182
31537
|
...state,
|
|
@@ -31188,7 +31543,7 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
31188
31543
|
};
|
|
31189
31544
|
await writeProjectFacts2(
|
|
31190
31545
|
statePath,
|
|
31191
|
-
|
|
31546
|
+
path61.join(mancodeDir, "project-profile.json"),
|
|
31192
31547
|
`${JSON.stringify(nextState, null, 2)}
|
|
31193
31548
|
`,
|
|
31194
31549
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -31255,7 +31610,7 @@ async function refreshV3Project(rootDir) {
|
|
|
31255
31610
|
}
|
|
31256
31611
|
async function hasProjectManifest2(rootDir) {
|
|
31257
31612
|
for (const manifest of PROJECT_MANIFESTS) {
|
|
31258
|
-
if (await pathExists11(
|
|
31613
|
+
if (await pathExists11(path61.join(rootDir, manifest))) return true;
|
|
31259
31614
|
}
|
|
31260
31615
|
return false;
|
|
31261
31616
|
}
|
|
@@ -31321,9 +31676,9 @@ async function readOptionalText(filePath) {
|
|
|
31321
31676
|
}
|
|
31322
31677
|
}
|
|
31323
31678
|
function temporaryPath(filePath) {
|
|
31324
|
-
return
|
|
31325
|
-
|
|
31326
|
-
`.${
|
|
31679
|
+
return path61.join(
|
|
31680
|
+
path61.dirname(filePath),
|
|
31681
|
+
`.${path61.basename(filePath)}.${process9.pid}.${randomUUID()}.tmp`
|
|
31327
31682
|
);
|
|
31328
31683
|
}
|
|
31329
31684
|
async function refreshStaticPlatforms(rootDir, config, fallbackPlatform, stack, uiLibrary, profile) {
|
|
@@ -31393,7 +31748,7 @@ async function pathExists11(filePath) {
|
|
|
31393
31748
|
|
|
31394
31749
|
// src/commands/refresh-style.ts
|
|
31395
31750
|
import { promises as fs8 } from "fs";
|
|
31396
|
-
import
|
|
31751
|
+
import path62 from "path";
|
|
31397
31752
|
import process10 from "process";
|
|
31398
31753
|
var EXIT_OK8 = 0;
|
|
31399
31754
|
var EXIT_NOT_INITIALIZED5 = 1;
|
|
@@ -31404,8 +31759,8 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31404
31759
|
console.error("\u2717 style scan root must stay inside the project root.");
|
|
31405
31760
|
return EXIT_V3_REFRESH_FAILED;
|
|
31406
31761
|
}
|
|
31407
|
-
const stateFile =
|
|
31408
|
-
if (await pathExists12(
|
|
31762
|
+
const stateFile = path62.join(rootDir, ".mancode", "state.json");
|
|
31763
|
+
if (await pathExists12(path62.join(rootDir, ".mancode", "schema.json"))) {
|
|
31409
31764
|
return refreshV3Style(rootDir, scanTarget.root, scanTarget.scopeRoot);
|
|
31410
31765
|
}
|
|
31411
31766
|
if (!await pathExists12(stateFile)) {
|
|
@@ -31415,7 +31770,7 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31415
31770
|
}
|
|
31416
31771
|
console.log("\u2713 \u5237\u65B0\u9879\u76EE profile...");
|
|
31417
31772
|
const profile = await detectProjectProfile(rootDir);
|
|
31418
|
-
const profilePath =
|
|
31773
|
+
const profilePath = path62.join(rootDir, ".mancode", "project-profile.json");
|
|
31419
31774
|
await fs8.writeFile(
|
|
31420
31775
|
profilePath,
|
|
31421
31776
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -31442,13 +31797,13 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31442
31797
|
uiLibraryHint,
|
|
31443
31798
|
scanTarget.scopeRoot
|
|
31444
31799
|
);
|
|
31445
|
-
const tokensPath =
|
|
31800
|
+
const tokensPath = path62.join(
|
|
31446
31801
|
rootDir,
|
|
31447
31802
|
".mancode",
|
|
31448
31803
|
"aesthetics",
|
|
31449
31804
|
"style-tokens.json"
|
|
31450
31805
|
);
|
|
31451
|
-
await fs8.mkdir(
|
|
31806
|
+
await fs8.mkdir(path62.dirname(tokensPath), { recursive: true });
|
|
31452
31807
|
await fs8.writeFile(
|
|
31453
31808
|
tokensPath,
|
|
31454
31809
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -31521,7 +31876,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31521
31876
|
console.log(
|
|
31522
31877
|
` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
|
|
31523
31878
|
);
|
|
31524
|
-
const tokensPath =
|
|
31879
|
+
const tokensPath = path62.join(
|
|
31525
31880
|
rootDir,
|
|
31526
31881
|
".mancode",
|
|
31527
31882
|
"local",
|
|
@@ -31538,7 +31893,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31538
31893
|
}
|
|
31539
31894
|
console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
|
|
31540
31895
|
const tokens = await scanAesthetics(scanRoot, uiLibraryHint, scopeRoot);
|
|
31541
|
-
await fs8.mkdir(
|
|
31896
|
+
await fs8.mkdir(path62.dirname(tokensPath), { recursive: true });
|
|
31542
31897
|
await fs8.writeFile(
|
|
31543
31898
|
tokensPath,
|
|
31544
31899
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -31572,7 +31927,7 @@ async function printStaticPlatformRefreshHint(rootDir) {
|
|
|
31572
31927
|
);
|
|
31573
31928
|
}
|
|
31574
31929
|
async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
31575
|
-
const statePath =
|
|
31930
|
+
const statePath = path62.join(rootDir, ".mancode", "state.json");
|
|
31576
31931
|
try {
|
|
31577
31932
|
const state = JSON.parse(await fs8.readFile(statePath, "utf-8"));
|
|
31578
31933
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
@@ -31596,7 +31951,7 @@ async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
|
31596
31951
|
async function readInstalledPlatforms2(rootDir) {
|
|
31597
31952
|
try {
|
|
31598
31953
|
const raw = await fs8.readFile(
|
|
31599
|
-
|
|
31954
|
+
path62.join(rootDir, ".mancode", "config.json"),
|
|
31600
31955
|
"utf-8"
|
|
31601
31956
|
);
|
|
31602
31957
|
const config = JSON.parse(raw);
|
|
@@ -31616,30 +31971,30 @@ async function pathExists12(p) {
|
|
|
31616
31971
|
}
|
|
31617
31972
|
}
|
|
31618
31973
|
async function resolveScanTarget(rootDir, requestedRoot) {
|
|
31619
|
-
const projectRoot = await fs8.realpath(
|
|
31974
|
+
const projectRoot = await fs8.realpath(path62.resolve(rootDir)).catch(() => null);
|
|
31620
31975
|
if (projectRoot === null) return null;
|
|
31621
31976
|
if (requestedRoot === void 0 || requestedRoot === ".") {
|
|
31622
31977
|
return { root: projectRoot, scopeRoot: "." };
|
|
31623
31978
|
}
|
|
31624
|
-
if (
|
|
31979
|
+
if (path62.isAbsolute(requestedRoot) || requestedRoot.includes("\0") || requestedRoot.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
31625
31980
|
return null;
|
|
31626
31981
|
}
|
|
31627
|
-
const candidate = await fs8.realpath(
|
|
31982
|
+
const candidate = await fs8.realpath(path62.resolve(projectRoot, requestedRoot)).catch(() => null);
|
|
31628
31983
|
if (candidate === null) return null;
|
|
31629
|
-
const relative =
|
|
31630
|
-
if (relative.startsWith(`..${
|
|
31984
|
+
const relative = path62.relative(projectRoot, candidate);
|
|
31985
|
+
if (relative.startsWith(`..${path62.sep}`) || relative === ".." || path62.isAbsolute(relative)) {
|
|
31631
31986
|
return null;
|
|
31632
31987
|
}
|
|
31633
31988
|
return {
|
|
31634
31989
|
root: candidate,
|
|
31635
|
-
scopeRoot: relative.split(
|
|
31990
|
+
scopeRoot: relative.split(path62.sep).join("/") || "."
|
|
31636
31991
|
};
|
|
31637
31992
|
}
|
|
31638
31993
|
|
|
31639
31994
|
// src/commands/status.ts
|
|
31640
31995
|
import { spawn } from "child_process";
|
|
31641
31996
|
import { promises as fs9 } from "fs";
|
|
31642
|
-
import
|
|
31997
|
+
import path63 from "path";
|
|
31643
31998
|
import process11 from "process";
|
|
31644
31999
|
|
|
31645
32000
|
// src/team/assessment.ts
|
|
@@ -31795,8 +32150,8 @@ var EXIT_OK9 = 0;
|
|
|
31795
32150
|
var EXIT_NOT_INITIALIZED6 = 1;
|
|
31796
32151
|
var EXIT_CORRUPT_STATE2 = 2;
|
|
31797
32152
|
async function status(rootDir = process11.cwd(), options = {}) {
|
|
31798
|
-
const stateFile =
|
|
31799
|
-
const v3SchemaFile =
|
|
32153
|
+
const stateFile = path63.join(rootDir, ".mancode", "state.json");
|
|
32154
|
+
const v3SchemaFile = path63.join(rootDir, ".mancode", "schema.json");
|
|
31800
32155
|
if (await pathExists13(v3SchemaFile)) {
|
|
31801
32156
|
return statusV3(rootDir, options);
|
|
31802
32157
|
}
|
|
@@ -32041,10 +32396,10 @@ async function readV3StatusSession(rootDir) {
|
|
|
32041
32396
|
}
|
|
32042
32397
|
async function shouldRefreshProject(rootDir, state) {
|
|
32043
32398
|
if (state.projectMode !== "generic") return false;
|
|
32044
|
-
const hasGit = await pathExists13(
|
|
32399
|
+
const hasGit = await pathExists13(path63.join(rootDir, ".git"));
|
|
32045
32400
|
if (hasGit) return true;
|
|
32046
32401
|
for (const manifest of PROJECT_MANIFESTS) {
|
|
32047
|
-
if (await pathExists13(
|
|
32402
|
+
if (await pathExists13(path63.join(rootDir, manifest))) return true;
|
|
32048
32403
|
}
|
|
32049
32404
|
return false;
|
|
32050
32405
|
}
|
|
@@ -32088,19 +32443,19 @@ async function getCurrentWorkflow(rootDir, taskId) {
|
|
|
32088
32443
|
}
|
|
32089
32444
|
async function getProjectName(rootDir) {
|
|
32090
32445
|
try {
|
|
32091
|
-
const raw = await fs9.readFile(
|
|
32446
|
+
const raw = await fs9.readFile(path63.join(rootDir, "package.json"), "utf-8");
|
|
32092
32447
|
const pkg = JSON.parse(raw);
|
|
32093
32448
|
if (pkg.name && typeof pkg.name === "string") {
|
|
32094
32449
|
return pkg.name;
|
|
32095
32450
|
}
|
|
32096
32451
|
} catch {
|
|
32097
32452
|
}
|
|
32098
|
-
return
|
|
32453
|
+
return path63.basename(rootDir);
|
|
32099
32454
|
}
|
|
32100
32455
|
async function readConfig3(rootDir) {
|
|
32101
32456
|
try {
|
|
32102
32457
|
const raw = await fs9.readFile(
|
|
32103
|
-
|
|
32458
|
+
path63.join(rootDir, ".mancode", "config.json"),
|
|
32104
32459
|
"utf-8"
|
|
32105
32460
|
);
|
|
32106
32461
|
return JSON.parse(raw);
|
|
@@ -32128,9 +32483,9 @@ function getEffectiveTeamStatus(state, config, detected) {
|
|
|
32128
32483
|
}
|
|
32129
32484
|
async function checkHooks(rootDir) {
|
|
32130
32485
|
const [sessionStart, userPromptSubmit, registered] = await Promise.all([
|
|
32131
|
-
pathExists13(
|
|
32486
|
+
pathExists13(path63.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
|
|
32132
32487
|
pathExists13(
|
|
32133
|
-
|
|
32488
|
+
path63.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
32134
32489
|
),
|
|
32135
32490
|
isRegistered(rootDir)
|
|
32136
32491
|
]);
|
|
@@ -32139,7 +32494,7 @@ async function checkHooks(rootDir) {
|
|
|
32139
32494
|
async function isRegistered(rootDir) {
|
|
32140
32495
|
try {
|
|
32141
32496
|
const raw = await fs9.readFile(
|
|
32142
|
-
|
|
32497
|
+
path63.join(rootDir, ".claude", "settings.json"),
|
|
32143
32498
|
"utf-8"
|
|
32144
32499
|
);
|
|
32145
32500
|
const settings = JSON.parse(raw);
|
|
@@ -32168,7 +32523,7 @@ function hasHookCommand2(value, needle) {
|
|
|
32168
32523
|
});
|
|
32169
32524
|
}
|
|
32170
32525
|
async function estimateHookInjection(rootDir) {
|
|
32171
|
-
const hookPath =
|
|
32526
|
+
const hookPath = path63.join(
|
|
32172
32527
|
rootDir,
|
|
32173
32528
|
".mancode",
|
|
32174
32529
|
"hooks",
|
|
@@ -33665,8 +34020,8 @@ function assertPositiveRevision2(value, label) {
|
|
|
33665
34020
|
}
|
|
33666
34021
|
|
|
33667
34022
|
// src/team/git-ref-handoff-repair.ts
|
|
33668
|
-
import { lstat as lstat23, mkdir as
|
|
33669
|
-
import
|
|
34023
|
+
import { lstat as lstat23, mkdir as mkdir38, readFile as readFile44, readdir as readdir19, writeFile as writeFile45 } from "fs/promises";
|
|
34024
|
+
import path64 from "path";
|
|
33670
34025
|
|
|
33671
34026
|
// src/team/git-ref-operation.ts
|
|
33672
34027
|
import { execFile as execFileCallback6 } from "child_process";
|
|
@@ -36244,7 +36599,7 @@ async function recoverGitRefHandoffRepairs(projectRoot) {
|
|
|
36244
36599
|
}
|
|
36245
36600
|
async function recoverGitRefHandoffRepair(projectRoot, operationId, transportReceipt) {
|
|
36246
36601
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
36247
|
-
const root =
|
|
36602
|
+
const root = path64.resolve(projectRoot);
|
|
36248
36603
|
let journal = await requireJournal2(root, operationId);
|
|
36249
36604
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
36250
36605
|
return recoveryResult2(journal);
|
|
@@ -36323,7 +36678,7 @@ async function recoverGitRefHandoffRepair(projectRoot, operationId, transportRec
|
|
|
36323
36678
|
}
|
|
36324
36679
|
}
|
|
36325
36680
|
async function prepareHandoffRepairWhileTaskLocked(projectRoot, rawPrepared) {
|
|
36326
|
-
const root =
|
|
36681
|
+
const root = path64.resolve(projectRoot);
|
|
36327
36682
|
const prepared2 = parsePrepared2(rawPrepared);
|
|
36328
36683
|
const runtime = await readProjectRuntimeContext(root);
|
|
36329
36684
|
const previousMetadata = bundleMetadata2(prepared2.predecessorBundle);
|
|
@@ -36386,7 +36741,7 @@ async function restorePredecessorMetadata2(projectRoot, journal) {
|
|
|
36386
36741
|
);
|
|
36387
36742
|
}
|
|
36388
36743
|
async function replaceMetadataVerified(projectRoot, expected, targetMetadata, alternateExpected) {
|
|
36389
|
-
const target =
|
|
36744
|
+
const target = path64.join(
|
|
36390
36745
|
taskRootPath(projectRoot, targetMetadata.taskRef),
|
|
36391
36746
|
"metadata.json"
|
|
36392
36747
|
);
|
|
@@ -36504,15 +36859,15 @@ function parseJournal3(value) {
|
|
|
36504
36859
|
pendingMetadata,
|
|
36505
36860
|
remoteReceipt,
|
|
36506
36861
|
transportReceipt: value.transportReceipt,
|
|
36507
|
-
createdAt:
|
|
36508
|
-
updatedAt:
|
|
36862
|
+
createdAt: parseTimestamp16(value.createdAt),
|
|
36863
|
+
updatedAt: parseTimestamp16(value.updatedAt)
|
|
36509
36864
|
};
|
|
36510
36865
|
}
|
|
36511
36866
|
async function createJournal3(projectRoot, journal) {
|
|
36512
36867
|
await ensureJournalDirectory2(projectRoot);
|
|
36513
36868
|
const target = journalPath3(projectRoot, journal.operationId);
|
|
36514
36869
|
try {
|
|
36515
|
-
await
|
|
36870
|
+
await writeFile45(target, serialize13(journal), {
|
|
36516
36871
|
encoding: "utf8",
|
|
36517
36872
|
flag: "wx"
|
|
36518
36873
|
});
|
|
@@ -36531,10 +36886,10 @@ async function replaceJournal3(projectRoot, journal) {
|
|
|
36531
36886
|
async function requireJournal2(projectRoot, operationId) {
|
|
36532
36887
|
try {
|
|
36533
36888
|
return parseJournal3(
|
|
36534
|
-
JSON.parse(await
|
|
36889
|
+
JSON.parse(await readFile44(journalPath3(projectRoot, operationId), "utf8"))
|
|
36535
36890
|
);
|
|
36536
36891
|
} catch (error) {
|
|
36537
|
-
if (error instanceof SyntaxError ||
|
|
36892
|
+
if (error instanceof SyntaxError || isNotFound31(error)) {
|
|
36538
36893
|
throw new Error("MANCODE_HANDOFF_REPAIR_JOURNAL_NOT_FOUND");
|
|
36539
36894
|
}
|
|
36540
36895
|
throw error;
|
|
@@ -36545,7 +36900,7 @@ async function listJournals2(projectRoot) {
|
|
|
36545
36900
|
try {
|
|
36546
36901
|
entries = await readdir19(journalDirectory2(projectRoot));
|
|
36547
36902
|
} catch (error) {
|
|
36548
|
-
if (
|
|
36903
|
+
if (isNotFound31(error)) return [];
|
|
36549
36904
|
throw error;
|
|
36550
36905
|
}
|
|
36551
36906
|
const journals = [];
|
|
@@ -36554,8 +36909,8 @@ async function listJournals2(projectRoot) {
|
|
|
36554
36909
|
journals.push(
|
|
36555
36910
|
parseJournal3(
|
|
36556
36911
|
JSON.parse(
|
|
36557
|
-
await
|
|
36558
|
-
|
|
36912
|
+
await readFile44(
|
|
36913
|
+
path64.join(journalDirectory2(projectRoot), entry),
|
|
36559
36914
|
"utf8"
|
|
36560
36915
|
)
|
|
36561
36916
|
)
|
|
@@ -36569,7 +36924,7 @@ async function readSafeFile2(target) {
|
|
|
36569
36924
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
36570
36925
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
36571
36926
|
}
|
|
36572
|
-
const content = await
|
|
36927
|
+
const content = await readFile44(target, "utf8");
|
|
36573
36928
|
const after = await lstat23(target);
|
|
36574
36929
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
36575
36930
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -36577,19 +36932,19 @@ async function readSafeFile2(target) {
|
|
|
36577
36932
|
return content;
|
|
36578
36933
|
}
|
|
36579
36934
|
async function atomicWrite2(target, content) {
|
|
36580
|
-
const temporary =
|
|
36581
|
-
|
|
36582
|
-
`.${
|
|
36935
|
+
const temporary = path64.join(
|
|
36936
|
+
path64.dirname(target),
|
|
36937
|
+
`.${path64.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
36583
36938
|
);
|
|
36584
|
-
await
|
|
36939
|
+
await writeFile45(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
36585
36940
|
await replaceFileAtomically(temporary, target);
|
|
36586
36941
|
}
|
|
36587
36942
|
async function ensureJournalDirectory2(projectRoot) {
|
|
36588
|
-
let current =
|
|
36943
|
+
let current = path64.resolve(projectRoot);
|
|
36589
36944
|
for (const segment of [".mancode", "local", "journals", "git-ref-handoff"]) {
|
|
36590
|
-
current =
|
|
36945
|
+
current = path64.join(current, segment);
|
|
36591
36946
|
try {
|
|
36592
|
-
await
|
|
36947
|
+
await mkdir38(current);
|
|
36593
36948
|
} catch (error) {
|
|
36594
36949
|
if (!isAlreadyExists24(error)) throw error;
|
|
36595
36950
|
}
|
|
@@ -36600,8 +36955,8 @@ async function ensureJournalDirectory2(projectRoot) {
|
|
|
36600
36955
|
}
|
|
36601
36956
|
}
|
|
36602
36957
|
function journalDirectory2(projectRoot) {
|
|
36603
|
-
return
|
|
36604
|
-
|
|
36958
|
+
return path64.join(
|
|
36959
|
+
path64.resolve(projectRoot),
|
|
36605
36960
|
".mancode",
|
|
36606
36961
|
"local",
|
|
36607
36962
|
"journals",
|
|
@@ -36610,13 +36965,13 @@ function journalDirectory2(projectRoot) {
|
|
|
36610
36965
|
}
|
|
36611
36966
|
function journalPath3(projectRoot, operationId) {
|
|
36612
36967
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
36613
|
-
return
|
|
36968
|
+
return path64.join(journalDirectory2(projectRoot), `${operationId}.json`);
|
|
36614
36969
|
}
|
|
36615
36970
|
function serialize13(value) {
|
|
36616
36971
|
return `${JSON.stringify(value, null, 2)}
|
|
36617
36972
|
`;
|
|
36618
36973
|
}
|
|
36619
|
-
function
|
|
36974
|
+
function parseTimestamp16(value) {
|
|
36620
36975
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
36621
36976
|
throw new Error("MANCODE_HANDOFF_REPAIR_JOURNAL_CORRUPT");
|
|
36622
36977
|
}
|
|
@@ -36625,7 +36980,7 @@ function parseTimestamp15(value) {
|
|
|
36625
36980
|
function isAlreadyExists24(error) {
|
|
36626
36981
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
36627
36982
|
}
|
|
36628
|
-
function
|
|
36983
|
+
function isNotFound31(error) {
|
|
36629
36984
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
36630
36985
|
}
|
|
36631
36986
|
|
|
@@ -36709,8 +37064,8 @@ function parseReceipt(value) {
|
|
|
36709
37064
|
}
|
|
36710
37065
|
|
|
36711
37066
|
// src/team/policy-operation.ts
|
|
36712
|
-
import { lstat as lstat24, mkdir as
|
|
36713
|
-
import
|
|
37067
|
+
import { lstat as lstat24, mkdir as mkdir39, readdir as readdir20, unlink as unlink3, writeFile as writeFile46 } from "fs/promises";
|
|
37068
|
+
import path65 from "path";
|
|
36714
37069
|
async function updateTeamPolicy(input) {
|
|
36715
37070
|
const operationId = input.operationId ?? createUlid();
|
|
36716
37071
|
const eventId = createUlid();
|
|
@@ -36721,7 +37076,7 @@ async function updateTeamPolicy(input) {
|
|
|
36721
37076
|
throw new Error("MANCODE_TEAM_POLICY_INVALID");
|
|
36722
37077
|
}
|
|
36723
37078
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
36724
|
-
const root =
|
|
37079
|
+
const root = path65.resolve(input.projectRoot);
|
|
36725
37080
|
const runtime = await readProjectRuntimeContext(root);
|
|
36726
37081
|
const store = resolveCoordinationEntityHomeStore(
|
|
36727
37082
|
runtime.entityHomeStoreContext
|
|
@@ -36802,7 +37157,7 @@ async function applyTeamTransportSet(input, write2) {
|
|
|
36802
37157
|
}
|
|
36803
37158
|
const remote = transportRemote(input.mode, input.remote);
|
|
36804
37159
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
36805
|
-
const root =
|
|
37160
|
+
const root = path65.resolve(input.projectRoot);
|
|
36806
37161
|
const runtime = await readProjectRuntimeContext(root);
|
|
36807
37162
|
const store = resolveCoordinationEntityHomeStore(
|
|
36808
37163
|
runtime.entityHomeStoreContext
|
|
@@ -36935,9 +37290,9 @@ async function assertTransportAuthorityEmpty(projectRoot, store) {
|
|
|
36935
37290
|
listClaims(store),
|
|
36936
37291
|
listHandoffs(store),
|
|
36937
37292
|
directoryHasEntries(taskHeadDirectory(store)),
|
|
36938
|
-
directoryHasEntries(
|
|
37293
|
+
directoryHasEntries(path65.join(store.root, "transport-migrations")),
|
|
36939
37294
|
directoryHasEntries(
|
|
36940
|
-
|
|
37295
|
+
path65.join(projectRoot, ".mancode", "shared", "team", "transport")
|
|
36941
37296
|
),
|
|
36942
37297
|
pathExists14(gitRefCachePath(projectRoot))
|
|
36943
37298
|
]);
|
|
@@ -36967,21 +37322,21 @@ function assertPositiveRevision5(value, label) {
|
|
|
36967
37322
|
}
|
|
36968
37323
|
}
|
|
36969
37324
|
function teamPolicyPath(projectRoot) {
|
|
36970
|
-
return
|
|
37325
|
+
return path65.join(projectRoot, ".mancode", "shared", "team", "policy.json");
|
|
36971
37326
|
}
|
|
36972
37327
|
function projectConfigPath(projectRoot) {
|
|
36973
|
-
return
|
|
37328
|
+
return path65.join(projectRoot, ".mancode", "shared", "config.json");
|
|
36974
37329
|
}
|
|
36975
37330
|
async function writeJsonAtomic4(target, value) {
|
|
36976
|
-
await
|
|
36977
|
-
await assertPlainDirectory(
|
|
37331
|
+
await mkdir39(path65.dirname(target), { recursive: true });
|
|
37332
|
+
await assertPlainDirectory(path65.dirname(target));
|
|
36978
37333
|
await assertPlainFileOrMissing(target);
|
|
36979
|
-
const temporary =
|
|
36980
|
-
|
|
36981
|
-
`.${
|
|
37334
|
+
const temporary = path65.join(
|
|
37335
|
+
path65.dirname(target),
|
|
37336
|
+
`.${path65.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
36982
37337
|
);
|
|
36983
37338
|
try {
|
|
36984
|
-
await
|
|
37339
|
+
await writeFile46(temporary, `${JSON.stringify(value, null, 2)}
|
|
36985
37340
|
`, {
|
|
36986
37341
|
encoding: "utf8",
|
|
36987
37342
|
flag: "wx"
|
|
@@ -37005,7 +37360,7 @@ async function assertPlainFileOrMissing(target) {
|
|
|
37005
37360
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37006
37361
|
}
|
|
37007
37362
|
} catch (error) {
|
|
37008
|
-
if (
|
|
37363
|
+
if (isNotFound32(error)) return;
|
|
37009
37364
|
throw error;
|
|
37010
37365
|
}
|
|
37011
37366
|
}
|
|
@@ -37017,7 +37372,7 @@ async function directoryHasEntries(target) {
|
|
|
37017
37372
|
}
|
|
37018
37373
|
return (await readdir20(target)).length > 0;
|
|
37019
37374
|
} catch (error) {
|
|
37020
|
-
if (
|
|
37375
|
+
if (isNotFound32(error)) return false;
|
|
37021
37376
|
throw error;
|
|
37022
37377
|
}
|
|
37023
37378
|
}
|
|
@@ -37026,28 +37381,28 @@ async function pathExists14(target) {
|
|
|
37026
37381
|
await lstat24(target);
|
|
37027
37382
|
return true;
|
|
37028
37383
|
} catch (error) {
|
|
37029
|
-
if (
|
|
37384
|
+
if (isNotFound32(error)) return false;
|
|
37030
37385
|
throw error;
|
|
37031
37386
|
}
|
|
37032
37387
|
}
|
|
37033
37388
|
async function releaseLocks4(locks) {
|
|
37034
37389
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
37035
37390
|
}
|
|
37036
|
-
function
|
|
37391
|
+
function isNotFound32(error) {
|
|
37037
37392
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
37038
37393
|
}
|
|
37039
37394
|
|
|
37040
37395
|
// src/team/transport-migration-adapters.ts
|
|
37041
37396
|
import {
|
|
37042
37397
|
lstat as lstat25,
|
|
37043
|
-
mkdir as
|
|
37044
|
-
readFile as
|
|
37398
|
+
mkdir as mkdir40,
|
|
37399
|
+
readFile as readFile45,
|
|
37045
37400
|
readdir as readdir21,
|
|
37046
|
-
rename as
|
|
37401
|
+
rename as rename13,
|
|
37047
37402
|
unlink as unlink4,
|
|
37048
|
-
writeFile as
|
|
37403
|
+
writeFile as writeFile47
|
|
37049
37404
|
} from "fs/promises";
|
|
37050
|
-
import
|
|
37405
|
+
import path66 from "path";
|
|
37051
37406
|
|
|
37052
37407
|
// src/team/transport-migration.ts
|
|
37053
37408
|
var DIGEST_PATTERN7 = /^sha256:[a-f0-9]{64}$/;
|
|
@@ -37871,7 +38226,7 @@ function parseTransportMigrationManifest(value) {
|
|
|
37871
38226
|
(left, right) => compareUtf813(left.handoffId, right.handoffId)
|
|
37872
38227
|
),
|
|
37873
38228
|
claimPolicy: "reissue-active",
|
|
37874
|
-
createdAt:
|
|
38229
|
+
createdAt: parseTimestamp17(value.createdAt, "createdAt")
|
|
37875
38230
|
};
|
|
37876
38231
|
if (manifest.workspaceId !== config.workspaceId || !manifest.actorProfiles.some(
|
|
37877
38232
|
(profile) => profile.actorId === manifest.actorId
|
|
@@ -37920,7 +38275,7 @@ function parseStagedTransportAuthority(value) {
|
|
|
37920
38275
|
"transportEpoch"
|
|
37921
38276
|
),
|
|
37922
38277
|
coordinationDomainId: parseCoordinationDomainId(value.coordinationDomainId),
|
|
37923
|
-
stagedAt:
|
|
38278
|
+
stagedAt: parseTimestamp17(value.stagedAt, "stagedAt")
|
|
37924
38279
|
};
|
|
37925
38280
|
}
|
|
37926
38281
|
function parseEstablishedTransportAuthority(value) {
|
|
@@ -37963,7 +38318,7 @@ function parseEstablishedTransportAuthority(value) {
|
|
|
37963
38318
|
parseClaim
|
|
37964
38319
|
).sort((left, right) => compareUtf813(left.claimId, right.claimId)),
|
|
37965
38320
|
receipt: parseNonEmptyString(value.receipt, "receipt"),
|
|
37966
|
-
establishedAt:
|
|
38321
|
+
establishedAt: parseTimestamp17(value.establishedAt, "establishedAt")
|
|
37967
38322
|
};
|
|
37968
38323
|
assertUniqueCoordinationEntities(established.activeClaims, []);
|
|
37969
38324
|
return established;
|
|
@@ -38099,7 +38454,7 @@ function parseDigest7(value, label) {
|
|
|
38099
38454
|
}
|
|
38100
38455
|
return value;
|
|
38101
38456
|
}
|
|
38102
|
-
function
|
|
38457
|
+
function parseTimestamp17(value, label) {
|
|
38103
38458
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
38104
38459
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
38105
38460
|
}
|
|
@@ -38119,7 +38474,7 @@ function compareUtf813(left, right) {
|
|
|
38119
38474
|
var STAGE_DIRECTORY = "transport-migrations";
|
|
38120
38475
|
var COLLECTIONS = ["claims", "handoffs", "task-heads"];
|
|
38121
38476
|
async function createTransportMigrationFileAdapters(input) {
|
|
38122
|
-
const projectRoot =
|
|
38477
|
+
const projectRoot = path66.resolve(input.projectRoot);
|
|
38123
38478
|
assertUlid(input.actorId, "transport migration adapter actorId");
|
|
38124
38479
|
if (input.operationId !== void 0) {
|
|
38125
38480
|
assertUlid(input.operationId, "transport migration adapter operationId");
|
|
@@ -38171,7 +38526,7 @@ async function createTransportMigrationFileAdapters(input) {
|
|
|
38171
38526
|
var FileSystemTransportMigrationConfigAdapter = class {
|
|
38172
38527
|
constructor(projectRoot, coordinationStore) {
|
|
38173
38528
|
this.coordinationStore = coordinationStore;
|
|
38174
|
-
this.projectRoot =
|
|
38529
|
+
this.projectRoot = path66.resolve(projectRoot);
|
|
38175
38530
|
}
|
|
38176
38531
|
projectRoot;
|
|
38177
38532
|
async read() {
|
|
@@ -39024,33 +39379,33 @@ async function publishMigrationActorProfiles(projectRoot, profiles) {
|
|
|
39024
39379
|
}
|
|
39025
39380
|
}
|
|
39026
39381
|
async function archiveLocalCoordinationCollections(store, operationId) {
|
|
39027
|
-
const archiveRoot =
|
|
39382
|
+
const archiveRoot = path66.join(
|
|
39028
39383
|
store.root,
|
|
39029
39384
|
STAGE_DIRECTORY,
|
|
39030
39385
|
"archive",
|
|
39031
39386
|
operationId
|
|
39032
39387
|
);
|
|
39033
|
-
await
|
|
39388
|
+
await mkdir40(archiveRoot, { recursive: true });
|
|
39034
39389
|
const directories = {
|
|
39035
39390
|
claims: claimDirectory(store),
|
|
39036
39391
|
handoffs: handoffDirectory(store),
|
|
39037
39392
|
"task-heads": taskHeadDirectory(store)
|
|
39038
39393
|
};
|
|
39039
39394
|
for (const name of COLLECTIONS) {
|
|
39040
|
-
const archived =
|
|
39041
|
-
const absent =
|
|
39395
|
+
const archived = path66.join(archiveRoot, name);
|
|
39396
|
+
const absent = path66.join(archiveRoot, `${name}.absent`);
|
|
39042
39397
|
if (await pathKind(archived) === "directory" || await pathKind(absent) === "file") {
|
|
39043
39398
|
continue;
|
|
39044
39399
|
}
|
|
39045
39400
|
const sourceKind = await pathKind(directories[name]);
|
|
39046
39401
|
if (sourceKind === null) {
|
|
39047
|
-
await
|
|
39402
|
+
await writeFile47(absent, "\n", { encoding: "utf8", flag: "wx" });
|
|
39048
39403
|
continue;
|
|
39049
39404
|
}
|
|
39050
39405
|
if (sourceKind !== "directory") {
|
|
39051
39406
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_LOCAL_AUTHORITY_UNSAFE");
|
|
39052
39407
|
}
|
|
39053
|
-
await
|
|
39408
|
+
await rename13(directories[name], archived);
|
|
39054
39409
|
}
|
|
39055
39410
|
}
|
|
39056
39411
|
async function listActorProfiles(projectRoot) {
|
|
@@ -39059,7 +39414,7 @@ async function listActorProfiles(projectRoot) {
|
|
|
39059
39414
|
try {
|
|
39060
39415
|
entries = await readdir21(directory);
|
|
39061
39416
|
} catch (error) {
|
|
39062
|
-
if (
|
|
39417
|
+
if (isNotFound33(error)) return [];
|
|
39063
39418
|
throw error;
|
|
39064
39419
|
}
|
|
39065
39420
|
const profiles = [];
|
|
@@ -39076,18 +39431,18 @@ async function listActorProfiles(projectRoot) {
|
|
|
39076
39431
|
return profiles;
|
|
39077
39432
|
}
|
|
39078
39433
|
async function listSharedTaskRefs(projectRoot) {
|
|
39079
|
-
const directory =
|
|
39434
|
+
const directory = path66.join(projectRoot, ".mancode", "shared", "workflows");
|
|
39080
39435
|
let entries;
|
|
39081
39436
|
try {
|
|
39082
39437
|
entries = await readdir21(directory);
|
|
39083
39438
|
} catch (error) {
|
|
39084
|
-
if (
|
|
39439
|
+
if (isNotFound33(error)) return [];
|
|
39085
39440
|
throw error;
|
|
39086
39441
|
}
|
|
39087
39442
|
const refs = [];
|
|
39088
39443
|
for (const taskId of entries.sort(compareUtf814)) {
|
|
39089
39444
|
assertUlid(taskId, "shared workflow directory");
|
|
39090
|
-
const stat5 = await lstat25(
|
|
39445
|
+
const stat5 = await lstat25(path66.join(directory, taskId));
|
|
39091
39446
|
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
39092
39447
|
throw new Error("MANCODE_CONTEXT_PATH_UNSAFE");
|
|
39093
39448
|
}
|
|
@@ -39099,7 +39454,7 @@ async function readTaskSnapshotOrNull(projectRoot, taskRef) {
|
|
|
39099
39454
|
try {
|
|
39100
39455
|
return await new V3ContextStore(projectRoot).readTaskSnapshot(taskRef);
|
|
39101
39456
|
} catch (error) {
|
|
39102
|
-
if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" ||
|
|
39457
|
+
if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" || isNotFound33(error))) {
|
|
39103
39458
|
return null;
|
|
39104
39459
|
}
|
|
39105
39460
|
throw error;
|
|
@@ -39161,7 +39516,7 @@ async function readStagedRecord(store, operationId) {
|
|
|
39161
39516
|
);
|
|
39162
39517
|
}
|
|
39163
39518
|
function stagedPath(store, operationId) {
|
|
39164
|
-
return
|
|
39519
|
+
return path66.join(
|
|
39165
39520
|
store.root,
|
|
39166
39521
|
STAGE_DIRECTORY,
|
|
39167
39522
|
"staged",
|
|
@@ -39169,7 +39524,7 @@ function stagedPath(store, operationId) {
|
|
|
39169
39524
|
);
|
|
39170
39525
|
}
|
|
39171
39526
|
function establishedPath(store, operationId) {
|
|
39172
|
-
return
|
|
39527
|
+
return path66.join(
|
|
39173
39528
|
store.root,
|
|
39174
39529
|
STAGE_DIRECTORY,
|
|
39175
39530
|
"established",
|
|
@@ -39177,12 +39532,12 @@ function establishedPath(store, operationId) {
|
|
|
39177
39532
|
);
|
|
39178
39533
|
}
|
|
39179
39534
|
function projectConfigPath2(projectRoot) {
|
|
39180
|
-
return
|
|
39535
|
+
return path66.join(projectRoot, ".mancode", "shared", "config.json");
|
|
39181
39536
|
}
|
|
39182
39537
|
async function readProjectConfigFile(projectRoot) {
|
|
39183
39538
|
try {
|
|
39184
39539
|
return parseProjectConfig(
|
|
39185
|
-
JSON.parse(await
|
|
39540
|
+
JSON.parse(await readFile45(projectConfigPath2(projectRoot), "utf8"))
|
|
39186
39541
|
);
|
|
39187
39542
|
} catch (error) {
|
|
39188
39543
|
if (error instanceof SyntaxError) {
|
|
@@ -39192,14 +39547,14 @@ async function readProjectConfigFile(projectRoot) {
|
|
|
39192
39547
|
}
|
|
39193
39548
|
}
|
|
39194
39549
|
async function writeJsonAtomic5(target, value) {
|
|
39195
|
-
await
|
|
39196
|
-
await assertPlainDirectory2(
|
|
39197
|
-
const temporary =
|
|
39198
|
-
|
|
39199
|
-
`.${
|
|
39550
|
+
await mkdir40(path66.dirname(target), { recursive: true });
|
|
39551
|
+
await assertPlainDirectory2(path66.dirname(target));
|
|
39552
|
+
const temporary = path66.join(
|
|
39553
|
+
path66.dirname(target),
|
|
39554
|
+
`.${path66.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
39200
39555
|
);
|
|
39201
39556
|
try {
|
|
39202
|
-
await
|
|
39557
|
+
await writeFile47(temporary, serialize14(value), {
|
|
39203
39558
|
encoding: "utf8",
|
|
39204
39559
|
flag: "wx"
|
|
39205
39560
|
});
|
|
@@ -39210,10 +39565,10 @@ async function writeJsonAtomic5(target, value) {
|
|
|
39210
39565
|
}
|
|
39211
39566
|
}
|
|
39212
39567
|
async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
|
|
39213
|
-
await
|
|
39214
|
-
await assertPlainDirectory2(
|
|
39568
|
+
await mkdir40(path66.dirname(target), { recursive: true });
|
|
39569
|
+
await assertPlainDirectory2(path66.dirname(target));
|
|
39215
39570
|
try {
|
|
39216
|
-
await
|
|
39571
|
+
await writeFile47(target, serialize14(value), { encoding: "utf8", flag: "wx" });
|
|
39217
39572
|
} catch (error) {
|
|
39218
39573
|
if (!isAlreadyExists25(error)) throw error;
|
|
39219
39574
|
const existing = await readJsonOrNull5(target, parser, conflictCode);
|
|
@@ -39229,14 +39584,14 @@ async function readJsonOrNull5(target, parser, corruptCode) {
|
|
|
39229
39584
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
39230
39585
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
39231
39586
|
}
|
|
39232
|
-
const parsed = parser(JSON.parse(await
|
|
39587
|
+
const parsed = parser(JSON.parse(await readFile45(target, "utf8")));
|
|
39233
39588
|
const after = await lstat25(target);
|
|
39234
39589
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
39235
39590
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
39236
39591
|
}
|
|
39237
39592
|
return parsed;
|
|
39238
39593
|
} catch (error) {
|
|
39239
|
-
if (
|
|
39594
|
+
if (isNotFound33(error)) return null;
|
|
39240
39595
|
if (error instanceof SyntaxError) throw new Error(corruptCode);
|
|
39241
39596
|
throw error;
|
|
39242
39597
|
}
|
|
@@ -39294,7 +39649,7 @@ async function pathKind(target) {
|
|
|
39294
39649
|
if (stat5.isDirectory()) return "directory";
|
|
39295
39650
|
return "other";
|
|
39296
39651
|
} catch (error) {
|
|
39297
|
-
if (
|
|
39652
|
+
if (isNotFound33(error)) return null;
|
|
39298
39653
|
throw error;
|
|
39299
39654
|
}
|
|
39300
39655
|
}
|
|
@@ -39308,7 +39663,7 @@ async function unlinkIfExists2(target) {
|
|
|
39308
39663
|
try {
|
|
39309
39664
|
await unlink4(target);
|
|
39310
39665
|
} catch (error) {
|
|
39311
|
-
if (!
|
|
39666
|
+
if (!isNotFound33(error)) throw error;
|
|
39312
39667
|
}
|
|
39313
39668
|
}
|
|
39314
39669
|
function serialize14(value) {
|
|
@@ -39321,7 +39676,7 @@ function compareUtf814(left, right) {
|
|
|
39321
39676
|
function isAlreadyExists25(error) {
|
|
39322
39677
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
39323
39678
|
}
|
|
39324
|
-
function
|
|
39679
|
+
function isNotFound33(error) {
|
|
39325
39680
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
39326
39681
|
}
|
|
39327
39682
|
|
|
@@ -40761,16 +41116,16 @@ function parsePositiveInteger6(value) {
|
|
|
40761
41116
|
}
|
|
40762
41117
|
|
|
40763
41118
|
// src/commands/uninstall.ts
|
|
40764
|
-
import { access as access5, readFile as
|
|
40765
|
-
import
|
|
41119
|
+
import { access as access5, readFile as readFile46, rm as rm21, writeFile as writeFile48 } from "fs/promises";
|
|
41120
|
+
import path67 from "path";
|
|
40766
41121
|
import process12 from "process";
|
|
40767
41122
|
var EXIT_OK10 = 0;
|
|
40768
41123
|
var EXIT_NOT_INITIALIZED7 = 1;
|
|
40769
41124
|
var EXIT_UNSUPPORTED_PLATFORM2 = 2;
|
|
40770
41125
|
var EXIT_V3_AUTHORITY_PROTECTED = 3;
|
|
40771
41126
|
async function uninstall(rootDir = process12.cwd(), platform, options = {}) {
|
|
40772
|
-
const stateFile =
|
|
40773
|
-
const v3SchemaFile =
|
|
41127
|
+
const stateFile = path67.join(rootDir, ".mancode", "state.json");
|
|
41128
|
+
const v3SchemaFile = path67.join(rootDir, ".mancode", "schema.json");
|
|
40774
41129
|
if (await pathExists15(v3SchemaFile)) {
|
|
40775
41130
|
return uninstallV3(rootDir, platform, options);
|
|
40776
41131
|
}
|
|
@@ -40865,7 +41220,7 @@ async function uninstallAll(rootDir) {
|
|
|
40865
41220
|
await uninstallPlatform(rootDir, p);
|
|
40866
41221
|
}
|
|
40867
41222
|
console.log("\u2713 Removing .mancode/ directory...");
|
|
40868
|
-
await
|
|
41223
|
+
await rm21(path67.join(rootDir, ".mancode"), {
|
|
40869
41224
|
recursive: true,
|
|
40870
41225
|
force: true
|
|
40871
41226
|
});
|
|
@@ -40875,10 +41230,10 @@ async function uninstallClaudeCode(rootDir) {
|
|
|
40875
41230
|
await cleanClaudeSettings(rootDir);
|
|
40876
41231
|
}
|
|
40877
41232
|
async function cleanClaudeSettings(rootDir) {
|
|
40878
|
-
const settingsPath =
|
|
41233
|
+
const settingsPath = path67.join(rootDir, ".claude", "settings.json");
|
|
40879
41234
|
let content;
|
|
40880
41235
|
try {
|
|
40881
|
-
content = await
|
|
41236
|
+
content = await readFile46(settingsPath, "utf-8");
|
|
40882
41237
|
} catch {
|
|
40883
41238
|
return;
|
|
40884
41239
|
}
|
|
@@ -40904,7 +41259,7 @@ async function cleanClaudeSettings(rootDir) {
|
|
|
40904
41259
|
);
|
|
40905
41260
|
settings.skills = Object.keys(retainedSkills).length > 0 ? retainedSkills : void 0;
|
|
40906
41261
|
}
|
|
40907
|
-
await
|
|
41262
|
+
await writeFile48(
|
|
40908
41263
|
settingsPath,
|
|
40909
41264
|
`${JSON.stringify(settings, null, 2)}
|
|
40910
41265
|
`,
|
|
@@ -40953,100 +41308,100 @@ async function uninstallCursor(rootDir) {
|
|
|
40953
41308
|
await removeCursorCommands(rootDir);
|
|
40954
41309
|
}
|
|
40955
41310
|
async function uninstallCodex(rootDir) {
|
|
40956
|
-
const agentsPath =
|
|
41311
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
40957
41312
|
try {
|
|
40958
|
-
const content = await
|
|
41313
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
40959
41314
|
const cleaned = removeManagedBlock(content);
|
|
40960
41315
|
if (cleaned.trim()) {
|
|
40961
|
-
await
|
|
41316
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
40962
41317
|
`, "utf-8");
|
|
40963
41318
|
} else {
|
|
40964
|
-
await
|
|
41319
|
+
await rm21(agentsPath, { force: true });
|
|
40965
41320
|
}
|
|
40966
41321
|
} catch {
|
|
40967
41322
|
}
|
|
40968
41323
|
await removeCodexSkills(rootDir);
|
|
40969
41324
|
}
|
|
40970
41325
|
async function uninstallCopilot(rootDir) {
|
|
40971
|
-
const instructionsPath =
|
|
41326
|
+
const instructionsPath = path67.join(
|
|
40972
41327
|
rootDir,
|
|
40973
41328
|
".github",
|
|
40974
41329
|
"copilot-instructions.md"
|
|
40975
41330
|
);
|
|
40976
41331
|
try {
|
|
40977
|
-
const content = await
|
|
41332
|
+
const content = await readFile46(instructionsPath, "utf-8");
|
|
40978
41333
|
const cleaned = removeManagedBlock(content);
|
|
40979
41334
|
if (cleaned.trim()) {
|
|
40980
|
-
await
|
|
41335
|
+
await writeFile48(instructionsPath, `${cleaned}
|
|
40981
41336
|
`, "utf-8");
|
|
40982
41337
|
} else {
|
|
40983
|
-
await
|
|
41338
|
+
await rm21(instructionsPath, { force: true });
|
|
40984
41339
|
}
|
|
40985
41340
|
} catch {
|
|
40986
41341
|
}
|
|
40987
41342
|
await removeCopilotPrompts(rootDir);
|
|
40988
41343
|
}
|
|
40989
41344
|
async function uninstallZcode(rootDir) {
|
|
40990
|
-
const agentsPath =
|
|
41345
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
40991
41346
|
try {
|
|
40992
|
-
const content = await
|
|
41347
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
40993
41348
|
const cleaned = removeManagedBlock(
|
|
40994
41349
|
content,
|
|
40995
41350
|
ZCODE_MANCODE_START_MARKER,
|
|
40996
41351
|
ZCODE_MANCODE_END_MARKER
|
|
40997
41352
|
);
|
|
40998
41353
|
if (cleaned.trim()) {
|
|
40999
|
-
await
|
|
41354
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
41000
41355
|
`, "utf-8");
|
|
41001
41356
|
} else {
|
|
41002
|
-
await
|
|
41357
|
+
await rm21(agentsPath, { force: true });
|
|
41003
41358
|
}
|
|
41004
41359
|
} catch {
|
|
41005
41360
|
}
|
|
41006
41361
|
await removeZcodeSkills(rootDir);
|
|
41007
41362
|
}
|
|
41008
41363
|
async function uninstallKimiCode(rootDir) {
|
|
41009
|
-
const agentsPath =
|
|
41364
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
41010
41365
|
try {
|
|
41011
|
-
const content = await
|
|
41366
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
41012
41367
|
const cleaned = removeManagedBlock(
|
|
41013
41368
|
content,
|
|
41014
41369
|
KIMI_MANCODE_START_MARKER,
|
|
41015
41370
|
KIMI_MANCODE_END_MARKER
|
|
41016
41371
|
);
|
|
41017
41372
|
if (cleaned.trim()) {
|
|
41018
|
-
await
|
|
41373
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
41019
41374
|
`, "utf-8");
|
|
41020
41375
|
} else {
|
|
41021
|
-
await
|
|
41376
|
+
await rm21(agentsPath, { force: true });
|
|
41022
41377
|
}
|
|
41023
41378
|
} catch {
|
|
41024
41379
|
}
|
|
41025
41380
|
await removeKimiSkills(rootDir);
|
|
41026
41381
|
}
|
|
41027
41382
|
async function uninstallQoder(rootDir) {
|
|
41028
|
-
const agentsPath =
|
|
41383
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
41029
41384
|
try {
|
|
41030
|
-
const content = await
|
|
41385
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
41031
41386
|
const cleaned = removeManagedBlock(
|
|
41032
41387
|
content,
|
|
41033
41388
|
QODER_MANCODE_START_MARKER,
|
|
41034
41389
|
QODER_MANCODE_END_MARKER
|
|
41035
41390
|
);
|
|
41036
41391
|
if (cleaned.trim()) {
|
|
41037
|
-
await
|
|
41392
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
41038
41393
|
`, "utf-8");
|
|
41039
41394
|
} else {
|
|
41040
|
-
await
|
|
41395
|
+
await rm21(agentsPath, { force: true });
|
|
41041
41396
|
}
|
|
41042
41397
|
} catch {
|
|
41043
41398
|
}
|
|
41044
41399
|
await removeQoderCommands(rootDir);
|
|
41045
41400
|
}
|
|
41046
41401
|
async function removeFromConfig(rootDir, platform) {
|
|
41047
|
-
const configPath =
|
|
41402
|
+
const configPath = path67.join(rootDir, ".mancode", "config.json");
|
|
41048
41403
|
try {
|
|
41049
|
-
const raw = await
|
|
41404
|
+
const raw = await readFile46(configPath, "utf-8");
|
|
41050
41405
|
const config = JSON.parse(raw);
|
|
41051
41406
|
if (Array.isArray(config.platforms)) {
|
|
41052
41407
|
config.platforms = config.platforms.filter((p) => p !== platform);
|
|
@@ -41058,7 +41413,7 @@ async function removeFromConfig(rootDir, platform) {
|
|
|
41058
41413
|
);
|
|
41059
41414
|
config.platformOptions = Object.keys(platformOptions).length > 0 ? platformOptions : void 0;
|
|
41060
41415
|
}
|
|
41061
|
-
await
|
|
41416
|
+
await writeFile48(
|
|
41062
41417
|
configPath,
|
|
41063
41418
|
`${JSON.stringify(config, null, 2)}
|
|
41064
41419
|
`,
|
|
@@ -41091,8 +41446,8 @@ function version() {
|
|
|
41091
41446
|
}
|
|
41092
41447
|
|
|
41093
41448
|
// src/commands/workflow.ts
|
|
41094
|
-
import { access as access6, readFile as
|
|
41095
|
-
import
|
|
41449
|
+
import { access as access6, readFile as readFile48, rm as rm23, writeFile as writeFile50 } from "fs/promises";
|
|
41450
|
+
import path69 from "path";
|
|
41096
41451
|
|
|
41097
41452
|
// src/context/child-result-merge.ts
|
|
41098
41453
|
async function mergeV3ChildResult(input) {
|
|
@@ -44152,13 +44507,13 @@ function updateMetadata4(previous, verification, operationId, updatedAt) {
|
|
|
44152
44507
|
// src/context/workflow-create.ts
|
|
44153
44508
|
import {
|
|
44154
44509
|
lstat as lstat26,
|
|
44155
|
-
mkdir as
|
|
44156
|
-
readFile as
|
|
44157
|
-
rename as
|
|
44158
|
-
rm as
|
|
44159
|
-
writeFile as
|
|
44510
|
+
mkdir as mkdir41,
|
|
44511
|
+
readFile as readFile47,
|
|
44512
|
+
rename as rename14,
|
|
44513
|
+
rm as rm22,
|
|
44514
|
+
writeFile as writeFile49
|
|
44160
44515
|
} from "fs/promises";
|
|
44161
|
-
import
|
|
44516
|
+
import path68 from "path";
|
|
44162
44517
|
|
|
44163
44518
|
// src/context/creation-resolution.ts
|
|
44164
44519
|
function resolveWorkflowCreation(request) {
|
|
@@ -44268,7 +44623,7 @@ function rejectConflict(provided, expected, label) {
|
|
|
44268
44623
|
|
|
44269
44624
|
// src/context/workflow-create.ts
|
|
44270
44625
|
async function createV3Workflow(input) {
|
|
44271
|
-
const projectRoot =
|
|
44626
|
+
const projectRoot = path68.resolve(requireProjectRoot2(input.projectRoot));
|
|
44272
44627
|
const task = requireText2(input.task, "workflow task");
|
|
44273
44628
|
const client = requireText2(input.client, "workflow client");
|
|
44274
44629
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -44453,8 +44808,8 @@ async function createV3Workflow(input) {
|
|
|
44453
44808
|
throw new Error("MANCODE_REVISION_CONFLICT");
|
|
44454
44809
|
}
|
|
44455
44810
|
const taskParent = await ensureSafeTaskParent3(projectRoot, taskRef);
|
|
44456
|
-
const targetDirectory =
|
|
44457
|
-
stagingDirectory =
|
|
44811
|
+
const targetDirectory = path68.join(taskParent, taskRef.taskId);
|
|
44812
|
+
stagingDirectory = path68.join(
|
|
44458
44813
|
taskParent,
|
|
44459
44814
|
`.${taskRef.taskId}.${operationId}.staging`
|
|
44460
44815
|
);
|
|
@@ -44903,10 +45258,10 @@ async function ensureSafeTaskParent3(projectRoot, taskRef) {
|
|
|
44903
45258
|
const segments = [".mancode", taskRef.namespace, "workflows"];
|
|
44904
45259
|
let current = projectRoot;
|
|
44905
45260
|
for (const segment of segments) {
|
|
44906
|
-
current =
|
|
45261
|
+
current = path68.join(current, segment);
|
|
44907
45262
|
const existing = await lstatOrNull5(current);
|
|
44908
45263
|
if (existing === null) {
|
|
44909
|
-
await
|
|
45264
|
+
await mkdir41(current);
|
|
44910
45265
|
continue;
|
|
44911
45266
|
}
|
|
44912
45267
|
if (!existing.isDirectory() || existing.isSymbolicLink()) {
|
|
@@ -44919,7 +45274,7 @@ async function assertDirectoryAbsent(target, code) {
|
|
|
44919
45274
|
if (await lstatOrNull5(target) !== null) throw new Error(code);
|
|
44920
45275
|
}
|
|
44921
45276
|
async function writeStagedEntities(stagingDirectory, entities) {
|
|
44922
|
-
await
|
|
45277
|
+
await mkdir41(stagingDirectory);
|
|
44923
45278
|
await assertDirectory(stagingDirectory);
|
|
44924
45279
|
await Promise.all([
|
|
44925
45280
|
writeStagedJson(stagingDirectory, "metadata.json", entities.metadata),
|
|
@@ -44939,8 +45294,8 @@ async function writeStagedEntities(stagingDirectory, entities) {
|
|
|
44939
45294
|
}
|
|
44940
45295
|
async function writeStagedJson(stagingDirectory, fileName, value) {
|
|
44941
45296
|
await assertDirectory(stagingDirectory);
|
|
44942
|
-
const target =
|
|
44943
|
-
await
|
|
45297
|
+
const target = path68.join(stagingDirectory, fileName);
|
|
45298
|
+
await writeFile49(target, `${JSON.stringify(value, null, 2)}
|
|
44944
45299
|
`, {
|
|
44945
45300
|
encoding: "utf8",
|
|
44946
45301
|
flag: "wx"
|
|
@@ -44977,12 +45332,12 @@ async function validateStagedEntities(stagingDirectory) {
|
|
|
44977
45332
|
});
|
|
44978
45333
|
}
|
|
44979
45334
|
async function readStagedJson(stagingDirectory, fileName, parser) {
|
|
44980
|
-
const target =
|
|
45335
|
+
const target = path68.join(stagingDirectory, fileName);
|
|
44981
45336
|
const before = await lstat26(target);
|
|
44982
45337
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
44983
45338
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
44984
45339
|
}
|
|
44985
|
-
const parsed = parser(JSON.parse(await
|
|
45340
|
+
const parsed = parser(JSON.parse(await readFile47(target, "utf8")));
|
|
44986
45341
|
const after = await lstat26(target);
|
|
44987
45342
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
44988
45343
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -44996,7 +45351,7 @@ async function publishStagedTask(stagingDirectory, targetDirectory) {
|
|
|
44996
45351
|
targetDirectory,
|
|
44997
45352
|
"MANCODE_WORKFLOW_ALREADY_EXISTS"
|
|
44998
45353
|
);
|
|
44999
|
-
await
|
|
45354
|
+
await rename14(stagingDirectory, targetDirectory);
|
|
45000
45355
|
await assertDirectory(targetDirectory);
|
|
45001
45356
|
}
|
|
45002
45357
|
async function advanceJournal(store, previous, stepId, now, canAbort) {
|
|
@@ -45074,7 +45429,7 @@ async function abortPreparedCreate(store, journal, stagingDirectory, now) {
|
|
|
45074
45429
|
{ canAbort: true }
|
|
45075
45430
|
);
|
|
45076
45431
|
} finally {
|
|
45077
|
-
await
|
|
45432
|
+
await rm22(stagingDirectory, { recursive: true, force: true });
|
|
45078
45433
|
}
|
|
45079
45434
|
}
|
|
45080
45435
|
async function assertDirectory(target) {
|
|
@@ -45087,7 +45442,7 @@ async function lstatOrNull5(target) {
|
|
|
45087
45442
|
try {
|
|
45088
45443
|
return await lstat26(target);
|
|
45089
45444
|
} catch (error) {
|
|
45090
|
-
if (
|
|
45445
|
+
if (isNotFound34(error)) return null;
|
|
45091
45446
|
throw error;
|
|
45092
45447
|
}
|
|
45093
45448
|
}
|
|
@@ -45107,7 +45462,7 @@ function requireText2(value, label) {
|
|
|
45107
45462
|
}
|
|
45108
45463
|
return value.trim();
|
|
45109
45464
|
}
|
|
45110
|
-
function
|
|
45465
|
+
function isNotFound34(error) {
|
|
45111
45466
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
45112
45467
|
}
|
|
45113
45468
|
|
|
@@ -46085,7 +46440,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
|
|
|
46085
46440
|
if (v3Activation === "v3_active") {
|
|
46086
46441
|
return workflowV3(rootDir, subcommand, args, options);
|
|
46087
46442
|
}
|
|
46088
|
-
if (!await pathExists16(
|
|
46443
|
+
if (!await pathExists16(path69.join(rootDir, ".mancode", "state.json"))) {
|
|
46089
46444
|
if (v3Activation !== null) {
|
|
46090
46445
|
return printV3Error(
|
|
46091
46446
|
options.json,
|
|
@@ -46980,7 +47335,6 @@ async function workflowReviewV3(rootDir, args, options) {
|
|
|
46980
47335
|
taskRef: result2.metadata.taskRef,
|
|
46981
47336
|
metadata: result2.metadata,
|
|
46982
47337
|
review: result2.review,
|
|
46983
|
-
verification: result2.verification,
|
|
46984
47338
|
aggregate: result2.aggregate,
|
|
46985
47339
|
taskHeadFence: result2.taskHeadFence,
|
|
46986
47340
|
operation: result2.operation
|
|
@@ -47058,8 +47412,6 @@ async function workflowPlanV3(rootDir, args, options) {
|
|
|
47058
47412
|
taskRef: result2.metadata.taskRef,
|
|
47059
47413
|
metadata: result2.metadata,
|
|
47060
47414
|
planDigest: result2.planDigest,
|
|
47061
|
-
review: result2.review,
|
|
47062
|
-
verification: result2.verification,
|
|
47063
47415
|
aggregate: result2.aggregate,
|
|
47064
47416
|
taskHeadFence: result2.taskHeadFence,
|
|
47065
47417
|
operation: result2.operation
|
|
@@ -47124,8 +47476,6 @@ async function workflowRequirementsV3(rootDir, args, options) {
|
|
|
47124
47476
|
taskRef: result2.metadata.taskRef,
|
|
47125
47477
|
metadata: result2.metadata,
|
|
47126
47478
|
requirements: result2.requirements,
|
|
47127
|
-
review: result2.review,
|
|
47128
|
-
verification: result2.verification,
|
|
47129
47479
|
aggregate: result2.aggregate,
|
|
47130
47480
|
taskHeadFence: result2.taskHeadFence,
|
|
47131
47481
|
operation: result2.operation
|
|
@@ -47177,8 +47527,8 @@ function parseV3ParticipantActorIds(values) {
|
|
|
47177
47527
|
return values;
|
|
47178
47528
|
}
|
|
47179
47529
|
async function readWorkflowInputFile(projectRoot, value) {
|
|
47180
|
-
const inputPath =
|
|
47181
|
-
return
|
|
47530
|
+
const inputPath = path69.isAbsolute(value) ? value : path69.resolve(projectRoot, value);
|
|
47531
|
+
return readFile48(inputPath, "utf8");
|
|
47182
47532
|
}
|
|
47183
47533
|
async function readWorkflowJsonInputFile(projectRoot, value) {
|
|
47184
47534
|
return JSON.parse(await readWorkflowInputFile(projectRoot, value));
|
|
@@ -47251,7 +47601,7 @@ async function readV3ActivationState2(rootDir) {
|
|
|
47251
47601
|
try {
|
|
47252
47602
|
const manifest = parseSchemaManifest(
|
|
47253
47603
|
JSON.parse(
|
|
47254
|
-
await
|
|
47604
|
+
await readFile48(path69.join(rootDir, ".mancode", "schema.json"), "utf8")
|
|
47255
47605
|
)
|
|
47256
47606
|
);
|
|
47257
47607
|
return manifest.activationState === "v3_active" ? "v3_active" : "other";
|
|
@@ -47296,21 +47646,21 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
47296
47646
|
"requirements can only be finalized for an in-progress man or manteam workflow at step 1 or 2"
|
|
47297
47647
|
);
|
|
47298
47648
|
}
|
|
47299
|
-
const workflowPath =
|
|
47300
|
-
const jsonPath =
|
|
47301
|
-
const markdownPath =
|
|
47302
|
-
const metadataPath3 =
|
|
47649
|
+
const workflowPath = path69.join(rootDir, ".mancode", "workflows", taskId);
|
|
47650
|
+
const jsonPath = path69.join(workflowPath, "requirements.json");
|
|
47651
|
+
const markdownPath = path69.join(workflowPath, "requirements.md");
|
|
47652
|
+
const metadataPath3 = path69.join(workflowPath, "metadata.json");
|
|
47303
47653
|
let originalJson;
|
|
47304
47654
|
let originalMarkdown;
|
|
47305
47655
|
let originalMetadata;
|
|
47306
47656
|
try {
|
|
47307
|
-
const inputPath =
|
|
47308
|
-
const input = await
|
|
47657
|
+
const inputPath = path69.isAbsolute(options.file) ? options.file : path69.resolve(rootDir, options.file);
|
|
47658
|
+
const input = await readFile48(inputPath, "utf-8");
|
|
47309
47659
|
const requirements = parseRequirementsLedger2(input);
|
|
47310
47660
|
[originalJson, originalMarkdown, originalMetadata] = await Promise.all([
|
|
47311
47661
|
readOptionalText2(jsonPath),
|
|
47312
47662
|
readOptionalText2(markdownPath),
|
|
47313
|
-
|
|
47663
|
+
readFile48(metadataPath3, "utf-8")
|
|
47314
47664
|
]);
|
|
47315
47665
|
await writeRequirementsArtifacts(rootDir, taskId, requirements);
|
|
47316
47666
|
await updateWorkflow(rootDir, taskId, {
|
|
@@ -47340,7 +47690,7 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
47340
47690
|
const rollback = await Promise.allSettled([
|
|
47341
47691
|
restoreOptionalText(jsonPath, originalJson),
|
|
47342
47692
|
restoreOptionalText(markdownPath, originalMarkdown),
|
|
47343
|
-
|
|
47693
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8")
|
|
47344
47694
|
]);
|
|
47345
47695
|
rollbackIncomplete = rollback.some(
|
|
47346
47696
|
(result2) => result2.status === "rejected"
|
|
@@ -47428,7 +47778,7 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
47428
47778
|
);
|
|
47429
47779
|
}
|
|
47430
47780
|
if (options.evidenceFile) {
|
|
47431
|
-
const evidencePath =
|
|
47781
|
+
const evidencePath = path69.isAbsolute(options.evidenceFile) ? options.evidenceFile : path69.resolve(rootDir, options.evidenceFile);
|
|
47432
47782
|
if (!await pathExists16(evidencePath)) {
|
|
47433
47783
|
return invalidArg(
|
|
47434
47784
|
options,
|
|
@@ -47488,17 +47838,17 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
47488
47838
|
}
|
|
47489
47839
|
async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
47490
47840
|
const ledgerPath = verificationLedgerPath(rootDir, meta.taskId);
|
|
47491
|
-
const metadataPath3 =
|
|
47841
|
+
const metadataPath3 = path69.join(
|
|
47492
47842
|
rootDir,
|
|
47493
47843
|
".mancode",
|
|
47494
47844
|
"workflows",
|
|
47495
47845
|
meta.taskId,
|
|
47496
47846
|
"metadata.json"
|
|
47497
47847
|
);
|
|
47498
|
-
const specPath =
|
|
47848
|
+
const specPath = path69.join(rootDir, ".mancode", "memory", "spec.md");
|
|
47499
47849
|
const [originalLedger, originalMetadata, originalSpec] = await Promise.all([
|
|
47500
47850
|
readOptionalText2(ledgerPath),
|
|
47501
|
-
|
|
47851
|
+
readFile48(metadataPath3, "utf-8"),
|
|
47502
47852
|
readOptionalText2(specPath)
|
|
47503
47853
|
]);
|
|
47504
47854
|
const wasVerificationBlocked = meta.status === "blocked" && meta.blockingReason?.startsWith("[verification]");
|
|
@@ -47527,7 +47877,7 @@ async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
|
47527
47877
|
} catch (error) {
|
|
47528
47878
|
const rollback = await Promise.allSettled([
|
|
47529
47879
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
47530
|
-
|
|
47880
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8"),
|
|
47531
47881
|
restoreOptionalText(specPath, originalSpec)
|
|
47532
47882
|
]);
|
|
47533
47883
|
const message = error instanceof Error ? error.message : "verification transition failed";
|
|
@@ -47659,7 +48009,7 @@ async function workflowReview(rootDir, args, options) {
|
|
|
47659
48009
|
}
|
|
47660
48010
|
async function commitReviewSkip(rootDir, meta, reason) {
|
|
47661
48011
|
const ledgerPath = reviewLedgerPath(rootDir, meta.taskId);
|
|
47662
|
-
const metadataPath3 =
|
|
48012
|
+
const metadataPath3 = path69.join(
|
|
47663
48013
|
rootDir,
|
|
47664
48014
|
".mancode",
|
|
47665
48015
|
"workflows",
|
|
@@ -47668,7 +48018,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
|
|
|
47668
48018
|
);
|
|
47669
48019
|
const [originalLedger, originalMetadata] = await Promise.all([
|
|
47670
48020
|
readOptionalText2(ledgerPath),
|
|
47671
|
-
|
|
48021
|
+
readFile48(metadataPath3, "utf-8")
|
|
47672
48022
|
]);
|
|
47673
48023
|
try {
|
|
47674
48024
|
await initializeSkippedReview(rootDir, meta.taskId, reason);
|
|
@@ -47679,7 +48029,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
|
|
|
47679
48029
|
} catch (error) {
|
|
47680
48030
|
const rollback = await Promise.allSettled([
|
|
47681
48031
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
47682
|
-
|
|
48032
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8")
|
|
47683
48033
|
]);
|
|
47684
48034
|
const message = error instanceof Error ? error.message : "review skip failed";
|
|
47685
48035
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -47899,18 +48249,18 @@ async function workflowHandoff(rootDir, taskId, options) {
|
|
|
47899
48249
|
"solo handoff requires an undecided in-progress workflow at step 4 with ready requirements"
|
|
47900
48250
|
);
|
|
47901
48251
|
}
|
|
47902
|
-
const workflowPath =
|
|
47903
|
-
if (!await pathExists16(
|
|
48252
|
+
const workflowPath = path69.join(rootDir, ".mancode", "workflows", taskId);
|
|
48253
|
+
if (!await pathExists16(path69.join(workflowPath, "requirements.md")) || !await pathExists16(path69.join(workflowPath, "plan.md"))) {
|
|
47904
48254
|
return invalidArg(
|
|
47905
48255
|
options,
|
|
47906
48256
|
"solo handoff requires requirements.md and plan.md"
|
|
47907
48257
|
);
|
|
47908
48258
|
}
|
|
47909
|
-
const statePath =
|
|
48259
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
47910
48260
|
let originalState;
|
|
47911
48261
|
let state;
|
|
47912
48262
|
try {
|
|
47913
|
-
originalState = await
|
|
48263
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
47914
48264
|
state = JSON.parse(originalState);
|
|
47915
48265
|
} catch {
|
|
47916
48266
|
return invalidArg(
|
|
@@ -47981,11 +48331,11 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
|
|
|
47981
48331
|
`workflow is not an active solo handoff: ${taskId}`
|
|
47982
48332
|
);
|
|
47983
48333
|
}
|
|
47984
|
-
const statePath =
|
|
48334
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
47985
48335
|
let originalState;
|
|
47986
48336
|
let state;
|
|
47987
48337
|
try {
|
|
47988
|
-
originalState = await
|
|
48338
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
47989
48339
|
state = JSON.parse(originalState);
|
|
47990
48340
|
} catch {
|
|
47991
48341
|
return invalidArg(
|
|
@@ -48048,18 +48398,18 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
48048
48398
|
`workflow is not ready for a plan-only decision: ${taskId}`
|
|
48049
48399
|
);
|
|
48050
48400
|
}
|
|
48051
|
-
const workflowPath =
|
|
48052
|
-
if (!await pathExists16(
|
|
48401
|
+
const workflowPath = path69.join(rootDir, ".mancode", "workflows", taskId);
|
|
48402
|
+
if (!await pathExists16(path69.join(workflowPath, "requirements.md")) || !await pathExists16(path69.join(workflowPath, "plan.md"))) {
|
|
48053
48403
|
return invalidArg(
|
|
48054
48404
|
options,
|
|
48055
48405
|
"plan-only requires requirements.md and plan.md"
|
|
48056
48406
|
);
|
|
48057
48407
|
}
|
|
48058
|
-
const statePath =
|
|
48408
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
48059
48409
|
let originalState;
|
|
48060
48410
|
let state;
|
|
48061
48411
|
try {
|
|
48062
|
-
originalState = await
|
|
48412
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
48063
48413
|
state = JSON.parse(originalState);
|
|
48064
48414
|
} catch {
|
|
48065
48415
|
return invalidArg(
|
|
@@ -48111,25 +48461,25 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
48111
48461
|
return EXIT_OK11;
|
|
48112
48462
|
}
|
|
48113
48463
|
async function commitPlanningTransition(args) {
|
|
48114
|
-
const metadataPath3 =
|
|
48464
|
+
const metadataPath3 = path69.join(
|
|
48115
48465
|
args.rootDir,
|
|
48116
48466
|
".mancode",
|
|
48117
48467
|
"workflows",
|
|
48118
48468
|
args.taskId,
|
|
48119
48469
|
"metadata.json"
|
|
48120
48470
|
);
|
|
48121
|
-
const specPath =
|
|
48471
|
+
const specPath = path69.join(args.rootDir, ".mancode", "memory", "spec.md");
|
|
48122
48472
|
let originalMetadata;
|
|
48123
48473
|
let originalSpec;
|
|
48124
48474
|
try {
|
|
48125
|
-
originalMetadata = await
|
|
48475
|
+
originalMetadata = await readFile48(metadataPath3, "utf-8");
|
|
48126
48476
|
originalSpec = await readOptionalText2(specPath);
|
|
48127
48477
|
} catch (error) {
|
|
48128
48478
|
return error instanceof Error ? `unable to prepare planning transition: ${error.message}` : "unable to prepare planning transition";
|
|
48129
48479
|
}
|
|
48130
48480
|
try {
|
|
48131
48481
|
await updateWorkflow(args.rootDir, args.taskId, args.workflowPatch);
|
|
48132
|
-
await
|
|
48482
|
+
await writeFile50(
|
|
48133
48483
|
args.statePath,
|
|
48134
48484
|
`${JSON.stringify(args.nextState, null, 2)}
|
|
48135
48485
|
`,
|
|
@@ -48143,9 +48493,9 @@ async function commitPlanningTransition(args) {
|
|
|
48143
48493
|
return null;
|
|
48144
48494
|
} catch (error) {
|
|
48145
48495
|
const rollback = await Promise.allSettled([
|
|
48146
|
-
|
|
48147
|
-
|
|
48148
|
-
originalSpec === null ?
|
|
48496
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8"),
|
|
48497
|
+
writeFile50(args.statePath, args.originalState, "utf-8"),
|
|
48498
|
+
originalSpec === null ? rm23(specPath, { force: true }) : writeFile50(specPath, originalSpec, "utf-8")
|
|
48149
48499
|
]);
|
|
48150
48500
|
const message = error instanceof Error ? error.message : "planning transition failed";
|
|
48151
48501
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -48153,7 +48503,7 @@ async function commitPlanningTransition(args) {
|
|
|
48153
48503
|
}
|
|
48154
48504
|
async function readOptionalText2(filePath) {
|
|
48155
48505
|
try {
|
|
48156
|
-
return await
|
|
48506
|
+
return await readFile48(filePath, "utf-8");
|
|
48157
48507
|
} catch (error) {
|
|
48158
48508
|
if (isNodeError10(error) && error.code === "ENOENT") return null;
|
|
48159
48509
|
throw error;
|
|
@@ -48161,10 +48511,10 @@ async function readOptionalText2(filePath) {
|
|
|
48161
48511
|
}
|
|
48162
48512
|
async function restoreOptionalText(filePath, content) {
|
|
48163
48513
|
if (content === null) {
|
|
48164
|
-
await
|
|
48514
|
+
await rm23(filePath, { force: true });
|
|
48165
48515
|
return;
|
|
48166
48516
|
}
|
|
48167
|
-
await
|
|
48517
|
+
await writeFile50(filePath, content, "utf-8");
|
|
48168
48518
|
}
|
|
48169
48519
|
function readActiveSoloPlan(value) {
|
|
48170
48520
|
if (!value || typeof value !== "object") return null;
|
|
@@ -48584,6 +48934,17 @@ contextProgram.command("reconcile-task-head <shared:id>").description(
|
|
|
48584
48934
|
options
|
|
48585
48935
|
);
|
|
48586
48936
|
});
|
|
48937
|
+
contextProgram.command("glossary <action>").description("Manage the user-confirmed shared project glossary").option("--term <term>", "Glossary term (add, update, remove)").option("--definition <text>", "Term definition (add, update)").option(
|
|
48938
|
+
"--alias <alias>",
|
|
48939
|
+
"Term alias; repeat for multiple aliases (add, update)",
|
|
48940
|
+
(value, previous) => [...previous, value],
|
|
48941
|
+
[]
|
|
48942
|
+
).option("--task <namespace:id>", "Source shared TaskRef (add, update)").option(
|
|
48943
|
+
"--expected-revision <n>",
|
|
48944
|
+
"Current glossary revision (0 for an empty glossary)"
|
|
48945
|
+
).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (action, options) => {
|
|
48946
|
+
process.exitCode = await contextGlossary(process.cwd(), action, options);
|
|
48947
|
+
});
|
|
48587
48948
|
var contextWorktreeProgram = contextProgram.command("worktree").description("Register and inspect the current mancode checkout binding");
|
|
48588
48949
|
contextWorktreeProgram.command("register").description(
|
|
48589
48950
|
"Register this linked worktree before using mancode coordination"
|