mancode 0.5.0 → 0.5.2
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 +24 -13
- package/README.md +21 -14
- package/dist/{chunk-73F46VQM.js → chunk-2JOKDC3X.js} +204 -29
- package/dist/chunk-2JOKDC3X.js.map +1 -0
- package/dist/{chunk-3FOBYCF4.js → chunk-VHZI2WKD.js} +4 -2
- package/dist/{chunk-3FOBYCF4.js.map → chunk-VHZI2WKD.js.map} +1 -1
- package/dist/cli.js +1346 -642
- package/dist/cli.js.map +1 -1
- package/dist/{store-GCLUP5IO.js → store-EEWJJANB.js} +2 -2
- package/dist/{v3-adapter-7XYKHGTB.js → v3-adapter-DBVEX5H5.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-73F46VQM.js.map +0 -1
- /package/dist/{store-GCLUP5IO.js.map → store-EEWJJANB.js.map} +0 -0
- /package/dist/{v3-adapter-7XYKHGTB.js.map → v3-adapter-DBVEX5H5.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -111,7 +111,7 @@ import {
|
|
|
111
111
|
workflowMetadataDigest,
|
|
112
112
|
writeOperationReservation,
|
|
113
113
|
writeProjectFacts
|
|
114
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-VHZI2WKD.js";
|
|
115
115
|
import {
|
|
116
116
|
DEFAULT_MANCODE_END_MARKER,
|
|
117
117
|
DEFAULT_MANCODE_START_MARKER,
|
|
@@ -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";
|
|
@@ -9427,7 +9427,9 @@ var MANAGED_ADAPTERS = [
|
|
|
9427
9427
|
"codex",
|
|
9428
9428
|
"cursor",
|
|
9429
9429
|
"copilot",
|
|
9430
|
-
"zcode"
|
|
9430
|
+
"zcode",
|
|
9431
|
+
"kimi-code",
|
|
9432
|
+
"qoder"
|
|
9431
9433
|
];
|
|
9432
9434
|
var DIGEST_PATTERN5 = /^sha256:[a-f0-9]{64}$/;
|
|
9433
9435
|
var STAGE_STATES = /* @__PURE__ */ new Set([
|
|
@@ -9618,7 +9620,7 @@ async function activateLegacyMigration(input) {
|
|
|
9618
9620
|
if (session === null || session.status !== "active") {
|
|
9619
9621
|
throw new Error("MANCODE_SESSION_NOT_FOUND");
|
|
9620
9622
|
}
|
|
9621
|
-
const store = new (await import("./store-
|
|
9623
|
+
const store = new (await import("./store-EEWJJANB.js")).V3ContextStore(root);
|
|
9622
9624
|
const project = await store.readProjectSnapshot();
|
|
9623
9625
|
const stage = await readMigrationStage(root, input.stageId);
|
|
9624
9626
|
if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
|
|
@@ -9881,7 +9883,7 @@ async function activateLegacyMigration(input) {
|
|
|
9881
9883
|
for (const action of payload.actions.filter(
|
|
9882
9884
|
(action2) => action2.kind === "v3_adapter_file"
|
|
9883
9885
|
)) {
|
|
9884
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
9886
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-DBVEX5H5.js");
|
|
9885
9887
|
await applyV3AdapterFilePlan2(root, action);
|
|
9886
9888
|
}
|
|
9887
9889
|
journal = await completeActivationStep(
|
|
@@ -13737,7 +13739,7 @@ async function upgradeV3Adapters(input) {
|
|
|
13737
13739
|
if (unfinished.length > 0) {
|
|
13738
13740
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
13739
13741
|
}
|
|
13740
|
-
const actualVersions = await import("./v3-adapter-
|
|
13742
|
+
const actualVersions = await import("./v3-adapter-DBVEX5H5.js").then(
|
|
13741
13743
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
13742
13744
|
root,
|
|
13743
13745
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -14149,7 +14151,7 @@ function primaryTargetForPlatform(platform) {
|
|
|
14149
14151
|
return platform === "claude-code" ? "claude-skill" : platform === "cursor" ? "cursor-rule" : platform === "copilot" ? "copilot-instructions" : "agents";
|
|
14150
14152
|
}
|
|
14151
14153
|
function modeTargetForPlatform(platform, mode) {
|
|
14152
|
-
const family = platform === "claude-code" ? "claude" : platform === "codex" || platform === "zcode" ? "agents" : platform;
|
|
14154
|
+
const family = platform === "claude-code" ? "claude" : platform === "codex" || platform === "zcode" || platform === "kimi-code" ? "agents" : platform;
|
|
14153
14155
|
return `${family}-mode-${mode}`;
|
|
14154
14156
|
}
|
|
14155
14157
|
function compareUtf88(left, right) {
|
|
@@ -14339,6 +14341,7 @@ var SCOUT_AGENT = {
|
|
|
14339
14341
|
- \u53EA\u5217\u5BF9\u5B9E\u65BD\u6709\u7528\u7684\u4FE1\u606F
|
|
14340
14342
|
- \u627E\u5230\u98CE\u9669\u70B9\u8981\u6807\u6CE8\uFF08\u26A0\uFE0F\uFF09
|
|
14341
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
|
|
14342
14345
|
- \u5F15\u7528\u6587\u4EF6\u7528 \`path:line\` \u683C\u5F0F\uFF0C\u8BA9 Head Coach \u4E00\u79D2\u8DF3\u8FC7\u53BB
|
|
14343
14346
|
|
|
14344
14347
|
## \u4F60\u4E0D\u662F\u51B3\u7B56\u8005
|
|
@@ -14451,7 +14454,7 @@ var PLAN_COACH_AGENT = {
|
|
|
14451
14454
|
tools: ["Read", "Grep", "Glob"],
|
|
14452
14455
|
body: `\u4F60\u662F mancode \u6559\u7EC3\u7EC4\u7684 Plan Coach\uFF08\u8BA1\u5212\u6559\u7EC3\uFF09\u3002
|
|
14453
14456
|
|
|
14454
|
-
\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
|
|
14455
14458
|
|
|
14456
14459
|
## \u786C\u7EA6\u675F
|
|
14457
14460
|
|
|
@@ -15319,7 +15322,7 @@ var MAN_SKILL = {
|
|
|
15319
15322
|
|
|
15320
15323
|
### Step 1: Scout \u8C03\u7814
|
|
15321
15324
|
|
|
15322
|
-
\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
|
|
15323
15326
|
|
|
15324
15327
|
### Step 2: \u9700\u6C42\u6F84\u6E05
|
|
15325
15328
|
|
|
@@ -15386,7 +15389,7 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
|
|
|
15386
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
|
|
15387
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
|
|
15388
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
|
|
15389
|
-
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
|
|
15390
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
|
|
15391
15394
|
|
|
15392
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
|
|
@@ -15613,7 +15616,7 @@ var MANSOLO_SKILL = {
|
|
|
15613
15616
|
description: "Switch back to solo mode. Clears the current workflow state and returns to lightweight daily-practice mode.",
|
|
15614
15617
|
body: `# mancode \xB7 /mansolo (Back to Practice)
|
|
15615
15618
|
|
|
15616
|
-
\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
|
|
15617
15620
|
|
|
15618
15621
|
## \u4F60\u8981\u505A\u7684
|
|
15619
15622
|
|
|
@@ -15671,7 +15674,7 @@ var MANTEAM_SKILL = {
|
|
|
15671
15674
|
description: "Team workflow for shared repositories. Adds contributor context, coordination notes, commit discipline, and hand-off summaries to the full /man flow.",
|
|
15672
15675
|
body: `# mancode \xB7 /manteam (Team Game)
|
|
15673
15676
|
|
|
15674
|
-
\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
|
|
15675
15678
|
|
|
15676
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
|
|
15677
15680
|
|
|
@@ -16234,10 +16237,12 @@ var MODE_NAMES = [
|
|
|
16234
16237
|
var LEGACY_MODE_NAMES = ["mamba", "man8"];
|
|
16235
16238
|
var CODEX_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:codex-skill. Do not edit this file manually. -->";
|
|
16236
16239
|
var ZCODE_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:zcode-skill. Do not edit this file manually. -->";
|
|
16240
|
+
var KIMI_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:kimi-skill. Do not edit this file manually. -->";
|
|
16237
16241
|
var MODE_FILE_MANAGED_MARKER = "<!-- Managed by mancode:mode-file. Do not edit this file manually. -->";
|
|
16238
16242
|
var MANCODE_AGENT_SKILL_MARKERS = [
|
|
16239
16243
|
CODEX_SKILL_MANAGED_MARKER,
|
|
16240
|
-
ZCODE_SKILL_MANAGED_MARKER
|
|
16244
|
+
ZCODE_SKILL_MANAGED_MARKER,
|
|
16245
|
+
KIMI_SKILL_MANAGED_MARKER
|
|
16241
16246
|
];
|
|
16242
16247
|
function renderModeSkill(mode, commandPrefix = "$") {
|
|
16243
16248
|
const meta = MODE_META[mode];
|
|
@@ -16344,6 +16349,37 @@ async function installZcodeSkills(projectRoot, minimal) {
|
|
|
16344
16349
|
}
|
|
16345
16350
|
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
16346
16351
|
}
|
|
16352
|
+
async function installKimiSkills(projectRoot, minimal) {
|
|
16353
|
+
if (minimal) {
|
|
16354
|
+
await removeKimiSkills(projectRoot);
|
|
16355
|
+
return;
|
|
16356
|
+
}
|
|
16357
|
+
const skillsDir = path27.join(projectRoot, ".agents", "skills");
|
|
16358
|
+
for (const mode of MODE_NAMES) {
|
|
16359
|
+
const modeDir = path27.join(skillsDir, mode);
|
|
16360
|
+
await mkdir23(modeDir, { recursive: true });
|
|
16361
|
+
const meta = MODE_META[mode];
|
|
16362
|
+
const content = [
|
|
16363
|
+
"---",
|
|
16364
|
+
`name: ${mode}`,
|
|
16365
|
+
`description: ${JSON.stringify(meta.description)}`,
|
|
16366
|
+
"---",
|
|
16367
|
+
"",
|
|
16368
|
+
KIMI_SKILL_MANAGED_MARKER,
|
|
16369
|
+
"",
|
|
16370
|
+
renderModeSkill(mode, "/skill:"),
|
|
16371
|
+
""
|
|
16372
|
+
].join("\n");
|
|
16373
|
+
await writeManagedSkill(
|
|
16374
|
+
path27.join(modeDir, "SKILL.md"),
|
|
16375
|
+
content,
|
|
16376
|
+
KIMI_SKILL_MANAGED_MARKER,
|
|
16377
|
+
"Kimi Code",
|
|
16378
|
+
MANCODE_AGENT_SKILL_MARKERS
|
|
16379
|
+
);
|
|
16380
|
+
}
|
|
16381
|
+
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
16382
|
+
}
|
|
16347
16383
|
async function installCursorCommands(projectRoot, minimal) {
|
|
16348
16384
|
if (minimal) {
|
|
16349
16385
|
await removeCursorCommands(projectRoot);
|
|
@@ -16373,6 +16409,47 @@ async function installCursorCommands(projectRoot, minimal) {
|
|
|
16373
16409
|
await removeManagedModeFile(path27.join(commandsDir, "mamba.md"), "mamba");
|
|
16374
16410
|
await removeLegacyGeneratedModeFile(path27.join(commandsDir, "man8.md"));
|
|
16375
16411
|
}
|
|
16412
|
+
var QODER_HOST_SCAN_GUIDANCE = [
|
|
16413
|
+
"## Qoder security scan interplay",
|
|
16414
|
+
"",
|
|
16415
|
+
"Qoder may inject L1/L2/L3 security scan findings as advisory context after",
|
|
16416
|
+
"code edits. Treat them as review input for the current step, never as",
|
|
16417
|
+
"authority to reopen completed reviews: in /man or /manteam, fold open",
|
|
16418
|
+
"findings into the single Step 9 remediation round. If any code changes",
|
|
16419
|
+
"after acceptance evidence was recorded, re-run and re-record the required",
|
|
16420
|
+
"checks before completing. Host scan findings never bypass the workflow",
|
|
16421
|
+
"record maintained through `mancode workflow`."
|
|
16422
|
+
].join("\n");
|
|
16423
|
+
async function installQoderCommands(projectRoot, minimal) {
|
|
16424
|
+
if (minimal) {
|
|
16425
|
+
await removeQoderCommands(projectRoot);
|
|
16426
|
+
return;
|
|
16427
|
+
}
|
|
16428
|
+
const commandsDir = path27.join(projectRoot, ".qoder", "commands");
|
|
16429
|
+
await mkdir23(commandsDir, { recursive: true });
|
|
16430
|
+
for (const mode of MODE_NAMES) {
|
|
16431
|
+
const meta = MODE_META[mode];
|
|
16432
|
+
const content = [
|
|
16433
|
+
"---",
|
|
16434
|
+
`name: ${mode}`,
|
|
16435
|
+
`description: ${JSON.stringify(meta.description)}`,
|
|
16436
|
+
"---",
|
|
16437
|
+
"",
|
|
16438
|
+
MODE_FILE_MANAGED_MARKER,
|
|
16439
|
+
"",
|
|
16440
|
+
renderModeSkill(mode, "/"),
|
|
16441
|
+
"",
|
|
16442
|
+
QODER_HOST_SCAN_GUIDANCE,
|
|
16443
|
+
""
|
|
16444
|
+
].join("\n");
|
|
16445
|
+
await writeManagedModeFile(
|
|
16446
|
+
path27.join(commandsDir, `${mode}.md`),
|
|
16447
|
+
content,
|
|
16448
|
+
mode,
|
|
16449
|
+
"Qoder"
|
|
16450
|
+
);
|
|
16451
|
+
}
|
|
16452
|
+
}
|
|
16376
16453
|
async function installCopilotPrompts(projectRoot, minimal) {
|
|
16377
16454
|
if (minimal) {
|
|
16378
16455
|
await removeCopilotPrompts(projectRoot);
|
|
@@ -16407,7 +16484,7 @@ async function installCopilotPrompts(projectRoot, minimal) {
|
|
|
16407
16484
|
await removeLegacyGeneratedModeFile(path27.join(promptsDir, "man8.prompt.md"));
|
|
16408
16485
|
}
|
|
16409
16486
|
async function removeCodexSkills(projectRoot) {
|
|
16410
|
-
if (!await
|
|
16487
|
+
if (!await anyPlatformNeedsSharedSkills(projectRoot, ["zcode", "kimi-code"])) {
|
|
16411
16488
|
await cleanManagedSkills(
|
|
16412
16489
|
path27.join(projectRoot, ".agents", "skills"),
|
|
16413
16490
|
MANCODE_AGENT_SKILL_MARKERS
|
|
@@ -16429,7 +16506,7 @@ async function cleanManagedSkills(skillsDir, markers) {
|
|
|
16429
16506
|
await removeIfEmpty2(skillsDir);
|
|
16430
16507
|
}
|
|
16431
16508
|
async function removeZcodeSkills(projectRoot) {
|
|
16432
|
-
if (!await
|
|
16509
|
+
if (!await anyPlatformNeedsSharedSkills(projectRoot, ["codex", "kimi-code"])) {
|
|
16433
16510
|
await cleanManagedSkills(
|
|
16434
16511
|
path27.join(projectRoot, ".agents", "skills"),
|
|
16435
16512
|
MANCODE_AGENT_SKILL_MARKERS
|
|
@@ -16439,6 +16516,20 @@ async function removeZcodeSkills(projectRoot) {
|
|
|
16439
16516
|
ZCODE_SKILL_MANAGED_MARKER
|
|
16440
16517
|
]);
|
|
16441
16518
|
}
|
|
16519
|
+
async function removeKimiSkills(projectRoot) {
|
|
16520
|
+
if (!await anyPlatformNeedsSharedSkills(projectRoot, ["codex", "zcode"])) {
|
|
16521
|
+
await cleanManagedSkills(
|
|
16522
|
+
path27.join(projectRoot, ".agents", "skills"),
|
|
16523
|
+
MANCODE_AGENT_SKILL_MARKERS
|
|
16524
|
+
);
|
|
16525
|
+
}
|
|
16526
|
+
}
|
|
16527
|
+
async function removeQoderCommands(projectRoot) {
|
|
16528
|
+
for (const mode of MODE_NAMES) {
|
|
16529
|
+
const filePath = path27.join(projectRoot, ".qoder", "commands", `${mode}.md`);
|
|
16530
|
+
await removeManagedModeFile(filePath, mode);
|
|
16531
|
+
}
|
|
16532
|
+
}
|
|
16442
16533
|
async function removeCursorCommands(projectRoot) {
|
|
16443
16534
|
for (const mode of [...MODE_NAMES, ...LEGACY_MODE_NAMES]) {
|
|
16444
16535
|
const filePath = path27.join(
|
|
@@ -16520,6 +16611,12 @@ async function isManagedByAnyMarker(skillPath, markers) {
|
|
|
16520
16611
|
const content = await readTextIfExists3(skillPath);
|
|
16521
16612
|
return content !== null && markers.some((marker) => content.includes(marker));
|
|
16522
16613
|
}
|
|
16614
|
+
async function anyPlatformNeedsSharedSkills(projectRoot, platforms) {
|
|
16615
|
+
for (const platform of platforms) {
|
|
16616
|
+
if (await platformNeedsSharedSkills(projectRoot, platform)) return true;
|
|
16617
|
+
}
|
|
16618
|
+
return false;
|
|
16619
|
+
}
|
|
16523
16620
|
async function platformNeedsSharedSkills(projectRoot, platform) {
|
|
16524
16621
|
try {
|
|
16525
16622
|
const raw = await readFile26(
|
|
@@ -16763,7 +16860,11 @@ function renderAesthetics(tokens) {
|
|
|
16763
16860
|
}
|
|
16764
16861
|
function renderModes(options) {
|
|
16765
16862
|
let commandLabel;
|
|
16766
|
-
if (options.
|
|
16863
|
+
if (options.platform === "kimi-code") {
|
|
16864
|
+
commandLabel = "Invoke mode skills with `/skill:man`, `/skill:manba`, `/skill:manteam`, `/skill:manps`, `/skill:mansolo`.";
|
|
16865
|
+
} else if (options.platform === "qoder") {
|
|
16866
|
+
commandLabel = "Invoke mode commands with `/man`, `/manba`, `/manteam`, `/manps`, `/mansolo`.";
|
|
16867
|
+
} else if (options.capabilities.skills === "agents-skills") {
|
|
16767
16868
|
commandLabel = "Invoke mode skills with `$man`, `$manba`, `$manteam`, `$manps`, `$mansolo`.";
|
|
16768
16869
|
} else if (options.capabilities.slashCommands === "native") {
|
|
16769
16870
|
commandLabel = "Use the named commands directly when available.";
|
|
@@ -17146,14 +17247,104 @@ function renderManpsRule() {
|
|
|
17146
17247
|
return renderModeSkill("manps", "/");
|
|
17147
17248
|
}
|
|
17148
17249
|
|
|
17149
|
-
// src/installers/
|
|
17250
|
+
// src/installers/kimi-code.ts
|
|
17150
17251
|
import { writeFile as writeFile29 } from "fs/promises";
|
|
17151
17252
|
import path32 from "path";
|
|
17253
|
+
var KIMI_MANCODE_START_MARKER = "<!-- mancode:kimi-code:start -->";
|
|
17254
|
+
var KIMI_MANCODE_END_MARKER = "<!-- mancode:kimi-code:end -->";
|
|
17255
|
+
async function installKimiCode(projectRoot, options) {
|
|
17256
|
+
await installMancodeCore(projectRoot);
|
|
17257
|
+
const agentsPath = path32.join(projectRoot, "AGENTS.md");
|
|
17258
|
+
const existing = await readTextIfExists(agentsPath);
|
|
17259
|
+
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17260
|
+
platform: "kimi-code",
|
|
17261
|
+
displayName: "Kimi Code (desktop/CLI)",
|
|
17262
|
+
capabilities: {
|
|
17263
|
+
slashCommands: "partial",
|
|
17264
|
+
subagents: false,
|
|
17265
|
+
hooks: false,
|
|
17266
|
+
skills: "agents-skills"
|
|
17267
|
+
},
|
|
17268
|
+
minimal: options.minimal,
|
|
17269
|
+
techStack: options.techStack,
|
|
17270
|
+
uiLibrary: options.uiLibrary,
|
|
17271
|
+
projectProfile: options.projectProfile
|
|
17272
|
+
});
|
|
17273
|
+
const block = [
|
|
17274
|
+
KIMI_MANCODE_START_MARKER,
|
|
17275
|
+
"<!-- Managed by mancode. Do not edit this block manually. -->",
|
|
17276
|
+
"",
|
|
17277
|
+
"# mancode Configuration",
|
|
17278
|
+
"",
|
|
17279
|
+
sharedContent.trim(),
|
|
17280
|
+
KIMI_MANCODE_END_MARKER
|
|
17281
|
+
].join("\n");
|
|
17282
|
+
await writeFile29(
|
|
17283
|
+
agentsPath,
|
|
17284
|
+
replaceManagedBlock(
|
|
17285
|
+
existing,
|
|
17286
|
+
block,
|
|
17287
|
+
KIMI_MANCODE_START_MARKER,
|
|
17288
|
+
KIMI_MANCODE_END_MARKER
|
|
17289
|
+
),
|
|
17290
|
+
"utf-8"
|
|
17291
|
+
);
|
|
17292
|
+
await installKimiSkills(projectRoot, options.minimal ?? false);
|
|
17293
|
+
}
|
|
17294
|
+
|
|
17295
|
+
// src/installers/qoder.ts
|
|
17296
|
+
import { writeFile as writeFile30 } from "fs/promises";
|
|
17297
|
+
import path33 from "path";
|
|
17298
|
+
var QODER_MANCODE_START_MARKER = "<!-- mancode:qoder:start -->";
|
|
17299
|
+
var QODER_MANCODE_END_MARKER = "<!-- mancode:qoder:end -->";
|
|
17300
|
+
async function installQoder(projectRoot, options) {
|
|
17301
|
+
await installMancodeCore(projectRoot);
|
|
17302
|
+
const agentsPath = path33.join(projectRoot, "AGENTS.md");
|
|
17303
|
+
const existing = await readTextIfExists(agentsPath);
|
|
17304
|
+
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17305
|
+
platform: "qoder",
|
|
17306
|
+
displayName: "Qoder (IDE/CLI)",
|
|
17307
|
+
capabilities: {
|
|
17308
|
+
slashCommands: "partial",
|
|
17309
|
+
subagents: false,
|
|
17310
|
+
hooks: false,
|
|
17311
|
+
skills: "rules"
|
|
17312
|
+
},
|
|
17313
|
+
minimal: options.minimal,
|
|
17314
|
+
techStack: options.techStack,
|
|
17315
|
+
uiLibrary: options.uiLibrary,
|
|
17316
|
+
projectProfile: options.projectProfile
|
|
17317
|
+
});
|
|
17318
|
+
const block = [
|
|
17319
|
+
QODER_MANCODE_START_MARKER,
|
|
17320
|
+
"<!-- Managed by mancode. Do not edit this block manually. -->",
|
|
17321
|
+
"",
|
|
17322
|
+
"# mancode Configuration",
|
|
17323
|
+
"",
|
|
17324
|
+
sharedContent.trim(),
|
|
17325
|
+
QODER_MANCODE_END_MARKER
|
|
17326
|
+
].join("\n");
|
|
17327
|
+
await writeFile30(
|
|
17328
|
+
agentsPath,
|
|
17329
|
+
replaceManagedBlock(
|
|
17330
|
+
existing,
|
|
17331
|
+
block,
|
|
17332
|
+
QODER_MANCODE_START_MARKER,
|
|
17333
|
+
QODER_MANCODE_END_MARKER
|
|
17334
|
+
),
|
|
17335
|
+
"utf-8"
|
|
17336
|
+
);
|
|
17337
|
+
await installQoderCommands(projectRoot, options.minimal ?? false);
|
|
17338
|
+
}
|
|
17339
|
+
|
|
17340
|
+
// src/installers/zcode.ts
|
|
17341
|
+
import { writeFile as writeFile31 } from "fs/promises";
|
|
17342
|
+
import path34 from "path";
|
|
17152
17343
|
var ZCODE_MANCODE_START_MARKER = "<!-- mancode:zcode:start -->";
|
|
17153
17344
|
var ZCODE_MANCODE_END_MARKER = "<!-- mancode:zcode:end -->";
|
|
17154
17345
|
async function installZcode(projectRoot, options) {
|
|
17155
17346
|
await installMancodeCore(projectRoot);
|
|
17156
|
-
const agentsPath =
|
|
17347
|
+
const agentsPath = path34.join(projectRoot, "AGENTS.md");
|
|
17157
17348
|
const existing = await readTextIfExists(agentsPath);
|
|
17158
17349
|
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17159
17350
|
platform: "zcode",
|
|
@@ -17178,7 +17369,7 @@ async function installZcode(projectRoot, options) {
|
|
|
17178
17369
|
sharedContent.trim(),
|
|
17179
17370
|
ZCODE_MANCODE_END_MARKER
|
|
17180
17371
|
].join("\n");
|
|
17181
|
-
await
|
|
17372
|
+
await writeFile31(
|
|
17182
17373
|
agentsPath,
|
|
17183
17374
|
replaceManagedBlock(
|
|
17184
17375
|
existing,
|
|
@@ -17247,6 +17438,28 @@ var PLATFORM_INSTALLERS = {
|
|
|
17247
17438
|
skills: "agents-skills"
|
|
17248
17439
|
},
|
|
17249
17440
|
install: installZcode
|
|
17441
|
+
},
|
|
17442
|
+
"kimi-code": {
|
|
17443
|
+
name: "kimi-code",
|
|
17444
|
+
displayName: "Kimi Code (desktop/CLI)",
|
|
17445
|
+
capabilities: {
|
|
17446
|
+
slashCommands: "partial",
|
|
17447
|
+
subagents: false,
|
|
17448
|
+
hooks: false,
|
|
17449
|
+
skills: "agents-skills"
|
|
17450
|
+
},
|
|
17451
|
+
install: installKimiCode
|
|
17452
|
+
},
|
|
17453
|
+
qoder: {
|
|
17454
|
+
name: "qoder",
|
|
17455
|
+
displayName: "Qoder (IDE/CLI)",
|
|
17456
|
+
capabilities: {
|
|
17457
|
+
slashCommands: "partial",
|
|
17458
|
+
subagents: false,
|
|
17459
|
+
hooks: false,
|
|
17460
|
+
skills: "rules"
|
|
17461
|
+
},
|
|
17462
|
+
install: installQoder
|
|
17250
17463
|
}
|
|
17251
17464
|
};
|
|
17252
17465
|
function getPlatformInstaller(platform) {
|
|
@@ -17264,11 +17477,11 @@ function isPlatformName(platform) {
|
|
|
17264
17477
|
}
|
|
17265
17478
|
|
|
17266
17479
|
// src/commands/v3-support.ts
|
|
17267
|
-
import
|
|
17480
|
+
import path36 from "path";
|
|
17268
17481
|
|
|
17269
17482
|
// src/runtime/platform-spike-store.ts
|
|
17270
|
-
import { lstat as lstat11, mkdir as mkdir26, readFile as readFile29, rm as rm13, writeFile as
|
|
17271
|
-
import
|
|
17483
|
+
import { lstat as lstat11, mkdir as mkdir26, readFile as readFile29, rm as rm13, writeFile as writeFile32 } from "fs/promises";
|
|
17484
|
+
import path35 from "path";
|
|
17272
17485
|
|
|
17273
17486
|
// src/runtime/platform-spike.ts
|
|
17274
17487
|
var SESSION_SPIKE_PLATFORMS = [
|
|
@@ -17276,7 +17489,9 @@ var SESSION_SPIKE_PLATFORMS = [
|
|
|
17276
17489
|
"codex",
|
|
17277
17490
|
"cursor",
|
|
17278
17491
|
"copilot",
|
|
17279
|
-
"zcode"
|
|
17492
|
+
"zcode",
|
|
17493
|
+
"kimi-code",
|
|
17494
|
+
"qoder"
|
|
17280
17495
|
];
|
|
17281
17496
|
function createPlatformSessionSpike(input) {
|
|
17282
17497
|
assertSessionSpikePlatform(input.platform);
|
|
@@ -17648,7 +17863,7 @@ async function readPlatformSessionSpike(projectRoot, platform) {
|
|
|
17648
17863
|
if (directory === null) return null;
|
|
17649
17864
|
try {
|
|
17650
17865
|
const raw = await readSafeRegularFile(
|
|
17651
|
-
|
|
17866
|
+
path35.join(directory, `${platform}.json`)
|
|
17652
17867
|
);
|
|
17653
17868
|
return parsePlatformSessionSpike(JSON.parse(raw));
|
|
17654
17869
|
} catch (error) {
|
|
@@ -17678,13 +17893,13 @@ async function writePlatformSessionSpike(projectRoot, spike) {
|
|
|
17678
17893
|
if (directory === null) {
|
|
17679
17894
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
17680
17895
|
}
|
|
17681
|
-
const target =
|
|
17896
|
+
const target = path35.join(directory, `${parsed.platform}.json`);
|
|
17682
17897
|
await assertSafeReplacementTarget(target);
|
|
17683
|
-
const temporary =
|
|
17898
|
+
const temporary = path35.join(
|
|
17684
17899
|
directory,
|
|
17685
17900
|
`.${parsed.platform}.${process.pid}.${Date.now()}.tmp`
|
|
17686
17901
|
);
|
|
17687
|
-
await
|
|
17902
|
+
await writeFile32(temporary, `${JSON.stringify(parsed, null, 2)}
|
|
17688
17903
|
`, {
|
|
17689
17904
|
encoding: "utf8",
|
|
17690
17905
|
flag: "wx"
|
|
@@ -17699,9 +17914,9 @@ async function writePlatformSessionSpike(projectRoot, spike) {
|
|
|
17699
17914
|
return parsed;
|
|
17700
17915
|
}
|
|
17701
17916
|
async function safeEvidenceDirectory(projectRoot, create) {
|
|
17702
|
-
let current =
|
|
17917
|
+
let current = path35.resolve(projectRoot);
|
|
17703
17918
|
for (const segment of EVIDENCE_DIRECTORY_SEGMENTS) {
|
|
17704
|
-
const target =
|
|
17919
|
+
const target = path35.join(current, segment);
|
|
17705
17920
|
try {
|
|
17706
17921
|
await assertSafeDirectory2(target);
|
|
17707
17922
|
} catch (error) {
|
|
@@ -17844,7 +18059,7 @@ var EXIT_V3_OK = 0;
|
|
|
17844
18059
|
var EXIT_V3_INVALID_ARGUMENT = 2;
|
|
17845
18060
|
var EXIT_V3_BLOCKED = 3;
|
|
17846
18061
|
async function readV3CommandProject(projectRoot) {
|
|
17847
|
-
const root =
|
|
18062
|
+
const root = path36.resolve(projectRoot);
|
|
17848
18063
|
const runtime = await readProjectRuntimeContext(root);
|
|
17849
18064
|
const store = new V3ContextStore(root);
|
|
17850
18065
|
return {
|
|
@@ -17897,7 +18112,7 @@ async function resolveV3SessionCandidate(project, input, client) {
|
|
|
17897
18112
|
});
|
|
17898
18113
|
}
|
|
17899
18114
|
function platformForClient(client) {
|
|
17900
|
-
return client === "claude-code" || client === "codex" || client === "cursor" || client === "copilot" || client === "zcode" ? client : null;
|
|
18115
|
+
return client === "claude-code" || client === "codex" || client === "cursor" || client === "copilot" || client === "zcode" || client === "kimi-code" || client === "qoder" ? client : null;
|
|
17901
18116
|
}
|
|
17902
18117
|
function commandClient(value) {
|
|
17903
18118
|
const client = value ?? "mancode-cli";
|
|
@@ -17908,7 +18123,7 @@ function commandClient(value) {
|
|
|
17908
18123
|
}
|
|
17909
18124
|
function printV3Result(json, result2) {
|
|
17910
18125
|
if (json) {
|
|
17911
|
-
console.log(JSON.stringify(result2
|
|
18126
|
+
console.log(JSON.stringify(result2));
|
|
17912
18127
|
} else {
|
|
17913
18128
|
console.log(JSON.stringify(result2, null, 2));
|
|
17914
18129
|
}
|
|
@@ -17917,7 +18132,7 @@ function printV3Result(json, result2) {
|
|
|
17917
18132
|
function printV3Error(json, code, message, exitCode = EXIT_V3_BLOCKED) {
|
|
17918
18133
|
const result2 = { schemaVersion: 1, error: { code, message } };
|
|
17919
18134
|
if (json) {
|
|
17920
|
-
console.log(JSON.stringify(result2
|
|
18135
|
+
console.log(JSON.stringify(result2));
|
|
17921
18136
|
} else {
|
|
17922
18137
|
console.error(`\u2717 ${code}`);
|
|
17923
18138
|
console.error(` ${message}`);
|
|
@@ -18021,9 +18236,263 @@ function selectUpgradePlatforms(options) {
|
|
|
18021
18236
|
return options.all === true ? [...V3_ADAPTER_PLATFORMS] : selectStatusPlatforms(options.platform);
|
|
18022
18237
|
}
|
|
18023
18238
|
|
|
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";
|
|
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
|
+
|
|
18024
18493
|
// src/context/publish-promote.ts
|
|
18025
|
-
import { lstat as lstat12, mkdir as
|
|
18026
|
-
import
|
|
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";
|
|
18027
18496
|
|
|
18028
18497
|
// src/context/task-mutation.ts
|
|
18029
18498
|
function markTaskReviewStale(previous, operationId, updatedAt) {
|
|
@@ -18755,15 +19224,15 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
18755
19224
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
18756
19225
|
const parent = await ensureSafeTaskParent2(projectRoot, destinationTaskRef);
|
|
18757
19226
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
18758
|
-
const staging =
|
|
19227
|
+
const staging = path38.join(
|
|
18759
19228
|
parent,
|
|
18760
19229
|
`.${destinationTaskRef.taskId}.${operationId}.staging`
|
|
18761
19230
|
);
|
|
18762
19231
|
await assertPathAbsent(staging, "MANCODE_PROMOTION_STAGING_CONFLICT");
|
|
18763
|
-
await
|
|
19232
|
+
await mkdir28(staging);
|
|
18764
19233
|
try {
|
|
18765
19234
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
18766
|
-
await
|
|
19235
|
+
await writeFile34(path38.join(staging, fileName), content, {
|
|
18767
19236
|
encoding: "utf8",
|
|
18768
19237
|
flag: "wx"
|
|
18769
19238
|
});
|
|
@@ -18771,7 +19240,7 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
18771
19240
|
await assertSafeDirectory3(staging);
|
|
18772
19241
|
return staging;
|
|
18773
19242
|
} catch (error) {
|
|
18774
|
-
await
|
|
19243
|
+
await rm15(staging, { recursive: true, force: true });
|
|
18775
19244
|
throw error;
|
|
18776
19245
|
}
|
|
18777
19246
|
}
|
|
@@ -18779,11 +19248,11 @@ async function ensureSafeTaskParent2(projectRoot, taskRef) {
|
|
|
18779
19248
|
await assertSafeDirectory3(projectRoot);
|
|
18780
19249
|
let current = projectRoot;
|
|
18781
19250
|
for (const segment of [".mancode", taskRef.namespace, "workflows"]) {
|
|
18782
|
-
current =
|
|
19251
|
+
current = path38.join(current, segment);
|
|
18783
19252
|
const existing = await lstatOrNull2(current);
|
|
18784
19253
|
if (existing === null) {
|
|
18785
19254
|
try {
|
|
18786
|
-
await
|
|
19255
|
+
await mkdir28(current);
|
|
18787
19256
|
continue;
|
|
18788
19257
|
} catch (error) {
|
|
18789
19258
|
if (!isAlreadyExists16(error)) throw error;
|
|
@@ -18800,7 +19269,7 @@ async function publishStagedDestination(projectRoot, destinationTaskRef, staging
|
|
|
18800
19269
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
18801
19270
|
await assertSafeDirectory3(staging);
|
|
18802
19271
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
18803
|
-
await
|
|
19272
|
+
await rename10(staging, target);
|
|
18804
19273
|
await assertSafeDirectory3(target);
|
|
18805
19274
|
}
|
|
18806
19275
|
async function assertDestinationAbsent(projectRoot, destinationHomeStore, destinationTaskRef) {
|
|
@@ -18955,7 +19424,7 @@ async function handlePromotionFailure(source, primaryStore, journal, stagingDire
|
|
|
18955
19424
|
} catch {
|
|
18956
19425
|
} finally {
|
|
18957
19426
|
if (stagingDirectory !== null) {
|
|
18958
|
-
await
|
|
19427
|
+
await rm15(stagingDirectory, { recursive: true, force: true });
|
|
18959
19428
|
}
|
|
18960
19429
|
}
|
|
18961
19430
|
}
|
|
@@ -18964,41 +19433,41 @@ async function renewPromotionLocks(source) {
|
|
|
18964
19433
|
}
|
|
18965
19434
|
async function writePromotionQuarantine(projectRoot, operationId, candidate, contents) {
|
|
18966
19435
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
18967
|
-
const parent =
|
|
18968
|
-
await
|
|
19436
|
+
const parent = path38.dirname(directory);
|
|
19437
|
+
await mkdir28(parent, { recursive: true });
|
|
18969
19438
|
await assertSafeDirectory3(parent);
|
|
18970
19439
|
await assertPathAbsent(directory, "MANCODE_PROMOTION_QUARANTINE_CONFLICT");
|
|
18971
|
-
await
|
|
19440
|
+
await mkdir28(directory);
|
|
18972
19441
|
try {
|
|
18973
|
-
await
|
|
18974
|
-
|
|
19442
|
+
await writeFile34(
|
|
19443
|
+
path38.join(directory, "candidate.json"),
|
|
18975
19444
|
serializeTaskAuthority(candidate),
|
|
18976
19445
|
{ encoding: "utf8", flag: "wx" }
|
|
18977
19446
|
);
|
|
18978
19447
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
18979
|
-
await
|
|
19448
|
+
await writeFile34(path38.join(directory, fileName), content, {
|
|
18980
19449
|
encoding: "utf8",
|
|
18981
19450
|
flag: "wx"
|
|
18982
19451
|
});
|
|
18983
19452
|
}
|
|
18984
19453
|
} catch (error) {
|
|
18985
|
-
await
|
|
19454
|
+
await rm15(directory, { recursive: true, force: true });
|
|
18986
19455
|
throw error;
|
|
18987
19456
|
}
|
|
18988
19457
|
}
|
|
18989
19458
|
async function rewritePromotionQuarantine(projectRoot, operationId, candidate) {
|
|
18990
19459
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
18991
19460
|
await assertSafeDirectory3(directory);
|
|
18992
|
-
const target =
|
|
18993
|
-
const temporary =
|
|
19461
|
+
const target = path38.join(directory, "candidate.json");
|
|
19462
|
+
const temporary = path38.join(
|
|
18994
19463
|
directory,
|
|
18995
19464
|
`.candidate.${process.pid}.${Date.now()}.tmp`
|
|
18996
19465
|
);
|
|
18997
|
-
await
|
|
19466
|
+
await writeFile34(temporary, serializeTaskAuthority(candidate), {
|
|
18998
19467
|
encoding: "utf8",
|
|
18999
19468
|
flag: "wx"
|
|
19000
19469
|
});
|
|
19001
|
-
await
|
|
19470
|
+
await rename10(temporary, target);
|
|
19002
19471
|
}
|
|
19003
19472
|
function completeOperationStep2(steps, stepId) {
|
|
19004
19473
|
const index = steps.findIndex((step) => step.id === stepId);
|
|
@@ -19040,11 +19509,11 @@ async function lstatOrNull2(target) {
|
|
|
19040
19509
|
try {
|
|
19041
19510
|
return await lstat12(target);
|
|
19042
19511
|
} catch (error) {
|
|
19043
|
-
if (
|
|
19512
|
+
if (isNotFound21(error)) return null;
|
|
19044
19513
|
throw error;
|
|
19045
19514
|
}
|
|
19046
19515
|
}
|
|
19047
|
-
function
|
|
19516
|
+
function isNotFound21(error) {
|
|
19048
19517
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
19049
19518
|
}
|
|
19050
19519
|
function isAlreadyExists16(error) {
|
|
@@ -19812,7 +20281,7 @@ function compareUtf89(left, right) {
|
|
|
19812
20281
|
|
|
19813
20282
|
// src/context/task-head-reconcile.ts
|
|
19814
20283
|
import { execFile as execFileCallback4 } from "child_process";
|
|
19815
|
-
import
|
|
20284
|
+
import path40 from "path";
|
|
19816
20285
|
import { promisify as promisify4 } from "util";
|
|
19817
20286
|
|
|
19818
20287
|
// src/team/conflicts.ts
|
|
@@ -20012,9 +20481,9 @@ function unique(values) {
|
|
|
20012
20481
|
|
|
20013
20482
|
// src/team/git-ref-transport.ts
|
|
20014
20483
|
import { execFile as execFileCallback3 } from "child_process";
|
|
20015
|
-
import { mkdtemp, rm as
|
|
20484
|
+
import { mkdtemp, rm as rm16, writeFile as writeFile35 } from "fs/promises";
|
|
20016
20485
|
import { tmpdir } from "os";
|
|
20017
|
-
import
|
|
20486
|
+
import path39 from "path";
|
|
20018
20487
|
import { promisify as promisify3 } from "util";
|
|
20019
20488
|
var execFile3 = promisify3(execFileCallback3);
|
|
20020
20489
|
var TEAM_REF = "refs/mancode/team";
|
|
@@ -20037,7 +20506,7 @@ async function resolveGitRefRemoteIdentityHash(projectRoot, remote) {
|
|
|
20037
20506
|
}
|
|
20038
20507
|
let configured = remote;
|
|
20039
20508
|
try {
|
|
20040
|
-
const output = await runGit2(
|
|
20509
|
+
const output = await runGit2(path39.resolve(projectRoot), [
|
|
20041
20510
|
"remote",
|
|
20042
20511
|
"get-url",
|
|
20043
20512
|
"--all",
|
|
@@ -20087,7 +20556,7 @@ var GitRefTeamManifestStore = class {
|
|
|
20087
20556
|
"git-ref configRevision"
|
|
20088
20557
|
);
|
|
20089
20558
|
parseOptionalDigest(options.configDigest, "git-ref configDigest");
|
|
20090
|
-
this.projectRoot =
|
|
20559
|
+
this.projectRoot = path39.resolve(options.projectRoot);
|
|
20091
20560
|
this.remote = options.remote;
|
|
20092
20561
|
this.workspaceId = options.workspaceId;
|
|
20093
20562
|
this.expectedHeader = {
|
|
@@ -20809,7 +21278,7 @@ function parseGitRefTeamManifest(value) {
|
|
|
20809
21278
|
parseGitRefRemoteMutationReceipt
|
|
20810
21279
|
).sort(compareReceipts),
|
|
20811
21280
|
lastMutation: normalized.lastMutation === null ? null : parseGitRefRemoteMutationReceipt(normalized.lastMutation),
|
|
20812
|
-
updatedAt:
|
|
21281
|
+
updatedAt: parseTimestamp13(
|
|
20813
21282
|
normalized.updatedAt,
|
|
20814
21283
|
"git-ref team manifest updatedAt"
|
|
20815
21284
|
)
|
|
@@ -20864,7 +21333,7 @@ function parseGitRefOwnershipFence(value) {
|
|
|
20864
21333
|
"git-ref ownership fence remoteRevision"
|
|
20865
21334
|
),
|
|
20866
21335
|
lastOperationId: value.lastOperationId,
|
|
20867
|
-
updatedAt:
|
|
21336
|
+
updatedAt: parseTimestamp13(
|
|
20868
21337
|
value.updatedAt,
|
|
20869
21338
|
"git-ref ownership fence updatedAt"
|
|
20870
21339
|
)
|
|
@@ -20927,7 +21396,7 @@ function parseGitRefTaskBundle(value) {
|
|
|
20927
21396
|
value.bundleDigest,
|
|
20928
21397
|
"git-ref task bundle bundleDigest"
|
|
20929
21398
|
),
|
|
20930
|
-
createdAt:
|
|
21399
|
+
createdAt: parseTimestamp13(value.createdAt, "git-ref task bundle createdAt")
|
|
20931
21400
|
};
|
|
20932
21401
|
assertTaskBundleConsistency(bundle);
|
|
20933
21402
|
const { bundleDigest: _digest, ...body } = bundle;
|
|
@@ -20983,7 +21452,7 @@ function parseGitRefRemoteMutationReceipt(value) {
|
|
|
20983
21452
|
),
|
|
20984
21453
|
ownershipEpoch,
|
|
20985
21454
|
entityDigests: parseReceiptEntityDigests(value.entityDigests),
|
|
20986
|
-
committedAt:
|
|
21455
|
+
committedAt: parseTimestamp13(
|
|
20987
21456
|
value.committedAt,
|
|
20988
21457
|
"git-ref mutation receipt committedAt"
|
|
20989
21458
|
)
|
|
@@ -21017,7 +21486,7 @@ function parseGitRefAuthorityTombstone(value) {
|
|
|
21017
21486
|
"git-ref authority tombstone successorEpoch"
|
|
21018
21487
|
),
|
|
21019
21488
|
operationId: value.operationId,
|
|
21020
|
-
tombstonedAt:
|
|
21489
|
+
tombstonedAt: parseTimestamp13(
|
|
21021
21490
|
value.tombstonedAt,
|
|
21022
21491
|
"git-ref authority tombstone tombstonedAt"
|
|
21023
21492
|
)
|
|
@@ -21051,7 +21520,7 @@ function parseGitRefAuthorityFreeze(value) {
|
|
|
21051
21520
|
"git-ref authority freeze successorEpoch"
|
|
21052
21521
|
),
|
|
21053
21522
|
operationId: value.operationId,
|
|
21054
|
-
frozenAt:
|
|
21523
|
+
frozenAt: parseTimestamp13(
|
|
21055
21524
|
value.frozenAt,
|
|
21056
21525
|
"git-ref authority freeze frozenAt"
|
|
21057
21526
|
)
|
|
@@ -21793,17 +22262,17 @@ function upsertActorProfile(profiles, profile) {
|
|
|
21793
22262
|
}
|
|
21794
22263
|
async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
21795
22264
|
const temporaryDirectory = await mkdtemp(
|
|
21796
|
-
|
|
22265
|
+
path39.join(tmpdir(), "mancode-git-ref-")
|
|
21797
22266
|
);
|
|
21798
|
-
const manifestPath =
|
|
21799
|
-
const indexPath =
|
|
22267
|
+
const manifestPath = path39.join(temporaryDirectory, "manifest.json");
|
|
22268
|
+
const indexPath = path39.join(temporaryDirectory, "index");
|
|
21800
22269
|
try {
|
|
21801
22270
|
const serialized = `${JSON.stringify(manifest, null, 2)}
|
|
21802
22271
|
`;
|
|
21803
22272
|
if (Buffer.byteLength(serialized, "utf8") > MAX_MANIFEST_BYTES) {
|
|
21804
22273
|
throw new Error("MANCODE_TRANSPORT_MANIFEST_TOO_LARGE");
|
|
21805
22274
|
}
|
|
21806
|
-
await
|
|
22275
|
+
await writeFile35(manifestPath, serialized);
|
|
21807
22276
|
const blob = (await runGit2(projectRoot, ["hash-object", "-w", manifestPath])).trim();
|
|
21808
22277
|
const environment = { ...process.env, GIT_INDEX_FILE: indexPath };
|
|
21809
22278
|
await runGit2(projectRoot, ["read-tree", "--empty"], environment);
|
|
@@ -21835,7 +22304,7 @@ async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
|
21835
22304
|
commitEnvironment
|
|
21836
22305
|
)).trim();
|
|
21837
22306
|
} finally {
|
|
21838
|
-
await
|
|
22307
|
+
await rm16(temporaryDirectory, { recursive: true, force: true });
|
|
21839
22308
|
}
|
|
21840
22309
|
}
|
|
21841
22310
|
async function pushWithLease(projectRoot, remote, expectedCommit, commit3) {
|
|
@@ -21917,7 +22386,7 @@ function normalizeRemoteIdentity(projectRoot, value) {
|
|
|
21917
22386
|
url.pathname = url.pathname.replace(/\/+$/g, "");
|
|
21918
22387
|
return url.toString();
|
|
21919
22388
|
} catch {
|
|
21920
|
-
return
|
|
22389
|
+
return path39.resolve(projectRoot, value).replaceAll("\\", "/");
|
|
21921
22390
|
}
|
|
21922
22391
|
}
|
|
21923
22392
|
function parseBundleCodeRef(value) {
|
|
@@ -21989,7 +22458,7 @@ function parseVersion(value, label) {
|
|
|
21989
22458
|
}
|
|
21990
22459
|
return value;
|
|
21991
22460
|
}
|
|
21992
|
-
function
|
|
22461
|
+
function parseTimestamp13(value, label) {
|
|
21993
22462
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
21994
22463
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
21995
22464
|
}
|
|
@@ -22291,8 +22760,8 @@ function injectAfterReconcileStep(stepId) {
|
|
|
22291
22760
|
throwIfOperationCrashInjected("task_head_reconcile", stepId);
|
|
22292
22761
|
}
|
|
22293
22762
|
async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
22294
|
-
const relativeTaskRoot =
|
|
22295
|
-
if (!relativeTaskRoot ||
|
|
22763
|
+
const relativeTaskRoot = path40.relative(projectRoot, taskRoot2);
|
|
22764
|
+
if (!relativeTaskRoot || path40.isAbsolute(relativeTaskRoot) || relativeTaskRoot.split(path40.sep).some((part) => part === "..")) {
|
|
22296
22765
|
throw new Error("MANCODE_TASK_UNAVAILABLE");
|
|
22297
22766
|
}
|
|
22298
22767
|
const authorityFiles = [
|
|
@@ -22300,7 +22769,7 @@ async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
|
22300
22769
|
"requirements.json",
|
|
22301
22770
|
"review-ledger.json",
|
|
22302
22771
|
"verification-ledger.json"
|
|
22303
|
-
].map((file) =>
|
|
22772
|
+
].map((file) => path40.join(relativeTaskRoot, file));
|
|
22304
22773
|
try {
|
|
22305
22774
|
await execFile4("git", ["rev-parse", "--verify", "HEAD^{commit}"], {
|
|
22306
22775
|
cwd: projectRoot,
|
|
@@ -22518,16 +22987,18 @@ var BETA_PLATFORMS = [
|
|
|
22518
22987
|
"codex",
|
|
22519
22988
|
"cursor",
|
|
22520
22989
|
"copilot",
|
|
22521
|
-
"zcode"
|
|
22990
|
+
"zcode",
|
|
22991
|
+
"kimi-code",
|
|
22992
|
+
"qoder"
|
|
22522
22993
|
];
|
|
22523
22994
|
|
|
22524
22995
|
// src/runtime/retention.ts
|
|
22525
|
-
import { lstat as lstat13, readFile as
|
|
22526
|
-
import
|
|
22996
|
+
import { lstat as lstat13, readFile as readFile31, readdir as readdir14, rm as rm17 } from "fs/promises";
|
|
22997
|
+
import path41 from "path";
|
|
22527
22998
|
var TERMINAL_JOURNAL_RETENTION_DAYS = 30;
|
|
22528
22999
|
var RETAINED_NON_MILESTONE_CHECKPOINTS = 10;
|
|
22529
23000
|
async function planContextCompaction(input) {
|
|
22530
|
-
const root =
|
|
23001
|
+
const root = path41.resolve(input.projectRoot);
|
|
22531
23002
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
22532
23003
|
const store = new V3ContextStore(root);
|
|
22533
23004
|
const [project, runtime] = await Promise.all([
|
|
@@ -22600,7 +23071,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22600
23071
|
if (taskRef.namespace !== "shared") continue;
|
|
22601
23072
|
const task = await store.readTaskSnapshot(taskRef);
|
|
22602
23073
|
if (!isTerminalTaskStatus(task.metadata.status)) continue;
|
|
22603
|
-
const directory =
|
|
23074
|
+
const directory = path41.join(
|
|
22604
23075
|
root,
|
|
22605
23076
|
".mancode",
|
|
22606
23077
|
"local",
|
|
@@ -22609,7 +23080,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22609
23080
|
"artifacts"
|
|
22610
23081
|
);
|
|
22611
23082
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
22612
|
-
const target =
|
|
23083
|
+
const target = path41.join(directory, entry);
|
|
22613
23084
|
const metadata = await regularFileMetadataOrNull(target);
|
|
22614
23085
|
if (metadata === null || metadata.mtimeMs >= threshold) continue;
|
|
22615
23086
|
candidates.push({
|
|
@@ -22626,7 +23097,7 @@ async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifact
|
|
|
22626
23097
|
}
|
|
22627
23098
|
async function planLocalCacheRetention(root, localCacheDays, now) {
|
|
22628
23099
|
const threshold = now.getTime() - localCacheDays * 864e5;
|
|
22629
|
-
const directory =
|
|
23100
|
+
const directory = path41.join(root, ".mancode", "local", "cache");
|
|
22630
23101
|
const candidates = [];
|
|
22631
23102
|
for (const target of await listRegularFilesRecursively(directory)) {
|
|
22632
23103
|
const metadata = await regularFileMetadataOrNull(target);
|
|
@@ -22689,7 +23160,7 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
22689
23160
|
}
|
|
22690
23161
|
candidates.push({
|
|
22691
23162
|
kind: "checkpoint",
|
|
22692
|
-
target:
|
|
23163
|
+
target: path41.join(
|
|
22693
23164
|
task.location.taskRoot,
|
|
22694
23165
|
"checkpoints",
|
|
22695
23166
|
`${checkpoint.checkpointId}.json`
|
|
@@ -22703,13 +23174,13 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
22703
23174
|
return { candidates, skippedReferencedCheckpoints };
|
|
22704
23175
|
}
|
|
22705
23176
|
async function planCompletedSessionRetention(root, completedSessionDays, now, protectedSessionIds) {
|
|
22706
|
-
const directory =
|
|
23177
|
+
const directory = path41.join(root, ".mancode", "local", "sessions");
|
|
22707
23178
|
const entries = await readDirectoryOrEmpty(directory);
|
|
22708
23179
|
const threshold = now.getTime() - completedSessionDays * 864e5;
|
|
22709
23180
|
const candidates = [];
|
|
22710
23181
|
for (const entry of entries) {
|
|
22711
23182
|
if (!entry.endsWith(".json")) continue;
|
|
22712
|
-
const target =
|
|
23183
|
+
const target = path41.join(directory, entry);
|
|
22713
23184
|
const session = parseSessionState(
|
|
22714
23185
|
JSON.parse(await readRegularFile(target))
|
|
22715
23186
|
);
|
|
@@ -22735,7 +23206,7 @@ async function planOperationRetention(stores, now) {
|
|
|
22735
23206
|
const entries = await readDirectoryOrEmpty(directory);
|
|
22736
23207
|
for (const entry of entries) {
|
|
22737
23208
|
if (!entry.endsWith(".json")) continue;
|
|
22738
|
-
const target =
|
|
23209
|
+
const target = path41.join(directory, entry);
|
|
22739
23210
|
const journal = parseOperationJournal(
|
|
22740
23211
|
JSON.parse(await readRegularFile(target))
|
|
22741
23212
|
);
|
|
@@ -22814,7 +23285,7 @@ function isTerminalTaskStatus(status2) {
|
|
|
22814
23285
|
async function listTaskRefs(root) {
|
|
22815
23286
|
const refs = [];
|
|
22816
23287
|
for (const namespace of ["local", "shared"]) {
|
|
22817
|
-
const directory =
|
|
23288
|
+
const directory = path41.join(root, ".mancode", namespace, "workflows");
|
|
22818
23289
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
22819
23290
|
if (!/^[0-9A-HJKMNP-TV-Z]{26}$/.test(entry)) continue;
|
|
22820
23291
|
refs.push({ namespace, taskId: entry });
|
|
@@ -22827,12 +23298,12 @@ async function listTaskRefs(root) {
|
|
|
22827
23298
|
);
|
|
22828
23299
|
}
|
|
22829
23300
|
async function listTaskCheckpoints(taskRoot2, taskRef) {
|
|
22830
|
-
const directory =
|
|
23301
|
+
const directory = path41.join(taskRoot2, "checkpoints");
|
|
22831
23302
|
const checkpoints = [];
|
|
22832
23303
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
22833
23304
|
if (!entry.endsWith(".json")) continue;
|
|
22834
23305
|
const checkpoint = parseCheckpoint(
|
|
22835
|
-
JSON.parse(await readRegularFile(
|
|
23306
|
+
JSON.parse(await readRegularFile(path41.join(directory, entry)))
|
|
22836
23307
|
);
|
|
22837
23308
|
if (!sameTaskRef(checkpoint.taskRef, taskRef) || entry !== `${checkpoint.checkpointId}.json`) {
|
|
22838
23309
|
throw new Error("MANCODE_RETENTION_CHECKPOINT_CORRUPT");
|
|
@@ -22864,14 +23335,14 @@ async function readDirectoryOrEmpty(directory) {
|
|
|
22864
23335
|
(left, right) => Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"))
|
|
22865
23336
|
);
|
|
22866
23337
|
} catch (error) {
|
|
22867
|
-
if (
|
|
23338
|
+
if (isNotFound22(error)) return [];
|
|
22868
23339
|
throw error;
|
|
22869
23340
|
}
|
|
22870
23341
|
}
|
|
22871
23342
|
async function listRegularFilesRecursively(directory) {
|
|
22872
23343
|
const files = [];
|
|
22873
23344
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
22874
|
-
const target =
|
|
23345
|
+
const target = path41.join(directory, entry);
|
|
22875
23346
|
const metadata = await lstatOrNull3(target);
|
|
22876
23347
|
if (metadata === null) continue;
|
|
22877
23348
|
if (metadata.isSymbolicLink()) {
|
|
@@ -22894,7 +23365,7 @@ async function readRegularFile(target) {
|
|
|
22894
23365
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
22895
23366
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
22896
23367
|
}
|
|
22897
|
-
const content = await
|
|
23368
|
+
const content = await readFile31(target, "utf8");
|
|
22898
23369
|
const after = await lstat13(target);
|
|
22899
23370
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
22900
23371
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
@@ -22903,14 +23374,14 @@ async function readRegularFile(target) {
|
|
|
22903
23374
|
}
|
|
22904
23375
|
async function removeRegularFile(target) {
|
|
22905
23376
|
await readRegularFile(target);
|
|
22906
|
-
await
|
|
23377
|
+
await rm17(target);
|
|
22907
23378
|
}
|
|
22908
23379
|
async function regularFileExists(target) {
|
|
22909
23380
|
try {
|
|
22910
23381
|
await readRegularFile(target);
|
|
22911
23382
|
return true;
|
|
22912
23383
|
} catch (error) {
|
|
22913
|
-
if (
|
|
23384
|
+
if (isNotFound22(error)) return false;
|
|
22914
23385
|
throw error;
|
|
22915
23386
|
}
|
|
22916
23387
|
}
|
|
@@ -22926,17 +23397,17 @@ async function lstatOrNull3(target) {
|
|
|
22926
23397
|
try {
|
|
22927
23398
|
return await lstat13(target);
|
|
22928
23399
|
} catch (error) {
|
|
22929
|
-
if (
|
|
23400
|
+
if (isNotFound22(error)) return null;
|
|
22930
23401
|
throw error;
|
|
22931
23402
|
}
|
|
22932
23403
|
}
|
|
22933
|
-
function
|
|
23404
|
+
function isNotFound22(error) {
|
|
22934
23405
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
22935
23406
|
}
|
|
22936
23407
|
|
|
22937
23408
|
// src/team/git-ref-cache.ts
|
|
22938
|
-
import { lstat as lstat14, mkdir as
|
|
22939
|
-
import
|
|
23409
|
+
import { lstat as lstat14, mkdir as mkdir29, readFile as readFile32, writeFile as writeFile36 } from "fs/promises";
|
|
23410
|
+
import path42 from "path";
|
|
22940
23411
|
var DEFAULT_GIT_REF_FRESHNESS_TTL_MS = 5 * 60 * 1e3;
|
|
22941
23412
|
async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
22942
23413
|
const remote = gitRefRemote(config);
|
|
@@ -22952,11 +23423,11 @@ async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
|
22952
23423
|
});
|
|
22953
23424
|
const directory = await ensureSafeCacheDirectory(projectRoot);
|
|
22954
23425
|
const target = gitRefCachePath(projectRoot);
|
|
22955
|
-
const temporary =
|
|
23426
|
+
const temporary = path42.join(
|
|
22956
23427
|
directory,
|
|
22957
23428
|
`.snapshot.${process.pid}.${Date.now()}.tmp`
|
|
22958
23429
|
);
|
|
22959
|
-
await
|
|
23430
|
+
await writeFile36(temporary, `${JSON.stringify(cache, null, 2)}
|
|
22960
23431
|
`, {
|
|
22961
23432
|
encoding: "utf8",
|
|
22962
23433
|
flag: "wx"
|
|
@@ -22974,7 +23445,7 @@ async function readGitRefTeamCache(projectRoot, config) {
|
|
|
22974
23445
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
22975
23446
|
}
|
|
22976
23447
|
const cache = parseGitRefTeamCache(
|
|
22977
|
-
JSON.parse(await
|
|
23448
|
+
JSON.parse(await readFile32(target, "utf8"))
|
|
22978
23449
|
);
|
|
22979
23450
|
const after = await lstat14(target);
|
|
22980
23451
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -22985,7 +23456,7 @@ async function readGitRefTeamCache(projectRoot, config) {
|
|
|
22985
23456
|
}
|
|
22986
23457
|
return cache;
|
|
22987
23458
|
} catch (error) {
|
|
22988
|
-
if (
|
|
23459
|
+
if (isNotFound23(error)) return null;
|
|
22989
23460
|
if (error instanceof SyntaxError) {
|
|
22990
23461
|
throw new Error("MANCODE_TRANSPORT_CACHE_CORRUPT");
|
|
22991
23462
|
}
|
|
@@ -23046,7 +23517,7 @@ function parseGitRefTeamCache(value) {
|
|
|
23046
23517
|
value.transportEpoch,
|
|
23047
23518
|
"git-ref cache transportEpoch"
|
|
23048
23519
|
);
|
|
23049
|
-
const fetchedAt =
|
|
23520
|
+
const fetchedAt = parseTimestamp14(value.fetchedAt, "git-ref cache fetchedAt");
|
|
23050
23521
|
const commit3 = parseCommitOrNull(value.commit);
|
|
23051
23522
|
const receipt = parseReceiptOrNull(value.receipt);
|
|
23052
23523
|
const manifest = value.manifest === null ? null : parseGitRefTeamManifest(value.manifest);
|
|
@@ -23068,11 +23539,11 @@ function parseGitRefTeamCache(value) {
|
|
|
23068
23539
|
};
|
|
23069
23540
|
}
|
|
23070
23541
|
function gitRefCachePath(projectRoot) {
|
|
23071
|
-
return
|
|
23542
|
+
return path42.join(gitRefCacheDirectory(projectRoot), "snapshot.json");
|
|
23072
23543
|
}
|
|
23073
23544
|
function gitRefCacheDirectory(projectRoot) {
|
|
23074
|
-
return
|
|
23075
|
-
|
|
23545
|
+
return path42.join(
|
|
23546
|
+
path42.resolve(projectRoot),
|
|
23076
23547
|
".mancode",
|
|
23077
23548
|
"local",
|
|
23078
23549
|
"cache",
|
|
@@ -23097,7 +23568,7 @@ function parsePositiveInteger4(value, label) {
|
|
|
23097
23568
|
}
|
|
23098
23569
|
return value;
|
|
23099
23570
|
}
|
|
23100
|
-
function
|
|
23571
|
+
function parseTimestamp14(value, label) {
|
|
23101
23572
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
23102
23573
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
23103
23574
|
}
|
|
@@ -23118,12 +23589,12 @@ function parseReceiptOrNull(value) {
|
|
|
23118
23589
|
return value;
|
|
23119
23590
|
}
|
|
23120
23591
|
async function ensureSafeCacheDirectory(projectRoot) {
|
|
23121
|
-
const root =
|
|
23592
|
+
const root = path42.resolve(projectRoot);
|
|
23122
23593
|
let current = root;
|
|
23123
23594
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23124
|
-
current =
|
|
23595
|
+
current = path42.join(current, segment);
|
|
23125
23596
|
try {
|
|
23126
|
-
await
|
|
23597
|
+
await mkdir29(current);
|
|
23127
23598
|
} catch (error) {
|
|
23128
23599
|
if (!isAlreadyExists17(error)) throw error;
|
|
23129
23600
|
}
|
|
@@ -23132,9 +23603,9 @@ async function ensureSafeCacheDirectory(projectRoot) {
|
|
|
23132
23603
|
return current;
|
|
23133
23604
|
}
|
|
23134
23605
|
async function assertSafeCacheDirectory(projectRoot) {
|
|
23135
|
-
let current =
|
|
23606
|
+
let current = path42.resolve(projectRoot);
|
|
23136
23607
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23137
|
-
current =
|
|
23608
|
+
current = path42.join(current, segment);
|
|
23138
23609
|
await assertDirectoryNotLinked(current);
|
|
23139
23610
|
}
|
|
23140
23611
|
}
|
|
@@ -23144,7 +23615,7 @@ async function assertDirectoryNotLinked(directory) {
|
|
|
23144
23615
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
23145
23616
|
}
|
|
23146
23617
|
}
|
|
23147
|
-
function
|
|
23618
|
+
function isNotFound23(error) {
|
|
23148
23619
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23149
23620
|
}
|
|
23150
23621
|
function isAlreadyExists17(error) {
|
|
@@ -23152,24 +23623,24 @@ function isAlreadyExists17(error) {
|
|
|
23152
23623
|
}
|
|
23153
23624
|
|
|
23154
23625
|
// src/team/git-ref-workflow-repair.ts
|
|
23155
|
-
import { lstat as lstat18, mkdir as
|
|
23156
|
-
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";
|
|
23157
23628
|
|
|
23158
23629
|
// src/team/git-ref-materialization.ts
|
|
23159
23630
|
import {
|
|
23160
23631
|
lstat as lstat17,
|
|
23161
|
-
mkdir as
|
|
23162
|
-
readFile as
|
|
23632
|
+
mkdir as mkdir32,
|
|
23633
|
+
readFile as readFile35,
|
|
23163
23634
|
readdir as readdir16,
|
|
23164
23635
|
unlink as unlink2,
|
|
23165
|
-
writeFile as
|
|
23636
|
+
writeFile as writeFile39
|
|
23166
23637
|
} from "fs/promises";
|
|
23167
|
-
import
|
|
23638
|
+
import path45 from "path";
|
|
23168
23639
|
|
|
23169
23640
|
// src/team/git-ref-bundle.ts
|
|
23170
23641
|
import { execFile as execFileCallback5 } from "child_process";
|
|
23171
|
-
import { lstat as lstat15, mkdir as
|
|
23172
|
-
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";
|
|
23173
23644
|
import { promisify as promisify5 } from "util";
|
|
23174
23645
|
var execFile5 = promisify5(execFileCallback5);
|
|
23175
23646
|
function createGitRefTaskBundle(input) {
|
|
@@ -23232,7 +23703,7 @@ async function assertGitRefBundleCodeReachable(projectRoot, bundle) {
|
|
|
23232
23703
|
"git",
|
|
23233
23704
|
["cat-file", "-e", `${parsed.codeRef.head}^{commit}`],
|
|
23234
23705
|
{
|
|
23235
|
-
cwd:
|
|
23706
|
+
cwd: path43.resolve(projectRoot),
|
|
23236
23707
|
windowsHide: true
|
|
23237
23708
|
}
|
|
23238
23709
|
);
|
|
@@ -23245,8 +23716,8 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23245
23716
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23246
23717
|
}
|
|
23247
23718
|
const parsed = parseGitRefTaskBundle(bundle);
|
|
23248
|
-
const directory =
|
|
23249
|
-
|
|
23719
|
+
const directory = path43.join(
|
|
23720
|
+
path43.resolve(projectRoot),
|
|
23250
23721
|
".mancode",
|
|
23251
23722
|
"local",
|
|
23252
23723
|
"quarantine",
|
|
@@ -23262,9 +23733,9 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23262
23733
|
parsed.taskRef.taskId,
|
|
23263
23734
|
String(remoteRevision)
|
|
23264
23735
|
]);
|
|
23265
|
-
const target =
|
|
23736
|
+
const target = path43.join(directory, `${parsed.bundleDigest.slice(7)}.json`);
|
|
23266
23737
|
try {
|
|
23267
|
-
await
|
|
23738
|
+
await writeFile37(target, `${JSON.stringify(parsed, null, 2)}
|
|
23268
23739
|
`, {
|
|
23269
23740
|
encoding: "utf8",
|
|
23270
23741
|
flag: "wx"
|
|
@@ -23279,8 +23750,8 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23279
23750
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23280
23751
|
}
|
|
23281
23752
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23282
|
-
const directory =
|
|
23283
|
-
|
|
23753
|
+
const directory = path43.join(
|
|
23754
|
+
path43.resolve(projectRoot),
|
|
23284
23755
|
".mancode",
|
|
23285
23756
|
"local",
|
|
23286
23757
|
"quarantine",
|
|
@@ -23300,19 +23771,19 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23300
23771
|
]);
|
|
23301
23772
|
entries = await readdir15(directory);
|
|
23302
23773
|
} catch (error) {
|
|
23303
|
-
if (
|
|
23774
|
+
if (isNotFound24(error)) return null;
|
|
23304
23775
|
throw error;
|
|
23305
23776
|
}
|
|
23306
23777
|
const matches = [];
|
|
23307
23778
|
for (const entry of entries.sort()) {
|
|
23308
23779
|
if (!/^[a-f0-9]{64}\.json$/.test(entry)) continue;
|
|
23309
|
-
const target =
|
|
23780
|
+
const target = path43.join(directory, entry);
|
|
23310
23781
|
const before = await lstat15(target);
|
|
23311
23782
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23312
23783
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23313
23784
|
}
|
|
23314
23785
|
const bundle = parseGitRefTaskBundle(
|
|
23315
|
-
JSON.parse(await
|
|
23786
|
+
JSON.parse(await readFile33(target, "utf8"))
|
|
23316
23787
|
);
|
|
23317
23788
|
const after = await lstat15(target);
|
|
23318
23789
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -23343,11 +23814,11 @@ function parseCodeRef(value) {
|
|
|
23343
23814
|
return { branch: value.branch, head: value.head };
|
|
23344
23815
|
}
|
|
23345
23816
|
async function ensureFixedDirectory(projectRoot, segments) {
|
|
23346
|
-
let current =
|
|
23817
|
+
let current = path43.resolve(projectRoot);
|
|
23347
23818
|
for (const segment of segments) {
|
|
23348
|
-
current =
|
|
23819
|
+
current = path43.join(current, segment);
|
|
23349
23820
|
try {
|
|
23350
|
-
await
|
|
23821
|
+
await mkdir30(current);
|
|
23351
23822
|
} catch (error) {
|
|
23352
23823
|
if (!isAlreadyExists18(error)) throw error;
|
|
23353
23824
|
}
|
|
@@ -23358,9 +23829,9 @@ async function ensureFixedDirectory(projectRoot, segments) {
|
|
|
23358
23829
|
}
|
|
23359
23830
|
}
|
|
23360
23831
|
async function assertFixedDirectory(projectRoot, segments) {
|
|
23361
|
-
let current =
|
|
23832
|
+
let current = path43.resolve(projectRoot);
|
|
23362
23833
|
for (const segment of segments) {
|
|
23363
|
-
current =
|
|
23834
|
+
current = path43.join(current, segment);
|
|
23364
23835
|
const entry = await lstat15(current);
|
|
23365
23836
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23366
23837
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -23370,13 +23841,13 @@ async function assertFixedDirectory(projectRoot, segments) {
|
|
|
23370
23841
|
function isAlreadyExists18(error) {
|
|
23371
23842
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
23372
23843
|
}
|
|
23373
|
-
function
|
|
23844
|
+
function isNotFound24(error) {
|
|
23374
23845
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23375
23846
|
}
|
|
23376
23847
|
|
|
23377
23848
|
// src/team/git-ref-task-base.ts
|
|
23378
|
-
import { lstat as lstat16, mkdir as
|
|
23379
|
-
import
|
|
23849
|
+
import { lstat as lstat16, mkdir as mkdir31, readFile as readFile34, writeFile as writeFile38 } from "fs/promises";
|
|
23850
|
+
import path44 from "path";
|
|
23380
23851
|
async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
23381
23852
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23382
23853
|
const runtime = await readProjectRuntimeContext(projectRoot);
|
|
@@ -23388,7 +23859,7 @@ async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
|
23388
23859
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23389
23860
|
}
|
|
23390
23861
|
const state = parseGitRefTaskRemoteBase(
|
|
23391
|
-
JSON.parse(await
|
|
23862
|
+
JSON.parse(await readFile34(target, "utf8"))
|
|
23392
23863
|
);
|
|
23393
23864
|
const after = await lstat16(target);
|
|
23394
23865
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
@@ -23399,7 +23870,7 @@ async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
|
23399
23870
|
}
|
|
23400
23871
|
return state;
|
|
23401
23872
|
} catch (error) {
|
|
23402
|
-
if (
|
|
23873
|
+
if (isNotFound25(error)) return null;
|
|
23403
23874
|
if (error instanceof SyntaxError) {
|
|
23404
23875
|
throw new Error("MANCODE_TRANSPORT_CACHE_CORRUPT");
|
|
23405
23876
|
}
|
|
@@ -23419,11 +23890,11 @@ async function recordGitRefTaskRemoteBase(projectRoot, remoteRevision, bundle) {
|
|
|
23419
23890
|
});
|
|
23420
23891
|
const directory = await ensureRemoteBaseDirectory(projectRoot);
|
|
23421
23892
|
const target = remoteBasePath(projectRoot, parsedBundle.taskRef);
|
|
23422
|
-
const temporary =
|
|
23893
|
+
const temporary = path44.join(
|
|
23423
23894
|
directory,
|
|
23424
23895
|
`.${parsedBundle.taskRef.taskId}.${process.pid}.${Date.now()}.tmp`
|
|
23425
23896
|
);
|
|
23426
|
-
await
|
|
23897
|
+
await writeFile38(temporary, `${JSON.stringify(state, null, 2)}
|
|
23427
23898
|
`, {
|
|
23428
23899
|
encoding: "utf8",
|
|
23429
23900
|
flag: "wx"
|
|
@@ -23456,7 +23927,7 @@ function parseGitRefTaskRemoteBase(value) {
|
|
|
23456
23927
|
};
|
|
23457
23928
|
}
|
|
23458
23929
|
async function ensureRemoteBaseDirectory(projectRoot) {
|
|
23459
|
-
let current =
|
|
23930
|
+
let current = path44.resolve(projectRoot);
|
|
23460
23931
|
for (const segment of [
|
|
23461
23932
|
".mancode",
|
|
23462
23933
|
"local",
|
|
@@ -23464,9 +23935,9 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
23464
23935
|
"git-ref",
|
|
23465
23936
|
"remote-bases"
|
|
23466
23937
|
]) {
|
|
23467
|
-
current =
|
|
23938
|
+
current = path44.join(current, segment);
|
|
23468
23939
|
try {
|
|
23469
|
-
await
|
|
23940
|
+
await mkdir31(current);
|
|
23470
23941
|
} catch (error) {
|
|
23471
23942
|
if (!isAlreadyExists19(error)) throw error;
|
|
23472
23943
|
}
|
|
@@ -23478,7 +23949,7 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
23478
23949
|
return current;
|
|
23479
23950
|
}
|
|
23480
23951
|
async function assertRemoteBaseDirectory(projectRoot) {
|
|
23481
|
-
let current =
|
|
23952
|
+
let current = path44.resolve(projectRoot);
|
|
23482
23953
|
for (const segment of [
|
|
23483
23954
|
".mancode",
|
|
23484
23955
|
"local",
|
|
@@ -23486,7 +23957,7 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
23486
23957
|
"git-ref",
|
|
23487
23958
|
"remote-bases"
|
|
23488
23959
|
]) {
|
|
23489
|
-
current =
|
|
23960
|
+
current = path44.join(current, segment);
|
|
23490
23961
|
const entry = await lstat16(current);
|
|
23491
23962
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23492
23963
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -23495,8 +23966,8 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
23495
23966
|
}
|
|
23496
23967
|
function remoteBasePath(projectRoot, taskRef) {
|
|
23497
23968
|
const parsed = parseTaskRefValue(taskRef);
|
|
23498
|
-
return
|
|
23499
|
-
|
|
23969
|
+
return path44.join(
|
|
23970
|
+
path44.resolve(projectRoot),
|
|
23500
23971
|
".mancode",
|
|
23501
23972
|
"local",
|
|
23502
23973
|
"cache",
|
|
@@ -23514,13 +23985,13 @@ function positiveInteger2(value) {
|
|
|
23514
23985
|
function isAlreadyExists19(error) {
|
|
23515
23986
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
23516
23987
|
}
|
|
23517
|
-
function
|
|
23988
|
+
function isNotFound25(error) {
|
|
23518
23989
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23519
23990
|
}
|
|
23520
23991
|
|
|
23521
23992
|
// src/team/git-ref-materialization.ts
|
|
23522
23993
|
async function materializeGitRefTaskBundle(input) {
|
|
23523
|
-
const projectRoot =
|
|
23994
|
+
const projectRoot = path45.resolve(input.projectRoot);
|
|
23524
23995
|
const remoteRevision = positiveInteger3(
|
|
23525
23996
|
input.remoteRevision,
|
|
23526
23997
|
"git-ref materialization remoteRevision"
|
|
@@ -23826,7 +24297,7 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
23826
24297
|
const target = safeTaskPath(taskRoot2, relativePath2);
|
|
23827
24298
|
await ensureSafeDirectory(
|
|
23828
24299
|
taskRoot2,
|
|
23829
|
-
|
|
24300
|
+
path45.dirname(relativePath2).split(path45.sep)
|
|
23830
24301
|
);
|
|
23831
24302
|
const current = await readSafeFileOrNull(target);
|
|
23832
24303
|
if (contentMatches(relativePath2, current, targetContent)) return;
|
|
@@ -23836,11 +24307,11 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
23836
24307
|
if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath2 !== "summary.md") {
|
|
23837
24308
|
throw new Error("MANCODE_SPLIT_BRAIN");
|
|
23838
24309
|
}
|
|
23839
|
-
const temporary =
|
|
23840
|
-
|
|
23841
|
-
`.${
|
|
24310
|
+
const temporary = path45.join(
|
|
24311
|
+
path45.dirname(target),
|
|
24312
|
+
`.${path45.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
23842
24313
|
);
|
|
23843
|
-
await
|
|
24314
|
+
await writeFile39(temporary, targetContent, { encoding: "utf8", flag: "wx" });
|
|
23844
24315
|
await replaceFileAtomically(temporary, target);
|
|
23845
24316
|
}
|
|
23846
24317
|
function contentMatches(relativePath2, current, expected) {
|
|
@@ -23894,27 +24365,27 @@ async function readSafeFileOrNull(target) {
|
|
|
23894
24365
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23895
24366
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23896
24367
|
}
|
|
23897
|
-
const content = await
|
|
24368
|
+
const content = await readFile35(target, "utf8");
|
|
23898
24369
|
const after = await lstat17(target);
|
|
23899
24370
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23900
24371
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23901
24372
|
}
|
|
23902
24373
|
return content;
|
|
23903
24374
|
} catch (error) {
|
|
23904
|
-
if (
|
|
24375
|
+
if (isNotFound26(error)) return null;
|
|
23905
24376
|
throw error;
|
|
23906
24377
|
}
|
|
23907
24378
|
}
|
|
23908
24379
|
async function ensureSafeDirectory(root, segments) {
|
|
23909
|
-
let current =
|
|
24380
|
+
let current = path45.resolve(root);
|
|
23910
24381
|
for (const segment of segments) {
|
|
23911
24382
|
if (!segment || segment === ".") continue;
|
|
23912
24383
|
if (segment === ".." || segment.includes("/") || segment.includes("\\")) {
|
|
23913
24384
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23914
24385
|
}
|
|
23915
|
-
current =
|
|
24386
|
+
current = path45.join(current, segment);
|
|
23916
24387
|
try {
|
|
23917
|
-
await
|
|
24388
|
+
await mkdir32(current);
|
|
23918
24389
|
} catch (error) {
|
|
23919
24390
|
if (!isAlreadyExists20(error)) throw error;
|
|
23920
24391
|
}
|
|
@@ -23925,9 +24396,9 @@ async function ensureSafeDirectory(root, segments) {
|
|
|
23925
24396
|
}
|
|
23926
24397
|
}
|
|
23927
24398
|
function safeTaskPath(taskRoot2, relativePath2) {
|
|
23928
|
-
const target =
|
|
23929
|
-
const relative =
|
|
23930
|
-
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)) {
|
|
23931
24402
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23932
24403
|
}
|
|
23933
24404
|
return target;
|
|
@@ -23939,7 +24410,7 @@ async function createJournal(projectRoot, journal) {
|
|
|
23939
24410
|
"journals",
|
|
23940
24411
|
"git-ref-materialize"
|
|
23941
24412
|
]);
|
|
23942
|
-
await
|
|
24413
|
+
await writeFile39(
|
|
23943
24414
|
journalPath(projectRoot, journal.operationId),
|
|
23944
24415
|
serialize11(journal),
|
|
23945
24416
|
{
|
|
@@ -23950,11 +24421,11 @@ async function createJournal(projectRoot, journal) {
|
|
|
23950
24421
|
}
|
|
23951
24422
|
async function replaceJournal(projectRoot, journal) {
|
|
23952
24423
|
const target = journalPath(projectRoot, journal.operationId);
|
|
23953
|
-
const temporary =
|
|
23954
|
-
|
|
24424
|
+
const temporary = path45.join(
|
|
24425
|
+
path45.dirname(target),
|
|
23955
24426
|
`.${journal.operationId}.${process.pid}.${Date.now()}.tmp`
|
|
23956
24427
|
);
|
|
23957
|
-
await
|
|
24428
|
+
await writeFile39(temporary, serialize11(journal), {
|
|
23958
24429
|
encoding: "utf8",
|
|
23959
24430
|
flag: "wx"
|
|
23960
24431
|
});
|
|
@@ -23962,7 +24433,7 @@ async function replaceJournal(projectRoot, journal) {
|
|
|
23962
24433
|
}
|
|
23963
24434
|
async function readJournal(target) {
|
|
23964
24435
|
try {
|
|
23965
|
-
const raw = JSON.parse(await
|
|
24436
|
+
const raw = JSON.parse(await readFile35(target, "utf8"));
|
|
23966
24437
|
return parseJournal(raw);
|
|
23967
24438
|
} catch (error) {
|
|
23968
24439
|
if (error instanceof SyntaxError) {
|
|
@@ -23977,13 +24448,13 @@ async function listJournals(projectRoot) {
|
|
|
23977
24448
|
try {
|
|
23978
24449
|
entries = await readdir16(directory);
|
|
23979
24450
|
} catch (error) {
|
|
23980
|
-
if (
|
|
24451
|
+
if (isNotFound26(error)) return [];
|
|
23981
24452
|
throw error;
|
|
23982
24453
|
}
|
|
23983
24454
|
const journals = [];
|
|
23984
24455
|
for (const entry of entries.sort()) {
|
|
23985
24456
|
if (!entry.endsWith(".json")) continue;
|
|
23986
|
-
journals.push(await readJournal(
|
|
24457
|
+
journals.push(await readJournal(path45.join(directory, entry)));
|
|
23987
24458
|
}
|
|
23988
24459
|
return journals;
|
|
23989
24460
|
}
|
|
@@ -24049,8 +24520,8 @@ function result(status2, bundle, localJournalPath, taskHeadFence) {
|
|
|
24049
24520
|
};
|
|
24050
24521
|
}
|
|
24051
24522
|
function journalDirectory(projectRoot) {
|
|
24052
|
-
return
|
|
24053
|
-
|
|
24523
|
+
return path45.join(
|
|
24524
|
+
path45.resolve(projectRoot),
|
|
24054
24525
|
".mancode",
|
|
24055
24526
|
"local",
|
|
24056
24527
|
"journals",
|
|
@@ -24059,7 +24530,7 @@ function journalDirectory(projectRoot) {
|
|
|
24059
24530
|
}
|
|
24060
24531
|
function journalPath(projectRoot, operationId) {
|
|
24061
24532
|
assertUlid(operationId, "git-ref materialization operationId");
|
|
24062
|
-
return
|
|
24533
|
+
return path45.join(journalDirectory(projectRoot), `${operationId}.json`);
|
|
24063
24534
|
}
|
|
24064
24535
|
function serialize11(value) {
|
|
24065
24536
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -24082,20 +24553,20 @@ async function pathExists3(target) {
|
|
|
24082
24553
|
await lstat17(target);
|
|
24083
24554
|
return true;
|
|
24084
24555
|
} catch (error) {
|
|
24085
|
-
if (
|
|
24556
|
+
if (isNotFound26(error)) return false;
|
|
24086
24557
|
throw error;
|
|
24087
24558
|
}
|
|
24088
24559
|
}
|
|
24089
24560
|
function isAlreadyExists20(error) {
|
|
24090
24561
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
24091
24562
|
}
|
|
24092
|
-
function
|
|
24563
|
+
function isNotFound26(error) {
|
|
24093
24564
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
24094
24565
|
}
|
|
24095
24566
|
|
|
24096
24567
|
// src/team/git-ref-workflow-repair.ts
|
|
24097
24568
|
async function prepareGitRefWorkflowRepair(input) {
|
|
24098
|
-
const root =
|
|
24569
|
+
const root = path46.resolve(input.projectRoot);
|
|
24099
24570
|
const prepared2 = parsePrepared(input.prepared);
|
|
24100
24571
|
const pendingMetadata = parseWorkflowMetadata(input.pendingMetadata);
|
|
24101
24572
|
assertPendingMetadata2(prepared2, pendingMetadata);
|
|
@@ -24130,7 +24601,7 @@ async function prepareGitRefWorkflowRepair(input) {
|
|
|
24130
24601
|
}
|
|
24131
24602
|
async function recoverGitRefWorkflowRepair(projectRoot, operationId, transportReceipt = null, options = {}) {
|
|
24132
24603
|
assertUlid(operationId, "git-ref workflow repair operationId");
|
|
24133
|
-
const root =
|
|
24604
|
+
const root = path46.resolve(projectRoot);
|
|
24134
24605
|
let journal = await requireJournal(root, operationId);
|
|
24135
24606
|
await assertRecoveryAuthorized(root, journal, options);
|
|
24136
24607
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
@@ -24497,7 +24968,7 @@ async function createJournal2(projectRoot, journal) {
|
|
|
24497
24968
|
await ensureJournalDirectory(projectRoot);
|
|
24498
24969
|
const target = gitRefWorkflowRepairJournalPath(projectRoot, journal.operationId);
|
|
24499
24970
|
try {
|
|
24500
|
-
await
|
|
24971
|
+
await writeFile40(target, serialize12(journal), {
|
|
24501
24972
|
encoding: "utf8",
|
|
24502
24973
|
flag: "wx"
|
|
24503
24974
|
});
|
|
@@ -24518,10 +24989,10 @@ async function replaceJournal2(projectRoot, journal) {
|
|
|
24518
24989
|
async function requireJournal(projectRoot, operationId) {
|
|
24519
24990
|
try {
|
|
24520
24991
|
return parseJournal2(
|
|
24521
|
-
JSON.parse(await
|
|
24992
|
+
JSON.parse(await readFile36(gitRefWorkflowRepairJournalPath(projectRoot, operationId), "utf8"))
|
|
24522
24993
|
);
|
|
24523
24994
|
} catch (error) {
|
|
24524
|
-
if (error instanceof SyntaxError ||
|
|
24995
|
+
if (error instanceof SyntaxError || isNotFound27(error)) {
|
|
24525
24996
|
throw new Error("MANCODE_REMOTE_WORKFLOW_REPAIR_JOURNAL_NOT_FOUND");
|
|
24526
24997
|
}
|
|
24527
24998
|
throw error;
|
|
@@ -24537,14 +25008,14 @@ function metadataFromBundle(bundle) {
|
|
|
24537
25008
|
return parseWorkflowMetadata(artifact2.content);
|
|
24538
25009
|
}
|
|
24539
25010
|
function metadataPath2(projectRoot, taskRef) {
|
|
24540
|
-
return
|
|
25011
|
+
return path46.join(taskRootPath(projectRoot, taskRef), "metadata.json");
|
|
24541
25012
|
}
|
|
24542
25013
|
async function readSafeFile(target) {
|
|
24543
25014
|
const before = await lstat18(target);
|
|
24544
25015
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
24545
25016
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24546
25017
|
}
|
|
24547
|
-
const content = await
|
|
25018
|
+
const content = await readFile36(target, "utf8");
|
|
24548
25019
|
const after = await lstat18(target);
|
|
24549
25020
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
24550
25021
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -24552,19 +25023,19 @@ async function readSafeFile(target) {
|
|
|
24552
25023
|
return content;
|
|
24553
25024
|
}
|
|
24554
25025
|
async function atomicWrite(target, content) {
|
|
24555
|
-
const temporary =
|
|
24556
|
-
|
|
24557
|
-
`.${
|
|
25026
|
+
const temporary = path46.join(
|
|
25027
|
+
path46.dirname(target),
|
|
25028
|
+
`.${path46.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
24558
25029
|
);
|
|
24559
|
-
await
|
|
25030
|
+
await writeFile40(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
24560
25031
|
await replaceFileAtomically(temporary, target);
|
|
24561
25032
|
}
|
|
24562
25033
|
async function ensureJournalDirectory(projectRoot) {
|
|
24563
|
-
let current =
|
|
25034
|
+
let current = path46.resolve(projectRoot);
|
|
24564
25035
|
for (const segment of [".mancode", "local", "journals", "git-ref-workflow"]) {
|
|
24565
|
-
current =
|
|
25036
|
+
current = path46.join(current, segment);
|
|
24566
25037
|
try {
|
|
24567
|
-
await
|
|
25038
|
+
await mkdir33(current);
|
|
24568
25039
|
} catch (error) {
|
|
24569
25040
|
if (!isAlreadyExists21(error)) throw error;
|
|
24570
25041
|
}
|
|
@@ -24596,7 +25067,7 @@ function serialize12(value) {
|
|
|
24596
25067
|
function isAlreadyExists21(error) {
|
|
24597
25068
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
24598
25069
|
}
|
|
24599
|
-
function
|
|
25070
|
+
function isNotFound27(error) {
|
|
24600
25071
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
24601
25072
|
}
|
|
24602
25073
|
|
|
@@ -25200,6 +25671,106 @@ async function contextReconcileTaskHead(rootDir, task, options) {
|
|
|
25200
25671
|
);
|
|
25201
25672
|
}
|
|
25202
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
|
+
}
|
|
25203
25774
|
async function resolveContext(project, session, request) {
|
|
25204
25775
|
const resolver = new ContextResolver({
|
|
25205
25776
|
projectRoot: project.projectRoot,
|
|
@@ -25306,20 +25877,20 @@ function parseExpectedRevision2(value) {
|
|
|
25306
25877
|
}
|
|
25307
25878
|
|
|
25308
25879
|
// src/commands/design.ts
|
|
25309
|
-
import { readFile as
|
|
25310
|
-
import
|
|
25880
|
+
import { readFile as readFile38, stat as stat4 } from "fs/promises";
|
|
25881
|
+
import path48 from "path";
|
|
25311
25882
|
import process2 from "process";
|
|
25312
25883
|
|
|
25313
25884
|
// src/context/design-policy.ts
|
|
25314
25885
|
import {
|
|
25315
25886
|
lstat as lstat19,
|
|
25316
|
-
mkdir as
|
|
25317
|
-
readFile as
|
|
25887
|
+
mkdir as mkdir34,
|
|
25888
|
+
readFile as readFile37,
|
|
25318
25889
|
realpath as realpath2,
|
|
25319
|
-
rm as
|
|
25320
|
-
writeFile as
|
|
25890
|
+
rm as rm18,
|
|
25891
|
+
writeFile as writeFile41
|
|
25321
25892
|
} from "fs/promises";
|
|
25322
|
-
import
|
|
25893
|
+
import path47 from "path";
|
|
25323
25894
|
var DEFAULT_DESIGN_POLICY = {
|
|
25324
25895
|
schemaVersion: 1,
|
|
25325
25896
|
revision: 0,
|
|
@@ -25333,8 +25904,8 @@ var DEFAULT_DESIGN_POLICY = {
|
|
|
25333
25904
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
25334
25905
|
};
|
|
25335
25906
|
function designPolicyPath(projectRoot) {
|
|
25336
|
-
return
|
|
25337
|
-
|
|
25907
|
+
return path47.join(
|
|
25908
|
+
path47.resolve(projectRoot),
|
|
25338
25909
|
".mancode",
|
|
25339
25910
|
"shared",
|
|
25340
25911
|
"context",
|
|
@@ -25405,10 +25976,10 @@ function parseDesignPolicy(value) {
|
|
|
25405
25976
|
async function readDesignPolicy(projectRoot) {
|
|
25406
25977
|
try {
|
|
25407
25978
|
return parseDesignPolicy(
|
|
25408
|
-
JSON.parse(await
|
|
25979
|
+
JSON.parse(await readFile37(designPolicyPath(projectRoot), "utf8"))
|
|
25409
25980
|
);
|
|
25410
25981
|
} catch (error) {
|
|
25411
|
-
if (
|
|
25982
|
+
if (isNotFound28(error)) return null;
|
|
25412
25983
|
if (error instanceof SyntaxError) {
|
|
25413
25984
|
throw new Error(
|
|
25414
25985
|
"MANCODE_CONTEXT_ENTITY_CORRUPT: shared/context/design-policy.json"
|
|
@@ -25422,7 +25993,7 @@ async function configureDesignPolicy(input) {
|
|
|
25422
25993
|
const operationId = input.operationId ?? createUlid();
|
|
25423
25994
|
assertUlid(operationId, "design policy operationId");
|
|
25424
25995
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
25425
|
-
const root =
|
|
25996
|
+
const root = path47.resolve(input.projectRoot);
|
|
25426
25997
|
const runtime = await readProjectRuntimeContext(root);
|
|
25427
25998
|
const store = resolveCoordinationEntityHomeStore(
|
|
25428
25999
|
runtime.entityHomeStoreContext
|
|
@@ -25477,12 +26048,12 @@ function isDesignBrowserValidation(value) {
|
|
|
25477
26048
|
}
|
|
25478
26049
|
async function writeDesignPolicy(projectRoot, policy) {
|
|
25479
26050
|
const target = designPolicyPath(projectRoot);
|
|
25480
|
-
await
|
|
25481
|
-
const temporary =
|
|
25482
|
-
|
|
25483
|
-
`.${
|
|
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`
|
|
25484
26055
|
);
|
|
25485
|
-
await
|
|
26056
|
+
await writeFile41(temporary, `${JSON.stringify(policy, null, 2)}
|
|
25486
26057
|
`, {
|
|
25487
26058
|
encoding: "utf8",
|
|
25488
26059
|
flag: "wx"
|
|
@@ -25490,17 +26061,17 @@ async function writeDesignPolicy(projectRoot, policy) {
|
|
|
25490
26061
|
try {
|
|
25491
26062
|
await replaceFileAtomically(temporary, target);
|
|
25492
26063
|
} finally {
|
|
25493
|
-
await
|
|
26064
|
+
await rm18(temporary, { force: true }).catch(() => void 0);
|
|
25494
26065
|
}
|
|
25495
26066
|
}
|
|
25496
26067
|
async function assertDesignPolicyPathSafe(projectRoot) {
|
|
25497
|
-
const root =
|
|
26068
|
+
const root = path47.resolve(projectRoot);
|
|
25498
26069
|
const policyPath = designPolicyPath(root);
|
|
25499
|
-
const contextDir =
|
|
26070
|
+
const contextDir = path47.dirname(policyPath);
|
|
25500
26071
|
try {
|
|
25501
26072
|
for (const directory of [
|
|
25502
|
-
|
|
25503
|
-
|
|
26073
|
+
path47.join(root, ".mancode"),
|
|
26074
|
+
path47.join(root, ".mancode", "shared"),
|
|
25504
26075
|
contextDir
|
|
25505
26076
|
]) {
|
|
25506
26077
|
const info = await lstat19(directory);
|
|
@@ -25512,8 +26083,8 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
25512
26083
|
realpath2(root),
|
|
25513
26084
|
realpath2(contextDir)
|
|
25514
26085
|
]);
|
|
25515
|
-
const relative =
|
|
25516
|
-
if (
|
|
26086
|
+
const relative = path47.relative(resolvedRoot, resolvedContextDir);
|
|
26087
|
+
if (path47.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path47.sep}`)) {
|
|
25517
26088
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
25518
26089
|
}
|
|
25519
26090
|
try {
|
|
@@ -25522,7 +26093,7 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
25522
26093
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
25523
26094
|
}
|
|
25524
26095
|
} catch (error) {
|
|
25525
|
-
if (!
|
|
26096
|
+
if (!isNotFound28(error)) throw error;
|
|
25526
26097
|
}
|
|
25527
26098
|
} catch (error) {
|
|
25528
26099
|
if (error instanceof Error && error.message === "MANCODE_DESIGN_POLICY_PATH_UNSAFE") {
|
|
@@ -25539,7 +26110,7 @@ function assertNonNegativeRevision(value) {
|
|
|
25539
26110
|
function isPositiveInteger(value) {
|
|
25540
26111
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
25541
26112
|
}
|
|
25542
|
-
function
|
|
26113
|
+
function isNotFound28(error) {
|
|
25543
26114
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
25544
26115
|
}
|
|
25545
26116
|
|
|
@@ -25756,8 +26327,8 @@ async function readProfile(rootDir, kind) {
|
|
|
25756
26327
|
}
|
|
25757
26328
|
try {
|
|
25758
26329
|
return JSON.parse(
|
|
25759
|
-
await
|
|
25760
|
-
|
|
26330
|
+
await readFile38(
|
|
26331
|
+
path48.join(rootDir, ".mancode", "project-profile.json"),
|
|
25761
26332
|
"utf8"
|
|
25762
26333
|
)
|
|
25763
26334
|
);
|
|
@@ -25766,9 +26337,9 @@ async function readProfile(rootDir, kind) {
|
|
|
25766
26337
|
}
|
|
25767
26338
|
}
|
|
25768
26339
|
async function readStyleSummary(rootDir, kind) {
|
|
25769
|
-
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");
|
|
25770
26341
|
try {
|
|
25771
|
-
const raw = JSON.parse(await
|
|
26342
|
+
const raw = JSON.parse(await readFile38(cachePath, "utf8"));
|
|
25772
26343
|
return sanitizeStyleSummary(rootDir, raw);
|
|
25773
26344
|
} catch {
|
|
25774
26345
|
return emptyStyleSummary();
|
|
@@ -25807,7 +26378,7 @@ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
|
|
|
25807
26378
|
const scannedAt = Date.parse(lastScanned);
|
|
25808
26379
|
for (const file of sourceFiles) {
|
|
25809
26380
|
try {
|
|
25810
|
-
const info = await stat4(
|
|
26381
|
+
const info = await stat4(path48.resolve(rootDir, scopeRoot, file));
|
|
25811
26382
|
if (info.mtimeMs > scannedAt) return "stale";
|
|
25812
26383
|
} catch {
|
|
25813
26384
|
return "stale";
|
|
@@ -25877,10 +26448,10 @@ function emptyStyleSummary() {
|
|
|
25877
26448
|
};
|
|
25878
26449
|
}
|
|
25879
26450
|
async function initializedKind(rootDir) {
|
|
25880
|
-
if (await exists(
|
|
26451
|
+
if (await exists(path48.join(rootDir, ".mancode", "schema.json"))) {
|
|
25881
26452
|
return "continuity";
|
|
25882
26453
|
}
|
|
25883
|
-
if (await exists(
|
|
26454
|
+
if (await exists(path48.join(rootDir, ".mancode", "state.json")))
|
|
25884
26455
|
return "legacy";
|
|
25885
26456
|
return null;
|
|
25886
26457
|
}
|
|
@@ -25945,7 +26516,7 @@ function safeShortText(value) {
|
|
|
25945
26516
|
return typeof value === "string" && value.length <= 100 && /^[A-Za-z0-9@/_. -]+$/.test(value) ? value : null;
|
|
25946
26517
|
}
|
|
25947
26518
|
function isSafeRelativeFile(value) {
|
|
25948
|
-
return value.length <= 240 && !
|
|
26519
|
+
return value.length <= 240 && !path48.isAbsolute(value) && !value.includes("\0") && value.split(/[\\/]/).every((part) => part !== "" && part !== "." && part !== "..");
|
|
25949
26520
|
}
|
|
25950
26521
|
function parseNonNegativeInteger2(value) {
|
|
25951
26522
|
if (value === void 0 || !/^\d+$/.test(value)) return null;
|
|
@@ -25953,7 +26524,7 @@ function parseNonNegativeInteger2(value) {
|
|
|
25953
26524
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
25954
26525
|
}
|
|
25955
26526
|
function relativePath(rootDir, target) {
|
|
25956
|
-
return
|
|
26527
|
+
return path48.relative(path48.resolve(rootDir), target).split(path48.sep).join("/");
|
|
25957
26528
|
}
|
|
25958
26529
|
function isRecord6(value) {
|
|
25959
26530
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -25985,12 +26556,12 @@ function errorCode3(error, fallback) {
|
|
|
25985
26556
|
// src/commands/init.ts
|
|
25986
26557
|
import { promises as fs4 } from "fs";
|
|
25987
26558
|
import os from "os";
|
|
25988
|
-
import
|
|
26559
|
+
import path54 from "path";
|
|
25989
26560
|
import process6 from "process";
|
|
25990
26561
|
|
|
25991
26562
|
// src/installers/platform-status.ts
|
|
25992
26563
|
import { promises as fs } from "fs";
|
|
25993
|
-
import
|
|
26564
|
+
import path49 from "path";
|
|
25994
26565
|
async function checkPlatformStatus(rootDir, platform, installed) {
|
|
25995
26566
|
const readiness = await checkPlatformReadiness(rootDir, platform);
|
|
25996
26567
|
return {
|
|
@@ -26007,13 +26578,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26007
26578
|
if (platform === "claude-code") {
|
|
26008
26579
|
const [hasSoloSkill, registered, hasHookFiles] = await Promise.all([
|
|
26009
26580
|
fileMatches(
|
|
26010
|
-
|
|
26581
|
+
path49.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
|
|
26011
26582
|
(content) => isGeneratedClaudeSkill(content, "solo")
|
|
26012
26583
|
),
|
|
26013
26584
|
claudeHooksRegistered(rootDir),
|
|
26014
26585
|
pathsExist([
|
|
26015
|
-
|
|
26016
|
-
|
|
26586
|
+
path49.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
|
|
26587
|
+
path49.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
26017
26588
|
])
|
|
26018
26589
|
]);
|
|
26019
26590
|
const present = hasSoloSkill && registered && hasHookFiles;
|
|
@@ -26029,7 +26600,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26029
26600
|
if (platform === "cursor") {
|
|
26030
26601
|
const hasCoreRules = await allManagedSkills(
|
|
26031
26602
|
MANCODE_CURSOR_CORE_RULE_FILES.map(
|
|
26032
|
-
(file) =>
|
|
26603
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
26033
26604
|
),
|
|
26034
26605
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26035
26606
|
);
|
|
@@ -26044,13 +26615,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26044
26615
|
const [hasRules, hasCommands] = await Promise.all([
|
|
26045
26616
|
allManagedSkills(
|
|
26046
26617
|
MANCODE_CURSOR_RULE_FILES.map(
|
|
26047
|
-
(file) =>
|
|
26618
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
26048
26619
|
),
|
|
26049
26620
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26050
26621
|
),
|
|
26051
26622
|
allManagedSkills(
|
|
26052
26623
|
MODE_NAMES.map(
|
|
26053
|
-
(mode) =>
|
|
26624
|
+
(mode) => path49.join(rootDir, ".cursor", "commands", `${mode}.md`)
|
|
26054
26625
|
),
|
|
26055
26626
|
[MODE_FILE_MANAGED_MARKER]
|
|
26056
26627
|
)
|
|
@@ -26063,7 +26634,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26063
26634
|
};
|
|
26064
26635
|
}
|
|
26065
26636
|
if (platform === "codex") {
|
|
26066
|
-
const hasBlock2 = await fileHasManagedBlock(
|
|
26637
|
+
const hasBlock2 = await fileHasManagedBlock(path49.join(rootDir, "AGENTS.md"));
|
|
26067
26638
|
if (!hasBlock2) {
|
|
26068
26639
|
return {
|
|
26069
26640
|
present: false,
|
|
@@ -26080,9 +26651,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26080
26651
|
readyDetail: "managed block present"
|
|
26081
26652
|
};
|
|
26082
26653
|
}
|
|
26083
|
-
const skillsDir =
|
|
26654
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26084
26655
|
const hasSkills = await allManagedSkills(
|
|
26085
|
-
MODE_NAMES.map((mode) =>
|
|
26656
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26086
26657
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26087
26658
|
);
|
|
26088
26659
|
return {
|
|
@@ -26094,7 +26665,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26094
26665
|
}
|
|
26095
26666
|
if (platform === "zcode") {
|
|
26096
26667
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26097
|
-
|
|
26668
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26098
26669
|
ZCODE_MANCODE_START_MARKER,
|
|
26099
26670
|
ZCODE_MANCODE_END_MARKER
|
|
26100
26671
|
);
|
|
@@ -26114,9 +26685,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26114
26685
|
readyDetail: "managed block present"
|
|
26115
26686
|
};
|
|
26116
26687
|
}
|
|
26117
|
-
const skillsDir =
|
|
26688
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26118
26689
|
const hasSkills = await allManagedSkills(
|
|
26119
|
-
MODE_NAMES.map((mode) =>
|
|
26690
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26120
26691
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26121
26692
|
);
|
|
26122
26693
|
return {
|
|
@@ -26126,8 +26697,76 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26126
26697
|
readyDetail: hasSkills ? "managed block and skills present" : "mode skills are missing, incomplete, or user-authored"
|
|
26127
26698
|
};
|
|
26128
26699
|
}
|
|
26700
|
+
if (platform === "kimi-code") {
|
|
26701
|
+
const hasBlock2 = await fileHasManagedBlock(
|
|
26702
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26703
|
+
KIMI_MANCODE_START_MARKER,
|
|
26704
|
+
KIMI_MANCODE_END_MARKER
|
|
26705
|
+
);
|
|
26706
|
+
if (!hasBlock2) {
|
|
26707
|
+
return {
|
|
26708
|
+
present: false,
|
|
26709
|
+
ready: false,
|
|
26710
|
+
target: "AGENTS.md",
|
|
26711
|
+
readyDetail: "managed block missing"
|
|
26712
|
+
};
|
|
26713
|
+
}
|
|
26714
|
+
if (await isPlatformMinimal(rootDir, "kimi-code")) {
|
|
26715
|
+
return {
|
|
26716
|
+
present: true,
|
|
26717
|
+
ready: true,
|
|
26718
|
+
target: "AGENTS.md",
|
|
26719
|
+
readyDetail: "managed block present"
|
|
26720
|
+
};
|
|
26721
|
+
}
|
|
26722
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
26723
|
+
const hasSkills = await allManagedSkills(
|
|
26724
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
26725
|
+
MANCODE_AGENT_SKILL_MARKERS
|
|
26726
|
+
);
|
|
26727
|
+
return {
|
|
26728
|
+
present: true,
|
|
26729
|
+
ready: hasSkills,
|
|
26730
|
+
target: "AGENTS.md + .agents/skills/",
|
|
26731
|
+
readyDetail: hasSkills ? "managed block and skills present" : "mode skills are missing, incomplete, or user-authored"
|
|
26732
|
+
};
|
|
26733
|
+
}
|
|
26734
|
+
if (platform === "qoder") {
|
|
26735
|
+
const hasBlock2 = await fileHasManagedBlock(
|
|
26736
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
26737
|
+
QODER_MANCODE_START_MARKER,
|
|
26738
|
+
QODER_MANCODE_END_MARKER
|
|
26739
|
+
);
|
|
26740
|
+
if (!hasBlock2) {
|
|
26741
|
+
return {
|
|
26742
|
+
present: false,
|
|
26743
|
+
ready: false,
|
|
26744
|
+
target: "AGENTS.md",
|
|
26745
|
+
readyDetail: "managed block missing"
|
|
26746
|
+
};
|
|
26747
|
+
}
|
|
26748
|
+
if (await isPlatformMinimal(rootDir, "qoder")) {
|
|
26749
|
+
return {
|
|
26750
|
+
present: true,
|
|
26751
|
+
ready: true,
|
|
26752
|
+
target: "AGENTS.md",
|
|
26753
|
+
readyDetail: "managed block present"
|
|
26754
|
+
};
|
|
26755
|
+
}
|
|
26756
|
+
const commandsDir = path49.join(rootDir, ".qoder", "commands");
|
|
26757
|
+
const hasCommands = await allManagedSkills(
|
|
26758
|
+
MODE_NAMES.map((mode) => path49.join(commandsDir, `${mode}.md`)),
|
|
26759
|
+
[MODE_FILE_MANAGED_MARKER]
|
|
26760
|
+
);
|
|
26761
|
+
return {
|
|
26762
|
+
present: true,
|
|
26763
|
+
ready: hasCommands,
|
|
26764
|
+
target: "AGENTS.md + .qoder/commands/",
|
|
26765
|
+
readyDetail: hasCommands ? "managed block and commands present" : "mode commands are missing, incomplete, or user-authored"
|
|
26766
|
+
};
|
|
26767
|
+
}
|
|
26129
26768
|
const hasBlock = await fileHasManagedBlock(
|
|
26130
|
-
|
|
26769
|
+
path49.join(rootDir, ".github", "copilot-instructions.md")
|
|
26131
26770
|
);
|
|
26132
26771
|
if (!hasBlock) {
|
|
26133
26772
|
return {
|
|
@@ -26138,9 +26777,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26138
26777
|
};
|
|
26139
26778
|
}
|
|
26140
26779
|
if (!await isPlatformMinimal(rootDir, "copilot")) {
|
|
26141
|
-
const promptsDir =
|
|
26780
|
+
const promptsDir = path49.join(rootDir, ".github", "prompts");
|
|
26142
26781
|
const hasPrompts = await allManagedSkills(
|
|
26143
|
-
MODE_NAMES.map((mode) =>
|
|
26782
|
+
MODE_NAMES.map((mode) => path49.join(promptsDir, `${mode}.prompt.md`)),
|
|
26144
26783
|
[MODE_FILE_MANAGED_MARKER]
|
|
26145
26784
|
);
|
|
26146
26785
|
return {
|
|
@@ -26173,13 +26812,13 @@ async function allManagedSkills(paths, markers) {
|
|
|
26173
26812
|
async function claudeFullContentReady(rootDir) {
|
|
26174
26813
|
const skillChecks = MVP2_SKILLS.map(
|
|
26175
26814
|
(skill) => fileMatches(
|
|
26176
|
-
|
|
26815
|
+
path49.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
|
|
26177
26816
|
(content) => isGeneratedClaudeSkill(content, skill.name)
|
|
26178
26817
|
)
|
|
26179
26818
|
);
|
|
26180
26819
|
const agentChecks = ALL_AGENTS.map(
|
|
26181
26820
|
(agent) => fileMatches(
|
|
26182
|
-
|
|
26821
|
+
path49.join(rootDir, ".claude", "agents", `${agent.name}.md`),
|
|
26183
26822
|
(content) => isGeneratedClaudeAgent(content, agent.name)
|
|
26184
26823
|
)
|
|
26185
26824
|
);
|
|
@@ -26207,7 +26846,7 @@ async function fileHasAnyMarker(filePath, needles) {
|
|
|
26207
26846
|
async function isPlatformMinimal(rootDir, platform) {
|
|
26208
26847
|
try {
|
|
26209
26848
|
const raw = await fs.readFile(
|
|
26210
|
-
|
|
26849
|
+
path49.join(rootDir, ".mancode", "config.json"),
|
|
26211
26850
|
"utf-8"
|
|
26212
26851
|
);
|
|
26213
26852
|
const config = JSON.parse(raw);
|
|
@@ -26229,7 +26868,7 @@ async function fileHasManagedBlock(filePath, startMarker = DEFAULT_MANCODE_START
|
|
|
26229
26868
|
async function claudeHooksRegistered(rootDir) {
|
|
26230
26869
|
try {
|
|
26231
26870
|
const raw = await fs.readFile(
|
|
26232
|
-
|
|
26871
|
+
path49.join(rootDir, ".claude", "settings.json"),
|
|
26233
26872
|
"utf-8"
|
|
26234
26873
|
);
|
|
26235
26874
|
const settings = JSON.parse(raw);
|
|
@@ -26272,7 +26911,7 @@ function isRecord7(value) {
|
|
|
26272
26911
|
// src/system/detect-team.ts
|
|
26273
26912
|
import { execFile as execFile6 } from "child_process";
|
|
26274
26913
|
import { access as access2 } from "fs/promises";
|
|
26275
|
-
import
|
|
26914
|
+
import path50 from "path";
|
|
26276
26915
|
import process3 from "process";
|
|
26277
26916
|
import { promisify as promisify6 } from "util";
|
|
26278
26917
|
var execFileAsync = promisify6(execFile6);
|
|
@@ -26382,7 +27021,7 @@ async function anyPathExists(projectRoot, candidates) {
|
|
|
26382
27021
|
const results = await Promise.all(
|
|
26383
27022
|
candidates.map(async (candidate) => {
|
|
26384
27023
|
try {
|
|
26385
|
-
await access2(
|
|
27024
|
+
await access2(path50.join(projectRoot, candidate));
|
|
26386
27025
|
return true;
|
|
26387
27026
|
} catch {
|
|
26388
27027
|
return false;
|
|
@@ -26423,7 +27062,7 @@ async function detectSystemDeps(env = process4.env) {
|
|
|
26423
27062
|
// src/system/init-onboarding.ts
|
|
26424
27063
|
import { execFileSync } from "child_process";
|
|
26425
27064
|
import { promises as fs2 } from "fs";
|
|
26426
|
-
import
|
|
27065
|
+
import path51 from "path";
|
|
26427
27066
|
import process5 from "process";
|
|
26428
27067
|
import { stdin, stdout } from "process";
|
|
26429
27068
|
import { createInterface } from "readline/promises";
|
|
@@ -26528,7 +27167,7 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
26528
27167
|
hints.add("copilot");
|
|
26529
27168
|
const exists2 = async (relative) => {
|
|
26530
27169
|
try {
|
|
26531
|
-
await fs2.access(
|
|
27170
|
+
await fs2.access(path51.join(rootDir, relative));
|
|
26532
27171
|
return true;
|
|
26533
27172
|
} catch {
|
|
26534
27173
|
return false;
|
|
@@ -26537,6 +27176,7 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
26537
27176
|
if (await exists2(".claude")) hints.add("claude-code");
|
|
26538
27177
|
if (await exists2(".cursor")) hints.add("cursor");
|
|
26539
27178
|
if (await exists2(".github/copilot-instructions.md")) hints.add("copilot");
|
|
27179
|
+
if (await exists2(".qoder")) hints.add("qoder");
|
|
26540
27180
|
return ALL_PLATFORMS.filter((platform) => hints.has(platform));
|
|
26541
27181
|
}
|
|
26542
27182
|
function createTerminalPrompter() {
|
|
@@ -26604,7 +27244,7 @@ function createTerminalPrompter() {
|
|
|
26604
27244
|
|
|
26605
27245
|
// src/system/scan-aesthetics.ts
|
|
26606
27246
|
import { promises as fs3 } from "fs";
|
|
26607
|
-
import
|
|
27247
|
+
import path52 from "path";
|
|
26608
27248
|
var MAX_COMPONENT_SCAN_DEPTH = 12;
|
|
26609
27249
|
var MAX_COMPONENT_FILES = 2e3;
|
|
26610
27250
|
async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
@@ -26640,7 +27280,7 @@ async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
|
26640
27280
|
} else if (await hasTailwindDep(projectRoot) || uiLibrary) {
|
|
26641
27281
|
matchLevel = "low";
|
|
26642
27282
|
}
|
|
26643
|
-
if (uiLibrary && await pathExists5(
|
|
27283
|
+
if (uiLibrary && await pathExists5(path52.join(projectRoot, "package.json"))) {
|
|
26644
27284
|
sourceFiles.push("package.json");
|
|
26645
27285
|
}
|
|
26646
27286
|
sourceFiles.push(...cssScan.sourceFiles);
|
|
@@ -26666,7 +27306,7 @@ async function findTailwindConfig(projectRoot) {
|
|
|
26666
27306
|
"tailwind.config.mjs"
|
|
26667
27307
|
];
|
|
26668
27308
|
for (const name of candidates) {
|
|
26669
|
-
const absPath =
|
|
27309
|
+
const absPath = path52.join(projectRoot, name);
|
|
26670
27310
|
if (await pathExists5(absPath)) {
|
|
26671
27311
|
return { absPath, relPath: name };
|
|
26672
27312
|
}
|
|
@@ -26893,7 +27533,7 @@ async function scanComponents(projectRoot) {
|
|
|
26893
27533
|
const names = /* @__PURE__ */ new Set();
|
|
26894
27534
|
let visitedFiles = 0;
|
|
26895
27535
|
for (const relRoot of roots) {
|
|
26896
|
-
const absRoot =
|
|
27536
|
+
const absRoot = path52.join(projectRoot, relRoot);
|
|
26897
27537
|
if (!await pathExists5(absRoot)) continue;
|
|
26898
27538
|
visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);
|
|
26899
27539
|
if (visitedFiles >= MAX_COMPONENT_FILES) break;
|
|
@@ -26913,7 +27553,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
26913
27553
|
}
|
|
26914
27554
|
for (const entry of entries) {
|
|
26915
27555
|
if (fileCount >= MAX_COMPONENT_FILES) return fileCount;
|
|
26916
|
-
const abs =
|
|
27556
|
+
const abs = path52.join(dir, entry);
|
|
26917
27557
|
let info;
|
|
26918
27558
|
try {
|
|
26919
27559
|
info = await fs3.lstat(abs);
|
|
@@ -26934,7 +27574,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
26934
27574
|
""
|
|
26935
27575
|
);
|
|
26936
27576
|
if (base === "index") {
|
|
26937
|
-
base =
|
|
27577
|
+
base = path52.basename(dir);
|
|
26938
27578
|
}
|
|
26939
27579
|
if (base.startsWith(".")) continue;
|
|
26940
27580
|
const componentName = toPascalCase(base);
|
|
@@ -26956,7 +27596,7 @@ async function scanCssVariables(projectRoot) {
|
|
|
26956
27596
|
const variables = {};
|
|
26957
27597
|
const sourceFiles = [];
|
|
26958
27598
|
for (const relPath of candidates) {
|
|
26959
|
-
const absPath =
|
|
27599
|
+
const absPath = path52.join(projectRoot, relPath);
|
|
26960
27600
|
if (!await pathExists5(absPath)) continue;
|
|
26961
27601
|
const content = await fs3.readFile(absPath, "utf-8");
|
|
26962
27602
|
const found = extractCssVariables(content);
|
|
@@ -27002,7 +27642,7 @@ function toPascalCase(value) {
|
|
|
27002
27642
|
async function hasTailwindDep(projectRoot) {
|
|
27003
27643
|
try {
|
|
27004
27644
|
const raw = await fs3.readFile(
|
|
27005
|
-
|
|
27645
|
+
path52.join(projectRoot, "package.json"),
|
|
27006
27646
|
"utf-8"
|
|
27007
27647
|
);
|
|
27008
27648
|
const pkg = JSON.parse(raw);
|
|
@@ -27028,14 +27668,14 @@ async function pathExists5(p) {
|
|
|
27028
27668
|
// src/context/greenfield-init.ts
|
|
27029
27669
|
import {
|
|
27030
27670
|
lstat as lstat20,
|
|
27031
|
-
mkdir as
|
|
27032
|
-
readFile as
|
|
27033
|
-
rename as
|
|
27034
|
-
rm as
|
|
27035
|
-
writeFile as
|
|
27671
|
+
mkdir as mkdir35,
|
|
27672
|
+
readFile as readFile39,
|
|
27673
|
+
rename as rename11,
|
|
27674
|
+
rm as rm19,
|
|
27675
|
+
writeFile as writeFile42
|
|
27036
27676
|
} from "fs/promises";
|
|
27037
|
-
import
|
|
27038
|
-
var JOURNAL_RELATIVE_DIRECTORY =
|
|
27677
|
+
import path53 from "path";
|
|
27678
|
+
var JOURNAL_RELATIVE_DIRECTORY = path53.join(
|
|
27039
27679
|
"local",
|
|
27040
27680
|
"runtime",
|
|
27041
27681
|
"initialization"
|
|
@@ -27058,7 +27698,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27058
27698
|
normalized.operationId
|
|
27059
27699
|
);
|
|
27060
27700
|
try {
|
|
27061
|
-
await
|
|
27701
|
+
await mkdir35(stagingRoot);
|
|
27062
27702
|
} catch (error) {
|
|
27063
27703
|
if (isAlreadyExists22(error)) {
|
|
27064
27704
|
throw new Error("MANCODE_GREENFIELD_STAGING_EXISTS");
|
|
@@ -27084,7 +27724,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27084
27724
|
operationId: normalized.operationId,
|
|
27085
27725
|
workspaceId: normalized.workspaceId,
|
|
27086
27726
|
state: "staged",
|
|
27087
|
-
stagingDirectoryName:
|
|
27727
|
+
stagingDirectoryName: path53.basename(stagingRoot),
|
|
27088
27728
|
targetDirectoryName: ".mancode",
|
|
27089
27729
|
manifestDigest: digestCanonicalJson(manifest),
|
|
27090
27730
|
configDigest: digestCanonicalJson(config),
|
|
@@ -27115,7 +27755,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27115
27755
|
return journal;
|
|
27116
27756
|
}
|
|
27117
27757
|
async function publishGreenfieldInitialization(input) {
|
|
27118
|
-
const root =
|
|
27758
|
+
const root = path53.resolve(input.projectRoot);
|
|
27119
27759
|
assertUlid(input.operationId, "greenfield operationId");
|
|
27120
27760
|
const stagingRoot = greenfieldStagingPath(root, input.operationId);
|
|
27121
27761
|
const targetRoot = greenfieldTargetPath(root);
|
|
@@ -27133,7 +27773,7 @@ async function publishGreenfieldInitialization(input) {
|
|
|
27133
27773
|
if (await lstatOrNull4(targetRoot) !== null) {
|
|
27134
27774
|
throw new Error("MANCODE_V3_TARGET_EXISTS");
|
|
27135
27775
|
}
|
|
27136
|
-
await
|
|
27776
|
+
await rename11(stagingRoot, targetRoot);
|
|
27137
27777
|
throwIfOperationCrashInjected("greenfield_initialize", "publish-v3-root");
|
|
27138
27778
|
return finishPublishedInitialization(
|
|
27139
27779
|
{ ...input, projectRoot: root },
|
|
@@ -27150,10 +27790,10 @@ async function initializeGreenfield(input, publication) {
|
|
|
27150
27790
|
}
|
|
27151
27791
|
function greenfieldStagingPath(projectRoot, operationId) {
|
|
27152
27792
|
assertUlid(operationId, "greenfield operationId");
|
|
27153
|
-
return
|
|
27793
|
+
return path53.join(path53.resolve(projectRoot), `.mancode.init-${operationId}`);
|
|
27154
27794
|
}
|
|
27155
27795
|
function greenfieldTargetPath(projectRoot) {
|
|
27156
|
-
return
|
|
27796
|
+
return path53.join(path53.resolve(projectRoot), ".mancode");
|
|
27157
27797
|
}
|
|
27158
27798
|
function parseGreenfieldInitializationJournal(value) {
|
|
27159
27799
|
assertRecord(value, "greenfield initialization journal");
|
|
@@ -27224,8 +27864,8 @@ function parseGreenfieldInitializationJournal(value) {
|
|
|
27224
27864
|
),
|
|
27225
27865
|
adapterPlans: parseAdapterPlans(value.adapterPlans),
|
|
27226
27866
|
bindingRegistered: value.bindingRegistered,
|
|
27227
|
-
createdAt:
|
|
27228
|
-
updatedAt:
|
|
27867
|
+
createdAt: parseTimestamp15(value.createdAt, "createdAt"),
|
|
27868
|
+
updatedAt: parseTimestamp15(value.updatedAt, "updatedAt")
|
|
27229
27869
|
};
|
|
27230
27870
|
}
|
|
27231
27871
|
async function finishPublishedInitialization(input, stagedJournal) {
|
|
@@ -27289,7 +27929,7 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
27289
27929
|
activatedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
27290
27930
|
};
|
|
27291
27931
|
assertSchemaManifestTransition(manifest, activeManifest);
|
|
27292
|
-
await writeJson(
|
|
27932
|
+
await writeJson(path53.join(targetRoot, "schema.json"), activeManifest);
|
|
27293
27933
|
throwIfOperationCrashInjected(
|
|
27294
27934
|
"greenfield_initialize",
|
|
27295
27935
|
"activate-v3-manifest"
|
|
@@ -27305,46 +27945,46 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
27305
27945
|
}
|
|
27306
27946
|
async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, projectFacts, journal) {
|
|
27307
27947
|
await Promise.all([
|
|
27308
|
-
|
|
27309
|
-
|
|
27948
|
+
mkdir35(path53.join(stagingRoot, "shared", "context"), { recursive: true }),
|
|
27949
|
+
mkdir35(path53.join(stagingRoot, "shared", "memory", "decisions"), {
|
|
27310
27950
|
recursive: true
|
|
27311
27951
|
}),
|
|
27312
|
-
|
|
27952
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "actors"), {
|
|
27313
27953
|
recursive: true
|
|
27314
27954
|
}),
|
|
27315
|
-
|
|
27955
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "handoffs"), {
|
|
27316
27956
|
recursive: true
|
|
27317
27957
|
}),
|
|
27318
|
-
|
|
27958
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "events"), {
|
|
27319
27959
|
recursive: true
|
|
27320
27960
|
}),
|
|
27321
|
-
|
|
27961
|
+
mkdir35(path53.join(stagingRoot, "shared", "team", "transport"), {
|
|
27322
27962
|
recursive: true
|
|
27323
27963
|
}),
|
|
27324
|
-
|
|
27325
|
-
|
|
27964
|
+
mkdir35(path53.join(stagingRoot, "local", "sessions"), { recursive: true }),
|
|
27965
|
+
mkdir35(path53.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
|
|
27326
27966
|
recursive: true
|
|
27327
27967
|
}),
|
|
27328
|
-
|
|
27329
|
-
|
|
27330
|
-
|
|
27331
|
-
|
|
27332
|
-
|
|
27333
|
-
|
|
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), {
|
|
27334
27974
|
recursive: true
|
|
27335
27975
|
})
|
|
27336
27976
|
]);
|
|
27337
27977
|
await Promise.all([
|
|
27338
|
-
writeJson(
|
|
27339
|
-
writeJson(
|
|
27340
|
-
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),
|
|
27341
27981
|
writeJson(
|
|
27342
|
-
|
|
27982
|
+
path53.join(stagingRoot, "shared", "context", "project.json"),
|
|
27343
27983
|
projectFacts
|
|
27344
27984
|
),
|
|
27345
27985
|
writeJson(journalPath2(stagingRoot, journal.operationId), journal),
|
|
27346
|
-
|
|
27347
|
-
|
|
27986
|
+
writeFile42(
|
|
27987
|
+
path53.join(stagingRoot, ".gitignore"),
|
|
27348
27988
|
`${V3_IGNORE.join("\n")}
|
|
27349
27989
|
`,
|
|
27350
27990
|
{ encoding: "utf8", flag: "wx" }
|
|
@@ -27353,14 +27993,14 @@ async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, proj
|
|
|
27353
27993
|
}
|
|
27354
27994
|
async function readGreenfieldJournal(root, operationId) {
|
|
27355
27995
|
try {
|
|
27356
|
-
const raw = await
|
|
27996
|
+
const raw = await readFile39(journalPath2(root, operationId), "utf8");
|
|
27357
27997
|
const journal = parseGreenfieldInitializationJournal(JSON.parse(raw));
|
|
27358
27998
|
if (journal.operationId !== operationId) {
|
|
27359
27999
|
throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
|
|
27360
28000
|
}
|
|
27361
28001
|
return journal;
|
|
27362
28002
|
} catch (error) {
|
|
27363
|
-
if (error instanceof SyntaxError ||
|
|
28003
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27364
28004
|
throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
|
|
27365
28005
|
}
|
|
27366
28006
|
throw error;
|
|
@@ -27369,10 +28009,10 @@ async function readGreenfieldJournal(root, operationId) {
|
|
|
27369
28009
|
async function readManifest(root) {
|
|
27370
28010
|
try {
|
|
27371
28011
|
return parseSchemaManifest(
|
|
27372
|
-
JSON.parse(await
|
|
28012
|
+
JSON.parse(await readFile39(path53.join(root, "schema.json"), "utf8"))
|
|
27373
28013
|
);
|
|
27374
28014
|
} catch (error) {
|
|
27375
|
-
if (error instanceof SyntaxError ||
|
|
28015
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27376
28016
|
throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
|
|
27377
28017
|
}
|
|
27378
28018
|
throw error;
|
|
@@ -27407,7 +28047,7 @@ async function readConfig(root) {
|
|
|
27407
28047
|
try {
|
|
27408
28048
|
config = parseProjectConfig(
|
|
27409
28049
|
JSON.parse(
|
|
27410
|
-
await
|
|
28050
|
+
await readFile39(path53.join(root, "shared", "config.json"), "utf8")
|
|
27411
28051
|
)
|
|
27412
28052
|
);
|
|
27413
28053
|
} catch (error) {
|
|
@@ -27423,8 +28063,8 @@ async function readPolicy(root) {
|
|
|
27423
28063
|
try {
|
|
27424
28064
|
policy = parseTeamPolicy(
|
|
27425
28065
|
JSON.parse(
|
|
27426
|
-
await
|
|
27427
|
-
|
|
28066
|
+
await readFile39(
|
|
28067
|
+
path53.join(root, "shared", "team", "policy.json"),
|
|
27428
28068
|
"utf8"
|
|
27429
28069
|
)
|
|
27430
28070
|
)
|
|
@@ -27441,14 +28081,14 @@ async function readProjectFactsAt(root) {
|
|
|
27441
28081
|
try {
|
|
27442
28082
|
return parseProjectFacts(
|
|
27443
28083
|
JSON.parse(
|
|
27444
|
-
await
|
|
27445
|
-
|
|
28084
|
+
await readFile39(
|
|
28085
|
+
path53.join(root, "shared", "context", "project.json"),
|
|
27446
28086
|
"utf8"
|
|
27447
28087
|
)
|
|
27448
28088
|
)
|
|
27449
28089
|
);
|
|
27450
28090
|
} catch (error) {
|
|
27451
|
-
if (error instanceof SyntaxError ||
|
|
28091
|
+
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
27452
28092
|
throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
|
|
27453
28093
|
}
|
|
27454
28094
|
throw error;
|
|
@@ -27481,7 +28121,7 @@ function normalizeInput(input) {
|
|
|
27481
28121
|
parseSchemaManifest(manifest);
|
|
27482
28122
|
return {
|
|
27483
28123
|
...input,
|
|
27484
|
-
projectRoot:
|
|
28124
|
+
projectRoot: path53.resolve(input.projectRoot),
|
|
27485
28125
|
projectConfig: config,
|
|
27486
28126
|
teamPolicy: policy,
|
|
27487
28127
|
projectFacts: input.projectFacts === void 0 ? void 0 : parseProjectFacts(input.projectFacts)
|
|
@@ -27579,21 +28219,21 @@ function initializationProjectFacts(input, now) {
|
|
|
27579
28219
|
}
|
|
27580
28220
|
function journalPath2(root, operationId) {
|
|
27581
28221
|
assertUlid(operationId, "greenfield operationId");
|
|
27582
|
-
return
|
|
28222
|
+
return path53.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
|
|
27583
28223
|
}
|
|
27584
28224
|
async function writeJson(target, value) {
|
|
27585
|
-
const directory =
|
|
27586
|
-
await
|
|
27587
|
-
const temporary =
|
|
28225
|
+
const directory = path53.dirname(target);
|
|
28226
|
+
await mkdir35(directory, { recursive: true });
|
|
28227
|
+
const temporary = path53.join(
|
|
27588
28228
|
directory,
|
|
27589
|
-
`.${
|
|
28229
|
+
`.${path53.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
27590
28230
|
);
|
|
27591
|
-
await
|
|
28231
|
+
await writeFile42(temporary, `${JSON.stringify(value, null, 2)}
|
|
27592
28232
|
`, {
|
|
27593
28233
|
encoding: "utf8",
|
|
27594
28234
|
flag: "wx"
|
|
27595
28235
|
});
|
|
27596
|
-
await
|
|
28236
|
+
await rename11(temporary, target);
|
|
27597
28237
|
}
|
|
27598
28238
|
function parseDigest6(value, label) {
|
|
27599
28239
|
if (typeof value !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value)) {
|
|
@@ -27601,7 +28241,7 @@ function parseDigest6(value, label) {
|
|
|
27601
28241
|
}
|
|
27602
28242
|
return value;
|
|
27603
28243
|
}
|
|
27604
|
-
function
|
|
28244
|
+
function parseTimestamp15(value, label) {
|
|
27605
28245
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
27606
28246
|
throw new Error(`greenfield initialization journal ${label} is invalid`);
|
|
27607
28247
|
}
|
|
@@ -27614,11 +28254,11 @@ async function lstatOrNull4(target) {
|
|
|
27614
28254
|
try {
|
|
27615
28255
|
return await lstat20(target);
|
|
27616
28256
|
} catch (error) {
|
|
27617
|
-
if (
|
|
28257
|
+
if (isNotFound29(error)) return null;
|
|
27618
28258
|
throw error;
|
|
27619
28259
|
}
|
|
27620
28260
|
}
|
|
27621
|
-
function
|
|
28261
|
+
function isNotFound29(error) {
|
|
27622
28262
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
27623
28263
|
}
|
|
27624
28264
|
function isAlreadyExists22(error) {
|
|
@@ -27706,9 +28346,9 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27706
28346
|
return EXIT_INIT_FAILED;
|
|
27707
28347
|
}
|
|
27708
28348
|
const authority = resolveInitAuthority(options);
|
|
27709
|
-
const mancodeDir =
|
|
27710
|
-
const stateFile =
|
|
27711
|
-
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");
|
|
27712
28352
|
const wasInitialized = await pathExists6(stateFile);
|
|
27713
28353
|
let mutationSnapshots = [];
|
|
27714
28354
|
let directorySnapshots = [];
|
|
@@ -27776,7 +28416,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27776
28416
|
}
|
|
27777
28417
|
return initializeV3(rootDir, options);
|
|
27778
28418
|
}
|
|
27779
|
-
const isGitRepo = await pathExists6(
|
|
28419
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
27780
28420
|
const hasManifest = await hasProjectManifest(rootDir);
|
|
27781
28421
|
let isGenericProject = false;
|
|
27782
28422
|
if (!isGitRepo && !hasManifest) {
|
|
@@ -27894,8 +28534,8 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27894
28534
|
const managedFiles = getInitManagedFilePaths(rootDir, selectedPlatforms);
|
|
27895
28535
|
mutationSnapshots = await snapshotFiles(managedFiles);
|
|
27896
28536
|
directorySnapshots = await snapshotDirectories(managedFiles, [
|
|
27897
|
-
|
|
27898
|
-
|
|
28537
|
+
path54.join(mancodeDir, "workflows"),
|
|
28538
|
+
path54.join(mancodeDir, "preseason-reports")
|
|
27899
28539
|
]);
|
|
27900
28540
|
const team = await detectTeamStatus(rootDir);
|
|
27901
28541
|
const platformMinimal = Object.fromEntries(
|
|
@@ -27956,7 +28596,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27956
28596
|
`;
|
|
27957
28597
|
await fs4.writeFile(stateFile, stateContent, "utf-8");
|
|
27958
28598
|
await fs4.writeFile(
|
|
27959
|
-
|
|
28599
|
+
path54.join(mancodeDir, "project-profile.json"),
|
|
27960
28600
|
`${JSON.stringify(profile, null, 2)}
|
|
27961
28601
|
`,
|
|
27962
28602
|
"utf-8"
|
|
@@ -27993,7 +28633,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
27993
28633
|
)
|
|
27994
28634
|
);
|
|
27995
28635
|
const tokens = await scanAesthetics(rootDir, uiLibrary);
|
|
27996
|
-
const tokensPath =
|
|
28636
|
+
const tokensPath = path54.join(
|
|
27997
28637
|
mancodeDir,
|
|
27998
28638
|
"aesthetics",
|
|
27999
28639
|
"style-tokens.json"
|
|
@@ -28157,7 +28797,7 @@ async function initializeV3(rootDir, options) {
|
|
|
28157
28797
|
);
|
|
28158
28798
|
return EXIT_INIT_FAILED;
|
|
28159
28799
|
}
|
|
28160
|
-
const schemaPath =
|
|
28800
|
+
const schemaPath = path54.join(rootDir, ".mancode", "schema.json");
|
|
28161
28801
|
let existingV3 = false;
|
|
28162
28802
|
let registeredAdapters = /* @__PURE__ */ new Set();
|
|
28163
28803
|
if (await pathExists6(schemaPath)) {
|
|
@@ -28260,7 +28900,7 @@ function printV3InitError(error) {
|
|
|
28260
28900
|
}
|
|
28261
28901
|
}
|
|
28262
28902
|
async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms) {
|
|
28263
|
-
const configPath =
|
|
28903
|
+
const configPath = path54.join(mancodeDir, "config.json");
|
|
28264
28904
|
let config = {};
|
|
28265
28905
|
try {
|
|
28266
28906
|
config = JSON.parse(await fs4.readFile(configPath, "utf-8"));
|
|
@@ -28293,7 +28933,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
|
|
|
28293
28933
|
async function readExistingInitPreferences(mancodeDir) {
|
|
28294
28934
|
try {
|
|
28295
28935
|
const config = JSON.parse(
|
|
28296
|
-
await fs4.readFile(
|
|
28936
|
+
await fs4.readFile(path54.join(mancodeDir, "config.json"), "utf-8")
|
|
28297
28937
|
);
|
|
28298
28938
|
const preferences = {
|
|
28299
28939
|
platforms: Array.isArray(config.platforms) ? config.platforms.filter(
|
|
@@ -28359,13 +28999,13 @@ async function selectInitPlatforms(input) {
|
|
|
28359
28999
|
}
|
|
28360
29000
|
async function hasProjectManifest(rootDir) {
|
|
28361
29001
|
for (const name of PROJECT_MANIFESTS) {
|
|
28362
|
-
if (await pathExists6(
|
|
29002
|
+
if (await pathExists6(path54.join(rootDir, name))) return true;
|
|
28363
29003
|
}
|
|
28364
29004
|
return false;
|
|
28365
29005
|
}
|
|
28366
29006
|
async function canInitializeGenericProject(rootDir) {
|
|
28367
|
-
const resolved =
|
|
28368
|
-
if (resolved ===
|
|
29007
|
+
const resolved = path54.resolve(rootDir);
|
|
29008
|
+
if (resolved === path54.parse(resolved).root || resolved === path54.resolve(os.homedir())) {
|
|
28369
29009
|
return { ok: false, reason: "unsafe" };
|
|
28370
29010
|
}
|
|
28371
29011
|
try {
|
|
@@ -28379,11 +29019,11 @@ async function canInitializeGenericProject(rootDir) {
|
|
|
28379
29019
|
}
|
|
28380
29020
|
}
|
|
28381
29021
|
async function validateV3CliProjectBoundary(rootDir, options, locale, legacyInitialized) {
|
|
28382
|
-
const isGitRepo = await pathExists6(
|
|
29022
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
28383
29023
|
const hasManifest = await hasProjectManifest(rootDir);
|
|
28384
29024
|
if (isGitRepo || hasManifest) return null;
|
|
28385
29025
|
const v3Initialized = await pathExists6(
|
|
28386
|
-
|
|
29026
|
+
path54.join(rootDir, ".mancode", "schema.json")
|
|
28387
29027
|
);
|
|
28388
29028
|
const legacyAuthorityPresent = legacyInitialized || (await scanLegacyAuthority(rootDir)).authorityPresent;
|
|
28389
29029
|
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
@@ -28480,7 +29120,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
28480
29120
|
files.push(`.cursor/commands/${mode}.md`);
|
|
28481
29121
|
}
|
|
28482
29122
|
}
|
|
28483
|
-
if (platforms.includes("codex") || platforms.includes("zcode")) {
|
|
29123
|
+
if (platforms.includes("codex") || platforms.includes("zcode") || platforms.includes("kimi-code")) {
|
|
28484
29124
|
files.push(
|
|
28485
29125
|
"AGENTS.md",
|
|
28486
29126
|
".agents/skills/mamba/SKILL.md",
|
|
@@ -28502,6 +29142,12 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
28502
29142
|
files.push(`.zcode/skills/${mode}/SKILL.md`);
|
|
28503
29143
|
}
|
|
28504
29144
|
}
|
|
29145
|
+
if (platforms.includes("qoder")) {
|
|
29146
|
+
files.push("AGENTS.md");
|
|
29147
|
+
for (const mode of MODE_NAMES) {
|
|
29148
|
+
files.push(`.qoder/commands/${mode}.md`);
|
|
29149
|
+
}
|
|
29150
|
+
}
|
|
28505
29151
|
if (platforms.includes("copilot")) {
|
|
28506
29152
|
files.push(
|
|
28507
29153
|
".github/copilot-instructions.md",
|
|
@@ -28512,7 +29158,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
28512
29158
|
files.push(`.github/prompts/${mode}.prompt.md`);
|
|
28513
29159
|
}
|
|
28514
29160
|
}
|
|
28515
|
-
return [...new Set(files.map((file) =>
|
|
29161
|
+
return [...new Set(files.map((file) => path54.join(rootDir, file)))];
|
|
28516
29162
|
}
|
|
28517
29163
|
async function snapshotFiles(filePaths) {
|
|
28518
29164
|
return Promise.all(
|
|
@@ -28531,10 +29177,10 @@ async function snapshotFiles(filePaths) {
|
|
|
28531
29177
|
async function snapshotDirectories(filePaths, additionalDirectories = []) {
|
|
28532
29178
|
const directories = new Set(additionalDirectories);
|
|
28533
29179
|
for (const filePath of filePaths) {
|
|
28534
|
-
let current =
|
|
28535
|
-
while (current !==
|
|
29180
|
+
let current = path54.dirname(filePath);
|
|
29181
|
+
while (current !== path54.dirname(current)) {
|
|
28536
29182
|
directories.add(current);
|
|
28537
|
-
current =
|
|
29183
|
+
current = path54.dirname(current);
|
|
28538
29184
|
}
|
|
28539
29185
|
}
|
|
28540
29186
|
return Promise.all(
|
|
@@ -28550,7 +29196,7 @@ async function restoreFiles(snapshots) {
|
|
|
28550
29196
|
await fs4.rm(snapshot.filePath, { force: true });
|
|
28551
29197
|
continue;
|
|
28552
29198
|
}
|
|
28553
|
-
await fs4.mkdir(
|
|
29199
|
+
await fs4.mkdir(path54.dirname(snapshot.filePath), { recursive: true });
|
|
28554
29200
|
await fs4.writeFile(snapshot.filePath, snapshot.content, "utf-8");
|
|
28555
29201
|
}
|
|
28556
29202
|
}
|
|
@@ -28601,6 +29247,16 @@ function printPlatformCreatedFiles(platform, locale) {
|
|
|
28601
29247
|
console.log(" .agents/skills/ # ZCode mode skills");
|
|
28602
29248
|
return;
|
|
28603
29249
|
}
|
|
29250
|
+
if (platform === "kimi-code") {
|
|
29251
|
+
console.log(" AGENTS.md # Kimi Code managed block");
|
|
29252
|
+
console.log(" .agents/skills/ # Kimi Code mode skills");
|
|
29253
|
+
return;
|
|
29254
|
+
}
|
|
29255
|
+
if (platform === "qoder") {
|
|
29256
|
+
console.log(" AGENTS.md # Qoder managed block");
|
|
29257
|
+
console.log(" .qoder/commands/ # Qoder mode commands");
|
|
29258
|
+
return;
|
|
29259
|
+
}
|
|
28604
29260
|
console.log(" .github/copilot-instructions.md # Copilot instructions");
|
|
28605
29261
|
}
|
|
28606
29262
|
function localize(locale, chinese, english) {
|
|
@@ -28617,15 +29273,15 @@ async function pathExists6(p) {
|
|
|
28617
29273
|
|
|
28618
29274
|
// src/commands/install.ts
|
|
28619
29275
|
import { promises as fs5 } from "fs";
|
|
28620
|
-
import
|
|
29276
|
+
import path55 from "path";
|
|
28621
29277
|
import process7 from "process";
|
|
28622
29278
|
var EXIT_OK3 = 0;
|
|
28623
29279
|
var EXIT_NOT_INITIALIZED2 = 1;
|
|
28624
29280
|
var EXIT_UNSUPPORTED_PLATFORM = 2;
|
|
28625
29281
|
var EXIT_INSTALL_FAILED = 3;
|
|
28626
29282
|
async function install(rootDir = process7.cwd(), platform = "claude-code", options = {}) {
|
|
28627
|
-
const stateFile =
|
|
28628
|
-
const v3SchemaFile =
|
|
29283
|
+
const stateFile = path55.join(rootDir, ".mancode", "state.json");
|
|
29284
|
+
const v3SchemaFile = path55.join(rootDir, ".mancode", "schema.json");
|
|
28629
29285
|
if (await pathExists7(v3SchemaFile)) {
|
|
28630
29286
|
return installV3(rootDir, platform, options);
|
|
28631
29287
|
}
|
|
@@ -28786,7 +29442,7 @@ function printUnsupportedPlatform(platform) {
|
|
|
28786
29442
|
}
|
|
28787
29443
|
}
|
|
28788
29444
|
async function readConfig2(rootDir) {
|
|
28789
|
-
const configPath =
|
|
29445
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
28790
29446
|
try {
|
|
28791
29447
|
const raw = await fs5.readFile(configPath, "utf-8");
|
|
28792
29448
|
return { config: JSON.parse(raw), valid: true };
|
|
@@ -28801,7 +29457,7 @@ function isNodeError7(err) {
|
|
|
28801
29457
|
return err instanceof Error && "code" in err;
|
|
28802
29458
|
}
|
|
28803
29459
|
async function updateConfig(rootDir, config) {
|
|
28804
|
-
const configPath =
|
|
29460
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
28805
29461
|
const content = `${JSON.stringify(config, null, 2)}
|
|
28806
29462
|
`;
|
|
28807
29463
|
await fs5.writeFile(configPath, content, "utf-8");
|
|
@@ -28837,7 +29493,7 @@ function readConfiguredMinimal(value, platform) {
|
|
|
28837
29493
|
async function readStatePlatform(rootDir) {
|
|
28838
29494
|
try {
|
|
28839
29495
|
const raw = await fs5.readFile(
|
|
28840
|
-
|
|
29496
|
+
path55.join(rootDir, ".mancode", "state.json"),
|
|
28841
29497
|
"utf-8"
|
|
28842
29498
|
);
|
|
28843
29499
|
const state = JSON.parse(raw);
|
|
@@ -28860,11 +29516,11 @@ function isRecord9(value) {
|
|
|
28860
29516
|
|
|
28861
29517
|
// src/commands/list-platforms.ts
|
|
28862
29518
|
import { promises as fs6 } from "fs";
|
|
28863
|
-
import
|
|
29519
|
+
import path56 from "path";
|
|
28864
29520
|
import process8 from "process";
|
|
28865
29521
|
var EXIT_OK4 = 0;
|
|
28866
29522
|
async function listPlatforms(rootDir = process8.cwd()) {
|
|
28867
|
-
if (await pathExists8(
|
|
29523
|
+
if (await pathExists8(path56.join(rootDir, ".mancode", "schema.json"))) {
|
|
28868
29524
|
return listV3Platforms(rootDir);
|
|
28869
29525
|
}
|
|
28870
29526
|
const installed = new Set(await readInstalledPlatforms(rootDir));
|
|
@@ -28900,7 +29556,7 @@ async function listV3Platforms(rootDir) {
|
|
|
28900
29556
|
async function readInstalledPlatforms(rootDir) {
|
|
28901
29557
|
try {
|
|
28902
29558
|
const raw = await fs6.readFile(
|
|
28903
|
-
|
|
29559
|
+
path56.join(rootDir, ".mancode", "config.json"),
|
|
28904
29560
|
"utf-8"
|
|
28905
29561
|
);
|
|
28906
29562
|
const config = JSON.parse(raw);
|
|
@@ -28932,8 +29588,8 @@ function describePlatform(platform) {
|
|
|
28932
29588
|
}
|
|
28933
29589
|
|
|
28934
29590
|
// src/commands/manps.ts
|
|
28935
|
-
import { access as access4, readFile as
|
|
28936
|
-
import
|
|
29591
|
+
import { access as access4, readFile as readFile41 } from "fs/promises";
|
|
29592
|
+
import path58 from "path";
|
|
28937
29593
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
28938
29594
|
|
|
28939
29595
|
// src/system/preseason.ts
|
|
@@ -28943,13 +29599,13 @@ import { existsSync, readFileSync } from "fs";
|
|
|
28943
29599
|
import {
|
|
28944
29600
|
access as access3,
|
|
28945
29601
|
lstat as lstat21,
|
|
28946
|
-
mkdir as
|
|
28947
|
-
readFile as
|
|
29602
|
+
mkdir as mkdir36,
|
|
29603
|
+
readFile as readFile40,
|
|
28948
29604
|
readdir as readdir18,
|
|
28949
|
-
rename as
|
|
28950
|
-
writeFile as
|
|
29605
|
+
rename as rename12,
|
|
29606
|
+
writeFile as writeFile43
|
|
28951
29607
|
} from "fs/promises";
|
|
28952
|
-
import
|
|
29608
|
+
import path57 from "path";
|
|
28953
29609
|
var PRESEASON_AREAS = [
|
|
28954
29610
|
"all",
|
|
28955
29611
|
"deps",
|
|
@@ -29029,10 +29685,10 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29029
29685
|
const needsFiles = normalizedArea === "all" || normalizedArea === "dead-code" || normalizedArea === "config";
|
|
29030
29686
|
const files = needsFiles ? await listProjectFiles(projectRoot) : [];
|
|
29031
29687
|
const issues = (await scanArea(projectRoot, normalizedArea, pkg, files)).slice(0, 20);
|
|
29032
|
-
const storageRoot = options.storageRoot ??
|
|
29033
|
-
const reportDir =
|
|
29034
|
-
await
|
|
29035
|
-
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");
|
|
29036
29692
|
const reportPath = await allocateReportPath(
|
|
29037
29693
|
reportDir,
|
|
29038
29694
|
`${generatedAt.replace(/[:.]/g, "-")}-${normalizedArea}`
|
|
@@ -29046,9 +29702,9 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29046
29702
|
issueDbPath
|
|
29047
29703
|
};
|
|
29048
29704
|
const database = await buildIssueDatabase(projectRoot, report);
|
|
29049
|
-
await
|
|
29050
|
-
await
|
|
29051
|
-
|
|
29705
|
+
await writeFile43(reportPath, renderPreseasonReport(report), "utf-8");
|
|
29706
|
+
await writeFile43(
|
|
29707
|
+
path57.join(storageRoot, "preseason-report.md"),
|
|
29052
29708
|
renderPreseasonReport(report),
|
|
29053
29709
|
"utf-8"
|
|
29054
29710
|
);
|
|
@@ -29056,7 +29712,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29056
29712
|
return report;
|
|
29057
29713
|
}
|
|
29058
29714
|
async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
29059
|
-
const issueDbPath = options.issueDbPath ??
|
|
29715
|
+
const issueDbPath = options.issueDbPath ?? path57.join(projectRoot, ".mancode", "preseason-issues.json");
|
|
29060
29716
|
const database = await readIssueDatabase(issueDbPath);
|
|
29061
29717
|
const keys = new Set(issues.map((issue) => issueKey(issue)));
|
|
29062
29718
|
const targets = database.issues.filter(
|
|
@@ -29134,7 +29790,7 @@ async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
|
29134
29790
|
write2(" Decision: skipped.");
|
|
29135
29791
|
}
|
|
29136
29792
|
database.updatedAt = now;
|
|
29137
|
-
await
|
|
29793
|
+
await writeFile43(
|
|
29138
29794
|
issueDbPath,
|
|
29139
29795
|
`${JSON.stringify(database, null, 2)}
|
|
29140
29796
|
`,
|
|
@@ -29166,7 +29822,7 @@ async function scanArea(projectRoot, area, pkg, files) {
|
|
|
29166
29822
|
async function allocateReportPath(reportDir, baseName) {
|
|
29167
29823
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
29168
29824
|
const suffix = attempt === 0 ? "" : `-${attempt + 1}`;
|
|
29169
|
-
const candidate =
|
|
29825
|
+
const candidate = path57.join(reportDir, `${baseName}${suffix}.md`);
|
|
29170
29826
|
if (!existsSync(candidate)) return candidate;
|
|
29171
29827
|
}
|
|
29172
29828
|
throw new Error(`unable to allocate preseason report path: ${baseName}`);
|
|
@@ -29215,8 +29871,8 @@ async function walk(root, current, results, depth) {
|
|
|
29215
29871
|
}
|
|
29216
29872
|
for (const entry of entries) {
|
|
29217
29873
|
if (IGNORE_DIRS.has(entry)) continue;
|
|
29218
|
-
const abs =
|
|
29219
|
-
const rel =
|
|
29874
|
+
const abs = path57.join(current, entry);
|
|
29875
|
+
const rel = path57.relative(root, abs);
|
|
29220
29876
|
let info;
|
|
29221
29877
|
try {
|
|
29222
29878
|
info = await lstat21(abs);
|
|
@@ -29226,7 +29882,7 @@ async function walk(root, current, results, depth) {
|
|
|
29226
29882
|
if (info.isSymbolicLink()) continue;
|
|
29227
29883
|
if (info.isDirectory()) {
|
|
29228
29884
|
await walk(root, abs, results, depth + 1);
|
|
29229
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
29885
|
+
} else if (SOURCE_EXTENSIONS.has(path57.extname(entry)) || entry === "package.json") {
|
|
29230
29886
|
results.push(rel);
|
|
29231
29887
|
if (results.length >= MAX_PROJECT_FILES) return;
|
|
29232
29888
|
}
|
|
@@ -29234,7 +29890,7 @@ async function walk(root, current, results, depth) {
|
|
|
29234
29890
|
}
|
|
29235
29891
|
async function readPackageJson(projectRoot) {
|
|
29236
29892
|
try {
|
|
29237
|
-
const raw = await
|
|
29893
|
+
const raw = await readFile40(path57.join(projectRoot, "package.json"), "utf-8");
|
|
29238
29894
|
return JSON.parse(raw);
|
|
29239
29895
|
} catch {
|
|
29240
29896
|
return null;
|
|
@@ -29327,7 +29983,7 @@ function scanTodos(projectRoot, files) {
|
|
|
29327
29983
|
const matches = [];
|
|
29328
29984
|
for (const file of files) {
|
|
29329
29985
|
if (matches.length >= 7) break;
|
|
29330
|
-
const abs =
|
|
29986
|
+
const abs = path57.join(projectRoot, file);
|
|
29331
29987
|
matches.push(...readTodoIssues(abs, file, matches.length));
|
|
29332
29988
|
}
|
|
29333
29989
|
return matches.slice(0, 7);
|
|
@@ -29368,7 +30024,7 @@ function scanTestGaps(files) {
|
|
|
29368
30024
|
if (sourceFiles.length === 0) return [];
|
|
29369
30025
|
const tests = new Set(files.filter((file) => file.startsWith("tests/")));
|
|
29370
30026
|
const missing = sourceFiles.filter((file) => {
|
|
29371
|
-
const base =
|
|
30027
|
+
const base = path57.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
29372
30028
|
return !Array.from(tests).some((test) => test.includes(base));
|
|
29373
30029
|
}).slice(0, 4);
|
|
29374
30030
|
return missing.map((file, index) => ({
|
|
@@ -29377,13 +30033,13 @@ function scanTestGaps(files) {
|
|
|
29377
30033
|
type: "tests",
|
|
29378
30034
|
title: "Core source file has no obvious test",
|
|
29379
30035
|
file,
|
|
29380
|
-
detail: `No matching test file was found for ${
|
|
30036
|
+
detail: `No matching test file was found for ${path57.basename(file)}.`,
|
|
29381
30037
|
recommendation: "Add focused coverage for the public behavior or document why this module is exercised indirectly."
|
|
29382
30038
|
}));
|
|
29383
30039
|
}
|
|
29384
30040
|
function scanConfig(projectRoot, files) {
|
|
29385
30041
|
const issues = [];
|
|
29386
|
-
if (!files.includes(".gitignore") && !pathExistsSync(
|
|
30042
|
+
if (!files.includes(".gitignore") && !pathExistsSync(path57.join(projectRoot, ".gitignore"))) {
|
|
29387
30043
|
issues.push({
|
|
29388
30044
|
id: "config-gitignore",
|
|
29389
30045
|
severity: "P1",
|
|
@@ -29394,7 +30050,7 @@ function scanConfig(projectRoot, files) {
|
|
|
29394
30050
|
recommendation: "Add a .gitignore that excludes dependencies, build output, coverage, and local env files."
|
|
29395
30051
|
});
|
|
29396
30052
|
}
|
|
29397
|
-
if (!files.includes(".editorconfig") && !pathExistsSync(
|
|
30053
|
+
if (!files.includes(".editorconfig") && !pathExistsSync(path57.join(projectRoot, ".editorconfig"))) {
|
|
29398
30054
|
issues.push({
|
|
29399
30055
|
id: "config-editorconfig",
|
|
29400
30056
|
severity: "P2",
|
|
@@ -29413,7 +30069,7 @@ function scanAestheticDrift(projectRoot, files, pkg) {
|
|
|
29413
30069
|
for (const file of frontendFiles) {
|
|
29414
30070
|
let content;
|
|
29415
30071
|
try {
|
|
29416
|
-
content = readFileSyncSafe(
|
|
30072
|
+
content = readFileSyncSafe(path57.join(projectRoot, file));
|
|
29417
30073
|
} catch {
|
|
29418
30074
|
continue;
|
|
29419
30075
|
}
|
|
@@ -29464,7 +30120,7 @@ function detectedIconSystems(pkg) {
|
|
|
29464
30120
|
return systems.filter(([, pattern]) => packages.some((name) => pattern.test(name))).map(([name]) => name);
|
|
29465
30121
|
}
|
|
29466
30122
|
async function scanArchitecture(projectRoot) {
|
|
29467
|
-
const localBinary =
|
|
30123
|
+
const localBinary = path57.join(
|
|
29468
30124
|
projectRoot,
|
|
29469
30125
|
"node_modules",
|
|
29470
30126
|
".bin",
|
|
@@ -29512,7 +30168,7 @@ async function hasDependencyCruiserConfig(projectRoot) {
|
|
|
29512
30168
|
"dependency-cruiser.config.mjs"
|
|
29513
30169
|
];
|
|
29514
30170
|
const results = await Promise.all(
|
|
29515
|
-
files.map((file) => pathExists9(
|
|
30171
|
+
files.map((file) => pathExists9(path57.join(projectRoot, file)))
|
|
29516
30172
|
);
|
|
29517
30173
|
return results.some(Boolean);
|
|
29518
30174
|
}
|
|
@@ -29618,9 +30274,9 @@ function inferCommands(pkg) {
|
|
|
29618
30274
|
return ["lint", "test", "build"].filter((name) => scripts[name]).map((name) => `npm run ${name}`);
|
|
29619
30275
|
}
|
|
29620
30276
|
async function buildIssueDatabase(projectRoot, report) {
|
|
29621
|
-
const reportRef =
|
|
30277
|
+
const reportRef = path57.relative(projectRoot, report.reportPath);
|
|
29622
30278
|
const run = {
|
|
29623
|
-
id:
|
|
30279
|
+
id: path57.basename(report.reportPath, ".md"),
|
|
29624
30280
|
generatedAt: report.generatedAt,
|
|
29625
30281
|
area: report.area,
|
|
29626
30282
|
reportPath: reportRef,
|
|
@@ -29662,7 +30318,7 @@ async function buildIssueDatabase(projectRoot, report) {
|
|
|
29662
30318
|
async function readIssueDatabase(issueDbPath) {
|
|
29663
30319
|
let raw;
|
|
29664
30320
|
try {
|
|
29665
|
-
raw = await
|
|
30321
|
+
raw = await readFile40(issueDbPath, "utf-8");
|
|
29666
30322
|
} catch (err) {
|
|
29667
30323
|
if (isNodeError8(err) && err.code === "ENOENT") {
|
|
29668
30324
|
return emptyIssueDatabase();
|
|
@@ -29683,9 +30339,9 @@ async function readIssueDatabase(issueDbPath) {
|
|
|
29683
30339
|
}
|
|
29684
30340
|
async function writeJsonAtomic3(file, value) {
|
|
29685
30341
|
const tmp = `${file}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
29686
|
-
await
|
|
30342
|
+
await writeFile43(tmp, `${JSON.stringify(value, null, 2)}
|
|
29687
30343
|
`, "utf-8");
|
|
29688
|
-
await
|
|
30344
|
+
await rename12(tmp, file);
|
|
29689
30345
|
}
|
|
29690
30346
|
function emptyIssueDatabase() {
|
|
29691
30347
|
return {
|
|
@@ -29726,20 +30382,20 @@ function compareIssueRecords(a, b) {
|
|
|
29726
30382
|
}
|
|
29727
30383
|
async function applySafeRemediation(projectRoot, issue) {
|
|
29728
30384
|
if (issue.id === "config-gitignore" && issue.file === ".gitignore") {
|
|
29729
|
-
const gitignorePath =
|
|
30385
|
+
const gitignorePath = path57.join(projectRoot, ".gitignore");
|
|
29730
30386
|
if (pathExistsSync(gitignorePath)) {
|
|
29731
30387
|
return { applied: false };
|
|
29732
30388
|
}
|
|
29733
|
-
await
|
|
30389
|
+
await writeFile43(gitignorePath, `${DEFAULT_GITIGNORE}
|
|
29734
30390
|
`, "utf-8");
|
|
29735
30391
|
return { applied: true, action: "created .gitignore" };
|
|
29736
30392
|
}
|
|
29737
30393
|
if (issue.id === "config-editorconfig" && issue.file === ".editorconfig") {
|
|
29738
|
-
const editorconfigPath =
|
|
30394
|
+
const editorconfigPath = path57.join(projectRoot, ".editorconfig");
|
|
29739
30395
|
if (pathExistsSync(editorconfigPath)) {
|
|
29740
30396
|
return { applied: false };
|
|
29741
30397
|
}
|
|
29742
|
-
await
|
|
30398
|
+
await writeFile43(editorconfigPath, `${DEFAULT_EDITORCONFIG}
|
|
29743
30399
|
`, "utf-8");
|
|
29744
30400
|
return { applied: true, action: "created .editorconfig" };
|
|
29745
30401
|
}
|
|
@@ -29775,10 +30431,10 @@ async function inferSafePackageScript(projectRoot, scriptName) {
|
|
|
29775
30431
|
}
|
|
29776
30432
|
}
|
|
29777
30433
|
async function addPackageScript(projectRoot, scriptName, script) {
|
|
29778
|
-
const packagePath =
|
|
30434
|
+
const packagePath = path57.join(projectRoot, "package.json");
|
|
29779
30435
|
let pkg;
|
|
29780
30436
|
try {
|
|
29781
|
-
pkg = JSON.parse(await
|
|
30437
|
+
pkg = JSON.parse(await readFile40(packagePath, "utf-8"));
|
|
29782
30438
|
} catch {
|
|
29783
30439
|
return false;
|
|
29784
30440
|
}
|
|
@@ -29788,7 +30444,7 @@ async function addPackageScript(projectRoot, scriptName, script) {
|
|
|
29788
30444
|
...scripts,
|
|
29789
30445
|
[scriptName]: script
|
|
29790
30446
|
};
|
|
29791
|
-
await
|
|
30447
|
+
await writeFile43(packagePath, `${JSON.stringify(pkg, null, 2)}
|
|
29792
30448
|
`, "utf-8");
|
|
29793
30449
|
return true;
|
|
29794
30450
|
}
|
|
@@ -29888,7 +30544,7 @@ var EXIT_NOT_INITIALIZED3 = 1;
|
|
|
29888
30544
|
var EXIT_SCAN_FAILED = 2;
|
|
29889
30545
|
var EXIT_INVALID_ARG = 3;
|
|
29890
30546
|
async function manps(rootDir, area = "all", options = {}) {
|
|
29891
|
-
const v3SchemaPath =
|
|
30547
|
+
const v3SchemaPath = path58.join(rootDir, ".mancode", "schema.json");
|
|
29892
30548
|
const v3Activation = await readV3ActivationState(v3SchemaPath);
|
|
29893
30549
|
if (v3Activation !== null && v3Activation !== "v3_active" && v3Activation !== "dual_read") {
|
|
29894
30550
|
const message = `manps is unavailable while mancode activation is ${v3Activation}`;
|
|
@@ -29901,7 +30557,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
29901
30557
|
return EXIT_SCAN_FAILED;
|
|
29902
30558
|
}
|
|
29903
30559
|
const v3Initialized = v3Activation === "v3_active";
|
|
29904
|
-
const initialized = v3Initialized || await pathExists10(
|
|
30560
|
+
const initialized = v3Initialized || await pathExists10(path58.join(rootDir, ".mancode", "state.json"));
|
|
29905
30561
|
if (!initialized) {
|
|
29906
30562
|
if (options.json) {
|
|
29907
30563
|
console.log(JSON.stringify({ error: "not initialized" }, null, 2));
|
|
@@ -29914,7 +30570,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
29914
30570
|
let report;
|
|
29915
30571
|
try {
|
|
29916
30572
|
report = await runPreseasonScan(rootDir, area, {
|
|
29917
|
-
storageRoot: v3Initialized ?
|
|
30573
|
+
storageRoot: v3Initialized ? path58.join(rootDir, ".mancode", "local") : void 0
|
|
29918
30574
|
});
|
|
29919
30575
|
} catch (err) {
|
|
29920
30576
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -29983,8 +30639,8 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
29983
30639
|
console.log(
|
|
29984
30640
|
`Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`
|
|
29985
30641
|
);
|
|
29986
|
-
console.log(`Report: ${
|
|
29987
|
-
console.log(`Issue DB: ${
|
|
30642
|
+
console.log(`Report: ${path58.relative(rootDir, report.reportPath)}`);
|
|
30643
|
+
console.log(`Issue DB: ${path58.relative(rootDir, report.issueDbPath)}`);
|
|
29988
30644
|
if (report.issues.length > 0) {
|
|
29989
30645
|
console.log("");
|
|
29990
30646
|
for (const issue of report.issues.slice(0, 7)) {
|
|
@@ -30000,7 +30656,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30000
30656
|
console.log(` Skipped: ${remediation.skipped}`);
|
|
30001
30657
|
console.log(` Fixed: ${remediation.fixed}`);
|
|
30002
30658
|
console.log(
|
|
30003
|
-
` Issue DB: ${
|
|
30659
|
+
` Issue DB: ${path58.relative(rootDir, remediation.issueDbPath)}`
|
|
30004
30660
|
);
|
|
30005
30661
|
}
|
|
30006
30662
|
return EXIT_OK5;
|
|
@@ -30061,7 +30717,7 @@ async function readV3ActivationState(schemaPath) {
|
|
|
30061
30717
|
if (!await pathExists10(schemaPath)) return null;
|
|
30062
30718
|
try {
|
|
30063
30719
|
const manifest = parseSchemaManifest(
|
|
30064
|
-
JSON.parse(await
|
|
30720
|
+
JSON.parse(await readFile41(schemaPath, "utf8"))
|
|
30065
30721
|
);
|
|
30066
30722
|
return manifest.activationState;
|
|
30067
30723
|
} catch {
|
|
@@ -30070,8 +30726,8 @@ async function readV3ActivationState(schemaPath) {
|
|
|
30070
30726
|
}
|
|
30071
30727
|
|
|
30072
30728
|
// src/commands/migrate.ts
|
|
30073
|
-
import { readFile as
|
|
30074
|
-
import
|
|
30729
|
+
import { readFile as readFile42 } from "fs/promises";
|
|
30730
|
+
import path59 from "path";
|
|
30075
30731
|
var EXIT_OK6 = 0;
|
|
30076
30732
|
var EXIT_INVALID_ARG2 = 2;
|
|
30077
30733
|
var EXIT_MIGRATION_BLOCKED = 3;
|
|
@@ -30197,14 +30853,14 @@ async function readScopeFile(rootDir, file) {
|
|
|
30197
30853
|
if (!file.trim() || file.includes("\0")) {
|
|
30198
30854
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30199
30855
|
}
|
|
30200
|
-
const resolved =
|
|
30201
|
-
const relative =
|
|
30202
|
-
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)) {
|
|
30203
30859
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30204
30860
|
}
|
|
30205
30861
|
try {
|
|
30206
30862
|
return JSON.parse(
|
|
30207
|
-
await
|
|
30863
|
+
await readFile42(resolved, "utf8")
|
|
30208
30864
|
);
|
|
30209
30865
|
} catch (error) {
|
|
30210
30866
|
if (error instanceof SyntaxError) {
|
|
@@ -30304,12 +30960,12 @@ async function runOperationMutation(rootDir, operationId, options, mode) {
|
|
|
30304
30960
|
}
|
|
30305
30961
|
|
|
30306
30962
|
// src/context/project-policy-upgrade.ts
|
|
30307
|
-
import { lstat as lstat22, mkdir as
|
|
30308
|
-
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";
|
|
30309
30965
|
var UPGRADE_OPERATION = "project_policy_upgrade";
|
|
30310
30966
|
async function dryRunProjectPolicyUpgrade(input) {
|
|
30311
30967
|
assertPolicyVersion(input.policyVersion);
|
|
30312
|
-
const root =
|
|
30968
|
+
const root = path60.resolve(input.projectRoot);
|
|
30313
30969
|
const project = await new V3ContextStore(root).readProjectSnapshot();
|
|
30314
30970
|
const beforeDigest = digestManifest(project.manifest);
|
|
30315
30971
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -30353,7 +31009,7 @@ async function dryRunProjectPolicyUpgrade(input) {
|
|
|
30353
31009
|
async function upgradeProjectPolicy(input) {
|
|
30354
31010
|
assertPolicyVersion(input.policyVersion);
|
|
30355
31011
|
assertUlid(input.sessionId, "project policy upgrade sessionId");
|
|
30356
|
-
const root =
|
|
31012
|
+
const root = path60.resolve(input.projectRoot);
|
|
30357
31013
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
30358
31014
|
const operationId = input.operationId;
|
|
30359
31015
|
if (operationId === void 0) {
|
|
@@ -30607,24 +31263,24 @@ function buildV2Manifest(manifest, operationId) {
|
|
|
30607
31263
|
return candidate;
|
|
30608
31264
|
}
|
|
30609
31265
|
async function readSchemaContent(root) {
|
|
30610
|
-
return
|
|
31266
|
+
return readFile43(path60.join(root, ".mancode", "schema.json"), "utf8");
|
|
30611
31267
|
}
|
|
30612
31268
|
async function writeSchemaContent(root, operationId, content) {
|
|
30613
|
-
const directory =
|
|
30614
|
-
const target =
|
|
31269
|
+
const directory = path60.join(root, ".mancode");
|
|
31270
|
+
const target = path60.join(directory, "schema.json");
|
|
30615
31271
|
const stat5 = await lstat22(target);
|
|
30616
31272
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
30617
31273
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
30618
31274
|
}
|
|
30619
|
-
const temporary =
|
|
31275
|
+
const temporary = path60.join(
|
|
30620
31276
|
directory,
|
|
30621
31277
|
`.schema.json.${operationId}.${process.pid}.tmp`
|
|
30622
31278
|
);
|
|
30623
|
-
await
|
|
31279
|
+
await writeFile44(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
30624
31280
|
try {
|
|
30625
31281
|
await replaceFileAtomically(temporary, target);
|
|
30626
31282
|
} catch (error) {
|
|
30627
|
-
await
|
|
31283
|
+
await rm20(temporary, { force: true });
|
|
30628
31284
|
throw error;
|
|
30629
31285
|
}
|
|
30630
31286
|
}
|
|
@@ -30692,15 +31348,15 @@ async function releaseLocks3(locks) {
|
|
|
30692
31348
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
30693
31349
|
}
|
|
30694
31350
|
function projectUpgradePreviewRoot(root, operationId) {
|
|
30695
|
-
return
|
|
31351
|
+
return path60.join(root, ".mancode", "staging", "project-upgrade", operationId);
|
|
30696
31352
|
}
|
|
30697
31353
|
async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
30698
31354
|
const directory = projectUpgradePreviewRoot(root, receipt.operationId);
|
|
30699
|
-
const receiptPath =
|
|
30700
|
-
const manifestPath =
|
|
30701
|
-
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 });
|
|
30702
31358
|
try {
|
|
30703
|
-
await
|
|
31359
|
+
await mkdir37(directory);
|
|
30704
31360
|
} catch (error) {
|
|
30705
31361
|
if (isAlreadyExists23(error)) {
|
|
30706
31362
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_EXISTS");
|
|
@@ -30708,25 +31364,25 @@ async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
|
30708
31364
|
throw error;
|
|
30709
31365
|
}
|
|
30710
31366
|
try {
|
|
30711
|
-
await
|
|
31367
|
+
await writeFile44(receiptPath, `${JSON.stringify(receipt, null, 2)}
|
|
30712
31368
|
`, {
|
|
30713
31369
|
encoding: "utf8",
|
|
30714
31370
|
flag: "wx"
|
|
30715
31371
|
});
|
|
30716
|
-
await
|
|
31372
|
+
await writeFile44(manifestPath, manifestContent, {
|
|
30717
31373
|
encoding: "utf8",
|
|
30718
31374
|
flag: "wx"
|
|
30719
31375
|
});
|
|
30720
31376
|
} catch (error) {
|
|
30721
|
-
await
|
|
31377
|
+
await rm20(directory, { recursive: true, force: true });
|
|
30722
31378
|
throw error;
|
|
30723
31379
|
}
|
|
30724
31380
|
}
|
|
30725
31381
|
async function assertProjectPolicyUpgradePreview(root, operationId, project) {
|
|
30726
31382
|
const directory = projectUpgradePreviewRoot(root, operationId);
|
|
30727
31383
|
const [receiptContent, manifestContent] = await Promise.all([
|
|
30728
|
-
readSafePreviewFile(
|
|
30729
|
-
readSafePreviewFile(
|
|
31384
|
+
readSafePreviewFile(path60.join(directory, "preview.json")),
|
|
31385
|
+
readSafePreviewFile(path60.join(directory, "schema.json"))
|
|
30730
31386
|
]);
|
|
30731
31387
|
let receipt;
|
|
30732
31388
|
try {
|
|
@@ -30753,9 +31409,9 @@ async function readSafePreviewFile(target) {
|
|
|
30753
31409
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
30754
31410
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_INVALID");
|
|
30755
31411
|
}
|
|
30756
|
-
return
|
|
31412
|
+
return readFile43(target, "utf8");
|
|
30757
31413
|
} catch (error) {
|
|
30758
|
-
if (
|
|
31414
|
+
if (isNotFound30(error)) {
|
|
30759
31415
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_REQUIRED");
|
|
30760
31416
|
}
|
|
30761
31417
|
throw error;
|
|
@@ -30788,7 +31444,7 @@ function parseProjectPolicyUpgradePreviewReceipt(value) {
|
|
|
30788
31444
|
createdAt: record.createdAt
|
|
30789
31445
|
};
|
|
30790
31446
|
}
|
|
30791
|
-
function
|
|
31447
|
+
function isNotFound30(error) {
|
|
30792
31448
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
30793
31449
|
}
|
|
30794
31450
|
function isAlreadyExists23(error) {
|
|
@@ -30842,16 +31498,16 @@ async function projectUpgrade(rootDir, options) {
|
|
|
30842
31498
|
// src/commands/refresh-project.ts
|
|
30843
31499
|
import { randomUUID } from "crypto";
|
|
30844
31500
|
import { promises as fs7 } from "fs";
|
|
30845
|
-
import
|
|
31501
|
+
import path61 from "path";
|
|
30846
31502
|
import process9 from "process";
|
|
30847
31503
|
var EXIT_OK7 = 0;
|
|
30848
31504
|
var EXIT_NOT_INITIALIZED4 = 1;
|
|
30849
31505
|
var EXIT_CORRUPT_STATE = 2;
|
|
30850
31506
|
var EXIT_REFRESH_FAILED = 3;
|
|
30851
31507
|
async function refreshProject(rootDir = process9.cwd()) {
|
|
30852
|
-
const mancodeDir =
|
|
30853
|
-
const statePath =
|
|
30854
|
-
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"))) {
|
|
30855
31511
|
return refreshV3Project(rootDir);
|
|
30856
31512
|
}
|
|
30857
31513
|
if (!await pathExists11(statePath)) {
|
|
@@ -30870,12 +31526,12 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
30870
31526
|
const [profile, team, hasGit, hasManifest] = await Promise.all([
|
|
30871
31527
|
detectProjectProfile(rootDir),
|
|
30872
31528
|
detectTeamStatus(rootDir),
|
|
30873
|
-
pathExists11(
|
|
31529
|
+
pathExists11(path61.join(rootDir, ".git")),
|
|
30874
31530
|
hasProjectManifest2(rootDir)
|
|
30875
31531
|
]);
|
|
30876
31532
|
const uiLibrary = primaryUiLibrary(profile);
|
|
30877
31533
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
30878
|
-
const config = await readJson2(
|
|
31534
|
+
const config = await readJson2(path61.join(mancodeDir, "config.json"));
|
|
30879
31535
|
const configuredTeam = config.forceTeamMode === true ? true : config.teamMode === "on" ? true : config.teamMode === "off" ? false : team.isTeam;
|
|
30880
31536
|
const nextState = {
|
|
30881
31537
|
...state,
|
|
@@ -30887,7 +31543,7 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
30887
31543
|
};
|
|
30888
31544
|
await writeProjectFacts2(
|
|
30889
31545
|
statePath,
|
|
30890
|
-
|
|
31546
|
+
path61.join(mancodeDir, "project-profile.json"),
|
|
30891
31547
|
`${JSON.stringify(nextState, null, 2)}
|
|
30892
31548
|
`,
|
|
30893
31549
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -30954,7 +31610,7 @@ async function refreshV3Project(rootDir) {
|
|
|
30954
31610
|
}
|
|
30955
31611
|
async function hasProjectManifest2(rootDir) {
|
|
30956
31612
|
for (const manifest of PROJECT_MANIFESTS) {
|
|
30957
|
-
if (await pathExists11(
|
|
31613
|
+
if (await pathExists11(path61.join(rootDir, manifest))) return true;
|
|
30958
31614
|
}
|
|
30959
31615
|
return false;
|
|
30960
31616
|
}
|
|
@@ -31020,9 +31676,9 @@ async function readOptionalText(filePath) {
|
|
|
31020
31676
|
}
|
|
31021
31677
|
}
|
|
31022
31678
|
function temporaryPath(filePath) {
|
|
31023
|
-
return
|
|
31024
|
-
|
|
31025
|
-
`.${
|
|
31679
|
+
return path61.join(
|
|
31680
|
+
path61.dirname(filePath),
|
|
31681
|
+
`.${path61.basename(filePath)}.${process9.pid}.${randomUUID()}.tmp`
|
|
31026
31682
|
);
|
|
31027
31683
|
}
|
|
31028
31684
|
async function refreshStaticPlatforms(rootDir, config, fallbackPlatform, stack, uiLibrary, profile) {
|
|
@@ -31092,7 +31748,7 @@ async function pathExists11(filePath) {
|
|
|
31092
31748
|
|
|
31093
31749
|
// src/commands/refresh-style.ts
|
|
31094
31750
|
import { promises as fs8 } from "fs";
|
|
31095
|
-
import
|
|
31751
|
+
import path62 from "path";
|
|
31096
31752
|
import process10 from "process";
|
|
31097
31753
|
var EXIT_OK8 = 0;
|
|
31098
31754
|
var EXIT_NOT_INITIALIZED5 = 1;
|
|
@@ -31103,8 +31759,8 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31103
31759
|
console.error("\u2717 style scan root must stay inside the project root.");
|
|
31104
31760
|
return EXIT_V3_REFRESH_FAILED;
|
|
31105
31761
|
}
|
|
31106
|
-
const stateFile =
|
|
31107
|
-
if (await pathExists12(
|
|
31762
|
+
const stateFile = path62.join(rootDir, ".mancode", "state.json");
|
|
31763
|
+
if (await pathExists12(path62.join(rootDir, ".mancode", "schema.json"))) {
|
|
31108
31764
|
return refreshV3Style(rootDir, scanTarget.root, scanTarget.scopeRoot);
|
|
31109
31765
|
}
|
|
31110
31766
|
if (!await pathExists12(stateFile)) {
|
|
@@ -31114,7 +31770,7 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31114
31770
|
}
|
|
31115
31771
|
console.log("\u2713 \u5237\u65B0\u9879\u76EE profile...");
|
|
31116
31772
|
const profile = await detectProjectProfile(rootDir);
|
|
31117
|
-
const profilePath =
|
|
31773
|
+
const profilePath = path62.join(rootDir, ".mancode", "project-profile.json");
|
|
31118
31774
|
await fs8.writeFile(
|
|
31119
31775
|
profilePath,
|
|
31120
31776
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -31141,13 +31797,13 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31141
31797
|
uiLibraryHint,
|
|
31142
31798
|
scanTarget.scopeRoot
|
|
31143
31799
|
);
|
|
31144
|
-
const tokensPath =
|
|
31800
|
+
const tokensPath = path62.join(
|
|
31145
31801
|
rootDir,
|
|
31146
31802
|
".mancode",
|
|
31147
31803
|
"aesthetics",
|
|
31148
31804
|
"style-tokens.json"
|
|
31149
31805
|
);
|
|
31150
|
-
await fs8.mkdir(
|
|
31806
|
+
await fs8.mkdir(path62.dirname(tokensPath), { recursive: true });
|
|
31151
31807
|
await fs8.writeFile(
|
|
31152
31808
|
tokensPath,
|
|
31153
31809
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -31220,7 +31876,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31220
31876
|
console.log(
|
|
31221
31877
|
` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
|
|
31222
31878
|
);
|
|
31223
|
-
const tokensPath =
|
|
31879
|
+
const tokensPath = path62.join(
|
|
31224
31880
|
rootDir,
|
|
31225
31881
|
".mancode",
|
|
31226
31882
|
"local",
|
|
@@ -31237,7 +31893,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31237
31893
|
}
|
|
31238
31894
|
console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
|
|
31239
31895
|
const tokens = await scanAesthetics(scanRoot, uiLibraryHint, scopeRoot);
|
|
31240
|
-
await fs8.mkdir(
|
|
31896
|
+
await fs8.mkdir(path62.dirname(tokensPath), { recursive: true });
|
|
31241
31897
|
await fs8.writeFile(
|
|
31242
31898
|
tokensPath,
|
|
31243
31899
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -31271,7 +31927,7 @@ async function printStaticPlatformRefreshHint(rootDir) {
|
|
|
31271
31927
|
);
|
|
31272
31928
|
}
|
|
31273
31929
|
async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
31274
|
-
const statePath =
|
|
31930
|
+
const statePath = path62.join(rootDir, ".mancode", "state.json");
|
|
31275
31931
|
try {
|
|
31276
31932
|
const state = JSON.parse(await fs8.readFile(statePath, "utf-8"));
|
|
31277
31933
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
@@ -31295,7 +31951,7 @@ async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
|
31295
31951
|
async function readInstalledPlatforms2(rootDir) {
|
|
31296
31952
|
try {
|
|
31297
31953
|
const raw = await fs8.readFile(
|
|
31298
|
-
|
|
31954
|
+
path62.join(rootDir, ".mancode", "config.json"),
|
|
31299
31955
|
"utf-8"
|
|
31300
31956
|
);
|
|
31301
31957
|
const config = JSON.parse(raw);
|
|
@@ -31315,30 +31971,30 @@ async function pathExists12(p) {
|
|
|
31315
31971
|
}
|
|
31316
31972
|
}
|
|
31317
31973
|
async function resolveScanTarget(rootDir, requestedRoot) {
|
|
31318
|
-
const projectRoot = await fs8.realpath(
|
|
31974
|
+
const projectRoot = await fs8.realpath(path62.resolve(rootDir)).catch(() => null);
|
|
31319
31975
|
if (projectRoot === null) return null;
|
|
31320
31976
|
if (requestedRoot === void 0 || requestedRoot === ".") {
|
|
31321
31977
|
return { root: projectRoot, scopeRoot: "." };
|
|
31322
31978
|
}
|
|
31323
|
-
if (
|
|
31979
|
+
if (path62.isAbsolute(requestedRoot) || requestedRoot.includes("\0") || requestedRoot.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
31324
31980
|
return null;
|
|
31325
31981
|
}
|
|
31326
|
-
const candidate = await fs8.realpath(
|
|
31982
|
+
const candidate = await fs8.realpath(path62.resolve(projectRoot, requestedRoot)).catch(() => null);
|
|
31327
31983
|
if (candidate === null) return null;
|
|
31328
|
-
const relative =
|
|
31329
|
-
if (relative.startsWith(`..${
|
|
31984
|
+
const relative = path62.relative(projectRoot, candidate);
|
|
31985
|
+
if (relative.startsWith(`..${path62.sep}`) || relative === ".." || path62.isAbsolute(relative)) {
|
|
31330
31986
|
return null;
|
|
31331
31987
|
}
|
|
31332
31988
|
return {
|
|
31333
31989
|
root: candidate,
|
|
31334
|
-
scopeRoot: relative.split(
|
|
31990
|
+
scopeRoot: relative.split(path62.sep).join("/") || "."
|
|
31335
31991
|
};
|
|
31336
31992
|
}
|
|
31337
31993
|
|
|
31338
31994
|
// src/commands/status.ts
|
|
31339
31995
|
import { spawn } from "child_process";
|
|
31340
31996
|
import { promises as fs9 } from "fs";
|
|
31341
|
-
import
|
|
31997
|
+
import path63 from "path";
|
|
31342
31998
|
import process11 from "process";
|
|
31343
31999
|
|
|
31344
32000
|
// src/team/assessment.ts
|
|
@@ -31494,8 +32150,8 @@ var EXIT_OK9 = 0;
|
|
|
31494
32150
|
var EXIT_NOT_INITIALIZED6 = 1;
|
|
31495
32151
|
var EXIT_CORRUPT_STATE2 = 2;
|
|
31496
32152
|
async function status(rootDir = process11.cwd(), options = {}) {
|
|
31497
|
-
const stateFile =
|
|
31498
|
-
const v3SchemaFile =
|
|
32153
|
+
const stateFile = path63.join(rootDir, ".mancode", "state.json");
|
|
32154
|
+
const v3SchemaFile = path63.join(rootDir, ".mancode", "schema.json");
|
|
31499
32155
|
if (await pathExists13(v3SchemaFile)) {
|
|
31500
32156
|
return statusV3(rootDir, options);
|
|
31501
32157
|
}
|
|
@@ -31740,10 +32396,10 @@ async function readV3StatusSession(rootDir) {
|
|
|
31740
32396
|
}
|
|
31741
32397
|
async function shouldRefreshProject(rootDir, state) {
|
|
31742
32398
|
if (state.projectMode !== "generic") return false;
|
|
31743
|
-
const hasGit = await pathExists13(
|
|
32399
|
+
const hasGit = await pathExists13(path63.join(rootDir, ".git"));
|
|
31744
32400
|
if (hasGit) return true;
|
|
31745
32401
|
for (const manifest of PROJECT_MANIFESTS) {
|
|
31746
|
-
if (await pathExists13(
|
|
32402
|
+
if (await pathExists13(path63.join(rootDir, manifest))) return true;
|
|
31747
32403
|
}
|
|
31748
32404
|
return false;
|
|
31749
32405
|
}
|
|
@@ -31787,19 +32443,19 @@ async function getCurrentWorkflow(rootDir, taskId) {
|
|
|
31787
32443
|
}
|
|
31788
32444
|
async function getProjectName(rootDir) {
|
|
31789
32445
|
try {
|
|
31790
|
-
const raw = await fs9.readFile(
|
|
32446
|
+
const raw = await fs9.readFile(path63.join(rootDir, "package.json"), "utf-8");
|
|
31791
32447
|
const pkg = JSON.parse(raw);
|
|
31792
32448
|
if (pkg.name && typeof pkg.name === "string") {
|
|
31793
32449
|
return pkg.name;
|
|
31794
32450
|
}
|
|
31795
32451
|
} catch {
|
|
31796
32452
|
}
|
|
31797
|
-
return
|
|
32453
|
+
return path63.basename(rootDir);
|
|
31798
32454
|
}
|
|
31799
32455
|
async function readConfig3(rootDir) {
|
|
31800
32456
|
try {
|
|
31801
32457
|
const raw = await fs9.readFile(
|
|
31802
|
-
|
|
32458
|
+
path63.join(rootDir, ".mancode", "config.json"),
|
|
31803
32459
|
"utf-8"
|
|
31804
32460
|
);
|
|
31805
32461
|
return JSON.parse(raw);
|
|
@@ -31827,9 +32483,9 @@ function getEffectiveTeamStatus(state, config, detected) {
|
|
|
31827
32483
|
}
|
|
31828
32484
|
async function checkHooks(rootDir) {
|
|
31829
32485
|
const [sessionStart, userPromptSubmit, registered] = await Promise.all([
|
|
31830
|
-
pathExists13(
|
|
32486
|
+
pathExists13(path63.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
|
|
31831
32487
|
pathExists13(
|
|
31832
|
-
|
|
32488
|
+
path63.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
31833
32489
|
),
|
|
31834
32490
|
isRegistered(rootDir)
|
|
31835
32491
|
]);
|
|
@@ -31838,7 +32494,7 @@ async function checkHooks(rootDir) {
|
|
|
31838
32494
|
async function isRegistered(rootDir) {
|
|
31839
32495
|
try {
|
|
31840
32496
|
const raw = await fs9.readFile(
|
|
31841
|
-
|
|
32497
|
+
path63.join(rootDir, ".claude", "settings.json"),
|
|
31842
32498
|
"utf-8"
|
|
31843
32499
|
);
|
|
31844
32500
|
const settings = JSON.parse(raw);
|
|
@@ -31867,7 +32523,7 @@ function hasHookCommand2(value, needle) {
|
|
|
31867
32523
|
});
|
|
31868
32524
|
}
|
|
31869
32525
|
async function estimateHookInjection(rootDir) {
|
|
31870
|
-
const hookPath =
|
|
32526
|
+
const hookPath = path63.join(
|
|
31871
32527
|
rootDir,
|
|
31872
32528
|
".mancode",
|
|
31873
32529
|
"hooks",
|
|
@@ -33364,8 +34020,8 @@ function assertPositiveRevision2(value, label) {
|
|
|
33364
34020
|
}
|
|
33365
34021
|
|
|
33366
34022
|
// src/team/git-ref-handoff-repair.ts
|
|
33367
|
-
import { lstat as lstat23, mkdir as
|
|
33368
|
-
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";
|
|
33369
34025
|
|
|
33370
34026
|
// src/team/git-ref-operation.ts
|
|
33371
34027
|
import { execFile as execFileCallback6 } from "child_process";
|
|
@@ -35943,7 +36599,7 @@ async function recoverGitRefHandoffRepairs(projectRoot) {
|
|
|
35943
36599
|
}
|
|
35944
36600
|
async function recoverGitRefHandoffRepair(projectRoot, operationId, transportReceipt) {
|
|
35945
36601
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
35946
|
-
const root =
|
|
36602
|
+
const root = path64.resolve(projectRoot);
|
|
35947
36603
|
let journal = await requireJournal2(root, operationId);
|
|
35948
36604
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
35949
36605
|
return recoveryResult2(journal);
|
|
@@ -36022,7 +36678,7 @@ async function recoverGitRefHandoffRepair(projectRoot, operationId, transportRec
|
|
|
36022
36678
|
}
|
|
36023
36679
|
}
|
|
36024
36680
|
async function prepareHandoffRepairWhileTaskLocked(projectRoot, rawPrepared) {
|
|
36025
|
-
const root =
|
|
36681
|
+
const root = path64.resolve(projectRoot);
|
|
36026
36682
|
const prepared2 = parsePrepared2(rawPrepared);
|
|
36027
36683
|
const runtime = await readProjectRuntimeContext(root);
|
|
36028
36684
|
const previousMetadata = bundleMetadata2(prepared2.predecessorBundle);
|
|
@@ -36085,7 +36741,7 @@ async function restorePredecessorMetadata2(projectRoot, journal) {
|
|
|
36085
36741
|
);
|
|
36086
36742
|
}
|
|
36087
36743
|
async function replaceMetadataVerified(projectRoot, expected, targetMetadata, alternateExpected) {
|
|
36088
|
-
const target =
|
|
36744
|
+
const target = path64.join(
|
|
36089
36745
|
taskRootPath(projectRoot, targetMetadata.taskRef),
|
|
36090
36746
|
"metadata.json"
|
|
36091
36747
|
);
|
|
@@ -36203,15 +36859,15 @@ function parseJournal3(value) {
|
|
|
36203
36859
|
pendingMetadata,
|
|
36204
36860
|
remoteReceipt,
|
|
36205
36861
|
transportReceipt: value.transportReceipt,
|
|
36206
|
-
createdAt:
|
|
36207
|
-
updatedAt:
|
|
36862
|
+
createdAt: parseTimestamp16(value.createdAt),
|
|
36863
|
+
updatedAt: parseTimestamp16(value.updatedAt)
|
|
36208
36864
|
};
|
|
36209
36865
|
}
|
|
36210
36866
|
async function createJournal3(projectRoot, journal) {
|
|
36211
36867
|
await ensureJournalDirectory2(projectRoot);
|
|
36212
36868
|
const target = journalPath3(projectRoot, journal.operationId);
|
|
36213
36869
|
try {
|
|
36214
|
-
await
|
|
36870
|
+
await writeFile45(target, serialize13(journal), {
|
|
36215
36871
|
encoding: "utf8",
|
|
36216
36872
|
flag: "wx"
|
|
36217
36873
|
});
|
|
@@ -36230,10 +36886,10 @@ async function replaceJournal3(projectRoot, journal) {
|
|
|
36230
36886
|
async function requireJournal2(projectRoot, operationId) {
|
|
36231
36887
|
try {
|
|
36232
36888
|
return parseJournal3(
|
|
36233
|
-
JSON.parse(await
|
|
36889
|
+
JSON.parse(await readFile44(journalPath3(projectRoot, operationId), "utf8"))
|
|
36234
36890
|
);
|
|
36235
36891
|
} catch (error) {
|
|
36236
|
-
if (error instanceof SyntaxError ||
|
|
36892
|
+
if (error instanceof SyntaxError || isNotFound31(error)) {
|
|
36237
36893
|
throw new Error("MANCODE_HANDOFF_REPAIR_JOURNAL_NOT_FOUND");
|
|
36238
36894
|
}
|
|
36239
36895
|
throw error;
|
|
@@ -36244,7 +36900,7 @@ async function listJournals2(projectRoot) {
|
|
|
36244
36900
|
try {
|
|
36245
36901
|
entries = await readdir19(journalDirectory2(projectRoot));
|
|
36246
36902
|
} catch (error) {
|
|
36247
|
-
if (
|
|
36903
|
+
if (isNotFound31(error)) return [];
|
|
36248
36904
|
throw error;
|
|
36249
36905
|
}
|
|
36250
36906
|
const journals = [];
|
|
@@ -36253,8 +36909,8 @@ async function listJournals2(projectRoot) {
|
|
|
36253
36909
|
journals.push(
|
|
36254
36910
|
parseJournal3(
|
|
36255
36911
|
JSON.parse(
|
|
36256
|
-
await
|
|
36257
|
-
|
|
36912
|
+
await readFile44(
|
|
36913
|
+
path64.join(journalDirectory2(projectRoot), entry),
|
|
36258
36914
|
"utf8"
|
|
36259
36915
|
)
|
|
36260
36916
|
)
|
|
@@ -36268,7 +36924,7 @@ async function readSafeFile2(target) {
|
|
|
36268
36924
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
36269
36925
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
36270
36926
|
}
|
|
36271
|
-
const content = await
|
|
36927
|
+
const content = await readFile44(target, "utf8");
|
|
36272
36928
|
const after = await lstat23(target);
|
|
36273
36929
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
36274
36930
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -36276,19 +36932,19 @@ async function readSafeFile2(target) {
|
|
|
36276
36932
|
return content;
|
|
36277
36933
|
}
|
|
36278
36934
|
async function atomicWrite2(target, content) {
|
|
36279
|
-
const temporary =
|
|
36280
|
-
|
|
36281
|
-
`.${
|
|
36935
|
+
const temporary = path64.join(
|
|
36936
|
+
path64.dirname(target),
|
|
36937
|
+
`.${path64.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
36282
36938
|
);
|
|
36283
|
-
await
|
|
36939
|
+
await writeFile45(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
36284
36940
|
await replaceFileAtomically(temporary, target);
|
|
36285
36941
|
}
|
|
36286
36942
|
async function ensureJournalDirectory2(projectRoot) {
|
|
36287
|
-
let current =
|
|
36943
|
+
let current = path64.resolve(projectRoot);
|
|
36288
36944
|
for (const segment of [".mancode", "local", "journals", "git-ref-handoff"]) {
|
|
36289
|
-
current =
|
|
36945
|
+
current = path64.join(current, segment);
|
|
36290
36946
|
try {
|
|
36291
|
-
await
|
|
36947
|
+
await mkdir38(current);
|
|
36292
36948
|
} catch (error) {
|
|
36293
36949
|
if (!isAlreadyExists24(error)) throw error;
|
|
36294
36950
|
}
|
|
@@ -36299,8 +36955,8 @@ async function ensureJournalDirectory2(projectRoot) {
|
|
|
36299
36955
|
}
|
|
36300
36956
|
}
|
|
36301
36957
|
function journalDirectory2(projectRoot) {
|
|
36302
|
-
return
|
|
36303
|
-
|
|
36958
|
+
return path64.join(
|
|
36959
|
+
path64.resolve(projectRoot),
|
|
36304
36960
|
".mancode",
|
|
36305
36961
|
"local",
|
|
36306
36962
|
"journals",
|
|
@@ -36309,13 +36965,13 @@ function journalDirectory2(projectRoot) {
|
|
|
36309
36965
|
}
|
|
36310
36966
|
function journalPath3(projectRoot, operationId) {
|
|
36311
36967
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
36312
|
-
return
|
|
36968
|
+
return path64.join(journalDirectory2(projectRoot), `${operationId}.json`);
|
|
36313
36969
|
}
|
|
36314
36970
|
function serialize13(value) {
|
|
36315
36971
|
return `${JSON.stringify(value, null, 2)}
|
|
36316
36972
|
`;
|
|
36317
36973
|
}
|
|
36318
|
-
function
|
|
36974
|
+
function parseTimestamp16(value) {
|
|
36319
36975
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
36320
36976
|
throw new Error("MANCODE_HANDOFF_REPAIR_JOURNAL_CORRUPT");
|
|
36321
36977
|
}
|
|
@@ -36324,7 +36980,7 @@ function parseTimestamp15(value) {
|
|
|
36324
36980
|
function isAlreadyExists24(error) {
|
|
36325
36981
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
36326
36982
|
}
|
|
36327
|
-
function
|
|
36983
|
+
function isNotFound31(error) {
|
|
36328
36984
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
36329
36985
|
}
|
|
36330
36986
|
|
|
@@ -36408,8 +37064,8 @@ function parseReceipt(value) {
|
|
|
36408
37064
|
}
|
|
36409
37065
|
|
|
36410
37066
|
// src/team/policy-operation.ts
|
|
36411
|
-
import { lstat as lstat24, mkdir as
|
|
36412
|
-
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";
|
|
36413
37069
|
async function updateTeamPolicy(input) {
|
|
36414
37070
|
const operationId = input.operationId ?? createUlid();
|
|
36415
37071
|
const eventId = createUlid();
|
|
@@ -36420,7 +37076,7 @@ async function updateTeamPolicy(input) {
|
|
|
36420
37076
|
throw new Error("MANCODE_TEAM_POLICY_INVALID");
|
|
36421
37077
|
}
|
|
36422
37078
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
36423
|
-
const root =
|
|
37079
|
+
const root = path65.resolve(input.projectRoot);
|
|
36424
37080
|
const runtime = await readProjectRuntimeContext(root);
|
|
36425
37081
|
const store = resolveCoordinationEntityHomeStore(
|
|
36426
37082
|
runtime.entityHomeStoreContext
|
|
@@ -36501,7 +37157,7 @@ async function applyTeamTransportSet(input, write2) {
|
|
|
36501
37157
|
}
|
|
36502
37158
|
const remote = transportRemote(input.mode, input.remote);
|
|
36503
37159
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
36504
|
-
const root =
|
|
37160
|
+
const root = path65.resolve(input.projectRoot);
|
|
36505
37161
|
const runtime = await readProjectRuntimeContext(root);
|
|
36506
37162
|
const store = resolveCoordinationEntityHomeStore(
|
|
36507
37163
|
runtime.entityHomeStoreContext
|
|
@@ -36634,9 +37290,9 @@ async function assertTransportAuthorityEmpty(projectRoot, store) {
|
|
|
36634
37290
|
listClaims(store),
|
|
36635
37291
|
listHandoffs(store),
|
|
36636
37292
|
directoryHasEntries(taskHeadDirectory(store)),
|
|
36637
|
-
directoryHasEntries(
|
|
37293
|
+
directoryHasEntries(path65.join(store.root, "transport-migrations")),
|
|
36638
37294
|
directoryHasEntries(
|
|
36639
|
-
|
|
37295
|
+
path65.join(projectRoot, ".mancode", "shared", "team", "transport")
|
|
36640
37296
|
),
|
|
36641
37297
|
pathExists14(gitRefCachePath(projectRoot))
|
|
36642
37298
|
]);
|
|
@@ -36666,21 +37322,21 @@ function assertPositiveRevision5(value, label) {
|
|
|
36666
37322
|
}
|
|
36667
37323
|
}
|
|
36668
37324
|
function teamPolicyPath(projectRoot) {
|
|
36669
|
-
return
|
|
37325
|
+
return path65.join(projectRoot, ".mancode", "shared", "team", "policy.json");
|
|
36670
37326
|
}
|
|
36671
37327
|
function projectConfigPath(projectRoot) {
|
|
36672
|
-
return
|
|
37328
|
+
return path65.join(projectRoot, ".mancode", "shared", "config.json");
|
|
36673
37329
|
}
|
|
36674
37330
|
async function writeJsonAtomic4(target, value) {
|
|
36675
|
-
await
|
|
36676
|
-
await assertPlainDirectory(
|
|
37331
|
+
await mkdir39(path65.dirname(target), { recursive: true });
|
|
37332
|
+
await assertPlainDirectory(path65.dirname(target));
|
|
36677
37333
|
await assertPlainFileOrMissing(target);
|
|
36678
|
-
const temporary =
|
|
36679
|
-
|
|
36680
|
-
`.${
|
|
37334
|
+
const temporary = path65.join(
|
|
37335
|
+
path65.dirname(target),
|
|
37336
|
+
`.${path65.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
36681
37337
|
);
|
|
36682
37338
|
try {
|
|
36683
|
-
await
|
|
37339
|
+
await writeFile46(temporary, `${JSON.stringify(value, null, 2)}
|
|
36684
37340
|
`, {
|
|
36685
37341
|
encoding: "utf8",
|
|
36686
37342
|
flag: "wx"
|
|
@@ -36704,7 +37360,7 @@ async function assertPlainFileOrMissing(target) {
|
|
|
36704
37360
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
36705
37361
|
}
|
|
36706
37362
|
} catch (error) {
|
|
36707
|
-
if (
|
|
37363
|
+
if (isNotFound32(error)) return;
|
|
36708
37364
|
throw error;
|
|
36709
37365
|
}
|
|
36710
37366
|
}
|
|
@@ -36716,7 +37372,7 @@ async function directoryHasEntries(target) {
|
|
|
36716
37372
|
}
|
|
36717
37373
|
return (await readdir20(target)).length > 0;
|
|
36718
37374
|
} catch (error) {
|
|
36719
|
-
if (
|
|
37375
|
+
if (isNotFound32(error)) return false;
|
|
36720
37376
|
throw error;
|
|
36721
37377
|
}
|
|
36722
37378
|
}
|
|
@@ -36725,28 +37381,28 @@ async function pathExists14(target) {
|
|
|
36725
37381
|
await lstat24(target);
|
|
36726
37382
|
return true;
|
|
36727
37383
|
} catch (error) {
|
|
36728
|
-
if (
|
|
37384
|
+
if (isNotFound32(error)) return false;
|
|
36729
37385
|
throw error;
|
|
36730
37386
|
}
|
|
36731
37387
|
}
|
|
36732
37388
|
async function releaseLocks4(locks) {
|
|
36733
37389
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
36734
37390
|
}
|
|
36735
|
-
function
|
|
37391
|
+
function isNotFound32(error) {
|
|
36736
37392
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
36737
37393
|
}
|
|
36738
37394
|
|
|
36739
37395
|
// src/team/transport-migration-adapters.ts
|
|
36740
37396
|
import {
|
|
36741
37397
|
lstat as lstat25,
|
|
36742
|
-
mkdir as
|
|
36743
|
-
readFile as
|
|
37398
|
+
mkdir as mkdir40,
|
|
37399
|
+
readFile as readFile45,
|
|
36744
37400
|
readdir as readdir21,
|
|
36745
|
-
rename as
|
|
37401
|
+
rename as rename13,
|
|
36746
37402
|
unlink as unlink4,
|
|
36747
|
-
writeFile as
|
|
37403
|
+
writeFile as writeFile47
|
|
36748
37404
|
} from "fs/promises";
|
|
36749
|
-
import
|
|
37405
|
+
import path66 from "path";
|
|
36750
37406
|
|
|
36751
37407
|
// src/team/transport-migration.ts
|
|
36752
37408
|
var DIGEST_PATTERN7 = /^sha256:[a-f0-9]{64}$/;
|
|
@@ -37570,7 +38226,7 @@ function parseTransportMigrationManifest(value) {
|
|
|
37570
38226
|
(left, right) => compareUtf813(left.handoffId, right.handoffId)
|
|
37571
38227
|
),
|
|
37572
38228
|
claimPolicy: "reissue-active",
|
|
37573
|
-
createdAt:
|
|
38229
|
+
createdAt: parseTimestamp17(value.createdAt, "createdAt")
|
|
37574
38230
|
};
|
|
37575
38231
|
if (manifest.workspaceId !== config.workspaceId || !manifest.actorProfiles.some(
|
|
37576
38232
|
(profile) => profile.actorId === manifest.actorId
|
|
@@ -37619,7 +38275,7 @@ function parseStagedTransportAuthority(value) {
|
|
|
37619
38275
|
"transportEpoch"
|
|
37620
38276
|
),
|
|
37621
38277
|
coordinationDomainId: parseCoordinationDomainId(value.coordinationDomainId),
|
|
37622
|
-
stagedAt:
|
|
38278
|
+
stagedAt: parseTimestamp17(value.stagedAt, "stagedAt")
|
|
37623
38279
|
};
|
|
37624
38280
|
}
|
|
37625
38281
|
function parseEstablishedTransportAuthority(value) {
|
|
@@ -37662,7 +38318,7 @@ function parseEstablishedTransportAuthority(value) {
|
|
|
37662
38318
|
parseClaim
|
|
37663
38319
|
).sort((left, right) => compareUtf813(left.claimId, right.claimId)),
|
|
37664
38320
|
receipt: parseNonEmptyString(value.receipt, "receipt"),
|
|
37665
|
-
establishedAt:
|
|
38321
|
+
establishedAt: parseTimestamp17(value.establishedAt, "establishedAt")
|
|
37666
38322
|
};
|
|
37667
38323
|
assertUniqueCoordinationEntities(established.activeClaims, []);
|
|
37668
38324
|
return established;
|
|
@@ -37798,7 +38454,7 @@ function parseDigest7(value, label) {
|
|
|
37798
38454
|
}
|
|
37799
38455
|
return value;
|
|
37800
38456
|
}
|
|
37801
|
-
function
|
|
38457
|
+
function parseTimestamp17(value, label) {
|
|
37802
38458
|
if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
|
|
37803
38459
|
throw new Error(`${label} must be an ISO timestamp`);
|
|
37804
38460
|
}
|
|
@@ -37818,7 +38474,7 @@ function compareUtf813(left, right) {
|
|
|
37818
38474
|
var STAGE_DIRECTORY = "transport-migrations";
|
|
37819
38475
|
var COLLECTIONS = ["claims", "handoffs", "task-heads"];
|
|
37820
38476
|
async function createTransportMigrationFileAdapters(input) {
|
|
37821
|
-
const projectRoot =
|
|
38477
|
+
const projectRoot = path66.resolve(input.projectRoot);
|
|
37822
38478
|
assertUlid(input.actorId, "transport migration adapter actorId");
|
|
37823
38479
|
if (input.operationId !== void 0) {
|
|
37824
38480
|
assertUlid(input.operationId, "transport migration adapter operationId");
|
|
@@ -37870,7 +38526,7 @@ async function createTransportMigrationFileAdapters(input) {
|
|
|
37870
38526
|
var FileSystemTransportMigrationConfigAdapter = class {
|
|
37871
38527
|
constructor(projectRoot, coordinationStore) {
|
|
37872
38528
|
this.coordinationStore = coordinationStore;
|
|
37873
|
-
this.projectRoot =
|
|
38529
|
+
this.projectRoot = path66.resolve(projectRoot);
|
|
37874
38530
|
}
|
|
37875
38531
|
projectRoot;
|
|
37876
38532
|
async read() {
|
|
@@ -38723,33 +39379,33 @@ async function publishMigrationActorProfiles(projectRoot, profiles) {
|
|
|
38723
39379
|
}
|
|
38724
39380
|
}
|
|
38725
39381
|
async function archiveLocalCoordinationCollections(store, operationId) {
|
|
38726
|
-
const archiveRoot =
|
|
39382
|
+
const archiveRoot = path66.join(
|
|
38727
39383
|
store.root,
|
|
38728
39384
|
STAGE_DIRECTORY,
|
|
38729
39385
|
"archive",
|
|
38730
39386
|
operationId
|
|
38731
39387
|
);
|
|
38732
|
-
await
|
|
39388
|
+
await mkdir40(archiveRoot, { recursive: true });
|
|
38733
39389
|
const directories = {
|
|
38734
39390
|
claims: claimDirectory(store),
|
|
38735
39391
|
handoffs: handoffDirectory(store),
|
|
38736
39392
|
"task-heads": taskHeadDirectory(store)
|
|
38737
39393
|
};
|
|
38738
39394
|
for (const name of COLLECTIONS) {
|
|
38739
|
-
const archived =
|
|
38740
|
-
const absent =
|
|
39395
|
+
const archived = path66.join(archiveRoot, name);
|
|
39396
|
+
const absent = path66.join(archiveRoot, `${name}.absent`);
|
|
38741
39397
|
if (await pathKind(archived) === "directory" || await pathKind(absent) === "file") {
|
|
38742
39398
|
continue;
|
|
38743
39399
|
}
|
|
38744
39400
|
const sourceKind = await pathKind(directories[name]);
|
|
38745
39401
|
if (sourceKind === null) {
|
|
38746
|
-
await
|
|
39402
|
+
await writeFile47(absent, "\n", { encoding: "utf8", flag: "wx" });
|
|
38747
39403
|
continue;
|
|
38748
39404
|
}
|
|
38749
39405
|
if (sourceKind !== "directory") {
|
|
38750
39406
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_LOCAL_AUTHORITY_UNSAFE");
|
|
38751
39407
|
}
|
|
38752
|
-
await
|
|
39408
|
+
await rename13(directories[name], archived);
|
|
38753
39409
|
}
|
|
38754
39410
|
}
|
|
38755
39411
|
async function listActorProfiles(projectRoot) {
|
|
@@ -38758,7 +39414,7 @@ async function listActorProfiles(projectRoot) {
|
|
|
38758
39414
|
try {
|
|
38759
39415
|
entries = await readdir21(directory);
|
|
38760
39416
|
} catch (error) {
|
|
38761
|
-
if (
|
|
39417
|
+
if (isNotFound33(error)) return [];
|
|
38762
39418
|
throw error;
|
|
38763
39419
|
}
|
|
38764
39420
|
const profiles = [];
|
|
@@ -38775,18 +39431,18 @@ async function listActorProfiles(projectRoot) {
|
|
|
38775
39431
|
return profiles;
|
|
38776
39432
|
}
|
|
38777
39433
|
async function listSharedTaskRefs(projectRoot) {
|
|
38778
|
-
const directory =
|
|
39434
|
+
const directory = path66.join(projectRoot, ".mancode", "shared", "workflows");
|
|
38779
39435
|
let entries;
|
|
38780
39436
|
try {
|
|
38781
39437
|
entries = await readdir21(directory);
|
|
38782
39438
|
} catch (error) {
|
|
38783
|
-
if (
|
|
39439
|
+
if (isNotFound33(error)) return [];
|
|
38784
39440
|
throw error;
|
|
38785
39441
|
}
|
|
38786
39442
|
const refs = [];
|
|
38787
39443
|
for (const taskId of entries.sort(compareUtf814)) {
|
|
38788
39444
|
assertUlid(taskId, "shared workflow directory");
|
|
38789
|
-
const stat5 = await lstat25(
|
|
39445
|
+
const stat5 = await lstat25(path66.join(directory, taskId));
|
|
38790
39446
|
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
38791
39447
|
throw new Error("MANCODE_CONTEXT_PATH_UNSAFE");
|
|
38792
39448
|
}
|
|
@@ -38798,7 +39454,7 @@ async function readTaskSnapshotOrNull(projectRoot, taskRef) {
|
|
|
38798
39454
|
try {
|
|
38799
39455
|
return await new V3ContextStore(projectRoot).readTaskSnapshot(taskRef);
|
|
38800
39456
|
} catch (error) {
|
|
38801
|
-
if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" ||
|
|
39457
|
+
if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" || isNotFound33(error))) {
|
|
38802
39458
|
return null;
|
|
38803
39459
|
}
|
|
38804
39460
|
throw error;
|
|
@@ -38860,7 +39516,7 @@ async function readStagedRecord(store, operationId) {
|
|
|
38860
39516
|
);
|
|
38861
39517
|
}
|
|
38862
39518
|
function stagedPath(store, operationId) {
|
|
38863
|
-
return
|
|
39519
|
+
return path66.join(
|
|
38864
39520
|
store.root,
|
|
38865
39521
|
STAGE_DIRECTORY,
|
|
38866
39522
|
"staged",
|
|
@@ -38868,7 +39524,7 @@ function stagedPath(store, operationId) {
|
|
|
38868
39524
|
);
|
|
38869
39525
|
}
|
|
38870
39526
|
function establishedPath(store, operationId) {
|
|
38871
|
-
return
|
|
39527
|
+
return path66.join(
|
|
38872
39528
|
store.root,
|
|
38873
39529
|
STAGE_DIRECTORY,
|
|
38874
39530
|
"established",
|
|
@@ -38876,12 +39532,12 @@ function establishedPath(store, operationId) {
|
|
|
38876
39532
|
);
|
|
38877
39533
|
}
|
|
38878
39534
|
function projectConfigPath2(projectRoot) {
|
|
38879
|
-
return
|
|
39535
|
+
return path66.join(projectRoot, ".mancode", "shared", "config.json");
|
|
38880
39536
|
}
|
|
38881
39537
|
async function readProjectConfigFile(projectRoot) {
|
|
38882
39538
|
try {
|
|
38883
39539
|
return parseProjectConfig(
|
|
38884
|
-
JSON.parse(await
|
|
39540
|
+
JSON.parse(await readFile45(projectConfigPath2(projectRoot), "utf8"))
|
|
38885
39541
|
);
|
|
38886
39542
|
} catch (error) {
|
|
38887
39543
|
if (error instanceof SyntaxError) {
|
|
@@ -38891,14 +39547,14 @@ async function readProjectConfigFile(projectRoot) {
|
|
|
38891
39547
|
}
|
|
38892
39548
|
}
|
|
38893
39549
|
async function writeJsonAtomic5(target, value) {
|
|
38894
|
-
await
|
|
38895
|
-
await assertPlainDirectory2(
|
|
38896
|
-
const temporary =
|
|
38897
|
-
|
|
38898
|
-
`.${
|
|
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`
|
|
38899
39555
|
);
|
|
38900
39556
|
try {
|
|
38901
|
-
await
|
|
39557
|
+
await writeFile47(temporary, serialize14(value), {
|
|
38902
39558
|
encoding: "utf8",
|
|
38903
39559
|
flag: "wx"
|
|
38904
39560
|
});
|
|
@@ -38909,10 +39565,10 @@ async function writeJsonAtomic5(target, value) {
|
|
|
38909
39565
|
}
|
|
38910
39566
|
}
|
|
38911
39567
|
async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
|
|
38912
|
-
await
|
|
38913
|
-
await assertPlainDirectory2(
|
|
39568
|
+
await mkdir40(path66.dirname(target), { recursive: true });
|
|
39569
|
+
await assertPlainDirectory2(path66.dirname(target));
|
|
38914
39570
|
try {
|
|
38915
|
-
await
|
|
39571
|
+
await writeFile47(target, serialize14(value), { encoding: "utf8", flag: "wx" });
|
|
38916
39572
|
} catch (error) {
|
|
38917
39573
|
if (!isAlreadyExists25(error)) throw error;
|
|
38918
39574
|
const existing = await readJsonOrNull5(target, parser, conflictCode);
|
|
@@ -38928,14 +39584,14 @@ async function readJsonOrNull5(target, parser, corruptCode) {
|
|
|
38928
39584
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
38929
39585
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
38930
39586
|
}
|
|
38931
|
-
const parsed = parser(JSON.parse(await
|
|
39587
|
+
const parsed = parser(JSON.parse(await readFile45(target, "utf8")));
|
|
38932
39588
|
const after = await lstat25(target);
|
|
38933
39589
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
38934
39590
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
38935
39591
|
}
|
|
38936
39592
|
return parsed;
|
|
38937
39593
|
} catch (error) {
|
|
38938
|
-
if (
|
|
39594
|
+
if (isNotFound33(error)) return null;
|
|
38939
39595
|
if (error instanceof SyntaxError) throw new Error(corruptCode);
|
|
38940
39596
|
throw error;
|
|
38941
39597
|
}
|
|
@@ -38993,7 +39649,7 @@ async function pathKind(target) {
|
|
|
38993
39649
|
if (stat5.isDirectory()) return "directory";
|
|
38994
39650
|
return "other";
|
|
38995
39651
|
} catch (error) {
|
|
38996
|
-
if (
|
|
39652
|
+
if (isNotFound33(error)) return null;
|
|
38997
39653
|
throw error;
|
|
38998
39654
|
}
|
|
38999
39655
|
}
|
|
@@ -39007,7 +39663,7 @@ async function unlinkIfExists2(target) {
|
|
|
39007
39663
|
try {
|
|
39008
39664
|
await unlink4(target);
|
|
39009
39665
|
} catch (error) {
|
|
39010
|
-
if (!
|
|
39666
|
+
if (!isNotFound33(error)) throw error;
|
|
39011
39667
|
}
|
|
39012
39668
|
}
|
|
39013
39669
|
function serialize14(value) {
|
|
@@ -39020,7 +39676,7 @@ function compareUtf814(left, right) {
|
|
|
39020
39676
|
function isAlreadyExists25(error) {
|
|
39021
39677
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
39022
39678
|
}
|
|
39023
|
-
function
|
|
39679
|
+
function isNotFound33(error) {
|
|
39024
39680
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
39025
39681
|
}
|
|
39026
39682
|
|
|
@@ -40460,16 +41116,16 @@ function parsePositiveInteger6(value) {
|
|
|
40460
41116
|
}
|
|
40461
41117
|
|
|
40462
41118
|
// src/commands/uninstall.ts
|
|
40463
|
-
import { access as access5, readFile as
|
|
40464
|
-
import
|
|
41119
|
+
import { access as access5, readFile as readFile46, rm as rm21, writeFile as writeFile48 } from "fs/promises";
|
|
41120
|
+
import path67 from "path";
|
|
40465
41121
|
import process12 from "process";
|
|
40466
41122
|
var EXIT_OK10 = 0;
|
|
40467
41123
|
var EXIT_NOT_INITIALIZED7 = 1;
|
|
40468
41124
|
var EXIT_UNSUPPORTED_PLATFORM2 = 2;
|
|
40469
41125
|
var EXIT_V3_AUTHORITY_PROTECTED = 3;
|
|
40470
41126
|
async function uninstall(rootDir = process12.cwd(), platform, options = {}) {
|
|
40471
|
-
const stateFile =
|
|
40472
|
-
const v3SchemaFile =
|
|
41127
|
+
const stateFile = path67.join(rootDir, ".mancode", "state.json");
|
|
41128
|
+
const v3SchemaFile = path67.join(rootDir, ".mancode", "schema.json");
|
|
40473
41129
|
if (await pathExists15(v3SchemaFile)) {
|
|
40474
41130
|
return uninstallV3(rootDir, platform, options);
|
|
40475
41131
|
}
|
|
@@ -40551,6 +41207,10 @@ async function uninstallPlatform(rootDir, platform) {
|
|
|
40551
41207
|
await uninstallCopilot(rootDir);
|
|
40552
41208
|
} else if (platform === "zcode") {
|
|
40553
41209
|
await uninstallZcode(rootDir);
|
|
41210
|
+
} else if (platform === "kimi-code") {
|
|
41211
|
+
await uninstallKimiCode(rootDir);
|
|
41212
|
+
} else if (platform === "qoder") {
|
|
41213
|
+
await uninstallQoder(rootDir);
|
|
40554
41214
|
}
|
|
40555
41215
|
await removeFromConfig(rootDir, platform);
|
|
40556
41216
|
}
|
|
@@ -40560,7 +41220,7 @@ async function uninstallAll(rootDir) {
|
|
|
40560
41220
|
await uninstallPlatform(rootDir, p);
|
|
40561
41221
|
}
|
|
40562
41222
|
console.log("\u2713 Removing .mancode/ directory...");
|
|
40563
|
-
await
|
|
41223
|
+
await rm21(path67.join(rootDir, ".mancode"), {
|
|
40564
41224
|
recursive: true,
|
|
40565
41225
|
force: true
|
|
40566
41226
|
});
|
|
@@ -40570,10 +41230,10 @@ async function uninstallClaudeCode(rootDir) {
|
|
|
40570
41230
|
await cleanClaudeSettings(rootDir);
|
|
40571
41231
|
}
|
|
40572
41232
|
async function cleanClaudeSettings(rootDir) {
|
|
40573
|
-
const settingsPath =
|
|
41233
|
+
const settingsPath = path67.join(rootDir, ".claude", "settings.json");
|
|
40574
41234
|
let content;
|
|
40575
41235
|
try {
|
|
40576
|
-
content = await
|
|
41236
|
+
content = await readFile46(settingsPath, "utf-8");
|
|
40577
41237
|
} catch {
|
|
40578
41238
|
return;
|
|
40579
41239
|
}
|
|
@@ -40599,7 +41259,7 @@ async function cleanClaudeSettings(rootDir) {
|
|
|
40599
41259
|
);
|
|
40600
41260
|
settings.skills = Object.keys(retainedSkills).length > 0 ? retainedSkills : void 0;
|
|
40601
41261
|
}
|
|
40602
|
-
await
|
|
41262
|
+
await writeFile48(
|
|
40603
41263
|
settingsPath,
|
|
40604
41264
|
`${JSON.stringify(settings, null, 2)}
|
|
40605
41265
|
`,
|
|
@@ -40648,62 +41308,100 @@ async function uninstallCursor(rootDir) {
|
|
|
40648
41308
|
await removeCursorCommands(rootDir);
|
|
40649
41309
|
}
|
|
40650
41310
|
async function uninstallCodex(rootDir) {
|
|
40651
|
-
const agentsPath =
|
|
41311
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
40652
41312
|
try {
|
|
40653
|
-
const content = await
|
|
41313
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
40654
41314
|
const cleaned = removeManagedBlock(content);
|
|
40655
41315
|
if (cleaned.trim()) {
|
|
40656
|
-
await
|
|
41316
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
40657
41317
|
`, "utf-8");
|
|
40658
41318
|
} else {
|
|
40659
|
-
await
|
|
41319
|
+
await rm21(agentsPath, { force: true });
|
|
40660
41320
|
}
|
|
40661
41321
|
} catch {
|
|
40662
41322
|
}
|
|
40663
41323
|
await removeCodexSkills(rootDir);
|
|
40664
41324
|
}
|
|
40665
41325
|
async function uninstallCopilot(rootDir) {
|
|
40666
|
-
const instructionsPath =
|
|
41326
|
+
const instructionsPath = path67.join(
|
|
40667
41327
|
rootDir,
|
|
40668
41328
|
".github",
|
|
40669
41329
|
"copilot-instructions.md"
|
|
40670
41330
|
);
|
|
40671
41331
|
try {
|
|
40672
|
-
const content = await
|
|
41332
|
+
const content = await readFile46(instructionsPath, "utf-8");
|
|
40673
41333
|
const cleaned = removeManagedBlock(content);
|
|
40674
41334
|
if (cleaned.trim()) {
|
|
40675
|
-
await
|
|
41335
|
+
await writeFile48(instructionsPath, `${cleaned}
|
|
40676
41336
|
`, "utf-8");
|
|
40677
41337
|
} else {
|
|
40678
|
-
await
|
|
41338
|
+
await rm21(instructionsPath, { force: true });
|
|
40679
41339
|
}
|
|
40680
41340
|
} catch {
|
|
40681
41341
|
}
|
|
40682
41342
|
await removeCopilotPrompts(rootDir);
|
|
40683
41343
|
}
|
|
40684
41344
|
async function uninstallZcode(rootDir) {
|
|
40685
|
-
const agentsPath =
|
|
41345
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
40686
41346
|
try {
|
|
40687
|
-
const content = await
|
|
41347
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
40688
41348
|
const cleaned = removeManagedBlock(
|
|
40689
41349
|
content,
|
|
40690
41350
|
ZCODE_MANCODE_START_MARKER,
|
|
40691
41351
|
ZCODE_MANCODE_END_MARKER
|
|
40692
41352
|
);
|
|
40693
41353
|
if (cleaned.trim()) {
|
|
40694
|
-
await
|
|
41354
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
40695
41355
|
`, "utf-8");
|
|
40696
41356
|
} else {
|
|
40697
|
-
await
|
|
41357
|
+
await rm21(agentsPath, { force: true });
|
|
40698
41358
|
}
|
|
40699
41359
|
} catch {
|
|
40700
41360
|
}
|
|
40701
41361
|
await removeZcodeSkills(rootDir);
|
|
40702
41362
|
}
|
|
41363
|
+
async function uninstallKimiCode(rootDir) {
|
|
41364
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
41365
|
+
try {
|
|
41366
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
41367
|
+
const cleaned = removeManagedBlock(
|
|
41368
|
+
content,
|
|
41369
|
+
KIMI_MANCODE_START_MARKER,
|
|
41370
|
+
KIMI_MANCODE_END_MARKER
|
|
41371
|
+
);
|
|
41372
|
+
if (cleaned.trim()) {
|
|
41373
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
41374
|
+
`, "utf-8");
|
|
41375
|
+
} else {
|
|
41376
|
+
await rm21(agentsPath, { force: true });
|
|
41377
|
+
}
|
|
41378
|
+
} catch {
|
|
41379
|
+
}
|
|
41380
|
+
await removeKimiSkills(rootDir);
|
|
41381
|
+
}
|
|
41382
|
+
async function uninstallQoder(rootDir) {
|
|
41383
|
+
const agentsPath = path67.join(rootDir, "AGENTS.md");
|
|
41384
|
+
try {
|
|
41385
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
41386
|
+
const cleaned = removeManagedBlock(
|
|
41387
|
+
content,
|
|
41388
|
+
QODER_MANCODE_START_MARKER,
|
|
41389
|
+
QODER_MANCODE_END_MARKER
|
|
41390
|
+
);
|
|
41391
|
+
if (cleaned.trim()) {
|
|
41392
|
+
await writeFile48(agentsPath, `${cleaned}
|
|
41393
|
+
`, "utf-8");
|
|
41394
|
+
} else {
|
|
41395
|
+
await rm21(agentsPath, { force: true });
|
|
41396
|
+
}
|
|
41397
|
+
} catch {
|
|
41398
|
+
}
|
|
41399
|
+
await removeQoderCommands(rootDir);
|
|
41400
|
+
}
|
|
40703
41401
|
async function removeFromConfig(rootDir, platform) {
|
|
40704
|
-
const configPath =
|
|
41402
|
+
const configPath = path67.join(rootDir, ".mancode", "config.json");
|
|
40705
41403
|
try {
|
|
40706
|
-
const raw = await
|
|
41404
|
+
const raw = await readFile46(configPath, "utf-8");
|
|
40707
41405
|
const config = JSON.parse(raw);
|
|
40708
41406
|
if (Array.isArray(config.platforms)) {
|
|
40709
41407
|
config.platforms = config.platforms.filter((p) => p !== platform);
|
|
@@ -40715,7 +41413,7 @@ async function removeFromConfig(rootDir, platform) {
|
|
|
40715
41413
|
);
|
|
40716
41414
|
config.platformOptions = Object.keys(platformOptions).length > 0 ? platformOptions : void 0;
|
|
40717
41415
|
}
|
|
40718
|
-
await
|
|
41416
|
+
await writeFile48(
|
|
40719
41417
|
configPath,
|
|
40720
41418
|
`${JSON.stringify(config, null, 2)}
|
|
40721
41419
|
`,
|
|
@@ -40748,8 +41446,8 @@ function version() {
|
|
|
40748
41446
|
}
|
|
40749
41447
|
|
|
40750
41448
|
// src/commands/workflow.ts
|
|
40751
|
-
import { access as access6, readFile as
|
|
40752
|
-
import
|
|
41449
|
+
import { access as access6, readFile as readFile48, rm as rm23, writeFile as writeFile50 } from "fs/promises";
|
|
41450
|
+
import path69 from "path";
|
|
40753
41451
|
|
|
40754
41452
|
// src/context/child-result-merge.ts
|
|
40755
41453
|
async function mergeV3ChildResult(input) {
|
|
@@ -43809,13 +44507,13 @@ function updateMetadata4(previous, verification, operationId, updatedAt) {
|
|
|
43809
44507
|
// src/context/workflow-create.ts
|
|
43810
44508
|
import {
|
|
43811
44509
|
lstat as lstat26,
|
|
43812
|
-
mkdir as
|
|
43813
|
-
readFile as
|
|
43814
|
-
rename as
|
|
43815
|
-
rm as
|
|
43816
|
-
writeFile as
|
|
44510
|
+
mkdir as mkdir41,
|
|
44511
|
+
readFile as readFile47,
|
|
44512
|
+
rename as rename14,
|
|
44513
|
+
rm as rm22,
|
|
44514
|
+
writeFile as writeFile49
|
|
43817
44515
|
} from "fs/promises";
|
|
43818
|
-
import
|
|
44516
|
+
import path68 from "path";
|
|
43819
44517
|
|
|
43820
44518
|
// src/context/creation-resolution.ts
|
|
43821
44519
|
function resolveWorkflowCreation(request) {
|
|
@@ -43925,7 +44623,7 @@ function rejectConflict(provided, expected, label) {
|
|
|
43925
44623
|
|
|
43926
44624
|
// src/context/workflow-create.ts
|
|
43927
44625
|
async function createV3Workflow(input) {
|
|
43928
|
-
const projectRoot =
|
|
44626
|
+
const projectRoot = path68.resolve(requireProjectRoot2(input.projectRoot));
|
|
43929
44627
|
const task = requireText2(input.task, "workflow task");
|
|
43930
44628
|
const client = requireText2(input.client, "workflow client");
|
|
43931
44629
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -44110,8 +44808,8 @@ async function createV3Workflow(input) {
|
|
|
44110
44808
|
throw new Error("MANCODE_REVISION_CONFLICT");
|
|
44111
44809
|
}
|
|
44112
44810
|
const taskParent = await ensureSafeTaskParent3(projectRoot, taskRef);
|
|
44113
|
-
const targetDirectory =
|
|
44114
|
-
stagingDirectory =
|
|
44811
|
+
const targetDirectory = path68.join(taskParent, taskRef.taskId);
|
|
44812
|
+
stagingDirectory = path68.join(
|
|
44115
44813
|
taskParent,
|
|
44116
44814
|
`.${taskRef.taskId}.${operationId}.staging`
|
|
44117
44815
|
);
|
|
@@ -44560,10 +45258,10 @@ async function ensureSafeTaskParent3(projectRoot, taskRef) {
|
|
|
44560
45258
|
const segments = [".mancode", taskRef.namespace, "workflows"];
|
|
44561
45259
|
let current = projectRoot;
|
|
44562
45260
|
for (const segment of segments) {
|
|
44563
|
-
current =
|
|
45261
|
+
current = path68.join(current, segment);
|
|
44564
45262
|
const existing = await lstatOrNull5(current);
|
|
44565
45263
|
if (existing === null) {
|
|
44566
|
-
await
|
|
45264
|
+
await mkdir41(current);
|
|
44567
45265
|
continue;
|
|
44568
45266
|
}
|
|
44569
45267
|
if (!existing.isDirectory() || existing.isSymbolicLink()) {
|
|
@@ -44576,7 +45274,7 @@ async function assertDirectoryAbsent(target, code) {
|
|
|
44576
45274
|
if (await lstatOrNull5(target) !== null) throw new Error(code);
|
|
44577
45275
|
}
|
|
44578
45276
|
async function writeStagedEntities(stagingDirectory, entities) {
|
|
44579
|
-
await
|
|
45277
|
+
await mkdir41(stagingDirectory);
|
|
44580
45278
|
await assertDirectory(stagingDirectory);
|
|
44581
45279
|
await Promise.all([
|
|
44582
45280
|
writeStagedJson(stagingDirectory, "metadata.json", entities.metadata),
|
|
@@ -44596,8 +45294,8 @@ async function writeStagedEntities(stagingDirectory, entities) {
|
|
|
44596
45294
|
}
|
|
44597
45295
|
async function writeStagedJson(stagingDirectory, fileName, value) {
|
|
44598
45296
|
await assertDirectory(stagingDirectory);
|
|
44599
|
-
const target =
|
|
44600
|
-
await
|
|
45297
|
+
const target = path68.join(stagingDirectory, fileName);
|
|
45298
|
+
await writeFile49(target, `${JSON.stringify(value, null, 2)}
|
|
44601
45299
|
`, {
|
|
44602
45300
|
encoding: "utf8",
|
|
44603
45301
|
flag: "wx"
|
|
@@ -44634,12 +45332,12 @@ async function validateStagedEntities(stagingDirectory) {
|
|
|
44634
45332
|
});
|
|
44635
45333
|
}
|
|
44636
45334
|
async function readStagedJson(stagingDirectory, fileName, parser) {
|
|
44637
|
-
const target =
|
|
45335
|
+
const target = path68.join(stagingDirectory, fileName);
|
|
44638
45336
|
const before = await lstat26(target);
|
|
44639
45337
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
44640
45338
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
44641
45339
|
}
|
|
44642
|
-
const parsed = parser(JSON.parse(await
|
|
45340
|
+
const parsed = parser(JSON.parse(await readFile47(target, "utf8")));
|
|
44643
45341
|
const after = await lstat26(target);
|
|
44644
45342
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
44645
45343
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -44653,7 +45351,7 @@ async function publishStagedTask(stagingDirectory, targetDirectory) {
|
|
|
44653
45351
|
targetDirectory,
|
|
44654
45352
|
"MANCODE_WORKFLOW_ALREADY_EXISTS"
|
|
44655
45353
|
);
|
|
44656
|
-
await
|
|
45354
|
+
await rename14(stagingDirectory, targetDirectory);
|
|
44657
45355
|
await assertDirectory(targetDirectory);
|
|
44658
45356
|
}
|
|
44659
45357
|
async function advanceJournal(store, previous, stepId, now, canAbort) {
|
|
@@ -44731,7 +45429,7 @@ async function abortPreparedCreate(store, journal, stagingDirectory, now) {
|
|
|
44731
45429
|
{ canAbort: true }
|
|
44732
45430
|
);
|
|
44733
45431
|
} finally {
|
|
44734
|
-
await
|
|
45432
|
+
await rm22(stagingDirectory, { recursive: true, force: true });
|
|
44735
45433
|
}
|
|
44736
45434
|
}
|
|
44737
45435
|
async function assertDirectory(target) {
|
|
@@ -44744,7 +45442,7 @@ async function lstatOrNull5(target) {
|
|
|
44744
45442
|
try {
|
|
44745
45443
|
return await lstat26(target);
|
|
44746
45444
|
} catch (error) {
|
|
44747
|
-
if (
|
|
45445
|
+
if (isNotFound34(error)) return null;
|
|
44748
45446
|
throw error;
|
|
44749
45447
|
}
|
|
44750
45448
|
}
|
|
@@ -44764,7 +45462,7 @@ function requireText2(value, label) {
|
|
|
44764
45462
|
}
|
|
44765
45463
|
return value.trim();
|
|
44766
45464
|
}
|
|
44767
|
-
function
|
|
45465
|
+
function isNotFound34(error) {
|
|
44768
45466
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
44769
45467
|
}
|
|
44770
45468
|
|
|
@@ -45742,7 +46440,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
|
|
|
45742
46440
|
if (v3Activation === "v3_active") {
|
|
45743
46441
|
return workflowV3(rootDir, subcommand, args, options);
|
|
45744
46442
|
}
|
|
45745
|
-
if (!await pathExists16(
|
|
46443
|
+
if (!await pathExists16(path69.join(rootDir, ".mancode", "state.json"))) {
|
|
45746
46444
|
if (v3Activation !== null) {
|
|
45747
46445
|
return printV3Error(
|
|
45748
46446
|
options.json,
|
|
@@ -46637,7 +47335,6 @@ async function workflowReviewV3(rootDir, args, options) {
|
|
|
46637
47335
|
taskRef: result2.metadata.taskRef,
|
|
46638
47336
|
metadata: result2.metadata,
|
|
46639
47337
|
review: result2.review,
|
|
46640
|
-
verification: result2.verification,
|
|
46641
47338
|
aggregate: result2.aggregate,
|
|
46642
47339
|
taskHeadFence: result2.taskHeadFence,
|
|
46643
47340
|
operation: result2.operation
|
|
@@ -46715,8 +47412,6 @@ async function workflowPlanV3(rootDir, args, options) {
|
|
|
46715
47412
|
taskRef: result2.metadata.taskRef,
|
|
46716
47413
|
metadata: result2.metadata,
|
|
46717
47414
|
planDigest: result2.planDigest,
|
|
46718
|
-
review: result2.review,
|
|
46719
|
-
verification: result2.verification,
|
|
46720
47415
|
aggregate: result2.aggregate,
|
|
46721
47416
|
taskHeadFence: result2.taskHeadFence,
|
|
46722
47417
|
operation: result2.operation
|
|
@@ -46781,8 +47476,6 @@ async function workflowRequirementsV3(rootDir, args, options) {
|
|
|
46781
47476
|
taskRef: result2.metadata.taskRef,
|
|
46782
47477
|
metadata: result2.metadata,
|
|
46783
47478
|
requirements: result2.requirements,
|
|
46784
|
-
review: result2.review,
|
|
46785
|
-
verification: result2.verification,
|
|
46786
47479
|
aggregate: result2.aggregate,
|
|
46787
47480
|
taskHeadFence: result2.taskHeadFence,
|
|
46788
47481
|
operation: result2.operation
|
|
@@ -46834,8 +47527,8 @@ function parseV3ParticipantActorIds(values) {
|
|
|
46834
47527
|
return values;
|
|
46835
47528
|
}
|
|
46836
47529
|
async function readWorkflowInputFile(projectRoot, value) {
|
|
46837
|
-
const inputPath =
|
|
46838
|
-
return
|
|
47530
|
+
const inputPath = path69.isAbsolute(value) ? value : path69.resolve(projectRoot, value);
|
|
47531
|
+
return readFile48(inputPath, "utf8");
|
|
46839
47532
|
}
|
|
46840
47533
|
async function readWorkflowJsonInputFile(projectRoot, value) {
|
|
46841
47534
|
return JSON.parse(await readWorkflowInputFile(projectRoot, value));
|
|
@@ -46908,7 +47601,7 @@ async function readV3ActivationState2(rootDir) {
|
|
|
46908
47601
|
try {
|
|
46909
47602
|
const manifest = parseSchemaManifest(
|
|
46910
47603
|
JSON.parse(
|
|
46911
|
-
await
|
|
47604
|
+
await readFile48(path69.join(rootDir, ".mancode", "schema.json"), "utf8")
|
|
46912
47605
|
)
|
|
46913
47606
|
);
|
|
46914
47607
|
return manifest.activationState === "v3_active" ? "v3_active" : "other";
|
|
@@ -46953,21 +47646,21 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
46953
47646
|
"requirements can only be finalized for an in-progress man or manteam workflow at step 1 or 2"
|
|
46954
47647
|
);
|
|
46955
47648
|
}
|
|
46956
|
-
const workflowPath =
|
|
46957
|
-
const jsonPath =
|
|
46958
|
-
const markdownPath =
|
|
46959
|
-
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");
|
|
46960
47653
|
let originalJson;
|
|
46961
47654
|
let originalMarkdown;
|
|
46962
47655
|
let originalMetadata;
|
|
46963
47656
|
try {
|
|
46964
|
-
const inputPath =
|
|
46965
|
-
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");
|
|
46966
47659
|
const requirements = parseRequirementsLedger2(input);
|
|
46967
47660
|
[originalJson, originalMarkdown, originalMetadata] = await Promise.all([
|
|
46968
47661
|
readOptionalText2(jsonPath),
|
|
46969
47662
|
readOptionalText2(markdownPath),
|
|
46970
|
-
|
|
47663
|
+
readFile48(metadataPath3, "utf-8")
|
|
46971
47664
|
]);
|
|
46972
47665
|
await writeRequirementsArtifacts(rootDir, taskId, requirements);
|
|
46973
47666
|
await updateWorkflow(rootDir, taskId, {
|
|
@@ -46997,7 +47690,7 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
46997
47690
|
const rollback = await Promise.allSettled([
|
|
46998
47691
|
restoreOptionalText(jsonPath, originalJson),
|
|
46999
47692
|
restoreOptionalText(markdownPath, originalMarkdown),
|
|
47000
|
-
|
|
47693
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8")
|
|
47001
47694
|
]);
|
|
47002
47695
|
rollbackIncomplete = rollback.some(
|
|
47003
47696
|
(result2) => result2.status === "rejected"
|
|
@@ -47085,7 +47778,7 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
47085
47778
|
);
|
|
47086
47779
|
}
|
|
47087
47780
|
if (options.evidenceFile) {
|
|
47088
|
-
const evidencePath =
|
|
47781
|
+
const evidencePath = path69.isAbsolute(options.evidenceFile) ? options.evidenceFile : path69.resolve(rootDir, options.evidenceFile);
|
|
47089
47782
|
if (!await pathExists16(evidencePath)) {
|
|
47090
47783
|
return invalidArg(
|
|
47091
47784
|
options,
|
|
@@ -47145,17 +47838,17 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
47145
47838
|
}
|
|
47146
47839
|
async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
47147
47840
|
const ledgerPath = verificationLedgerPath(rootDir, meta.taskId);
|
|
47148
|
-
const metadataPath3 =
|
|
47841
|
+
const metadataPath3 = path69.join(
|
|
47149
47842
|
rootDir,
|
|
47150
47843
|
".mancode",
|
|
47151
47844
|
"workflows",
|
|
47152
47845
|
meta.taskId,
|
|
47153
47846
|
"metadata.json"
|
|
47154
47847
|
);
|
|
47155
|
-
const specPath =
|
|
47848
|
+
const specPath = path69.join(rootDir, ".mancode", "memory", "spec.md");
|
|
47156
47849
|
const [originalLedger, originalMetadata, originalSpec] = await Promise.all([
|
|
47157
47850
|
readOptionalText2(ledgerPath),
|
|
47158
|
-
|
|
47851
|
+
readFile48(metadataPath3, "utf-8"),
|
|
47159
47852
|
readOptionalText2(specPath)
|
|
47160
47853
|
]);
|
|
47161
47854
|
const wasVerificationBlocked = meta.status === "blocked" && meta.blockingReason?.startsWith("[verification]");
|
|
@@ -47184,7 +47877,7 @@ async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
|
47184
47877
|
} catch (error) {
|
|
47185
47878
|
const rollback = await Promise.allSettled([
|
|
47186
47879
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
47187
|
-
|
|
47880
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8"),
|
|
47188
47881
|
restoreOptionalText(specPath, originalSpec)
|
|
47189
47882
|
]);
|
|
47190
47883
|
const message = error instanceof Error ? error.message : "verification transition failed";
|
|
@@ -47316,7 +48009,7 @@ async function workflowReview(rootDir, args, options) {
|
|
|
47316
48009
|
}
|
|
47317
48010
|
async function commitReviewSkip(rootDir, meta, reason) {
|
|
47318
48011
|
const ledgerPath = reviewLedgerPath(rootDir, meta.taskId);
|
|
47319
|
-
const metadataPath3 =
|
|
48012
|
+
const metadataPath3 = path69.join(
|
|
47320
48013
|
rootDir,
|
|
47321
48014
|
".mancode",
|
|
47322
48015
|
"workflows",
|
|
@@ -47325,7 +48018,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
|
|
|
47325
48018
|
);
|
|
47326
48019
|
const [originalLedger, originalMetadata] = await Promise.all([
|
|
47327
48020
|
readOptionalText2(ledgerPath),
|
|
47328
|
-
|
|
48021
|
+
readFile48(metadataPath3, "utf-8")
|
|
47329
48022
|
]);
|
|
47330
48023
|
try {
|
|
47331
48024
|
await initializeSkippedReview(rootDir, meta.taskId, reason);
|
|
@@ -47336,7 +48029,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
|
|
|
47336
48029
|
} catch (error) {
|
|
47337
48030
|
const rollback = await Promise.allSettled([
|
|
47338
48031
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
47339
|
-
|
|
48032
|
+
writeFile50(metadataPath3, originalMetadata, "utf-8")
|
|
47340
48033
|
]);
|
|
47341
48034
|
const message = error instanceof Error ? error.message : "review skip failed";
|
|
47342
48035
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -47556,18 +48249,18 @@ async function workflowHandoff(rootDir, taskId, options) {
|
|
|
47556
48249
|
"solo handoff requires an undecided in-progress workflow at step 4 with ready requirements"
|
|
47557
48250
|
);
|
|
47558
48251
|
}
|
|
47559
|
-
const workflowPath =
|
|
47560
|
-
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"))) {
|
|
47561
48254
|
return invalidArg(
|
|
47562
48255
|
options,
|
|
47563
48256
|
"solo handoff requires requirements.md and plan.md"
|
|
47564
48257
|
);
|
|
47565
48258
|
}
|
|
47566
|
-
const statePath =
|
|
48259
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
47567
48260
|
let originalState;
|
|
47568
48261
|
let state;
|
|
47569
48262
|
try {
|
|
47570
|
-
originalState = await
|
|
48263
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
47571
48264
|
state = JSON.parse(originalState);
|
|
47572
48265
|
} catch {
|
|
47573
48266
|
return invalidArg(
|
|
@@ -47638,11 +48331,11 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
|
|
|
47638
48331
|
`workflow is not an active solo handoff: ${taskId}`
|
|
47639
48332
|
);
|
|
47640
48333
|
}
|
|
47641
|
-
const statePath =
|
|
48334
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
47642
48335
|
let originalState;
|
|
47643
48336
|
let state;
|
|
47644
48337
|
try {
|
|
47645
|
-
originalState = await
|
|
48338
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
47646
48339
|
state = JSON.parse(originalState);
|
|
47647
48340
|
} catch {
|
|
47648
48341
|
return invalidArg(
|
|
@@ -47705,18 +48398,18 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
47705
48398
|
`workflow is not ready for a plan-only decision: ${taskId}`
|
|
47706
48399
|
);
|
|
47707
48400
|
}
|
|
47708
|
-
const workflowPath =
|
|
47709
|
-
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"))) {
|
|
47710
48403
|
return invalidArg(
|
|
47711
48404
|
options,
|
|
47712
48405
|
"plan-only requires requirements.md and plan.md"
|
|
47713
48406
|
);
|
|
47714
48407
|
}
|
|
47715
|
-
const statePath =
|
|
48408
|
+
const statePath = path69.join(rootDir, ".mancode", "state.json");
|
|
47716
48409
|
let originalState;
|
|
47717
48410
|
let state;
|
|
47718
48411
|
try {
|
|
47719
|
-
originalState = await
|
|
48412
|
+
originalState = await readFile48(statePath, "utf-8");
|
|
47720
48413
|
state = JSON.parse(originalState);
|
|
47721
48414
|
} catch {
|
|
47722
48415
|
return invalidArg(
|
|
@@ -47768,25 +48461,25 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
47768
48461
|
return EXIT_OK11;
|
|
47769
48462
|
}
|
|
47770
48463
|
async function commitPlanningTransition(args) {
|
|
47771
|
-
const metadataPath3 =
|
|
48464
|
+
const metadataPath3 = path69.join(
|
|
47772
48465
|
args.rootDir,
|
|
47773
48466
|
".mancode",
|
|
47774
48467
|
"workflows",
|
|
47775
48468
|
args.taskId,
|
|
47776
48469
|
"metadata.json"
|
|
47777
48470
|
);
|
|
47778
|
-
const specPath =
|
|
48471
|
+
const specPath = path69.join(args.rootDir, ".mancode", "memory", "spec.md");
|
|
47779
48472
|
let originalMetadata;
|
|
47780
48473
|
let originalSpec;
|
|
47781
48474
|
try {
|
|
47782
|
-
originalMetadata = await
|
|
48475
|
+
originalMetadata = await readFile48(metadataPath3, "utf-8");
|
|
47783
48476
|
originalSpec = await readOptionalText2(specPath);
|
|
47784
48477
|
} catch (error) {
|
|
47785
48478
|
return error instanceof Error ? `unable to prepare planning transition: ${error.message}` : "unable to prepare planning transition";
|
|
47786
48479
|
}
|
|
47787
48480
|
try {
|
|
47788
48481
|
await updateWorkflow(args.rootDir, args.taskId, args.workflowPatch);
|
|
47789
|
-
await
|
|
48482
|
+
await writeFile50(
|
|
47790
48483
|
args.statePath,
|
|
47791
48484
|
`${JSON.stringify(args.nextState, null, 2)}
|
|
47792
48485
|
`,
|
|
@@ -47800,9 +48493,9 @@ async function commitPlanningTransition(args) {
|
|
|
47800
48493
|
return null;
|
|
47801
48494
|
} catch (error) {
|
|
47802
48495
|
const rollback = await Promise.allSettled([
|
|
47803
|
-
|
|
47804
|
-
|
|
47805
|
-
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")
|
|
47806
48499
|
]);
|
|
47807
48500
|
const message = error instanceof Error ? error.message : "planning transition failed";
|
|
47808
48501
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -47810,7 +48503,7 @@ async function commitPlanningTransition(args) {
|
|
|
47810
48503
|
}
|
|
47811
48504
|
async function readOptionalText2(filePath) {
|
|
47812
48505
|
try {
|
|
47813
|
-
return await
|
|
48506
|
+
return await readFile48(filePath, "utf-8");
|
|
47814
48507
|
} catch (error) {
|
|
47815
48508
|
if (isNodeError10(error) && error.code === "ENOENT") return null;
|
|
47816
48509
|
throw error;
|
|
@@ -47818,10 +48511,10 @@ async function readOptionalText2(filePath) {
|
|
|
47818
48511
|
}
|
|
47819
48512
|
async function restoreOptionalText(filePath, content) {
|
|
47820
48513
|
if (content === null) {
|
|
47821
|
-
await
|
|
48514
|
+
await rm23(filePath, { force: true });
|
|
47822
48515
|
return;
|
|
47823
48516
|
}
|
|
47824
|
-
await
|
|
48517
|
+
await writeFile50(filePath, content, "utf-8");
|
|
47825
48518
|
}
|
|
47826
48519
|
function readActiveSoloPlan(value) {
|
|
47827
48520
|
if (!value || typeof value !== "object") return null;
|
|
@@ -48084,7 +48777,7 @@ program.command("init").description("Initialize mancode in the current project")
|
|
|
48084
48777
|
process.exitCode = code;
|
|
48085
48778
|
});
|
|
48086
48779
|
program.command("install [platform]").description(
|
|
48087
|
-
"Install platform adapter (claude-code, cursor, codex, copilot, zcode)"
|
|
48780
|
+
"Install platform adapter (claude-code, cursor, codex, copilot, zcode, kimi-code, qoder)"
|
|
48088
48781
|
).option("--force", "Reinstall even if already installed").option("--minimal", "Minimal install (MVP-2)").option(
|
|
48089
48782
|
"--shadow",
|
|
48090
48783
|
"Stage a mancode bootstrap candidate without changing live files"
|
|
@@ -48171,7 +48864,7 @@ contextSessionProgram.command("show").description("Show one explicit session wit
|
|
|
48171
48864
|
});
|
|
48172
48865
|
contextSessionProgram.command("spike").description("Record real-host session evidence without persisting host keys").requiredOption(
|
|
48173
48866
|
"--platform <platform>",
|
|
48174
|
-
"claude-code, codex, cursor, copilot, or
|
|
48867
|
+
"claude-code, codex, cursor, copilot, zcode, kimi-code, or qoder"
|
|
48175
48868
|
).requiredOption("--session-mode <mode>", "Evidence path: host or explicit").requiredOption(
|
|
48176
48869
|
"--host-session-source <source>",
|
|
48177
48870
|
"hook_stdin, environment, api, or none for explicit sessions"
|
|
@@ -48241,6 +48934,17 @@ contextProgram.command("reconcile-task-head <shared:id>").description(
|
|
|
48241
48934
|
options
|
|
48242
48935
|
);
|
|
48243
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
|
+
});
|
|
48244
48948
|
var contextWorktreeProgram = contextProgram.command("worktree").description("Register and inspect the current mancode checkout binding");
|
|
48245
48949
|
contextWorktreeProgram.command("register").description(
|
|
48246
48950
|
"Register this linked worktree before using mancode coordination"
|