mancode 0.5.6 → 0.6.1
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 +58 -24
- package/README.md +47 -19
- package/dist/{chunk-M5CWWECP.js → chunk-44UHUCE6.js} +59 -16
- package/dist/{chunk-M5CWWECP.js.map → chunk-44UHUCE6.js.map} +1 -1
- package/dist/{chunk-AWOIP2LC.js → chunk-PBXSV352.js} +99 -34
- package/dist/chunk-PBXSV352.js.map +1 -0
- package/dist/cli.js +849 -617
- package/dist/cli.js.map +1 -1
- package/dist/{store-Z53OE53A.js → store-TQFQCAAF.js} +2 -2
- package/dist/{v3-adapter-TCEFETAG.js → v3-adapter-TPXL336I.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-AWOIP2LC.js.map +0 -1
- /package/dist/{store-Z53OE53A.js.map → store-TQFQCAAF.js.map} +0 -0
- /package/dist/{v3-adapter-TCEFETAG.js.map → v3-adapter-TPXL336I.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
VERSION
|
|
4
4
|
} from "./chunk-57PJQDQ3.js";
|
|
5
5
|
import {
|
|
6
|
-
PROJECT_MANIFESTS,
|
|
7
6
|
V3ContextStore,
|
|
8
7
|
assertActivationRollbackManifestTransition,
|
|
9
8
|
assertClaimTransition,
|
|
@@ -51,6 +50,7 @@ import {
|
|
|
51
50
|
formatTaskRef,
|
|
52
51
|
gitRefWorkflowRepairJournalPath,
|
|
53
52
|
handoffDirectory,
|
|
53
|
+
hasProjectEvidence,
|
|
54
54
|
implementationScopeIsExecutable,
|
|
55
55
|
isUlid,
|
|
56
56
|
listGitRefWorkflowRepairJournalSummaries,
|
|
@@ -114,7 +114,7 @@ import {
|
|
|
114
114
|
workflowMetadataDigest,
|
|
115
115
|
writeOperationReservation,
|
|
116
116
|
writeProjectFacts
|
|
117
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-44UHUCE6.js";
|
|
118
118
|
import {
|
|
119
119
|
DEFAULT_MANCODE_END_MARKER,
|
|
120
120
|
DEFAULT_MANCODE_START_MARKER,
|
|
@@ -139,7 +139,7 @@ import {
|
|
|
139
139
|
stageV3AdapterUpgradeFiles,
|
|
140
140
|
v3AdapterTargetPath,
|
|
141
141
|
v3AdapterVersionsFromStatuses
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-PBXSV352.js";
|
|
143
143
|
|
|
144
144
|
// src/cli.ts
|
|
145
145
|
import { realpathSync } from "fs";
|
|
@@ -9485,7 +9485,8 @@ var MANAGED_ADAPTERS = [
|
|
|
9485
9485
|
"copilot",
|
|
9486
9486
|
"zcode",
|
|
9487
9487
|
"kimi-code",
|
|
9488
|
-
"qoder"
|
|
9488
|
+
"qoder",
|
|
9489
|
+
"dsh"
|
|
9489
9490
|
];
|
|
9490
9491
|
var DIGEST_PATTERN5 = /^sha256:[a-f0-9]{64}$/;
|
|
9491
9492
|
var STAGE_STATES = /* @__PURE__ */ new Set([
|
|
@@ -9676,7 +9677,7 @@ async function activateLegacyMigration(input) {
|
|
|
9676
9677
|
if (session === null || session.status !== "active") {
|
|
9677
9678
|
throw new Error("MANCODE_SESSION_NOT_FOUND");
|
|
9678
9679
|
}
|
|
9679
|
-
const store = new (await import("./store-
|
|
9680
|
+
const store = new (await import("./store-TQFQCAAF.js")).V3ContextStore(root);
|
|
9680
9681
|
const project = await store.readProjectSnapshot();
|
|
9681
9682
|
const stage = await readMigrationStage(root, input.stageId);
|
|
9682
9683
|
if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
|
|
@@ -9939,7 +9940,7 @@ async function activateLegacyMigration(input) {
|
|
|
9939
9940
|
for (const action of payload.actions.filter(
|
|
9940
9941
|
(action2) => action2.kind === "v3_adapter_file"
|
|
9941
9942
|
)) {
|
|
9942
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
9943
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-TPXL336I.js");
|
|
9943
9944
|
await applyV3AdapterFilePlan2(root, action);
|
|
9944
9945
|
}
|
|
9945
9946
|
journal = await completeActivationStep(
|
|
@@ -13795,7 +13796,7 @@ async function upgradeV3Adapters(input) {
|
|
|
13795
13796
|
if (unfinished.length > 0) {
|
|
13796
13797
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
13797
13798
|
}
|
|
13798
|
-
const actualVersions = await import("./v3-adapter-
|
|
13799
|
+
const actualVersions = await import("./v3-adapter-TPXL336I.js").then(
|
|
13799
13800
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
13800
13801
|
root,
|
|
13801
13802
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -16344,6 +16345,8 @@ var LEGACY_MODE_NAMES = ["mamba", "man8"];
|
|
|
16344
16345
|
var CODEX_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:codex-skill. Do not edit this file manually. -->";
|
|
16345
16346
|
var ZCODE_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:zcode-skill. Do not edit this file manually. -->";
|
|
16346
16347
|
var KIMI_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:kimi-skill. Do not edit this file manually. -->";
|
|
16348
|
+
var DSH_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:dsh-skill. Do not edit this file manually. -->";
|
|
16349
|
+
var MANCODE_DSH_SKILL_MARKERS = [DSH_SKILL_MANAGED_MARKER];
|
|
16347
16350
|
var MODE_FILE_MANAGED_MARKER = "<!-- Managed by mancode:mode-file. Do not edit this file manually. -->";
|
|
16348
16351
|
var MANCODE_AGENT_SKILL_MARKERS = [
|
|
16349
16352
|
CODEX_SKILL_MANAGED_MARKER,
|
|
@@ -16484,6 +16487,39 @@ async function installKimiSkills(projectRoot, minimal) {
|
|
|
16484
16487
|
}
|
|
16485
16488
|
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
16486
16489
|
}
|
|
16490
|
+
async function installDshSkills(projectRoot, minimal) {
|
|
16491
|
+
if (minimal) {
|
|
16492
|
+
await removeDshSkills(projectRoot);
|
|
16493
|
+
return;
|
|
16494
|
+
}
|
|
16495
|
+
const skillsDir = path27.join(projectRoot, ".dsh", "skills");
|
|
16496
|
+
for (const mode of MODE_NAMES) {
|
|
16497
|
+
const modeDir = path27.join(skillsDir, mode);
|
|
16498
|
+
await mkdir23(modeDir, { recursive: true });
|
|
16499
|
+
const meta = MODE_META[mode];
|
|
16500
|
+
const content = [
|
|
16501
|
+
"---",
|
|
16502
|
+
`name: ${mode}`,
|
|
16503
|
+
`description: ${JSON.stringify(meta.description)}`,
|
|
16504
|
+
"disable-model-invocation: true",
|
|
16505
|
+
"user-invocable: true",
|
|
16506
|
+
"---",
|
|
16507
|
+
"",
|
|
16508
|
+
DSH_SKILL_MANAGED_MARKER,
|
|
16509
|
+
"",
|
|
16510
|
+
renderModeSkill(mode, "/"),
|
|
16511
|
+
""
|
|
16512
|
+
].join("\n");
|
|
16513
|
+
await writeManagedSkill(
|
|
16514
|
+
path27.join(modeDir, "SKILL.md"),
|
|
16515
|
+
content,
|
|
16516
|
+
DSH_SKILL_MANAGED_MARKER,
|
|
16517
|
+
"DeepSeek Harness",
|
|
16518
|
+
MANCODE_DSH_SKILL_MARKERS
|
|
16519
|
+
);
|
|
16520
|
+
}
|
|
16521
|
+
await removeLegacyManagedSkills(skillsDir, MANCODE_DSH_SKILL_MARKERS);
|
|
16522
|
+
}
|
|
16487
16523
|
async function installCursorCommands(projectRoot, minimal) {
|
|
16488
16524
|
if (minimal) {
|
|
16489
16525
|
await removeCursorCommands(projectRoot);
|
|
@@ -16628,6 +16664,12 @@ async function removeKimiSkills(projectRoot) {
|
|
|
16628
16664
|
);
|
|
16629
16665
|
}
|
|
16630
16666
|
}
|
|
16667
|
+
async function removeDshSkills(projectRoot) {
|
|
16668
|
+
await cleanManagedSkills(
|
|
16669
|
+
path27.join(projectRoot, ".dsh", "skills"),
|
|
16670
|
+
MANCODE_DSH_SKILL_MARKERS
|
|
16671
|
+
);
|
|
16672
|
+
}
|
|
16631
16673
|
async function removeQoderCommands(projectRoot) {
|
|
16632
16674
|
for (const mode of MODE_NAMES) {
|
|
16633
16675
|
const filePath = path27.join(projectRoot, ".qoder", "commands", `${mode}.md`);
|
|
@@ -16976,6 +17018,8 @@ function renderModes(options) {
|
|
|
16976
17018
|
commandLabel = "Invoke mode skills with `/skill:man`, `/skill:manba`, `/skill:manteam`, `/skill:manps`, `/skill:mansolo`.";
|
|
16977
17019
|
} else if (options.platform === "qoder") {
|
|
16978
17020
|
commandLabel = "Invoke mode commands with `/man`, `/manba`, `/manteam`, `/manps`, `/mansolo`.";
|
|
17021
|
+
} else if (options.platform === "dsh") {
|
|
17022
|
+
commandLabel = "Invoke user-only mode skills with `/man`, `/manba`, `/manteam`, `/manps`, `/mansolo`.";
|
|
16979
17023
|
} else if (options.capabilities.skills === "agents-skills") {
|
|
16980
17024
|
commandLabel = "Invoke mode skills with `$man`, `$manba`, `$manteam`, `$manps`, `$mansolo`.";
|
|
16981
17025
|
} else if (options.capabilities.slashCommands === "native") {
|
|
@@ -17361,14 +17405,124 @@ function renderManpsRule() {
|
|
|
17361
17405
|
return renderModeSkill("manps", "/");
|
|
17362
17406
|
}
|
|
17363
17407
|
|
|
17364
|
-
// src/installers/
|
|
17365
|
-
import { writeFile as writeFile29 } from "fs/promises";
|
|
17408
|
+
// src/installers/dsh.ts
|
|
17409
|
+
import { lstat as lstat11, rename as rename9, rm as rm13, writeFile as writeFile29 } from "fs/promises";
|
|
17366
17410
|
import path32 from "path";
|
|
17411
|
+
var DSH_MANCODE_START_MARKER = "<!-- mancode:dsh:start -->";
|
|
17412
|
+
var DSH_MANCODE_END_MARKER = "<!-- mancode:dsh:end -->";
|
|
17413
|
+
var DSH_MODE_PATH_NAMES = [
|
|
17414
|
+
"manba",
|
|
17415
|
+
"man",
|
|
17416
|
+
"manteam",
|
|
17417
|
+
"manps",
|
|
17418
|
+
"mansolo",
|
|
17419
|
+
"mamba",
|
|
17420
|
+
"man8"
|
|
17421
|
+
];
|
|
17422
|
+
async function installDsh(projectRoot, options) {
|
|
17423
|
+
const root = path32.resolve(projectRoot);
|
|
17424
|
+
await assertDshAdapterPathsSafe(root);
|
|
17425
|
+
await installMancodeCore(root);
|
|
17426
|
+
const agentsPath = path32.join(root, "AGENTS.md");
|
|
17427
|
+
const existing = await readTextIfExists(agentsPath);
|
|
17428
|
+
const sharedContent = await generateSharedContent(root, {
|
|
17429
|
+
platform: "dsh",
|
|
17430
|
+
displayName: "DeepSeek Harness",
|
|
17431
|
+
capabilities: {
|
|
17432
|
+
slashCommands: "partial",
|
|
17433
|
+
subagents: true,
|
|
17434
|
+
hooks: false,
|
|
17435
|
+
skills: "dsh-skills"
|
|
17436
|
+
},
|
|
17437
|
+
minimal: options.minimal,
|
|
17438
|
+
techStack: options.techStack,
|
|
17439
|
+
uiLibrary: options.uiLibrary,
|
|
17440
|
+
projectProfile: options.projectProfile
|
|
17441
|
+
});
|
|
17442
|
+
const block = [
|
|
17443
|
+
DSH_MANCODE_START_MARKER,
|
|
17444
|
+
"<!-- Managed by mancode. Do not edit this block manually. -->",
|
|
17445
|
+
"",
|
|
17446
|
+
"# mancode Configuration",
|
|
17447
|
+
"",
|
|
17448
|
+
sharedContent.trim(),
|
|
17449
|
+
DSH_MANCODE_END_MARKER
|
|
17450
|
+
].join("\n");
|
|
17451
|
+
await writeDshAgentsFile(
|
|
17452
|
+
root,
|
|
17453
|
+
replaceManagedBlock(
|
|
17454
|
+
existing,
|
|
17455
|
+
block,
|
|
17456
|
+
DSH_MANCODE_START_MARKER,
|
|
17457
|
+
DSH_MANCODE_END_MARKER
|
|
17458
|
+
)
|
|
17459
|
+
);
|
|
17460
|
+
await assertDshAdapterPathsSafe(root);
|
|
17461
|
+
await installDshSkills(root, options.minimal ?? false);
|
|
17462
|
+
}
|
|
17463
|
+
async function assertDshAdapterPathsSafe(projectRoot) {
|
|
17464
|
+
const root = path32.resolve(projectRoot);
|
|
17465
|
+
const targets = [
|
|
17466
|
+
path32.join(root, "AGENTS.md"),
|
|
17467
|
+
...DSH_MODE_PATH_NAMES.map(
|
|
17468
|
+
(mode) => path32.join(root, ".dsh", "skills", mode, "SKILL.md")
|
|
17469
|
+
)
|
|
17470
|
+
];
|
|
17471
|
+
for (const target of targets) {
|
|
17472
|
+
await assertDshArtifactPathSafe(root, target);
|
|
17473
|
+
}
|
|
17474
|
+
}
|
|
17475
|
+
async function writeDshAgentsFile(projectRoot, content) {
|
|
17476
|
+
const root = path32.resolve(projectRoot);
|
|
17477
|
+
const agentsPath = path32.join(root, "AGENTS.md");
|
|
17478
|
+
await assertDshArtifactPathSafe(root, agentsPath);
|
|
17479
|
+
const temporary = path32.join(
|
|
17480
|
+
root,
|
|
17481
|
+
`.AGENTS.md.${process.pid}.${Date.now()}.tmp`
|
|
17482
|
+
);
|
|
17483
|
+
try {
|
|
17484
|
+
await writeFile29(temporary, content, { encoding: "utf-8", flag: "wx" });
|
|
17485
|
+
await rename9(temporary, agentsPath);
|
|
17486
|
+
} finally {
|
|
17487
|
+
await rm13(temporary, { force: true }).catch(() => void 0);
|
|
17488
|
+
}
|
|
17489
|
+
}
|
|
17490
|
+
async function assertDshArtifactPathSafe(root, target) {
|
|
17491
|
+
const relative = path32.relative(root, target);
|
|
17492
|
+
if (!relative || relative.startsWith("..") || path32.isAbsolute(relative)) {
|
|
17493
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
17494
|
+
}
|
|
17495
|
+
const rootEntry = await lstat11(root);
|
|
17496
|
+
if (!rootEntry.isDirectory() || rootEntry.isSymbolicLink()) {
|
|
17497
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
17498
|
+
}
|
|
17499
|
+
const segments = relative.split(path32.sep);
|
|
17500
|
+
let current = root;
|
|
17501
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
17502
|
+
current = path32.join(current, segments[index] ?? "");
|
|
17503
|
+
try {
|
|
17504
|
+
const entry = await lstat11(current);
|
|
17505
|
+
if (entry.isSymbolicLink() || index < segments.length - 1 && !entry.isDirectory() || index === segments.length - 1 && !entry.isFile()) {
|
|
17506
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
17507
|
+
}
|
|
17508
|
+
} catch (error) {
|
|
17509
|
+
if (isNodeError6(error) && error.code === "ENOENT") return;
|
|
17510
|
+
throw error;
|
|
17511
|
+
}
|
|
17512
|
+
}
|
|
17513
|
+
}
|
|
17514
|
+
function isNodeError6(error) {
|
|
17515
|
+
return error instanceof Error && "code" in error;
|
|
17516
|
+
}
|
|
17517
|
+
|
|
17518
|
+
// src/installers/kimi-code.ts
|
|
17519
|
+
import { writeFile as writeFile30 } from "fs/promises";
|
|
17520
|
+
import path33 from "path";
|
|
17367
17521
|
var KIMI_MANCODE_START_MARKER = "<!-- mancode:kimi-code:start -->";
|
|
17368
17522
|
var KIMI_MANCODE_END_MARKER = "<!-- mancode:kimi-code:end -->";
|
|
17369
17523
|
async function installKimiCode(projectRoot, options) {
|
|
17370
17524
|
await installMancodeCore(projectRoot);
|
|
17371
|
-
const agentsPath =
|
|
17525
|
+
const agentsPath = path33.join(projectRoot, "AGENTS.md");
|
|
17372
17526
|
const existing = await readTextIfExists(agentsPath);
|
|
17373
17527
|
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17374
17528
|
platform: "kimi-code",
|
|
@@ -17393,7 +17547,7 @@ async function installKimiCode(projectRoot, options) {
|
|
|
17393
17547
|
sharedContent.trim(),
|
|
17394
17548
|
KIMI_MANCODE_END_MARKER
|
|
17395
17549
|
].join("\n");
|
|
17396
|
-
await
|
|
17550
|
+
await writeFile30(
|
|
17397
17551
|
agentsPath,
|
|
17398
17552
|
replaceManagedBlock(
|
|
17399
17553
|
existing,
|
|
@@ -17407,13 +17561,13 @@ async function installKimiCode(projectRoot, options) {
|
|
|
17407
17561
|
}
|
|
17408
17562
|
|
|
17409
17563
|
// src/installers/qoder.ts
|
|
17410
|
-
import { writeFile as
|
|
17411
|
-
import
|
|
17564
|
+
import { writeFile as writeFile31 } from "fs/promises";
|
|
17565
|
+
import path34 from "path";
|
|
17412
17566
|
var QODER_MANCODE_START_MARKER = "<!-- mancode:qoder:start -->";
|
|
17413
17567
|
var QODER_MANCODE_END_MARKER = "<!-- mancode:qoder:end -->";
|
|
17414
17568
|
async function installQoder(projectRoot, options) {
|
|
17415
17569
|
await installMancodeCore(projectRoot);
|
|
17416
|
-
const agentsPath =
|
|
17570
|
+
const agentsPath = path34.join(projectRoot, "AGENTS.md");
|
|
17417
17571
|
const existing = await readTextIfExists(agentsPath);
|
|
17418
17572
|
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17419
17573
|
platform: "qoder",
|
|
@@ -17438,7 +17592,7 @@ async function installQoder(projectRoot, options) {
|
|
|
17438
17592
|
sharedContent.trim(),
|
|
17439
17593
|
QODER_MANCODE_END_MARKER
|
|
17440
17594
|
].join("\n");
|
|
17441
|
-
await
|
|
17595
|
+
await writeFile31(
|
|
17442
17596
|
agentsPath,
|
|
17443
17597
|
replaceManagedBlock(
|
|
17444
17598
|
existing,
|
|
@@ -17452,13 +17606,13 @@ async function installQoder(projectRoot, options) {
|
|
|
17452
17606
|
}
|
|
17453
17607
|
|
|
17454
17608
|
// src/installers/zcode.ts
|
|
17455
|
-
import { writeFile as
|
|
17456
|
-
import
|
|
17609
|
+
import { writeFile as writeFile32 } from "fs/promises";
|
|
17610
|
+
import path35 from "path";
|
|
17457
17611
|
var ZCODE_MANCODE_START_MARKER = "<!-- mancode:zcode:start -->";
|
|
17458
17612
|
var ZCODE_MANCODE_END_MARKER = "<!-- mancode:zcode:end -->";
|
|
17459
17613
|
async function installZcode(projectRoot, options) {
|
|
17460
17614
|
await installMancodeCore(projectRoot);
|
|
17461
|
-
const agentsPath =
|
|
17615
|
+
const agentsPath = path35.join(projectRoot, "AGENTS.md");
|
|
17462
17616
|
const existing = await readTextIfExists(agentsPath);
|
|
17463
17617
|
const sharedContent = await generateSharedContent(projectRoot, {
|
|
17464
17618
|
platform: "zcode",
|
|
@@ -17483,7 +17637,7 @@ async function installZcode(projectRoot, options) {
|
|
|
17483
17637
|
sharedContent.trim(),
|
|
17484
17638
|
ZCODE_MANCODE_END_MARKER
|
|
17485
17639
|
].join("\n");
|
|
17486
|
-
await
|
|
17640
|
+
await writeFile32(
|
|
17487
17641
|
agentsPath,
|
|
17488
17642
|
replaceManagedBlock(
|
|
17489
17643
|
existing,
|
|
@@ -17574,6 +17728,17 @@ var PLATFORM_INSTALLERS = {
|
|
|
17574
17728
|
skills: "rules"
|
|
17575
17729
|
},
|
|
17576
17730
|
install: installQoder
|
|
17731
|
+
},
|
|
17732
|
+
dsh: {
|
|
17733
|
+
name: "dsh",
|
|
17734
|
+
displayName: "DeepSeek Harness",
|
|
17735
|
+
capabilities: {
|
|
17736
|
+
slashCommands: "partial",
|
|
17737
|
+
subagents: true,
|
|
17738
|
+
hooks: false,
|
|
17739
|
+
skills: "dsh-skills"
|
|
17740
|
+
},
|
|
17741
|
+
install: installDsh
|
|
17577
17742
|
}
|
|
17578
17743
|
};
|
|
17579
17744
|
function getPlatformInstaller(platform) {
|
|
@@ -17591,11 +17756,11 @@ function isPlatformName(platform) {
|
|
|
17591
17756
|
}
|
|
17592
17757
|
|
|
17593
17758
|
// src/commands/v3-support.ts
|
|
17594
|
-
import
|
|
17759
|
+
import path37 from "path";
|
|
17595
17760
|
|
|
17596
17761
|
// src/runtime/platform-spike-store.ts
|
|
17597
|
-
import { lstat as
|
|
17598
|
-
import
|
|
17762
|
+
import { lstat as lstat12, mkdir as mkdir26, readFile as readFile29, rm as rm14, writeFile as writeFile33 } from "fs/promises";
|
|
17763
|
+
import path36 from "path";
|
|
17599
17764
|
|
|
17600
17765
|
// src/runtime/platform-spike.ts
|
|
17601
17766
|
var SESSION_SPIKE_PLATFORMS = [
|
|
@@ -17605,7 +17770,8 @@ var SESSION_SPIKE_PLATFORMS = [
|
|
|
17605
17770
|
"copilot",
|
|
17606
17771
|
"zcode",
|
|
17607
17772
|
"kimi-code",
|
|
17608
|
-
"qoder"
|
|
17773
|
+
"qoder",
|
|
17774
|
+
"dsh"
|
|
17609
17775
|
];
|
|
17610
17776
|
function createPlatformSessionSpike(input) {
|
|
17611
17777
|
assertSessionSpikePlatform(input.platform);
|
|
@@ -17977,7 +18143,7 @@ async function readPlatformSessionSpike(projectRoot, platform) {
|
|
|
17977
18143
|
if (directory === null) return null;
|
|
17978
18144
|
try {
|
|
17979
18145
|
const raw = await readSafeRegularFile(
|
|
17980
|
-
|
|
18146
|
+
path36.join(directory, `${platform}.json`)
|
|
17981
18147
|
);
|
|
17982
18148
|
return parsePlatformSessionSpike(JSON.parse(raw));
|
|
17983
18149
|
} catch (error) {
|
|
@@ -18007,13 +18173,13 @@ async function writePlatformSessionSpike(projectRoot, spike) {
|
|
|
18007
18173
|
if (directory === null) {
|
|
18008
18174
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
18009
18175
|
}
|
|
18010
|
-
const target =
|
|
18176
|
+
const target = path36.join(directory, `${parsed.platform}.json`);
|
|
18011
18177
|
await assertSafeReplacementTarget(target);
|
|
18012
|
-
const temporary =
|
|
18178
|
+
const temporary = path36.join(
|
|
18013
18179
|
directory,
|
|
18014
18180
|
`.${parsed.platform}.${process.pid}.${Date.now()}.tmp`
|
|
18015
18181
|
);
|
|
18016
|
-
await
|
|
18182
|
+
await writeFile33(temporary, `${JSON.stringify(parsed, null, 2)}
|
|
18017
18183
|
`, {
|
|
18018
18184
|
encoding: "utf8",
|
|
18019
18185
|
flag: "wx"
|
|
@@ -18022,15 +18188,15 @@ async function writePlatformSessionSpike(projectRoot, spike) {
|
|
|
18022
18188
|
await replaceFileAtomically(temporary, target);
|
|
18023
18189
|
await assertSafeReplacementTarget(target);
|
|
18024
18190
|
} catch (error) {
|
|
18025
|
-
await
|
|
18191
|
+
await rm14(temporary, { force: true });
|
|
18026
18192
|
throw error;
|
|
18027
18193
|
}
|
|
18028
18194
|
return parsed;
|
|
18029
18195
|
}
|
|
18030
18196
|
async function safeEvidenceDirectory(projectRoot, create) {
|
|
18031
|
-
let current =
|
|
18197
|
+
let current = path36.resolve(projectRoot);
|
|
18032
18198
|
for (const segment of EVIDENCE_DIRECTORY_SEGMENTS) {
|
|
18033
|
-
const target =
|
|
18199
|
+
const target = path36.join(current, segment);
|
|
18034
18200
|
try {
|
|
18035
18201
|
await assertSafeDirectory2(target);
|
|
18036
18202
|
} catch (error) {
|
|
@@ -18048,14 +18214,14 @@ async function safeEvidenceDirectory(projectRoot, create) {
|
|
|
18048
18214
|
return current;
|
|
18049
18215
|
}
|
|
18050
18216
|
async function assertSafeDirectory2(target) {
|
|
18051
|
-
const entry = await
|
|
18217
|
+
const entry = await lstat12(target);
|
|
18052
18218
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
18053
18219
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
18054
18220
|
}
|
|
18055
18221
|
}
|
|
18056
18222
|
async function assertSafeReplacementTarget(target) {
|
|
18057
18223
|
try {
|
|
18058
|
-
const entry = await
|
|
18224
|
+
const entry = await lstat12(target);
|
|
18059
18225
|
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
18060
18226
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
18061
18227
|
}
|
|
@@ -18065,12 +18231,12 @@ async function assertSafeReplacementTarget(target) {
|
|
|
18065
18231
|
}
|
|
18066
18232
|
}
|
|
18067
18233
|
async function readSafeRegularFile(target) {
|
|
18068
|
-
const before = await
|
|
18234
|
+
const before = await lstat12(target);
|
|
18069
18235
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
18070
18236
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
18071
18237
|
}
|
|
18072
18238
|
const content = await readFile29(target, "utf8");
|
|
18073
|
-
const after = await
|
|
18239
|
+
const after = await lstat12(target);
|
|
18074
18240
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
18075
18241
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
18076
18242
|
}
|
|
@@ -18173,7 +18339,7 @@ var EXIT_V3_OK = 0;
|
|
|
18173
18339
|
var EXIT_V3_INVALID_ARGUMENT = 2;
|
|
18174
18340
|
var EXIT_V3_BLOCKED = 3;
|
|
18175
18341
|
async function readV3CommandProject(projectRoot) {
|
|
18176
|
-
const root =
|
|
18342
|
+
const root = path37.resolve(projectRoot);
|
|
18177
18343
|
const runtime = await readProjectRuntimeContext(root);
|
|
18178
18344
|
const store = new V3ContextStore(root);
|
|
18179
18345
|
return {
|
|
@@ -18226,7 +18392,7 @@ async function resolveV3SessionCandidate(project, input, client) {
|
|
|
18226
18392
|
});
|
|
18227
18393
|
}
|
|
18228
18394
|
function platformForClient(client) {
|
|
18229
|
-
return client === "claude-code" || client === "codex" || client === "cursor" || client === "copilot" || client === "zcode" || client === "kimi-code" || client === "qoder" ? client : null;
|
|
18395
|
+
return client === "claude-code" || client === "codex" || client === "cursor" || client === "copilot" || client === "zcode" || client === "kimi-code" || client === "qoder" || client === "dsh" ? client : null;
|
|
18230
18396
|
}
|
|
18231
18397
|
function commandClient(value) {
|
|
18232
18398
|
const client = value ?? "mancode-cli";
|
|
@@ -18351,8 +18517,8 @@ function selectUpgradePlatforms(options) {
|
|
|
18351
18517
|
}
|
|
18352
18518
|
|
|
18353
18519
|
// src/context/glossary.ts
|
|
18354
|
-
import { mkdir as mkdir27, readFile as readFile30, rename as
|
|
18355
|
-
import
|
|
18520
|
+
import { mkdir as mkdir27, readFile as readFile30, rename as rename10, rm as rm15, writeFile as writeFile34 } from "fs/promises";
|
|
18521
|
+
import path38 from "path";
|
|
18356
18522
|
var GLOSSARY_TERM_MAX_LENGTH = 64;
|
|
18357
18523
|
var GLOSSARY_DEFINITION_MAX_LENGTH = 500;
|
|
18358
18524
|
var GLOSSARY_MAX_ENTRIES = 200;
|
|
@@ -18428,8 +18594,8 @@ function parseGlossaryEntry(value) {
|
|
|
18428
18594
|
};
|
|
18429
18595
|
}
|
|
18430
18596
|
function projectGlossaryPath(projectRoot) {
|
|
18431
|
-
return
|
|
18432
|
-
|
|
18597
|
+
return path38.join(
|
|
18598
|
+
path38.resolve(projectRoot),
|
|
18433
18599
|
".mancode",
|
|
18434
18600
|
"shared",
|
|
18435
18601
|
"context",
|
|
@@ -18556,20 +18722,20 @@ async function mutateProjectGlossary(projectRoot, store, expectedRevision, mutat
|
|
|
18556
18722
|
}
|
|
18557
18723
|
async function writeGlossaryFile(projectRoot, glossary) {
|
|
18558
18724
|
const target = projectGlossaryPath(projectRoot);
|
|
18559
|
-
await mkdir27(
|
|
18560
|
-
const temporary =
|
|
18561
|
-
|
|
18562
|
-
`.${
|
|
18725
|
+
await mkdir27(path38.dirname(target), { recursive: true });
|
|
18726
|
+
const temporary = path38.join(
|
|
18727
|
+
path38.dirname(target),
|
|
18728
|
+
`.${path38.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
18563
18729
|
);
|
|
18564
18730
|
try {
|
|
18565
|
-
await
|
|
18731
|
+
await writeFile34(temporary, `${JSON.stringify(glossary, null, 2)}
|
|
18566
18732
|
`, {
|
|
18567
18733
|
encoding: "utf8",
|
|
18568
18734
|
flag: "wx"
|
|
18569
18735
|
});
|
|
18570
|
-
await
|
|
18736
|
+
await rename10(temporary, target);
|
|
18571
18737
|
} finally {
|
|
18572
|
-
await
|
|
18738
|
+
await rm15(temporary, { force: true }).catch(() => void 0);
|
|
18573
18739
|
}
|
|
18574
18740
|
}
|
|
18575
18741
|
function assertGlobalTermUniqueness(entries) {
|
|
@@ -18605,8 +18771,8 @@ function isNotFound20(error) {
|
|
|
18605
18771
|
}
|
|
18606
18772
|
|
|
18607
18773
|
// src/context/publish-promote.ts
|
|
18608
|
-
import { lstat as
|
|
18609
|
-
import
|
|
18774
|
+
import { lstat as lstat13, mkdir as mkdir28, rename as rename11, rm as rm16, writeFile as writeFile35 } from "fs/promises";
|
|
18775
|
+
import path39 from "path";
|
|
18610
18776
|
|
|
18611
18777
|
// src/context/task-mutation.ts
|
|
18612
18778
|
function markTaskReviewStale(previous, operationId, updatedAt) {
|
|
@@ -19338,7 +19504,7 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
19338
19504
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
19339
19505
|
const parent = await ensureSafeTaskParent2(projectRoot, destinationTaskRef);
|
|
19340
19506
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
19341
|
-
const staging =
|
|
19507
|
+
const staging = path39.join(
|
|
19342
19508
|
parent,
|
|
19343
19509
|
`.${destinationTaskRef.taskId}.${operationId}.staging`
|
|
19344
19510
|
);
|
|
@@ -19346,7 +19512,7 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
19346
19512
|
await mkdir28(staging);
|
|
19347
19513
|
try {
|
|
19348
19514
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
19349
|
-
await
|
|
19515
|
+
await writeFile35(path39.join(staging, fileName), content, {
|
|
19350
19516
|
encoding: "utf8",
|
|
19351
19517
|
flag: "wx"
|
|
19352
19518
|
});
|
|
@@ -19354,7 +19520,7 @@ async function stageDestinationAuthority(projectRoot, destinationTaskRef, operat
|
|
|
19354
19520
|
await assertSafeDirectory3(staging);
|
|
19355
19521
|
return staging;
|
|
19356
19522
|
} catch (error) {
|
|
19357
|
-
await
|
|
19523
|
+
await rm16(staging, { recursive: true, force: true });
|
|
19358
19524
|
throw error;
|
|
19359
19525
|
}
|
|
19360
19526
|
}
|
|
@@ -19362,7 +19528,7 @@ async function ensureSafeTaskParent2(projectRoot, taskRef) {
|
|
|
19362
19528
|
await assertSafeDirectory3(projectRoot);
|
|
19363
19529
|
let current = projectRoot;
|
|
19364
19530
|
for (const segment of [".mancode", taskRef.namespace, "workflows"]) {
|
|
19365
|
-
current =
|
|
19531
|
+
current = path39.join(current, segment);
|
|
19366
19532
|
const existing = await lstatOrNull2(current);
|
|
19367
19533
|
if (existing === null) {
|
|
19368
19534
|
try {
|
|
@@ -19372,7 +19538,7 @@ async function ensureSafeTaskParent2(projectRoot, taskRef) {
|
|
|
19372
19538
|
if (!isAlreadyExists16(error)) throw error;
|
|
19373
19539
|
}
|
|
19374
19540
|
}
|
|
19375
|
-
const checked = existing ?? await
|
|
19541
|
+
const checked = existing ?? await lstat13(current);
|
|
19376
19542
|
if (!checked.isDirectory() || checked.isSymbolicLink()) {
|
|
19377
19543
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
19378
19544
|
}
|
|
@@ -19383,7 +19549,7 @@ async function publishStagedDestination(projectRoot, destinationTaskRef, staging
|
|
|
19383
19549
|
const target = taskRootPath(projectRoot, destinationTaskRef);
|
|
19384
19550
|
await assertSafeDirectory3(staging);
|
|
19385
19551
|
await assertPathAbsent(target, "MANCODE_PROMOTION_DESTINATION_EXISTS");
|
|
19386
|
-
await
|
|
19552
|
+
await rename11(staging, target);
|
|
19387
19553
|
await assertSafeDirectory3(target);
|
|
19388
19554
|
}
|
|
19389
19555
|
async function assertDestinationAbsent(projectRoot, destinationHomeStore, destinationTaskRef) {
|
|
@@ -19538,7 +19704,7 @@ async function handlePromotionFailure(source, primaryStore, journal, stagingDire
|
|
|
19538
19704
|
} catch {
|
|
19539
19705
|
} finally {
|
|
19540
19706
|
if (stagingDirectory !== null) {
|
|
19541
|
-
await
|
|
19707
|
+
await rm16(stagingDirectory, { recursive: true, force: true });
|
|
19542
19708
|
}
|
|
19543
19709
|
}
|
|
19544
19710
|
}
|
|
@@ -19547,41 +19713,41 @@ async function renewPromotionLocks(source) {
|
|
|
19547
19713
|
}
|
|
19548
19714
|
async function writePromotionQuarantine(projectRoot, operationId, candidate, contents) {
|
|
19549
19715
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
19550
|
-
const parent =
|
|
19716
|
+
const parent = path39.dirname(directory);
|
|
19551
19717
|
await mkdir28(parent, { recursive: true });
|
|
19552
19718
|
await assertSafeDirectory3(parent);
|
|
19553
19719
|
await assertPathAbsent(directory, "MANCODE_PROMOTION_QUARANTINE_CONFLICT");
|
|
19554
19720
|
await mkdir28(directory);
|
|
19555
19721
|
try {
|
|
19556
|
-
await
|
|
19557
|
-
|
|
19722
|
+
await writeFile35(
|
|
19723
|
+
path39.join(directory, "candidate.json"),
|
|
19558
19724
|
serializeTaskAuthority(candidate),
|
|
19559
19725
|
{ encoding: "utf8", flag: "wx" }
|
|
19560
19726
|
);
|
|
19561
19727
|
for (const [fileName, content] of Object.entries(contents)) {
|
|
19562
|
-
await
|
|
19728
|
+
await writeFile35(path39.join(directory, fileName), content, {
|
|
19563
19729
|
encoding: "utf8",
|
|
19564
19730
|
flag: "wx"
|
|
19565
19731
|
});
|
|
19566
19732
|
}
|
|
19567
19733
|
} catch (error) {
|
|
19568
|
-
await
|
|
19734
|
+
await rm16(directory, { recursive: true, force: true });
|
|
19569
19735
|
throw error;
|
|
19570
19736
|
}
|
|
19571
19737
|
}
|
|
19572
19738
|
async function rewritePromotionQuarantine(projectRoot, operationId, candidate) {
|
|
19573
19739
|
const directory = publishStagingDirectory(projectRoot, operationId);
|
|
19574
19740
|
await assertSafeDirectory3(directory);
|
|
19575
|
-
const target =
|
|
19576
|
-
const temporary =
|
|
19741
|
+
const target = path39.join(directory, "candidate.json");
|
|
19742
|
+
const temporary = path39.join(
|
|
19577
19743
|
directory,
|
|
19578
19744
|
`.candidate.${process.pid}.${Date.now()}.tmp`
|
|
19579
19745
|
);
|
|
19580
|
-
await
|
|
19746
|
+
await writeFile35(temporary, serializeTaskAuthority(candidate), {
|
|
19581
19747
|
encoding: "utf8",
|
|
19582
19748
|
flag: "wx"
|
|
19583
19749
|
});
|
|
19584
|
-
await
|
|
19750
|
+
await rename11(temporary, target);
|
|
19585
19751
|
}
|
|
19586
19752
|
function completeOperationStep2(steps, stepId) {
|
|
19587
19753
|
const index = steps.findIndex((step) => step.id === stepId);
|
|
@@ -19614,14 +19780,14 @@ async function assertPathAbsent(target, code) {
|
|
|
19614
19780
|
throw new Error(code);
|
|
19615
19781
|
}
|
|
19616
19782
|
async function assertSafeDirectory3(target) {
|
|
19617
|
-
const entry = await
|
|
19783
|
+
const entry = await lstat13(target);
|
|
19618
19784
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
19619
19785
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
19620
19786
|
}
|
|
19621
19787
|
}
|
|
19622
19788
|
async function lstatOrNull2(target) {
|
|
19623
19789
|
try {
|
|
19624
|
-
return await
|
|
19790
|
+
return await lstat13(target);
|
|
19625
19791
|
} catch (error) {
|
|
19626
19792
|
if (isNotFound21(error)) return null;
|
|
19627
19793
|
throw error;
|
|
@@ -20395,7 +20561,7 @@ function compareUtf89(left, right) {
|
|
|
20395
20561
|
|
|
20396
20562
|
// src/context/task-head-reconcile.ts
|
|
20397
20563
|
import { execFile as execFileCallback4 } from "child_process";
|
|
20398
|
-
import
|
|
20564
|
+
import path41 from "path";
|
|
20399
20565
|
import { promisify as promisify4 } from "util";
|
|
20400
20566
|
|
|
20401
20567
|
// src/team/conflicts.ts
|
|
@@ -20595,9 +20761,9 @@ function unique(values) {
|
|
|
20595
20761
|
|
|
20596
20762
|
// src/team/git-ref-transport.ts
|
|
20597
20763
|
import { execFile as execFileCallback3 } from "child_process";
|
|
20598
|
-
import { mkdtemp, rm as
|
|
20764
|
+
import { mkdtemp, rm as rm17, writeFile as writeFile36 } from "fs/promises";
|
|
20599
20765
|
import { tmpdir } from "os";
|
|
20600
|
-
import
|
|
20766
|
+
import path40 from "path";
|
|
20601
20767
|
import { promisify as promisify3 } from "util";
|
|
20602
20768
|
var execFile3 = promisify3(execFileCallback3);
|
|
20603
20769
|
var TEAM_REF = "refs/mancode/team";
|
|
@@ -20620,7 +20786,7 @@ async function resolveGitRefRemoteIdentityHash(projectRoot, remote) {
|
|
|
20620
20786
|
}
|
|
20621
20787
|
let configured = remote;
|
|
20622
20788
|
try {
|
|
20623
|
-
const output = await runGit2(
|
|
20789
|
+
const output = await runGit2(path40.resolve(projectRoot), [
|
|
20624
20790
|
"remote",
|
|
20625
20791
|
"get-url",
|
|
20626
20792
|
"--all",
|
|
@@ -20670,7 +20836,7 @@ var GitRefTeamManifestStore = class {
|
|
|
20670
20836
|
"git-ref configRevision"
|
|
20671
20837
|
);
|
|
20672
20838
|
parseOptionalDigest(options.configDigest, "git-ref configDigest");
|
|
20673
|
-
this.projectRoot =
|
|
20839
|
+
this.projectRoot = path40.resolve(options.projectRoot);
|
|
20674
20840
|
this.remote = options.remote;
|
|
20675
20841
|
this.workspaceId = options.workspaceId;
|
|
20676
20842
|
this.expectedHeader = {
|
|
@@ -22376,17 +22542,17 @@ function upsertActorProfile(profiles, profile) {
|
|
|
22376
22542
|
}
|
|
22377
22543
|
async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
22378
22544
|
const temporaryDirectory = await mkdtemp(
|
|
22379
|
-
|
|
22545
|
+
path40.join(tmpdir(), "mancode-git-ref-")
|
|
22380
22546
|
);
|
|
22381
|
-
const manifestPath =
|
|
22382
|
-
const indexPath =
|
|
22547
|
+
const manifestPath = path40.join(temporaryDirectory, "manifest.json");
|
|
22548
|
+
const indexPath = path40.join(temporaryDirectory, "index");
|
|
22383
22549
|
try {
|
|
22384
22550
|
const serialized = `${JSON.stringify(manifest, null, 2)}
|
|
22385
22551
|
`;
|
|
22386
22552
|
if (Buffer.byteLength(serialized, "utf8") > MAX_MANIFEST_BYTES) {
|
|
22387
22553
|
throw new Error("MANCODE_TRANSPORT_MANIFEST_TOO_LARGE");
|
|
22388
22554
|
}
|
|
22389
|
-
await
|
|
22555
|
+
await writeFile36(manifestPath, serialized);
|
|
22390
22556
|
const blob = (await runGit2(projectRoot, ["hash-object", "-w", manifestPath])).trim();
|
|
22391
22557
|
const environment = { ...process.env, GIT_INDEX_FILE: indexPath };
|
|
22392
22558
|
await runGit2(projectRoot, ["read-tree", "--empty"], environment);
|
|
@@ -22418,7 +22584,7 @@ async function writeManifestCommit(projectRoot, parent, manifest, now) {
|
|
|
22418
22584
|
commitEnvironment
|
|
22419
22585
|
)).trim();
|
|
22420
22586
|
} finally {
|
|
22421
|
-
await
|
|
22587
|
+
await rm17(temporaryDirectory, { recursive: true, force: true });
|
|
22422
22588
|
}
|
|
22423
22589
|
}
|
|
22424
22590
|
async function pushWithLease(projectRoot, remote, expectedCommit, commit3) {
|
|
@@ -22500,7 +22666,7 @@ function normalizeRemoteIdentity(projectRoot, value) {
|
|
|
22500
22666
|
url.pathname = url.pathname.replace(/\/+$/g, "");
|
|
22501
22667
|
return url.toString();
|
|
22502
22668
|
} catch {
|
|
22503
|
-
return
|
|
22669
|
+
return path40.resolve(projectRoot, value).replaceAll("\\", "/");
|
|
22504
22670
|
}
|
|
22505
22671
|
}
|
|
22506
22672
|
function parseBundleCodeRef(value) {
|
|
@@ -22874,8 +23040,8 @@ function injectAfterReconcileStep(stepId) {
|
|
|
22874
23040
|
throwIfOperationCrashInjected("task_head_reconcile", stepId);
|
|
22875
23041
|
}
|
|
22876
23042
|
async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
22877
|
-
const relativeTaskRoot =
|
|
22878
|
-
if (!relativeTaskRoot ||
|
|
23043
|
+
const relativeTaskRoot = path41.relative(projectRoot, taskRoot2);
|
|
23044
|
+
if (!relativeTaskRoot || path41.isAbsolute(relativeTaskRoot) || relativeTaskRoot.split(path41.sep).some((part) => part === "..")) {
|
|
22879
23045
|
throw new Error("MANCODE_TASK_UNAVAILABLE");
|
|
22880
23046
|
}
|
|
22881
23047
|
const authorityFiles = [
|
|
@@ -22883,7 +23049,7 @@ async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
|
22883
23049
|
"requirements.json",
|
|
22884
23050
|
"review-ledger.json",
|
|
22885
23051
|
"verification-ledger.json"
|
|
22886
|
-
].map((file) =>
|
|
23052
|
+
].map((file) => path41.join(relativeTaskRoot, file));
|
|
22887
23053
|
try {
|
|
22888
23054
|
await execFile4("git", ["rev-parse", "--verify", "HEAD^{commit}"], {
|
|
22889
23055
|
cwd: projectRoot,
|
|
@@ -23103,16 +23269,17 @@ var BETA_PLATFORMS = [
|
|
|
23103
23269
|
"copilot",
|
|
23104
23270
|
"zcode",
|
|
23105
23271
|
"kimi-code",
|
|
23106
|
-
"qoder"
|
|
23272
|
+
"qoder",
|
|
23273
|
+
"dsh"
|
|
23107
23274
|
];
|
|
23108
23275
|
|
|
23109
23276
|
// src/runtime/retention.ts
|
|
23110
|
-
import { lstat as
|
|
23111
|
-
import
|
|
23277
|
+
import { lstat as lstat14, readFile as readFile31, readdir as readdir14, rm as rm18 } from "fs/promises";
|
|
23278
|
+
import path42 from "path";
|
|
23112
23279
|
var TERMINAL_JOURNAL_RETENTION_DAYS = 30;
|
|
23113
23280
|
var RETAINED_NON_MILESTONE_CHECKPOINTS = 10;
|
|
23114
23281
|
async function planContextCompaction(input) {
|
|
23115
|
-
const root =
|
|
23282
|
+
const root = path42.resolve(input.projectRoot);
|
|
23116
23283
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
23117
23284
|
const store = new V3ContextStore(root);
|
|
23118
23285
|
const [project, runtime] = await Promise.all([
|
|
@@ -23172,7 +23339,7 @@ async function planContextCompaction(input) {
|
|
|
23172
23339
|
}
|
|
23173
23340
|
async function planLocalCacheRetention(root, localCacheDays, now) {
|
|
23174
23341
|
const threshold = now.getTime() - localCacheDays * 864e5;
|
|
23175
|
-
const directory =
|
|
23342
|
+
const directory = path42.join(root, ".mancode", "local", "cache");
|
|
23176
23343
|
const candidates = [];
|
|
23177
23344
|
for (const target of await listRegularFilesRecursively(directory)) {
|
|
23178
23345
|
const metadata = await regularFileMetadataOrNull(target);
|
|
@@ -23235,7 +23402,7 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
23235
23402
|
}
|
|
23236
23403
|
candidates.push({
|
|
23237
23404
|
kind: "checkpoint",
|
|
23238
|
-
target:
|
|
23405
|
+
target: path42.join(
|
|
23239
23406
|
task.location.taskRoot,
|
|
23240
23407
|
"checkpoints",
|
|
23241
23408
|
`${checkpoint.checkpointId}.json`
|
|
@@ -23249,13 +23416,13 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
23249
23416
|
return { candidates, skippedReferencedCheckpoints };
|
|
23250
23417
|
}
|
|
23251
23418
|
async function planCompletedSessionRetention(root, completedSessionDays, now, protectedSessionIds) {
|
|
23252
|
-
const directory =
|
|
23419
|
+
const directory = path42.join(root, ".mancode", "local", "sessions");
|
|
23253
23420
|
const entries = await readDirectoryOrEmpty(directory);
|
|
23254
23421
|
const threshold = now.getTime() - completedSessionDays * 864e5;
|
|
23255
23422
|
const candidates = [];
|
|
23256
23423
|
for (const entry of entries) {
|
|
23257
23424
|
if (!entry.endsWith(".json")) continue;
|
|
23258
|
-
const target =
|
|
23425
|
+
const target = path42.join(directory, entry);
|
|
23259
23426
|
const session = parseSessionState(
|
|
23260
23427
|
JSON.parse(await readRegularFile(target))
|
|
23261
23428
|
);
|
|
@@ -23281,7 +23448,7 @@ async function planOperationRetention(stores, now) {
|
|
|
23281
23448
|
const entries = await readDirectoryOrEmpty(directory);
|
|
23282
23449
|
for (const entry of entries) {
|
|
23283
23450
|
if (!entry.endsWith(".json")) continue;
|
|
23284
|
-
const target =
|
|
23451
|
+
const target = path42.join(directory, entry);
|
|
23285
23452
|
const journal = parseOperationJournal(
|
|
23286
23453
|
JSON.parse(await readRegularFile(target))
|
|
23287
23454
|
);
|
|
@@ -23357,7 +23524,7 @@ function taskRefKeyFromEntityKey(entityKey) {
|
|
|
23357
23524
|
async function listTaskRefs(root) {
|
|
23358
23525
|
const refs = [];
|
|
23359
23526
|
for (const namespace of ["local", "shared"]) {
|
|
23360
|
-
const directory =
|
|
23527
|
+
const directory = path42.join(root, ".mancode", namespace, "workflows");
|
|
23361
23528
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23362
23529
|
if (!/^[0-9A-HJKMNP-TV-Z]{26}$/.test(entry)) continue;
|
|
23363
23530
|
refs.push({ namespace, taskId: entry });
|
|
@@ -23370,12 +23537,12 @@ async function listTaskRefs(root) {
|
|
|
23370
23537
|
);
|
|
23371
23538
|
}
|
|
23372
23539
|
async function listTaskCheckpoints(taskRoot2, taskRef) {
|
|
23373
|
-
const directory =
|
|
23540
|
+
const directory = path42.join(taskRoot2, "checkpoints");
|
|
23374
23541
|
const checkpoints = [];
|
|
23375
23542
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23376
23543
|
if (!entry.endsWith(".json")) continue;
|
|
23377
23544
|
const checkpoint = parseCheckpoint(
|
|
23378
|
-
JSON.parse(await readRegularFile(
|
|
23545
|
+
JSON.parse(await readRegularFile(path42.join(directory, entry)))
|
|
23379
23546
|
);
|
|
23380
23547
|
if (!sameTaskRef(checkpoint.taskRef, taskRef) || entry !== `${checkpoint.checkpointId}.json`) {
|
|
23381
23548
|
throw new Error("MANCODE_RETENTION_CHECKPOINT_CORRUPT");
|
|
@@ -23399,7 +23566,7 @@ function uniqueStores(stores) {
|
|
|
23399
23566
|
}
|
|
23400
23567
|
async function readDirectoryOrEmpty(directory) {
|
|
23401
23568
|
try {
|
|
23402
|
-
const entry = await
|
|
23569
|
+
const entry = await lstat14(directory);
|
|
23403
23570
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23404
23571
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
23405
23572
|
}
|
|
@@ -23414,7 +23581,7 @@ async function readDirectoryOrEmpty(directory) {
|
|
|
23414
23581
|
async function listRegularFilesRecursively(directory) {
|
|
23415
23582
|
const files = [];
|
|
23416
23583
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
23417
|
-
const target =
|
|
23584
|
+
const target = path42.join(directory, entry);
|
|
23418
23585
|
const metadata = await lstatOrNull3(target);
|
|
23419
23586
|
if (metadata === null) continue;
|
|
23420
23587
|
if (metadata.isSymbolicLink()) {
|
|
@@ -23433,12 +23600,12 @@ async function listRegularFilesRecursively(directory) {
|
|
|
23433
23600
|
return files;
|
|
23434
23601
|
}
|
|
23435
23602
|
async function readRegularFile(target) {
|
|
23436
|
-
const before = await
|
|
23603
|
+
const before = await lstat14(target);
|
|
23437
23604
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23438
23605
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
23439
23606
|
}
|
|
23440
23607
|
const content = await readFile31(target, "utf8");
|
|
23441
|
-
const after = await
|
|
23608
|
+
const after = await lstat14(target);
|
|
23442
23609
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23443
23610
|
throw new Error("MANCODE_RETENTION_PATH_UNSAFE");
|
|
23444
23611
|
}
|
|
@@ -23446,7 +23613,7 @@ async function readRegularFile(target) {
|
|
|
23446
23613
|
}
|
|
23447
23614
|
async function removeRegularFile(target) {
|
|
23448
23615
|
await readRegularFile(target);
|
|
23449
|
-
await
|
|
23616
|
+
await rm18(target);
|
|
23450
23617
|
}
|
|
23451
23618
|
async function regularFileExists(target) {
|
|
23452
23619
|
try {
|
|
@@ -23467,7 +23634,7 @@ async function regularFileMetadataOrNull(target) {
|
|
|
23467
23634
|
}
|
|
23468
23635
|
async function lstatOrNull3(target) {
|
|
23469
23636
|
try {
|
|
23470
|
-
return await
|
|
23637
|
+
return await lstat14(target);
|
|
23471
23638
|
} catch (error) {
|
|
23472
23639
|
if (isNotFound22(error)) return null;
|
|
23473
23640
|
throw error;
|
|
@@ -23478,8 +23645,8 @@ function isNotFound22(error) {
|
|
|
23478
23645
|
}
|
|
23479
23646
|
|
|
23480
23647
|
// src/team/git-ref-cache.ts
|
|
23481
|
-
import { lstat as
|
|
23482
|
-
import
|
|
23648
|
+
import { lstat as lstat15, mkdir as mkdir29, readFile as readFile32, writeFile as writeFile37 } from "fs/promises";
|
|
23649
|
+
import path43 from "path";
|
|
23483
23650
|
var DEFAULT_GIT_REF_FRESHNESS_TTL_MS = 5 * 60 * 1e3;
|
|
23484
23651
|
async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
23485
23652
|
const remote = gitRefRemote(config);
|
|
@@ -23495,11 +23662,11 @@ async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
|
23495
23662
|
});
|
|
23496
23663
|
const directory = await ensureSafeCacheDirectory(projectRoot);
|
|
23497
23664
|
const target = gitRefCachePath(projectRoot);
|
|
23498
|
-
const temporary =
|
|
23665
|
+
const temporary = path43.join(
|
|
23499
23666
|
directory,
|
|
23500
23667
|
`.snapshot.${process.pid}.${Date.now()}.tmp`
|
|
23501
23668
|
);
|
|
23502
|
-
await
|
|
23669
|
+
await writeFile37(temporary, `${JSON.stringify(cache, null, 2)}
|
|
23503
23670
|
`, {
|
|
23504
23671
|
encoding: "utf8",
|
|
23505
23672
|
flag: "wx"
|
|
@@ -23512,14 +23679,14 @@ async function readGitRefTeamCache(projectRoot, config) {
|
|
|
23512
23679
|
const target = gitRefCachePath(projectRoot);
|
|
23513
23680
|
try {
|
|
23514
23681
|
await assertSafeCacheDirectory(projectRoot);
|
|
23515
|
-
const before = await
|
|
23682
|
+
const before = await lstat15(target);
|
|
23516
23683
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23517
23684
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
23518
23685
|
}
|
|
23519
23686
|
const cache = parseGitRefTeamCache(
|
|
23520
23687
|
JSON.parse(await readFile32(target, "utf8"))
|
|
23521
23688
|
);
|
|
23522
|
-
const after = await
|
|
23689
|
+
const after = await lstat15(target);
|
|
23523
23690
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23524
23691
|
throw new Error("MANCODE_TRANSPORT_CACHE_CHANGED_DURING_READ");
|
|
23525
23692
|
}
|
|
@@ -23611,11 +23778,11 @@ function parseGitRefTeamCache(value) {
|
|
|
23611
23778
|
};
|
|
23612
23779
|
}
|
|
23613
23780
|
function gitRefCachePath(projectRoot) {
|
|
23614
|
-
return
|
|
23781
|
+
return path43.join(gitRefCacheDirectory(projectRoot), "snapshot.json");
|
|
23615
23782
|
}
|
|
23616
23783
|
function gitRefCacheDirectory(projectRoot) {
|
|
23617
|
-
return
|
|
23618
|
-
|
|
23784
|
+
return path43.join(
|
|
23785
|
+
path43.resolve(projectRoot),
|
|
23619
23786
|
".mancode",
|
|
23620
23787
|
"local",
|
|
23621
23788
|
"cache",
|
|
@@ -23661,10 +23828,10 @@ function parseReceiptOrNull(value) {
|
|
|
23661
23828
|
return value;
|
|
23662
23829
|
}
|
|
23663
23830
|
async function ensureSafeCacheDirectory(projectRoot) {
|
|
23664
|
-
const root =
|
|
23831
|
+
const root = path43.resolve(projectRoot);
|
|
23665
23832
|
let current = root;
|
|
23666
23833
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23667
|
-
current =
|
|
23834
|
+
current = path43.join(current, segment);
|
|
23668
23835
|
try {
|
|
23669
23836
|
await mkdir29(current);
|
|
23670
23837
|
} catch (error) {
|
|
@@ -23675,14 +23842,14 @@ async function ensureSafeCacheDirectory(projectRoot) {
|
|
|
23675
23842
|
return current;
|
|
23676
23843
|
}
|
|
23677
23844
|
async function assertSafeCacheDirectory(projectRoot) {
|
|
23678
|
-
let current =
|
|
23845
|
+
let current = path43.resolve(projectRoot);
|
|
23679
23846
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
23680
|
-
current =
|
|
23847
|
+
current = path43.join(current, segment);
|
|
23681
23848
|
await assertDirectoryNotLinked(current);
|
|
23682
23849
|
}
|
|
23683
23850
|
}
|
|
23684
23851
|
async function assertDirectoryNotLinked(directory) {
|
|
23685
|
-
const entry = await
|
|
23852
|
+
const entry = await lstat15(directory);
|
|
23686
23853
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23687
23854
|
throw new Error("MANCODE_TRANSPORT_CACHE_UNSAFE");
|
|
23688
23855
|
}
|
|
@@ -23695,24 +23862,24 @@ function isAlreadyExists17(error) {
|
|
|
23695
23862
|
}
|
|
23696
23863
|
|
|
23697
23864
|
// src/team/git-ref-workflow-repair.ts
|
|
23698
|
-
import { lstat as
|
|
23699
|
-
import
|
|
23865
|
+
import { lstat as lstat19, mkdir as mkdir33, readFile as readFile36, readdir as readdir17, writeFile as writeFile41 } from "fs/promises";
|
|
23866
|
+
import path47 from "path";
|
|
23700
23867
|
|
|
23701
23868
|
// src/team/git-ref-materialization.ts
|
|
23702
23869
|
import {
|
|
23703
|
-
lstat as
|
|
23870
|
+
lstat as lstat18,
|
|
23704
23871
|
mkdir as mkdir32,
|
|
23705
23872
|
readFile as readFile35,
|
|
23706
23873
|
readdir as readdir16,
|
|
23707
23874
|
unlink as unlink2,
|
|
23708
|
-
writeFile as
|
|
23875
|
+
writeFile as writeFile40
|
|
23709
23876
|
} from "fs/promises";
|
|
23710
|
-
import
|
|
23877
|
+
import path46 from "path";
|
|
23711
23878
|
|
|
23712
23879
|
// src/team/git-ref-bundle.ts
|
|
23713
23880
|
import { execFile as execFileCallback5 } from "child_process";
|
|
23714
|
-
import { lstat as
|
|
23715
|
-
import
|
|
23881
|
+
import { lstat as lstat16, mkdir as mkdir30, readFile as readFile33, readdir as readdir15, writeFile as writeFile38 } from "fs/promises";
|
|
23882
|
+
import path44 from "path";
|
|
23716
23883
|
import { promisify as promisify5 } from "util";
|
|
23717
23884
|
var execFile5 = promisify5(execFileCallback5);
|
|
23718
23885
|
function createGitRefTaskBundle(input) {
|
|
@@ -23775,7 +23942,7 @@ async function assertGitRefBundleCodeReachable(projectRoot, bundle) {
|
|
|
23775
23942
|
"git",
|
|
23776
23943
|
["cat-file", "-e", `${parsed.codeRef.head}^{commit}`],
|
|
23777
23944
|
{
|
|
23778
|
-
cwd:
|
|
23945
|
+
cwd: path44.resolve(projectRoot),
|
|
23779
23946
|
windowsHide: true
|
|
23780
23947
|
}
|
|
23781
23948
|
);
|
|
@@ -23788,8 +23955,8 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23788
23955
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23789
23956
|
}
|
|
23790
23957
|
const parsed = parseGitRefTaskBundle(bundle);
|
|
23791
|
-
const directory =
|
|
23792
|
-
|
|
23958
|
+
const directory = path44.join(
|
|
23959
|
+
path44.resolve(projectRoot),
|
|
23793
23960
|
".mancode",
|
|
23794
23961
|
"local",
|
|
23795
23962
|
"quarantine",
|
|
@@ -23805,9 +23972,9 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
23805
23972
|
parsed.taskRef.taskId,
|
|
23806
23973
|
String(remoteRevision)
|
|
23807
23974
|
]);
|
|
23808
|
-
const target =
|
|
23975
|
+
const target = path44.join(directory, `${parsed.bundleDigest.slice(7)}.json`);
|
|
23809
23976
|
try {
|
|
23810
|
-
await
|
|
23977
|
+
await writeFile38(target, `${JSON.stringify(parsed, null, 2)}
|
|
23811
23978
|
`, {
|
|
23812
23979
|
encoding: "utf8",
|
|
23813
23980
|
flag: "wx"
|
|
@@ -23822,8 +23989,8 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23822
23989
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
23823
23990
|
}
|
|
23824
23991
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23825
|
-
const directory =
|
|
23826
|
-
|
|
23992
|
+
const directory = path44.join(
|
|
23993
|
+
path44.resolve(projectRoot),
|
|
23827
23994
|
".mancode",
|
|
23828
23995
|
"local",
|
|
23829
23996
|
"quarantine",
|
|
@@ -23849,15 +24016,15 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
23849
24016
|
const matches = [];
|
|
23850
24017
|
for (const entry of entries.sort()) {
|
|
23851
24018
|
if (!/^[a-f0-9]{64}\.json$/.test(entry)) continue;
|
|
23852
|
-
const target =
|
|
23853
|
-
const before = await
|
|
24019
|
+
const target = path44.join(directory, entry);
|
|
24020
|
+
const before = await lstat16(target);
|
|
23854
24021
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23855
24022
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23856
24023
|
}
|
|
23857
24024
|
const bundle = parseGitRefTaskBundle(
|
|
23858
24025
|
JSON.parse(await readFile33(target, "utf8"))
|
|
23859
24026
|
);
|
|
23860
|
-
const after = await
|
|
24027
|
+
const after = await lstat16(target);
|
|
23861
24028
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23862
24029
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23863
24030
|
}
|
|
@@ -23886,25 +24053,25 @@ function parseCodeRef(value) {
|
|
|
23886
24053
|
return { branch: value.branch, head: value.head };
|
|
23887
24054
|
}
|
|
23888
24055
|
async function ensureFixedDirectory(projectRoot, segments) {
|
|
23889
|
-
let current =
|
|
24056
|
+
let current = path44.resolve(projectRoot);
|
|
23890
24057
|
for (const segment of segments) {
|
|
23891
|
-
current =
|
|
24058
|
+
current = path44.join(current, segment);
|
|
23892
24059
|
try {
|
|
23893
24060
|
await mkdir30(current);
|
|
23894
24061
|
} catch (error) {
|
|
23895
24062
|
if (!isAlreadyExists18(error)) throw error;
|
|
23896
24063
|
}
|
|
23897
|
-
const entry = await
|
|
24064
|
+
const entry = await lstat16(current);
|
|
23898
24065
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23899
24066
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23900
24067
|
}
|
|
23901
24068
|
}
|
|
23902
24069
|
}
|
|
23903
24070
|
async function assertFixedDirectory(projectRoot, segments) {
|
|
23904
|
-
let current =
|
|
24071
|
+
let current = path44.resolve(projectRoot);
|
|
23905
24072
|
for (const segment of segments) {
|
|
23906
|
-
current =
|
|
23907
|
-
const entry = await
|
|
24073
|
+
current = path44.join(current, segment);
|
|
24074
|
+
const entry = await lstat16(current);
|
|
23908
24075
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
23909
24076
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23910
24077
|
}
|
|
@@ -23918,22 +24085,22 @@ function isNotFound24(error) {
|
|
|
23918
24085
|
}
|
|
23919
24086
|
|
|
23920
24087
|
// src/team/git-ref-task-base.ts
|
|
23921
|
-
import { lstat as
|
|
23922
|
-
import
|
|
24088
|
+
import { lstat as lstat17, mkdir as mkdir31, readFile as readFile34, writeFile as writeFile39 } from "fs/promises";
|
|
24089
|
+
import path45 from "path";
|
|
23923
24090
|
async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
23924
24091
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
23925
24092
|
const runtime = await readProjectRuntimeContext(projectRoot);
|
|
23926
24093
|
const target = remoteBasePath(projectRoot, parsedTaskRef);
|
|
23927
24094
|
try {
|
|
23928
24095
|
await assertRemoteBaseDirectory(projectRoot);
|
|
23929
|
-
const before = await
|
|
24096
|
+
const before = await lstat17(target);
|
|
23930
24097
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
23931
24098
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23932
24099
|
}
|
|
23933
24100
|
const state = parseGitRefTaskRemoteBase(
|
|
23934
24101
|
JSON.parse(await readFile34(target, "utf8"))
|
|
23935
24102
|
);
|
|
23936
|
-
const after = await
|
|
24103
|
+
const after = await lstat17(target);
|
|
23937
24104
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
23938
24105
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
23939
24106
|
}
|
|
@@ -23962,11 +24129,11 @@ async function recordGitRefTaskRemoteBase(projectRoot, remoteRevision, bundle) {
|
|
|
23962
24129
|
});
|
|
23963
24130
|
const directory = await ensureRemoteBaseDirectory(projectRoot);
|
|
23964
24131
|
const target = remoteBasePath(projectRoot, parsedBundle.taskRef);
|
|
23965
|
-
const temporary =
|
|
24132
|
+
const temporary = path45.join(
|
|
23966
24133
|
directory,
|
|
23967
24134
|
`.${parsedBundle.taskRef.taskId}.${process.pid}.${Date.now()}.tmp`
|
|
23968
24135
|
);
|
|
23969
|
-
await
|
|
24136
|
+
await writeFile39(temporary, `${JSON.stringify(state, null, 2)}
|
|
23970
24137
|
`, {
|
|
23971
24138
|
encoding: "utf8",
|
|
23972
24139
|
flag: "wx"
|
|
@@ -23999,7 +24166,7 @@ function parseGitRefTaskRemoteBase(value) {
|
|
|
23999
24166
|
};
|
|
24000
24167
|
}
|
|
24001
24168
|
async function ensureRemoteBaseDirectory(projectRoot) {
|
|
24002
|
-
let current =
|
|
24169
|
+
let current = path45.resolve(projectRoot);
|
|
24003
24170
|
for (const segment of [
|
|
24004
24171
|
".mancode",
|
|
24005
24172
|
"local",
|
|
@@ -24007,13 +24174,13 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
24007
24174
|
"git-ref",
|
|
24008
24175
|
"remote-bases"
|
|
24009
24176
|
]) {
|
|
24010
|
-
current =
|
|
24177
|
+
current = path45.join(current, segment);
|
|
24011
24178
|
try {
|
|
24012
24179
|
await mkdir31(current);
|
|
24013
24180
|
} catch (error) {
|
|
24014
24181
|
if (!isAlreadyExists19(error)) throw error;
|
|
24015
24182
|
}
|
|
24016
|
-
const entry = await
|
|
24183
|
+
const entry = await lstat17(current);
|
|
24017
24184
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
24018
24185
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24019
24186
|
}
|
|
@@ -24021,7 +24188,7 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
24021
24188
|
return current;
|
|
24022
24189
|
}
|
|
24023
24190
|
async function assertRemoteBaseDirectory(projectRoot) {
|
|
24024
|
-
let current =
|
|
24191
|
+
let current = path45.resolve(projectRoot);
|
|
24025
24192
|
for (const segment of [
|
|
24026
24193
|
".mancode",
|
|
24027
24194
|
"local",
|
|
@@ -24029,8 +24196,8 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
24029
24196
|
"git-ref",
|
|
24030
24197
|
"remote-bases"
|
|
24031
24198
|
]) {
|
|
24032
|
-
current =
|
|
24033
|
-
const entry = await
|
|
24199
|
+
current = path45.join(current, segment);
|
|
24200
|
+
const entry = await lstat17(current);
|
|
24034
24201
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
24035
24202
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24036
24203
|
}
|
|
@@ -24038,8 +24205,8 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
24038
24205
|
}
|
|
24039
24206
|
function remoteBasePath(projectRoot, taskRef) {
|
|
24040
24207
|
const parsed = parseTaskRefValue(taskRef);
|
|
24041
|
-
return
|
|
24042
|
-
|
|
24208
|
+
return path45.join(
|
|
24209
|
+
path45.resolve(projectRoot),
|
|
24043
24210
|
".mancode",
|
|
24044
24211
|
"local",
|
|
24045
24212
|
"cache",
|
|
@@ -24063,7 +24230,7 @@ function isNotFound25(error) {
|
|
|
24063
24230
|
|
|
24064
24231
|
// src/team/git-ref-materialization.ts
|
|
24065
24232
|
async function materializeGitRefTaskBundle(input) {
|
|
24066
|
-
const projectRoot =
|
|
24233
|
+
const projectRoot = path46.resolve(input.projectRoot);
|
|
24067
24234
|
const remoteRevision = positiveInteger3(
|
|
24068
24235
|
input.remoteRevision,
|
|
24069
24236
|
"git-ref materialization remoteRevision"
|
|
@@ -24369,7 +24536,7 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
24369
24536
|
const target = safeTaskPath(taskRoot2, relativePath2);
|
|
24370
24537
|
await ensureSafeDirectory(
|
|
24371
24538
|
taskRoot2,
|
|
24372
|
-
|
|
24539
|
+
path46.dirname(relativePath2).split(path46.sep)
|
|
24373
24540
|
);
|
|
24374
24541
|
const current = await readSafeFileOrNull(target);
|
|
24375
24542
|
if (contentMatches(relativePath2, current, targetContent)) return;
|
|
@@ -24379,11 +24546,11 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
24379
24546
|
if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath2 !== "summary.md") {
|
|
24380
24547
|
throw new Error("MANCODE_SPLIT_BRAIN");
|
|
24381
24548
|
}
|
|
24382
|
-
const temporary =
|
|
24383
|
-
|
|
24384
|
-
`.${
|
|
24549
|
+
const temporary = path46.join(
|
|
24550
|
+
path46.dirname(target),
|
|
24551
|
+
`.${path46.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
24385
24552
|
);
|
|
24386
|
-
await
|
|
24553
|
+
await writeFile40(temporary, targetContent, { encoding: "utf8", flag: "wx" });
|
|
24387
24554
|
await replaceFileAtomically(temporary, target);
|
|
24388
24555
|
}
|
|
24389
24556
|
function contentMatches(relativePath2, current, expected) {
|
|
@@ -24433,12 +24600,12 @@ async function removeVerifiedFile(taskRoot2, relativePath2, predecessorContent)
|
|
|
24433
24600
|
}
|
|
24434
24601
|
async function readSafeFileOrNull(target) {
|
|
24435
24602
|
try {
|
|
24436
|
-
const before = await
|
|
24603
|
+
const before = await lstat18(target);
|
|
24437
24604
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
24438
24605
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24439
24606
|
}
|
|
24440
24607
|
const content = await readFile35(target, "utf8");
|
|
24441
|
-
const after = await
|
|
24608
|
+
const after = await lstat18(target);
|
|
24442
24609
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
24443
24610
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24444
24611
|
}
|
|
@@ -24449,28 +24616,28 @@ async function readSafeFileOrNull(target) {
|
|
|
24449
24616
|
}
|
|
24450
24617
|
}
|
|
24451
24618
|
async function ensureSafeDirectory(root, segments) {
|
|
24452
|
-
let current =
|
|
24619
|
+
let current = path46.resolve(root);
|
|
24453
24620
|
for (const segment of segments) {
|
|
24454
24621
|
if (!segment || segment === ".") continue;
|
|
24455
24622
|
if (segment === ".." || segment.includes("/") || segment.includes("\\")) {
|
|
24456
24623
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24457
24624
|
}
|
|
24458
|
-
current =
|
|
24625
|
+
current = path46.join(current, segment);
|
|
24459
24626
|
try {
|
|
24460
24627
|
await mkdir32(current);
|
|
24461
24628
|
} catch (error) {
|
|
24462
24629
|
if (!isAlreadyExists20(error)) throw error;
|
|
24463
24630
|
}
|
|
24464
|
-
const entry = await
|
|
24631
|
+
const entry = await lstat18(current);
|
|
24465
24632
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
24466
24633
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24467
24634
|
}
|
|
24468
24635
|
}
|
|
24469
24636
|
}
|
|
24470
24637
|
function safeTaskPath(taskRoot2, relativePath2) {
|
|
24471
|
-
const target =
|
|
24472
|
-
const relative =
|
|
24473
|
-
if (!relative || relative.startsWith("..") ||
|
|
24638
|
+
const target = path46.resolve(taskRoot2, relativePath2);
|
|
24639
|
+
const relative = path46.relative(taskRoot2, target);
|
|
24640
|
+
if (!relative || relative.startsWith("..") || path46.isAbsolute(relative)) {
|
|
24474
24641
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
24475
24642
|
}
|
|
24476
24643
|
return target;
|
|
@@ -24482,7 +24649,7 @@ async function createJournal(projectRoot, journal) {
|
|
|
24482
24649
|
"journals",
|
|
24483
24650
|
"git-ref-materialize"
|
|
24484
24651
|
]);
|
|
24485
|
-
await
|
|
24652
|
+
await writeFile40(
|
|
24486
24653
|
journalPath(projectRoot, journal.operationId),
|
|
24487
24654
|
serialize11(journal),
|
|
24488
24655
|
{
|
|
@@ -24493,11 +24660,11 @@ async function createJournal(projectRoot, journal) {
|
|
|
24493
24660
|
}
|
|
24494
24661
|
async function replaceJournal(projectRoot, journal) {
|
|
24495
24662
|
const target = journalPath(projectRoot, journal.operationId);
|
|
24496
|
-
const temporary =
|
|
24497
|
-
|
|
24663
|
+
const temporary = path46.join(
|
|
24664
|
+
path46.dirname(target),
|
|
24498
24665
|
`.${journal.operationId}.${process.pid}.${Date.now()}.tmp`
|
|
24499
24666
|
);
|
|
24500
|
-
await
|
|
24667
|
+
await writeFile40(temporary, serialize11(journal), {
|
|
24501
24668
|
encoding: "utf8",
|
|
24502
24669
|
flag: "wx"
|
|
24503
24670
|
});
|
|
@@ -24526,7 +24693,7 @@ async function listJournals(projectRoot) {
|
|
|
24526
24693
|
const journals = [];
|
|
24527
24694
|
for (const entry of entries.sort()) {
|
|
24528
24695
|
if (!entry.endsWith(".json")) continue;
|
|
24529
|
-
journals.push(await readJournal(
|
|
24696
|
+
journals.push(await readJournal(path46.join(directory, entry)));
|
|
24530
24697
|
}
|
|
24531
24698
|
return journals;
|
|
24532
24699
|
}
|
|
@@ -24592,8 +24759,8 @@ function result(status2, bundle, localJournalPath, taskHeadFence) {
|
|
|
24592
24759
|
};
|
|
24593
24760
|
}
|
|
24594
24761
|
function journalDirectory(projectRoot) {
|
|
24595
|
-
return
|
|
24596
|
-
|
|
24762
|
+
return path46.join(
|
|
24763
|
+
path46.resolve(projectRoot),
|
|
24597
24764
|
".mancode",
|
|
24598
24765
|
"local",
|
|
24599
24766
|
"journals",
|
|
@@ -24602,7 +24769,7 @@ function journalDirectory(projectRoot) {
|
|
|
24602
24769
|
}
|
|
24603
24770
|
function journalPath(projectRoot, operationId) {
|
|
24604
24771
|
assertUlid(operationId, "git-ref materialization operationId");
|
|
24605
|
-
return
|
|
24772
|
+
return path46.join(journalDirectory(projectRoot), `${operationId}.json`);
|
|
24606
24773
|
}
|
|
24607
24774
|
function serialize11(value) {
|
|
24608
24775
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -24622,7 +24789,7 @@ function timestamp2(value) {
|
|
|
24622
24789
|
}
|
|
24623
24790
|
async function pathExists3(target) {
|
|
24624
24791
|
try {
|
|
24625
|
-
await
|
|
24792
|
+
await lstat18(target);
|
|
24626
24793
|
return true;
|
|
24627
24794
|
} catch (error) {
|
|
24628
24795
|
if (isNotFound26(error)) return false;
|
|
@@ -24638,7 +24805,7 @@ function isNotFound26(error) {
|
|
|
24638
24805
|
|
|
24639
24806
|
// src/team/git-ref-workflow-repair.ts
|
|
24640
24807
|
async function prepareGitRefWorkflowRepair(input) {
|
|
24641
|
-
const root =
|
|
24808
|
+
const root = path47.resolve(input.projectRoot);
|
|
24642
24809
|
const prepared2 = parsePrepared(input.prepared);
|
|
24643
24810
|
const pendingMetadata = parseWorkflowMetadata(input.pendingMetadata);
|
|
24644
24811
|
assertPendingMetadata2(prepared2, pendingMetadata);
|
|
@@ -24673,7 +24840,7 @@ async function prepareGitRefWorkflowRepair(input) {
|
|
|
24673
24840
|
}
|
|
24674
24841
|
async function recoverGitRefWorkflowRepair(projectRoot, operationId, transportReceipt = null, options = {}) {
|
|
24675
24842
|
assertUlid(operationId, "git-ref workflow repair operationId");
|
|
24676
|
-
const root =
|
|
24843
|
+
const root = path47.resolve(projectRoot);
|
|
24677
24844
|
let journal = await requireJournal(root, operationId);
|
|
24678
24845
|
await assertRecoveryAuthorized(root, journal, options);
|
|
24679
24846
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
@@ -25040,7 +25207,7 @@ async function createJournal2(projectRoot, journal) {
|
|
|
25040
25207
|
await ensureJournalDirectory(projectRoot);
|
|
25041
25208
|
const target = gitRefWorkflowRepairJournalPath(projectRoot, journal.operationId);
|
|
25042
25209
|
try {
|
|
25043
|
-
await
|
|
25210
|
+
await writeFile41(target, serialize12(journal), {
|
|
25044
25211
|
encoding: "utf8",
|
|
25045
25212
|
flag: "wx"
|
|
25046
25213
|
});
|
|
@@ -25080,38 +25247,38 @@ function metadataFromBundle(bundle) {
|
|
|
25080
25247
|
return parseWorkflowMetadata(artifact2.content);
|
|
25081
25248
|
}
|
|
25082
25249
|
function metadataPath2(projectRoot, taskRef) {
|
|
25083
|
-
return
|
|
25250
|
+
return path47.join(taskRootPath(projectRoot, taskRef), "metadata.json");
|
|
25084
25251
|
}
|
|
25085
25252
|
async function readSafeFile(target) {
|
|
25086
|
-
const before = await
|
|
25253
|
+
const before = await lstat19(target);
|
|
25087
25254
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
25088
25255
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
25089
25256
|
}
|
|
25090
25257
|
const content = await readFile36(target, "utf8");
|
|
25091
|
-
const after = await
|
|
25258
|
+
const after = await lstat19(target);
|
|
25092
25259
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
25093
25260
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
25094
25261
|
}
|
|
25095
25262
|
return content;
|
|
25096
25263
|
}
|
|
25097
25264
|
async function atomicWrite(target, content) {
|
|
25098
|
-
const temporary =
|
|
25099
|
-
|
|
25100
|
-
`.${
|
|
25265
|
+
const temporary = path47.join(
|
|
25266
|
+
path47.dirname(target),
|
|
25267
|
+
`.${path47.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
25101
25268
|
);
|
|
25102
|
-
await
|
|
25269
|
+
await writeFile41(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
25103
25270
|
await replaceFileAtomically(temporary, target);
|
|
25104
25271
|
}
|
|
25105
25272
|
async function ensureJournalDirectory(projectRoot) {
|
|
25106
|
-
let current =
|
|
25273
|
+
let current = path47.resolve(projectRoot);
|
|
25107
25274
|
for (const segment of [".mancode", "local", "journals", "git-ref-workflow"]) {
|
|
25108
|
-
current =
|
|
25275
|
+
current = path47.join(current, segment);
|
|
25109
25276
|
try {
|
|
25110
25277
|
await mkdir33(current);
|
|
25111
25278
|
} catch (error) {
|
|
25112
25279
|
if (!isAlreadyExists21(error)) throw error;
|
|
25113
25280
|
}
|
|
25114
|
-
const entry = await
|
|
25281
|
+
const entry = await lstat19(current);
|
|
25115
25282
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
25116
25283
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
25117
25284
|
}
|
|
@@ -25950,19 +26117,19 @@ function parseExpectedRevision2(value) {
|
|
|
25950
26117
|
|
|
25951
26118
|
// src/commands/design.ts
|
|
25952
26119
|
import { readFile as readFile38, stat as stat4 } from "fs/promises";
|
|
25953
|
-
import
|
|
26120
|
+
import path49 from "path";
|
|
25954
26121
|
import process2 from "process";
|
|
25955
26122
|
|
|
25956
26123
|
// src/context/design-policy.ts
|
|
25957
26124
|
import {
|
|
25958
|
-
lstat as
|
|
26125
|
+
lstat as lstat20,
|
|
25959
26126
|
mkdir as mkdir34,
|
|
25960
26127
|
readFile as readFile37,
|
|
25961
26128
|
realpath as realpath2,
|
|
25962
|
-
rm as
|
|
25963
|
-
writeFile as
|
|
26129
|
+
rm as rm19,
|
|
26130
|
+
writeFile as writeFile42
|
|
25964
26131
|
} from "fs/promises";
|
|
25965
|
-
import
|
|
26132
|
+
import path48 from "path";
|
|
25966
26133
|
var DEFAULT_DESIGN_POLICY = {
|
|
25967
26134
|
schemaVersion: 1,
|
|
25968
26135
|
revision: 0,
|
|
@@ -25976,8 +26143,8 @@ var DEFAULT_DESIGN_POLICY = {
|
|
|
25976
26143
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
25977
26144
|
};
|
|
25978
26145
|
function designPolicyPath(projectRoot) {
|
|
25979
|
-
return
|
|
25980
|
-
|
|
26146
|
+
return path48.join(
|
|
26147
|
+
path48.resolve(projectRoot),
|
|
25981
26148
|
".mancode",
|
|
25982
26149
|
"shared",
|
|
25983
26150
|
"context",
|
|
@@ -26065,7 +26232,7 @@ async function configureDesignPolicy(input) {
|
|
|
26065
26232
|
const operationId = input.operationId ?? createUlid();
|
|
26066
26233
|
assertUlid(operationId, "design policy operationId");
|
|
26067
26234
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
26068
|
-
const root =
|
|
26235
|
+
const root = path48.resolve(input.projectRoot);
|
|
26069
26236
|
const runtime = await readProjectRuntimeContext(root);
|
|
26070
26237
|
const store = resolveCoordinationEntityHomeStore(
|
|
26071
26238
|
runtime.entityHomeStoreContext
|
|
@@ -26121,12 +26288,12 @@ function isDesignBrowserValidation(value) {
|
|
|
26121
26288
|
}
|
|
26122
26289
|
async function writeDesignPolicy(projectRoot, policy) {
|
|
26123
26290
|
const target = designPolicyPath(projectRoot);
|
|
26124
|
-
await mkdir34(
|
|
26125
|
-
const temporary =
|
|
26126
|
-
|
|
26127
|
-
`.${
|
|
26291
|
+
await mkdir34(path48.dirname(target), { recursive: true });
|
|
26292
|
+
const temporary = path48.join(
|
|
26293
|
+
path48.dirname(target),
|
|
26294
|
+
`.${path48.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
26128
26295
|
);
|
|
26129
|
-
await
|
|
26296
|
+
await writeFile42(temporary, `${JSON.stringify(policy, null, 2)}
|
|
26130
26297
|
`, {
|
|
26131
26298
|
encoding: "utf8",
|
|
26132
26299
|
flag: "wx"
|
|
@@ -26134,20 +26301,20 @@ async function writeDesignPolicy(projectRoot, policy) {
|
|
|
26134
26301
|
try {
|
|
26135
26302
|
await replaceFileAtomically(temporary, target);
|
|
26136
26303
|
} finally {
|
|
26137
|
-
await
|
|
26304
|
+
await rm19(temporary, { force: true }).catch(() => void 0);
|
|
26138
26305
|
}
|
|
26139
26306
|
}
|
|
26140
26307
|
async function assertDesignPolicyPathSafe(projectRoot) {
|
|
26141
|
-
const root =
|
|
26308
|
+
const root = path48.resolve(projectRoot);
|
|
26142
26309
|
const policyPath = designPolicyPath(root);
|
|
26143
|
-
const contextDir =
|
|
26310
|
+
const contextDir = path48.dirname(policyPath);
|
|
26144
26311
|
try {
|
|
26145
26312
|
for (const directory of [
|
|
26146
|
-
|
|
26147
|
-
|
|
26313
|
+
path48.join(root, ".mancode"),
|
|
26314
|
+
path48.join(root, ".mancode", "shared"),
|
|
26148
26315
|
contextDir
|
|
26149
26316
|
]) {
|
|
26150
|
-
const info = await
|
|
26317
|
+
const info = await lstat20(directory);
|
|
26151
26318
|
if (info.isSymbolicLink() || !info.isDirectory()) {
|
|
26152
26319
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
26153
26320
|
}
|
|
@@ -26156,12 +26323,12 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
26156
26323
|
realpath2(root),
|
|
26157
26324
|
realpath2(contextDir)
|
|
26158
26325
|
]);
|
|
26159
|
-
const relative =
|
|
26160
|
-
if (
|
|
26326
|
+
const relative = path48.relative(resolvedRoot, resolvedContextDir);
|
|
26327
|
+
if (path48.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path48.sep}`)) {
|
|
26161
26328
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
26162
26329
|
}
|
|
26163
26330
|
try {
|
|
26164
|
-
const info = await
|
|
26331
|
+
const info = await lstat20(policyPath);
|
|
26165
26332
|
if (info.isSymbolicLink() || !info.isFile()) {
|
|
26166
26333
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
26167
26334
|
}
|
|
@@ -26412,7 +26579,7 @@ async function readProfile(rootDir, kind) {
|
|
|
26412
26579
|
try {
|
|
26413
26580
|
return JSON.parse(
|
|
26414
26581
|
await readFile38(
|
|
26415
|
-
|
|
26582
|
+
path49.join(rootDir, ".mancode", "project-profile.json"),
|
|
26416
26583
|
"utf8"
|
|
26417
26584
|
)
|
|
26418
26585
|
);
|
|
@@ -26421,7 +26588,7 @@ async function readProfile(rootDir, kind) {
|
|
|
26421
26588
|
}
|
|
26422
26589
|
}
|
|
26423
26590
|
async function readStyleSummary(rootDir, kind) {
|
|
26424
|
-
const cachePath = kind === "continuity" ?
|
|
26591
|
+
const cachePath = kind === "continuity" ? path49.join(rootDir, ".mancode", "local", "cache", "style-tokens.json") : path49.join(rootDir, ".mancode", "aesthetics", "style-tokens.json");
|
|
26425
26592
|
try {
|
|
26426
26593
|
const raw = JSON.parse(await readFile38(cachePath, "utf8"));
|
|
26427
26594
|
return sanitizeStyleSummary(rootDir, raw);
|
|
@@ -26462,7 +26629,7 @@ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
|
|
|
26462
26629
|
const scannedAt = Date.parse(lastScanned);
|
|
26463
26630
|
for (const file of sourceFiles) {
|
|
26464
26631
|
try {
|
|
26465
|
-
const info = await stat4(
|
|
26632
|
+
const info = await stat4(path49.resolve(rootDir, scopeRoot, file));
|
|
26466
26633
|
if (info.mtimeMs > scannedAt) return "stale";
|
|
26467
26634
|
} catch {
|
|
26468
26635
|
return "stale";
|
|
@@ -26539,10 +26706,10 @@ function emptyStyleSummary() {
|
|
|
26539
26706
|
};
|
|
26540
26707
|
}
|
|
26541
26708
|
async function initializedKind(rootDir) {
|
|
26542
|
-
if (await exists(
|
|
26709
|
+
if (await exists(path49.join(rootDir, ".mancode", "schema.json"))) {
|
|
26543
26710
|
return "continuity";
|
|
26544
26711
|
}
|
|
26545
|
-
if (await exists(
|
|
26712
|
+
if (await exists(path49.join(rootDir, ".mancode", "state.json")))
|
|
26546
26713
|
return "legacy";
|
|
26547
26714
|
return null;
|
|
26548
26715
|
}
|
|
@@ -26607,7 +26774,7 @@ function safeShortText(value) {
|
|
|
26607
26774
|
return typeof value === "string" && value.length <= 100 && /^[A-Za-z0-9@/_. -]+$/.test(value) ? value : null;
|
|
26608
26775
|
}
|
|
26609
26776
|
function isSafeRelativeFile(value) {
|
|
26610
|
-
return value.length <= 240 && !
|
|
26777
|
+
return value.length <= 240 && !path49.isAbsolute(value) && !value.includes("\0") && value.split(/[\\/]/).every((part) => part !== "" && part !== "." && part !== "..");
|
|
26611
26778
|
}
|
|
26612
26779
|
function parseNonNegativeInteger2(value) {
|
|
26613
26780
|
if (value === void 0 || !/^\d+$/.test(value)) return null;
|
|
@@ -26615,7 +26782,7 @@ function parseNonNegativeInteger2(value) {
|
|
|
26615
26782
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
26616
26783
|
}
|
|
26617
26784
|
function relativePath(rootDir, target) {
|
|
26618
|
-
return
|
|
26785
|
+
return path49.relative(path49.resolve(rootDir), target).split(path49.sep).join("/");
|
|
26619
26786
|
}
|
|
26620
26787
|
function isRecord6(value) {
|
|
26621
26788
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -26647,12 +26814,12 @@ function errorCode3(error, fallback) {
|
|
|
26647
26814
|
// src/commands/init.ts
|
|
26648
26815
|
import { promises as fs4 } from "fs";
|
|
26649
26816
|
import os from "os";
|
|
26650
|
-
import
|
|
26817
|
+
import path55 from "path";
|
|
26651
26818
|
import process6 from "process";
|
|
26652
26819
|
|
|
26653
26820
|
// src/installers/platform-status.ts
|
|
26654
26821
|
import { promises as fs } from "fs";
|
|
26655
|
-
import
|
|
26822
|
+
import path50 from "path";
|
|
26656
26823
|
async function checkPlatformStatus(rootDir, platform, installed) {
|
|
26657
26824
|
const readiness = await checkPlatformReadiness(rootDir, platform);
|
|
26658
26825
|
return {
|
|
@@ -26669,13 +26836,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26669
26836
|
if (platform === "claude-code") {
|
|
26670
26837
|
const [hasSoloSkill, registered, hasHookFiles] = await Promise.all([
|
|
26671
26838
|
fileMatches(
|
|
26672
|
-
|
|
26839
|
+
path50.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
|
|
26673
26840
|
(content) => isGeneratedClaudeSkill(content, "solo")
|
|
26674
26841
|
),
|
|
26675
26842
|
claudeHooksRegistered(rootDir),
|
|
26676
26843
|
pathsExist([
|
|
26677
|
-
|
|
26678
|
-
|
|
26844
|
+
path50.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
|
|
26845
|
+
path50.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
26679
26846
|
])
|
|
26680
26847
|
]);
|
|
26681
26848
|
const present = hasSoloSkill && registered && hasHookFiles;
|
|
@@ -26691,7 +26858,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26691
26858
|
if (platform === "cursor") {
|
|
26692
26859
|
const hasCoreRules = await allManagedSkills(
|
|
26693
26860
|
MANCODE_CURSOR_CORE_RULE_FILES.map(
|
|
26694
|
-
(file) =>
|
|
26861
|
+
(file) => path50.join(rootDir, ".cursor", "rules", file)
|
|
26695
26862
|
),
|
|
26696
26863
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26697
26864
|
);
|
|
@@ -26706,13 +26873,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26706
26873
|
const [hasRules, hasCommands] = await Promise.all([
|
|
26707
26874
|
allManagedSkills(
|
|
26708
26875
|
MANCODE_CURSOR_RULE_FILES.map(
|
|
26709
|
-
(file) =>
|
|
26876
|
+
(file) => path50.join(rootDir, ".cursor", "rules", file)
|
|
26710
26877
|
),
|
|
26711
26878
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
26712
26879
|
),
|
|
26713
26880
|
allManagedSkills(
|
|
26714
26881
|
MODE_NAMES.map(
|
|
26715
|
-
(mode) =>
|
|
26882
|
+
(mode) => path50.join(rootDir, ".cursor", "commands", `${mode}.md`)
|
|
26716
26883
|
),
|
|
26717
26884
|
[MODE_FILE_MANAGED_MARKER]
|
|
26718
26885
|
)
|
|
@@ -26725,7 +26892,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26725
26892
|
};
|
|
26726
26893
|
}
|
|
26727
26894
|
if (platform === "codex") {
|
|
26728
|
-
const hasBlock2 = await fileHasManagedBlock(
|
|
26895
|
+
const hasBlock2 = await fileHasManagedBlock(path50.join(rootDir, "AGENTS.md"));
|
|
26729
26896
|
if (!hasBlock2) {
|
|
26730
26897
|
return {
|
|
26731
26898
|
present: false,
|
|
@@ -26742,9 +26909,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26742
26909
|
readyDetail: "managed block present"
|
|
26743
26910
|
};
|
|
26744
26911
|
}
|
|
26745
|
-
const skillsDir =
|
|
26912
|
+
const skillsDir = path50.join(rootDir, ".agents", "skills");
|
|
26746
26913
|
const hasSkills = await allManagedSkills(
|
|
26747
|
-
MODE_NAMES.map((mode) =>
|
|
26914
|
+
MODE_NAMES.map((mode) => path50.join(skillsDir, mode, "SKILL.md")),
|
|
26748
26915
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26749
26916
|
);
|
|
26750
26917
|
return {
|
|
@@ -26756,7 +26923,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26756
26923
|
}
|
|
26757
26924
|
if (platform === "zcode") {
|
|
26758
26925
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26759
|
-
|
|
26926
|
+
path50.join(rootDir, "AGENTS.md"),
|
|
26760
26927
|
ZCODE_MANCODE_START_MARKER,
|
|
26761
26928
|
ZCODE_MANCODE_END_MARKER
|
|
26762
26929
|
);
|
|
@@ -26776,9 +26943,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26776
26943
|
readyDetail: "managed block present"
|
|
26777
26944
|
};
|
|
26778
26945
|
}
|
|
26779
|
-
const skillsDir =
|
|
26946
|
+
const skillsDir = path50.join(rootDir, ".agents", "skills");
|
|
26780
26947
|
const hasSkills = await allManagedSkills(
|
|
26781
|
-
MODE_NAMES.map((mode) =>
|
|
26948
|
+
MODE_NAMES.map((mode) => path50.join(skillsDir, mode, "SKILL.md")),
|
|
26782
26949
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26783
26950
|
);
|
|
26784
26951
|
return {
|
|
@@ -26790,7 +26957,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26790
26957
|
}
|
|
26791
26958
|
if (platform === "kimi-code") {
|
|
26792
26959
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26793
|
-
|
|
26960
|
+
path50.join(rootDir, "AGENTS.md"),
|
|
26794
26961
|
KIMI_MANCODE_START_MARKER,
|
|
26795
26962
|
KIMI_MANCODE_END_MARKER
|
|
26796
26963
|
);
|
|
@@ -26810,9 +26977,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26810
26977
|
readyDetail: "managed block present"
|
|
26811
26978
|
};
|
|
26812
26979
|
}
|
|
26813
|
-
const skillsDir =
|
|
26980
|
+
const skillsDir = path50.join(rootDir, ".agents", "skills");
|
|
26814
26981
|
const hasSkills = await allManagedSkills(
|
|
26815
|
-
MODE_NAMES.map((mode) =>
|
|
26982
|
+
MODE_NAMES.map((mode) => path50.join(skillsDir, mode, "SKILL.md")),
|
|
26816
26983
|
MANCODE_AGENT_SKILL_MARKERS
|
|
26817
26984
|
);
|
|
26818
26985
|
return {
|
|
@@ -26824,7 +26991,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26824
26991
|
}
|
|
26825
26992
|
if (platform === "qoder") {
|
|
26826
26993
|
const hasBlock2 = await fileHasManagedBlock(
|
|
26827
|
-
|
|
26994
|
+
path50.join(rootDir, "AGENTS.md"),
|
|
26828
26995
|
QODER_MANCODE_START_MARKER,
|
|
26829
26996
|
QODER_MANCODE_END_MARKER
|
|
26830
26997
|
);
|
|
@@ -26844,9 +27011,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26844
27011
|
readyDetail: "managed block present"
|
|
26845
27012
|
};
|
|
26846
27013
|
}
|
|
26847
|
-
const commandsDir =
|
|
27014
|
+
const commandsDir = path50.join(rootDir, ".qoder", "commands");
|
|
26848
27015
|
const hasCommands = await allManagedSkills(
|
|
26849
|
-
MODE_NAMES.map((mode) =>
|
|
27016
|
+
MODE_NAMES.map((mode) => path50.join(commandsDir, `${mode}.md`)),
|
|
26850
27017
|
[MODE_FILE_MANAGED_MARKER]
|
|
26851
27018
|
);
|
|
26852
27019
|
return {
|
|
@@ -26856,8 +27023,42 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26856
27023
|
readyDetail: hasCommands ? "managed block and commands present" : "mode commands are missing, incomplete, or user-authored"
|
|
26857
27024
|
};
|
|
26858
27025
|
}
|
|
27026
|
+
if (platform === "dsh") {
|
|
27027
|
+
const hasBlock2 = await fileHasManagedBlock(
|
|
27028
|
+
path50.join(rootDir, "AGENTS.md"),
|
|
27029
|
+
DSH_MANCODE_START_MARKER,
|
|
27030
|
+
DSH_MANCODE_END_MARKER
|
|
27031
|
+
);
|
|
27032
|
+
if (!hasBlock2) {
|
|
27033
|
+
return {
|
|
27034
|
+
present: false,
|
|
27035
|
+
ready: false,
|
|
27036
|
+
target: "AGENTS.md",
|
|
27037
|
+
readyDetail: "managed block missing"
|
|
27038
|
+
};
|
|
27039
|
+
}
|
|
27040
|
+
if (await isPlatformMinimal(rootDir, "dsh")) {
|
|
27041
|
+
return {
|
|
27042
|
+
present: true,
|
|
27043
|
+
ready: true,
|
|
27044
|
+
target: "AGENTS.md",
|
|
27045
|
+
readyDetail: "managed block present"
|
|
27046
|
+
};
|
|
27047
|
+
}
|
|
27048
|
+
const skillsDir = path50.join(rootDir, ".dsh", "skills");
|
|
27049
|
+
const hasSkills = await allManagedSkills(
|
|
27050
|
+
MODE_NAMES.map((mode) => path50.join(skillsDir, mode, "SKILL.md")),
|
|
27051
|
+
MANCODE_DSH_SKILL_MARKERS
|
|
27052
|
+
);
|
|
27053
|
+
return {
|
|
27054
|
+
present: true,
|
|
27055
|
+
ready: hasSkills,
|
|
27056
|
+
target: "AGENTS.md + .dsh/skills/",
|
|
27057
|
+
readyDetail: hasSkills ? "managed block and skills present" : "mode skills are missing, incomplete, or user-authored"
|
|
27058
|
+
};
|
|
27059
|
+
}
|
|
26859
27060
|
const hasBlock = await fileHasManagedBlock(
|
|
26860
|
-
|
|
27061
|
+
path50.join(rootDir, ".github", "copilot-instructions.md")
|
|
26861
27062
|
);
|
|
26862
27063
|
if (!hasBlock) {
|
|
26863
27064
|
return {
|
|
@@ -26868,9 +27069,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
26868
27069
|
};
|
|
26869
27070
|
}
|
|
26870
27071
|
if (!await isPlatformMinimal(rootDir, "copilot")) {
|
|
26871
|
-
const promptsDir =
|
|
27072
|
+
const promptsDir = path50.join(rootDir, ".github", "prompts");
|
|
26872
27073
|
const hasPrompts = await allManagedSkills(
|
|
26873
|
-
MODE_NAMES.map((mode) =>
|
|
27074
|
+
MODE_NAMES.map((mode) => path50.join(promptsDir, `${mode}.prompt.md`)),
|
|
26874
27075
|
[MODE_FILE_MANAGED_MARKER]
|
|
26875
27076
|
);
|
|
26876
27077
|
return {
|
|
@@ -26903,13 +27104,13 @@ async function allManagedSkills(paths, markers) {
|
|
|
26903
27104
|
async function claudeFullContentReady(rootDir) {
|
|
26904
27105
|
const skillChecks = MVP2_SKILLS.map(
|
|
26905
27106
|
(skill) => fileMatches(
|
|
26906
|
-
|
|
27107
|
+
path50.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
|
|
26907
27108
|
(content) => isGeneratedClaudeSkill(content, skill.name)
|
|
26908
27109
|
)
|
|
26909
27110
|
);
|
|
26910
27111
|
const agentChecks = ALL_AGENTS.map(
|
|
26911
27112
|
(agent) => fileMatches(
|
|
26912
|
-
|
|
27113
|
+
path50.join(rootDir, ".claude", "agents", `${agent.name}.md`),
|
|
26913
27114
|
(content) => isGeneratedClaudeAgent(content, agent.name)
|
|
26914
27115
|
)
|
|
26915
27116
|
);
|
|
@@ -26937,7 +27138,7 @@ async function fileHasAnyMarker(filePath, needles) {
|
|
|
26937
27138
|
async function isPlatformMinimal(rootDir, platform) {
|
|
26938
27139
|
try {
|
|
26939
27140
|
const raw = await fs.readFile(
|
|
26940
|
-
|
|
27141
|
+
path50.join(rootDir, ".mancode", "config.json"),
|
|
26941
27142
|
"utf-8"
|
|
26942
27143
|
);
|
|
26943
27144
|
const config = JSON.parse(raw);
|
|
@@ -26959,7 +27160,7 @@ async function fileHasManagedBlock(filePath, startMarker = DEFAULT_MANCODE_START
|
|
|
26959
27160
|
async function claudeHooksRegistered(rootDir) {
|
|
26960
27161
|
try {
|
|
26961
27162
|
const raw = await fs.readFile(
|
|
26962
|
-
|
|
27163
|
+
path50.join(rootDir, ".claude", "settings.json"),
|
|
26963
27164
|
"utf-8"
|
|
26964
27165
|
);
|
|
26965
27166
|
const settings = JSON.parse(raw);
|
|
@@ -27002,7 +27203,7 @@ function isRecord7(value) {
|
|
|
27002
27203
|
// src/system/detect-team.ts
|
|
27003
27204
|
import { execFile as execFile6 } from "child_process";
|
|
27004
27205
|
import { access as access2 } from "fs/promises";
|
|
27005
|
-
import
|
|
27206
|
+
import path51 from "path";
|
|
27006
27207
|
import process3 from "process";
|
|
27007
27208
|
import { promisify as promisify6 } from "util";
|
|
27008
27209
|
var execFileAsync = promisify6(execFile6);
|
|
@@ -27112,7 +27313,7 @@ async function anyPathExists(projectRoot, candidates) {
|
|
|
27112
27313
|
const results = await Promise.all(
|
|
27113
27314
|
candidates.map(async (candidate) => {
|
|
27114
27315
|
try {
|
|
27115
|
-
await access2(
|
|
27316
|
+
await access2(path51.join(projectRoot, candidate));
|
|
27116
27317
|
return true;
|
|
27117
27318
|
} catch {
|
|
27118
27319
|
return false;
|
|
@@ -27153,7 +27354,7 @@ async function detectSystemDeps(env = process4.env) {
|
|
|
27153
27354
|
// src/system/init-onboarding.ts
|
|
27154
27355
|
import { execFileSync } from "child_process";
|
|
27155
27356
|
import { promises as fs2 } from "fs";
|
|
27156
|
-
import
|
|
27357
|
+
import path52 from "path";
|
|
27157
27358
|
import process5 from "process";
|
|
27158
27359
|
import { stdin, stdout } from "process";
|
|
27159
27360
|
import { createInterface } from "readline/promises";
|
|
@@ -27256,9 +27457,10 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
27256
27457
|
if (environment.CURSOR_TRACE_ID) hints.add("cursor");
|
|
27257
27458
|
if (environment.COPILOT_AGENT || environment.GITHUB_COPILOT)
|
|
27258
27459
|
hints.add("copilot");
|
|
27460
|
+
if (environment.DSH_SHELL === "1") hints.add("dsh");
|
|
27259
27461
|
const exists2 = async (relative) => {
|
|
27260
27462
|
try {
|
|
27261
|
-
await fs2.access(
|
|
27463
|
+
await fs2.access(path52.join(rootDir, relative));
|
|
27262
27464
|
return true;
|
|
27263
27465
|
} catch {
|
|
27264
27466
|
return false;
|
|
@@ -27268,6 +27470,7 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
27268
27470
|
if (await exists2(".cursor")) hints.add("cursor");
|
|
27269
27471
|
if (await exists2(".github/copilot-instructions.md")) hints.add("copilot");
|
|
27270
27472
|
if (await exists2(".qoder")) hints.add("qoder");
|
|
27473
|
+
if (await exists2(".dsh")) hints.add("dsh");
|
|
27271
27474
|
return ALL_PLATFORMS.filter((platform) => hints.has(platform));
|
|
27272
27475
|
}
|
|
27273
27476
|
function createTerminalPrompter() {
|
|
@@ -27335,7 +27538,7 @@ function createTerminalPrompter() {
|
|
|
27335
27538
|
|
|
27336
27539
|
// src/system/scan-aesthetics.ts
|
|
27337
27540
|
import { promises as fs3 } from "fs";
|
|
27338
|
-
import
|
|
27541
|
+
import path53 from "path";
|
|
27339
27542
|
var MAX_COMPONENT_SCAN_DEPTH = 12;
|
|
27340
27543
|
var MAX_COMPONENT_FILES = 2e3;
|
|
27341
27544
|
async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
@@ -27371,7 +27574,7 @@ async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
|
27371
27574
|
} else if (await hasTailwindDep(projectRoot) || uiLibrary) {
|
|
27372
27575
|
matchLevel = "low";
|
|
27373
27576
|
}
|
|
27374
|
-
if (uiLibrary && await pathExists5(
|
|
27577
|
+
if (uiLibrary && await pathExists5(path53.join(projectRoot, "package.json"))) {
|
|
27375
27578
|
sourceFiles.push("package.json");
|
|
27376
27579
|
}
|
|
27377
27580
|
sourceFiles.push(...cssScan.sourceFiles);
|
|
@@ -27397,7 +27600,7 @@ async function findTailwindConfig(projectRoot) {
|
|
|
27397
27600
|
"tailwind.config.mjs"
|
|
27398
27601
|
];
|
|
27399
27602
|
for (const name of candidates) {
|
|
27400
|
-
const absPath =
|
|
27603
|
+
const absPath = path53.join(projectRoot, name);
|
|
27401
27604
|
if (await pathExists5(absPath)) {
|
|
27402
27605
|
return { absPath, relPath: name };
|
|
27403
27606
|
}
|
|
@@ -27624,7 +27827,7 @@ async function scanComponents(projectRoot) {
|
|
|
27624
27827
|
const names = /* @__PURE__ */ new Set();
|
|
27625
27828
|
let visitedFiles = 0;
|
|
27626
27829
|
for (const relRoot of roots) {
|
|
27627
|
-
const absRoot =
|
|
27830
|
+
const absRoot = path53.join(projectRoot, relRoot);
|
|
27628
27831
|
if (!await pathExists5(absRoot)) continue;
|
|
27629
27832
|
visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);
|
|
27630
27833
|
if (visitedFiles >= MAX_COMPONENT_FILES) break;
|
|
@@ -27644,7 +27847,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
27644
27847
|
}
|
|
27645
27848
|
for (const entry of entries) {
|
|
27646
27849
|
if (fileCount >= MAX_COMPONENT_FILES) return fileCount;
|
|
27647
|
-
const abs =
|
|
27850
|
+
const abs = path53.join(dir, entry);
|
|
27648
27851
|
let info;
|
|
27649
27852
|
try {
|
|
27650
27853
|
info = await fs3.lstat(abs);
|
|
@@ -27665,7 +27868,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
27665
27868
|
""
|
|
27666
27869
|
);
|
|
27667
27870
|
if (base === "index") {
|
|
27668
|
-
base =
|
|
27871
|
+
base = path53.basename(dir);
|
|
27669
27872
|
}
|
|
27670
27873
|
if (base.startsWith(".")) continue;
|
|
27671
27874
|
const componentName = toPascalCase(base);
|
|
@@ -27687,7 +27890,7 @@ async function scanCssVariables(projectRoot) {
|
|
|
27687
27890
|
const variables = {};
|
|
27688
27891
|
const sourceFiles = [];
|
|
27689
27892
|
for (const relPath of candidates) {
|
|
27690
|
-
const absPath =
|
|
27893
|
+
const absPath = path53.join(projectRoot, relPath);
|
|
27691
27894
|
if (!await pathExists5(absPath)) continue;
|
|
27692
27895
|
const content = await fs3.readFile(absPath, "utf-8");
|
|
27693
27896
|
const found = extractCssVariables(content);
|
|
@@ -27733,7 +27936,7 @@ function toPascalCase(value) {
|
|
|
27733
27936
|
async function hasTailwindDep(projectRoot) {
|
|
27734
27937
|
try {
|
|
27735
27938
|
const raw = await fs3.readFile(
|
|
27736
|
-
|
|
27939
|
+
path53.join(projectRoot, "package.json"),
|
|
27737
27940
|
"utf-8"
|
|
27738
27941
|
);
|
|
27739
27942
|
const pkg = JSON.parse(raw);
|
|
@@ -27758,15 +27961,15 @@ async function pathExists5(p) {
|
|
|
27758
27961
|
|
|
27759
27962
|
// src/context/greenfield-init.ts
|
|
27760
27963
|
import {
|
|
27761
|
-
lstat as
|
|
27964
|
+
lstat as lstat21,
|
|
27762
27965
|
mkdir as mkdir35,
|
|
27763
27966
|
readFile as readFile39,
|
|
27764
|
-
rename as
|
|
27765
|
-
rm as
|
|
27766
|
-
writeFile as
|
|
27967
|
+
rename as rename12,
|
|
27968
|
+
rm as rm20,
|
|
27969
|
+
writeFile as writeFile43
|
|
27767
27970
|
} from "fs/promises";
|
|
27768
|
-
import
|
|
27769
|
-
var JOURNAL_RELATIVE_DIRECTORY =
|
|
27971
|
+
import path54 from "path";
|
|
27972
|
+
var JOURNAL_RELATIVE_DIRECTORY = path54.join(
|
|
27770
27973
|
"local",
|
|
27771
27974
|
"runtime",
|
|
27772
27975
|
"initialization"
|
|
@@ -27815,7 +28018,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27815
28018
|
operationId: normalized.operationId,
|
|
27816
28019
|
workspaceId: normalized.workspaceId,
|
|
27817
28020
|
state: "staged",
|
|
27818
|
-
stagingDirectoryName:
|
|
28021
|
+
stagingDirectoryName: path54.basename(stagingRoot),
|
|
27819
28022
|
targetDirectoryName: ".mancode",
|
|
27820
28023
|
manifestDigest: digestCanonicalJson(manifest),
|
|
27821
28024
|
configDigest: digestCanonicalJson(config),
|
|
@@ -27846,7 +28049,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
27846
28049
|
return journal;
|
|
27847
28050
|
}
|
|
27848
28051
|
async function publishGreenfieldInitialization(input) {
|
|
27849
|
-
const root =
|
|
28052
|
+
const root = path54.resolve(input.projectRoot);
|
|
27850
28053
|
assertUlid(input.operationId, "greenfield operationId");
|
|
27851
28054
|
const stagingRoot = greenfieldStagingPath(root, input.operationId);
|
|
27852
28055
|
const targetRoot = greenfieldTargetPath(root);
|
|
@@ -27864,7 +28067,7 @@ async function publishGreenfieldInitialization(input) {
|
|
|
27864
28067
|
if (await lstatOrNull4(targetRoot) !== null) {
|
|
27865
28068
|
throw new Error("MANCODE_V3_TARGET_EXISTS");
|
|
27866
28069
|
}
|
|
27867
|
-
await
|
|
28070
|
+
await rename12(stagingRoot, targetRoot);
|
|
27868
28071
|
throwIfOperationCrashInjected("greenfield_initialize", "publish-v3-root");
|
|
27869
28072
|
return finishPublishedInitialization(
|
|
27870
28073
|
{ ...input, projectRoot: root },
|
|
@@ -27881,10 +28084,10 @@ async function initializeGreenfield(input, publication) {
|
|
|
27881
28084
|
}
|
|
27882
28085
|
function greenfieldStagingPath(projectRoot, operationId) {
|
|
27883
28086
|
assertUlid(operationId, "greenfield operationId");
|
|
27884
|
-
return
|
|
28087
|
+
return path54.join(path54.resolve(projectRoot), `.mancode.init-${operationId}`);
|
|
27885
28088
|
}
|
|
27886
28089
|
function greenfieldTargetPath(projectRoot) {
|
|
27887
|
-
return
|
|
28090
|
+
return path54.join(path54.resolve(projectRoot), ".mancode");
|
|
27888
28091
|
}
|
|
27889
28092
|
function parseGreenfieldInitializationJournal(value) {
|
|
27890
28093
|
assertRecord(value, "greenfield initialization journal");
|
|
@@ -28020,7 +28223,7 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
28020
28223
|
activatedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
28021
28224
|
};
|
|
28022
28225
|
assertSchemaManifestTransition(manifest, activeManifest);
|
|
28023
|
-
await writeJson(
|
|
28226
|
+
await writeJson(path54.join(targetRoot, "schema.json"), activeManifest);
|
|
28024
28227
|
throwIfOperationCrashInjected(
|
|
28025
28228
|
"greenfield_initialize",
|
|
28026
28229
|
"activate-v3-manifest"
|
|
@@ -28036,45 +28239,45 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
28036
28239
|
}
|
|
28037
28240
|
async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, projectFacts, journal) {
|
|
28038
28241
|
await Promise.all([
|
|
28039
|
-
mkdir35(
|
|
28040
|
-
mkdir35(
|
|
28242
|
+
mkdir35(path54.join(stagingRoot, "shared", "context"), { recursive: true }),
|
|
28243
|
+
mkdir35(path54.join(stagingRoot, "shared", "memory", "decisions"), {
|
|
28041
28244
|
recursive: true
|
|
28042
28245
|
}),
|
|
28043
|
-
mkdir35(
|
|
28246
|
+
mkdir35(path54.join(stagingRoot, "shared", "team", "actors"), {
|
|
28044
28247
|
recursive: true
|
|
28045
28248
|
}),
|
|
28046
|
-
mkdir35(
|
|
28249
|
+
mkdir35(path54.join(stagingRoot, "shared", "team", "handoffs"), {
|
|
28047
28250
|
recursive: true
|
|
28048
28251
|
}),
|
|
28049
|
-
mkdir35(
|
|
28252
|
+
mkdir35(path54.join(stagingRoot, "shared", "team", "events"), {
|
|
28050
28253
|
recursive: true
|
|
28051
28254
|
}),
|
|
28052
|
-
mkdir35(
|
|
28255
|
+
mkdir35(path54.join(stagingRoot, "shared", "team", "transport"), {
|
|
28053
28256
|
recursive: true
|
|
28054
28257
|
}),
|
|
28055
|
-
mkdir35(
|
|
28056
|
-
mkdir35(
|
|
28258
|
+
mkdir35(path54.join(stagingRoot, "local", "sessions"), { recursive: true }),
|
|
28259
|
+
mkdir35(path54.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
|
|
28057
28260
|
recursive: true
|
|
28058
28261
|
}),
|
|
28059
|
-
mkdir35(
|
|
28060
|
-
mkdir35(
|
|
28061
|
-
mkdir35(
|
|
28062
|
-
mkdir35(
|
|
28063
|
-
mkdir35(
|
|
28262
|
+
mkdir35(path54.join(stagingRoot, "local", "workflows"), { recursive: true }),
|
|
28263
|
+
mkdir35(path54.join(stagingRoot, "local", "quarantine"), { recursive: true }),
|
|
28264
|
+
mkdir35(path54.join(stagingRoot, "local", "publish"), { recursive: true }),
|
|
28265
|
+
mkdir35(path54.join(stagingRoot, "local", "cache"), { recursive: true }),
|
|
28266
|
+
mkdir35(path54.join(stagingRoot, "runtime", "non-git", journal.workspaceId), {
|
|
28064
28267
|
recursive: true
|
|
28065
28268
|
})
|
|
28066
28269
|
]);
|
|
28067
28270
|
await Promise.all([
|
|
28068
|
-
writeJson(
|
|
28069
|
-
writeJson(
|
|
28070
|
-
writeJson(
|
|
28271
|
+
writeJson(path54.join(stagingRoot, "schema.json"), manifest),
|
|
28272
|
+
writeJson(path54.join(stagingRoot, "shared", "config.json"), config),
|
|
28273
|
+
writeJson(path54.join(stagingRoot, "shared", "team", "policy.json"), policy),
|
|
28071
28274
|
writeJson(
|
|
28072
|
-
|
|
28275
|
+
path54.join(stagingRoot, "shared", "context", "project.json"),
|
|
28073
28276
|
projectFacts
|
|
28074
28277
|
),
|
|
28075
28278
|
writeJson(journalPath2(stagingRoot, journal.operationId), journal),
|
|
28076
|
-
|
|
28077
|
-
|
|
28279
|
+
writeFile43(
|
|
28280
|
+
path54.join(stagingRoot, ".gitignore"),
|
|
28078
28281
|
`${V3_IGNORE.join("\n")}
|
|
28079
28282
|
`,
|
|
28080
28283
|
{ encoding: "utf8", flag: "wx" }
|
|
@@ -28099,7 +28302,7 @@ async function readGreenfieldJournal(root, operationId) {
|
|
|
28099
28302
|
async function readManifest(root) {
|
|
28100
28303
|
try {
|
|
28101
28304
|
return parseSchemaManifest(
|
|
28102
|
-
JSON.parse(await readFile39(
|
|
28305
|
+
JSON.parse(await readFile39(path54.join(root, "schema.json"), "utf8"))
|
|
28103
28306
|
);
|
|
28104
28307
|
} catch (error) {
|
|
28105
28308
|
if (error instanceof SyntaxError || isNotFound29(error)) {
|
|
@@ -28137,7 +28340,7 @@ async function readConfig(root) {
|
|
|
28137
28340
|
try {
|
|
28138
28341
|
config = parseProjectConfig(
|
|
28139
28342
|
JSON.parse(
|
|
28140
|
-
await readFile39(
|
|
28343
|
+
await readFile39(path54.join(root, "shared", "config.json"), "utf8")
|
|
28141
28344
|
)
|
|
28142
28345
|
);
|
|
28143
28346
|
} catch (error) {
|
|
@@ -28154,7 +28357,7 @@ async function readPolicy(root) {
|
|
|
28154
28357
|
policy = parseTeamPolicy(
|
|
28155
28358
|
JSON.parse(
|
|
28156
28359
|
await readFile39(
|
|
28157
|
-
|
|
28360
|
+
path54.join(root, "shared", "team", "policy.json"),
|
|
28158
28361
|
"utf8"
|
|
28159
28362
|
)
|
|
28160
28363
|
)
|
|
@@ -28172,7 +28375,7 @@ async function readProjectFactsAt(root) {
|
|
|
28172
28375
|
return parseProjectFacts(
|
|
28173
28376
|
JSON.parse(
|
|
28174
28377
|
await readFile39(
|
|
28175
|
-
|
|
28378
|
+
path54.join(root, "shared", "context", "project.json"),
|
|
28176
28379
|
"utf8"
|
|
28177
28380
|
)
|
|
28178
28381
|
)
|
|
@@ -28211,7 +28414,7 @@ function normalizeInput(input) {
|
|
|
28211
28414
|
parseSchemaManifest(manifest);
|
|
28212
28415
|
return {
|
|
28213
28416
|
...input,
|
|
28214
|
-
projectRoot:
|
|
28417
|
+
projectRoot: path54.resolve(input.projectRoot),
|
|
28215
28418
|
projectConfig: config,
|
|
28216
28419
|
teamPolicy: policy,
|
|
28217
28420
|
projectFacts: input.projectFacts === void 0 ? void 0 : parseProjectFacts(input.projectFacts)
|
|
@@ -28309,21 +28512,21 @@ function initializationProjectFacts(input, now) {
|
|
|
28309
28512
|
}
|
|
28310
28513
|
function journalPath2(root, operationId) {
|
|
28311
28514
|
assertUlid(operationId, "greenfield operationId");
|
|
28312
|
-
return
|
|
28515
|
+
return path54.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
|
|
28313
28516
|
}
|
|
28314
28517
|
async function writeJson(target, value) {
|
|
28315
|
-
const directory =
|
|
28518
|
+
const directory = path54.dirname(target);
|
|
28316
28519
|
await mkdir35(directory, { recursive: true });
|
|
28317
|
-
const temporary =
|
|
28520
|
+
const temporary = path54.join(
|
|
28318
28521
|
directory,
|
|
28319
|
-
`.${
|
|
28522
|
+
`.${path54.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
28320
28523
|
);
|
|
28321
|
-
await
|
|
28524
|
+
await writeFile43(temporary, `${JSON.stringify(value, null, 2)}
|
|
28322
28525
|
`, {
|
|
28323
28526
|
encoding: "utf8",
|
|
28324
28527
|
flag: "wx"
|
|
28325
28528
|
});
|
|
28326
|
-
await
|
|
28529
|
+
await rename12(temporary, target);
|
|
28327
28530
|
}
|
|
28328
28531
|
function parseDigest6(value, label) {
|
|
28329
28532
|
if (typeof value !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value)) {
|
|
@@ -28342,7 +28545,7 @@ function isState(value) {
|
|
|
28342
28545
|
}
|
|
28343
28546
|
async function lstatOrNull4(target) {
|
|
28344
28547
|
try {
|
|
28345
|
-
return await
|
|
28548
|
+
return await lstat21(target);
|
|
28346
28549
|
} catch (error) {
|
|
28347
28550
|
if (isNotFound29(error)) return null;
|
|
28348
28551
|
throw error;
|
|
@@ -28436,9 +28639,9 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28436
28639
|
return EXIT_INIT_FAILED;
|
|
28437
28640
|
}
|
|
28438
28641
|
const authority = resolveInitAuthority(options);
|
|
28439
|
-
const mancodeDir =
|
|
28440
|
-
const stateFile =
|
|
28441
|
-
const v3SchemaFile =
|
|
28642
|
+
const mancodeDir = path55.join(rootDir, ".mancode");
|
|
28643
|
+
const stateFile = path55.join(mancodeDir, "state.json");
|
|
28644
|
+
const v3SchemaFile = path55.join(mancodeDir, "schema.json");
|
|
28442
28645
|
const wasInitialized = await pathExists6(stateFile);
|
|
28443
28646
|
let mutationSnapshots = [];
|
|
28444
28647
|
let directorySnapshots = [];
|
|
@@ -28506,11 +28709,15 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28506
28709
|
}
|
|
28507
28710
|
return initializeV3(rootDir, options);
|
|
28508
28711
|
}
|
|
28509
|
-
const
|
|
28510
|
-
|
|
28712
|
+
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
28713
|
+
if (!genericSafety.ok && genericSafety.reason === "unsafe") {
|
|
28714
|
+
printNotProjectDirectory(rootDir, locale, "unsafe");
|
|
28715
|
+
return EXIT_NOT_A_PROJECT_DIR;
|
|
28716
|
+
}
|
|
28717
|
+
const isGitRepo = await pathExists6(path55.join(rootDir, ".git"));
|
|
28718
|
+
const hasEvidence = await hasProjectEvidence(rootDir);
|
|
28511
28719
|
let isGenericProject = false;
|
|
28512
|
-
if (!isGitRepo && !
|
|
28513
|
-
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
28720
|
+
if (!isGitRepo && !hasEvidence) {
|
|
28514
28721
|
if (!genericSafety.ok && !(wasInitialized && genericSafety.reason === "nonempty")) {
|
|
28515
28722
|
printNotProjectDirectory(rootDir, locale, genericSafety.reason);
|
|
28516
28723
|
return EXIT_NOT_A_PROJECT_DIR;
|
|
@@ -28564,12 +28771,12 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28564
28771
|
if (uiLibrary) {
|
|
28565
28772
|
console.log(` UI: ${uiLibraryStr}`);
|
|
28566
28773
|
}
|
|
28567
|
-
} else if (
|
|
28774
|
+
} else if (hasEvidence) {
|
|
28568
28775
|
console.log(
|
|
28569
28776
|
localize(
|
|
28570
28777
|
locale,
|
|
28571
|
-
" \u5DF2\u53D1\u73B0\u9879\u76EE
|
|
28572
|
-
" Project
|
|
28778
|
+
" \u5DF2\u53D1\u73B0\u9879\u76EE\u6E90\u7801\uFF0C\u672A\u8BC6\u522B\u5230\u6846\u67B6\u4F9D\u8D56",
|
|
28779
|
+
" Project source found; no known framework dependencies"
|
|
28573
28780
|
)
|
|
28574
28781
|
);
|
|
28575
28782
|
} else {
|
|
@@ -28624,8 +28831,8 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28624
28831
|
const managedFiles = getInitManagedFilePaths(rootDir, selectedPlatforms);
|
|
28625
28832
|
mutationSnapshots = await snapshotFiles(managedFiles);
|
|
28626
28833
|
directorySnapshots = await snapshotDirectories(managedFiles, [
|
|
28627
|
-
|
|
28628
|
-
|
|
28834
|
+
path55.join(mancodeDir, "workflows"),
|
|
28835
|
+
path55.join(mancodeDir, "preseason-reports")
|
|
28629
28836
|
]);
|
|
28630
28837
|
const team = await detectTeamStatus(rootDir);
|
|
28631
28838
|
const platformMinimal = Object.fromEntries(
|
|
@@ -28686,7 +28893,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28686
28893
|
`;
|
|
28687
28894
|
await fs4.writeFile(stateFile, stateContent, "utf-8");
|
|
28688
28895
|
await fs4.writeFile(
|
|
28689
|
-
|
|
28896
|
+
path55.join(mancodeDir, "project-profile.json"),
|
|
28690
28897
|
`${JSON.stringify(profile, null, 2)}
|
|
28691
28898
|
`,
|
|
28692
28899
|
"utf-8"
|
|
@@ -28723,7 +28930,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
28723
28930
|
)
|
|
28724
28931
|
);
|
|
28725
28932
|
const tokens = await scanAesthetics(rootDir, uiLibrary);
|
|
28726
|
-
const tokensPath =
|
|
28933
|
+
const tokensPath = path55.join(
|
|
28727
28934
|
mancodeDir,
|
|
28728
28935
|
"aesthetics",
|
|
28729
28936
|
"style-tokens.json"
|
|
@@ -28887,7 +29094,7 @@ async function initializeV3(rootDir, options) {
|
|
|
28887
29094
|
);
|
|
28888
29095
|
return EXIT_INIT_FAILED;
|
|
28889
29096
|
}
|
|
28890
|
-
const schemaPath =
|
|
29097
|
+
const schemaPath = path55.join(rootDir, ".mancode", "schema.json");
|
|
28891
29098
|
let existingV3 = false;
|
|
28892
29099
|
let registeredAdapters = /* @__PURE__ */ new Set();
|
|
28893
29100
|
if (await pathExists6(schemaPath)) {
|
|
@@ -28990,7 +29197,7 @@ function printV3InitError(error) {
|
|
|
28990
29197
|
}
|
|
28991
29198
|
}
|
|
28992
29199
|
async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms) {
|
|
28993
|
-
const configPath =
|
|
29200
|
+
const configPath = path55.join(mancodeDir, "config.json");
|
|
28994
29201
|
let config = {};
|
|
28995
29202
|
try {
|
|
28996
29203
|
config = JSON.parse(await fs4.readFile(configPath, "utf-8"));
|
|
@@ -29023,7 +29230,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
|
|
|
29023
29230
|
async function readExistingInitPreferences(mancodeDir) {
|
|
29024
29231
|
try {
|
|
29025
29232
|
const config = JSON.parse(
|
|
29026
|
-
await fs4.readFile(
|
|
29233
|
+
await fs4.readFile(path55.join(mancodeDir, "config.json"), "utf-8")
|
|
29027
29234
|
);
|
|
29028
29235
|
const preferences = {
|
|
29029
29236
|
platforms: Array.isArray(config.platforms) ? config.platforms.filter(
|
|
@@ -29087,15 +29294,9 @@ async function selectInitPlatforms(input) {
|
|
|
29087
29294
|
}
|
|
29088
29295
|
return [DEFAULT_INIT_PLATFORM];
|
|
29089
29296
|
}
|
|
29090
|
-
async function hasProjectManifest(rootDir) {
|
|
29091
|
-
for (const name of PROJECT_MANIFESTS) {
|
|
29092
|
-
if (await pathExists6(path54.join(rootDir, name))) return true;
|
|
29093
|
-
}
|
|
29094
|
-
return false;
|
|
29095
|
-
}
|
|
29096
29297
|
async function canInitializeGenericProject(rootDir) {
|
|
29097
|
-
const resolved =
|
|
29098
|
-
if (resolved ===
|
|
29298
|
+
const resolved = path55.resolve(rootDir);
|
|
29299
|
+
if (resolved === path55.parse(resolved).root || resolved === path55.resolve(os.homedir())) {
|
|
29099
29300
|
return { ok: false, reason: "unsafe" };
|
|
29100
29301
|
}
|
|
29101
29302
|
try {
|
|
@@ -29109,14 +29310,18 @@ async function canInitializeGenericProject(rootDir) {
|
|
|
29109
29310
|
}
|
|
29110
29311
|
}
|
|
29111
29312
|
async function validateV3CliProjectBoundary(rootDir, options, locale, legacyInitialized) {
|
|
29112
|
-
const
|
|
29113
|
-
|
|
29114
|
-
|
|
29313
|
+
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
29314
|
+
if (!genericSafety.ok && genericSafety.reason === "unsafe") {
|
|
29315
|
+
printNotProjectDirectory(rootDir, locale, "unsafe");
|
|
29316
|
+
return EXIT_NOT_A_PROJECT_DIR;
|
|
29317
|
+
}
|
|
29318
|
+
const isGitRepo = await pathExists6(path55.join(rootDir, ".git"));
|
|
29319
|
+
const hasEvidence = await hasProjectEvidence(rootDir);
|
|
29320
|
+
if (isGitRepo || hasEvidence) return null;
|
|
29115
29321
|
const v3Initialized = await pathExists6(
|
|
29116
|
-
|
|
29322
|
+
path55.join(rootDir, ".mancode", "schema.json")
|
|
29117
29323
|
);
|
|
29118
29324
|
const legacyAuthorityPresent = legacyInitialized || (await scanLegacyAuthority(rootDir)).authorityPresent;
|
|
29119
|
-
const genericSafety = await canInitializeGenericProject(rootDir);
|
|
29120
29325
|
if (!genericSafety.ok && !((legacyAuthorityPresent || v3Initialized) && genericSafety.reason === "nonempty")) {
|
|
29121
29326
|
printNotProjectDirectory(rootDir, locale, genericSafety.reason);
|
|
29122
29327
|
return EXIT_NOT_A_PROJECT_DIR;
|
|
@@ -29137,7 +29342,7 @@ function printNotProjectDirectory(rootDir, locale, reason) {
|
|
|
29137
29342
|
console.error(" \u4E3A\u907F\u514D\u8BEF\u5199\uFF0C\u4E0D\u80FD\u5728 Home \u76EE\u5F55\u6216\u78C1\u76D8\u6839\u76EE\u5F55\u521D\u59CB\u5316\u3002");
|
|
29138
29343
|
} else if (reason === "nonempty") {
|
|
29139
29344
|
console.error(
|
|
29140
|
-
" \u672A\u8BC6\u522B\u5230\u9879\u76EE\
|
|
29345
|
+
" \u672A\u8BC6\u522B\u5230\u9876\u5C42\u9879\u76EE\u6E05\u5355\u3001\u6E90\u7801\u6587\u4EF6\u6216\u6E90\u7801\u76EE\u5F55\u3002\u8BF7\u5148\u8FDB\u5165\u5B9E\u9645\u9879\u76EE\u6839\u76EE\u5F55\u3002"
|
|
29141
29346
|
);
|
|
29142
29347
|
} else {
|
|
29143
29348
|
console.error(
|
|
@@ -29153,7 +29358,7 @@ function printNotProjectDirectory(rootDir, locale, reason) {
|
|
|
29153
29358
|
);
|
|
29154
29359
|
} else if (reason === "nonempty") {
|
|
29155
29360
|
console.error(
|
|
29156
|
-
" No
|
|
29361
|
+
" No top-level manifest, source file, or source directory was detected."
|
|
29157
29362
|
);
|
|
29158
29363
|
} else {
|
|
29159
29364
|
console.error(
|
|
@@ -29238,6 +29443,12 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
29238
29443
|
files.push(`.qoder/commands/${mode}.md`);
|
|
29239
29444
|
}
|
|
29240
29445
|
}
|
|
29446
|
+
if (platforms.includes("dsh")) {
|
|
29447
|
+
files.push("AGENTS.md");
|
|
29448
|
+
for (const mode of MODE_NAMES) {
|
|
29449
|
+
files.push(`.dsh/skills/${mode}/SKILL.md`);
|
|
29450
|
+
}
|
|
29451
|
+
}
|
|
29241
29452
|
if (platforms.includes("copilot")) {
|
|
29242
29453
|
files.push(
|
|
29243
29454
|
".github/copilot-instructions.md",
|
|
@@ -29248,7 +29459,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
29248
29459
|
files.push(`.github/prompts/${mode}.prompt.md`);
|
|
29249
29460
|
}
|
|
29250
29461
|
}
|
|
29251
|
-
return [...new Set(files.map((file) =>
|
|
29462
|
+
return [...new Set(files.map((file) => path55.join(rootDir, file)))];
|
|
29252
29463
|
}
|
|
29253
29464
|
async function snapshotFiles(filePaths) {
|
|
29254
29465
|
return Promise.all(
|
|
@@ -29256,7 +29467,7 @@ async function snapshotFiles(filePaths) {
|
|
|
29256
29467
|
try {
|
|
29257
29468
|
return { filePath, content: await fs4.readFile(filePath, "utf-8") };
|
|
29258
29469
|
} catch (error) {
|
|
29259
|
-
if (
|
|
29470
|
+
if (isNodeError7(error) && error.code === "ENOENT") {
|
|
29260
29471
|
return { filePath, content: null };
|
|
29261
29472
|
}
|
|
29262
29473
|
throw error;
|
|
@@ -29267,10 +29478,10 @@ async function snapshotFiles(filePaths) {
|
|
|
29267
29478
|
async function snapshotDirectories(filePaths, additionalDirectories = []) {
|
|
29268
29479
|
const directories = new Set(additionalDirectories);
|
|
29269
29480
|
for (const filePath of filePaths) {
|
|
29270
|
-
let current =
|
|
29271
|
-
while (current !==
|
|
29481
|
+
let current = path55.dirname(filePath);
|
|
29482
|
+
while (current !== path55.dirname(current)) {
|
|
29272
29483
|
directories.add(current);
|
|
29273
|
-
current =
|
|
29484
|
+
current = path55.dirname(current);
|
|
29274
29485
|
}
|
|
29275
29486
|
}
|
|
29276
29487
|
return Promise.all(
|
|
@@ -29286,7 +29497,7 @@ async function restoreFiles(snapshots) {
|
|
|
29286
29497
|
await fs4.rm(snapshot.filePath, { force: true });
|
|
29287
29498
|
continue;
|
|
29288
29499
|
}
|
|
29289
|
-
await fs4.mkdir(
|
|
29500
|
+
await fs4.mkdir(path55.dirname(snapshot.filePath), { recursive: true });
|
|
29290
29501
|
await fs4.writeFile(snapshot.filePath, snapshot.content, "utf-8");
|
|
29291
29502
|
}
|
|
29292
29503
|
}
|
|
@@ -29302,7 +29513,7 @@ async function removeNewEmptyDirectories(snapshots) {
|
|
|
29302
29513
|
function isRecord8(value) {
|
|
29303
29514
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29304
29515
|
}
|
|
29305
|
-
function
|
|
29516
|
+
function isNodeError7(error) {
|
|
29306
29517
|
return error instanceof Error && "code" in error;
|
|
29307
29518
|
}
|
|
29308
29519
|
function printPlatformCreatedFiles(platform, locale) {
|
|
@@ -29347,6 +29558,13 @@ function printPlatformCreatedFiles(platform, locale) {
|
|
|
29347
29558
|
console.log(" .qoder/commands/ # Qoder mode commands");
|
|
29348
29559
|
return;
|
|
29349
29560
|
}
|
|
29561
|
+
if (platform === "dsh") {
|
|
29562
|
+
console.log(
|
|
29563
|
+
" AGENTS.md # DeepSeek Harness managed block"
|
|
29564
|
+
);
|
|
29565
|
+
console.log(" .dsh/skills/ # DeepSeek Harness mode skills");
|
|
29566
|
+
return;
|
|
29567
|
+
}
|
|
29350
29568
|
console.log(" .github/copilot-instructions.md # Copilot instructions");
|
|
29351
29569
|
}
|
|
29352
29570
|
function localize(locale, chinese, english) {
|
|
@@ -29363,15 +29581,15 @@ async function pathExists6(p) {
|
|
|
29363
29581
|
|
|
29364
29582
|
// src/commands/install.ts
|
|
29365
29583
|
import { promises as fs5 } from "fs";
|
|
29366
|
-
import
|
|
29584
|
+
import path56 from "path";
|
|
29367
29585
|
import process7 from "process";
|
|
29368
29586
|
var EXIT_OK3 = 0;
|
|
29369
29587
|
var EXIT_NOT_INITIALIZED2 = 1;
|
|
29370
29588
|
var EXIT_UNSUPPORTED_PLATFORM = 2;
|
|
29371
29589
|
var EXIT_INSTALL_FAILED = 3;
|
|
29372
29590
|
async function install(rootDir = process7.cwd(), platform = "claude-code", options = {}) {
|
|
29373
|
-
const stateFile =
|
|
29374
|
-
const v3SchemaFile =
|
|
29591
|
+
const stateFile = path56.join(rootDir, ".mancode", "state.json");
|
|
29592
|
+
const v3SchemaFile = path56.join(rootDir, ".mancode", "schema.json");
|
|
29375
29593
|
if (await pathExists7(v3SchemaFile)) {
|
|
29376
29594
|
return installV3(rootDir, platform, options);
|
|
29377
29595
|
}
|
|
@@ -29532,22 +29750,22 @@ function printUnsupportedPlatform(platform) {
|
|
|
29532
29750
|
}
|
|
29533
29751
|
}
|
|
29534
29752
|
async function readConfig2(rootDir) {
|
|
29535
|
-
const configPath =
|
|
29753
|
+
const configPath = path56.join(rootDir, ".mancode", "config.json");
|
|
29536
29754
|
try {
|
|
29537
29755
|
const raw = await fs5.readFile(configPath, "utf-8");
|
|
29538
29756
|
return { config: JSON.parse(raw), valid: true };
|
|
29539
29757
|
} catch (err) {
|
|
29540
|
-
if (
|
|
29758
|
+
if (isNodeError8(err) && err.code === "ENOENT") {
|
|
29541
29759
|
return { config: {}, valid: false };
|
|
29542
29760
|
}
|
|
29543
29761
|
throw err;
|
|
29544
29762
|
}
|
|
29545
29763
|
}
|
|
29546
|
-
function
|
|
29764
|
+
function isNodeError8(err) {
|
|
29547
29765
|
return err instanceof Error && "code" in err;
|
|
29548
29766
|
}
|
|
29549
29767
|
async function updateConfig(rootDir, config) {
|
|
29550
|
-
const configPath =
|
|
29768
|
+
const configPath = path56.join(rootDir, ".mancode", "config.json");
|
|
29551
29769
|
const content = `${JSON.stringify(config, null, 2)}
|
|
29552
29770
|
`;
|
|
29553
29771
|
await fs5.writeFile(configPath, content, "utf-8");
|
|
@@ -29583,7 +29801,7 @@ function readConfiguredMinimal(value, platform) {
|
|
|
29583
29801
|
async function readStatePlatform(rootDir) {
|
|
29584
29802
|
try {
|
|
29585
29803
|
const raw = await fs5.readFile(
|
|
29586
|
-
|
|
29804
|
+
path56.join(rootDir, ".mancode", "state.json"),
|
|
29587
29805
|
"utf-8"
|
|
29588
29806
|
);
|
|
29589
29807
|
const state = JSON.parse(raw);
|
|
@@ -29606,11 +29824,11 @@ function isRecord9(value) {
|
|
|
29606
29824
|
|
|
29607
29825
|
// src/commands/list-platforms.ts
|
|
29608
29826
|
import { promises as fs6 } from "fs";
|
|
29609
|
-
import
|
|
29827
|
+
import path57 from "path";
|
|
29610
29828
|
import process8 from "process";
|
|
29611
29829
|
var EXIT_OK4 = 0;
|
|
29612
29830
|
async function listPlatforms(rootDir = process8.cwd()) {
|
|
29613
|
-
if (await pathExists8(
|
|
29831
|
+
if (await pathExists8(path57.join(rootDir, ".mancode", "schema.json"))) {
|
|
29614
29832
|
return listV3Platforms(rootDir);
|
|
29615
29833
|
}
|
|
29616
29834
|
const installed = new Set(await readInstalledPlatforms(rootDir));
|
|
@@ -29646,7 +29864,7 @@ async function listV3Platforms(rootDir) {
|
|
|
29646
29864
|
async function readInstalledPlatforms(rootDir) {
|
|
29647
29865
|
try {
|
|
29648
29866
|
const raw = await fs6.readFile(
|
|
29649
|
-
|
|
29867
|
+
path57.join(rootDir, ".mancode", "config.json"),
|
|
29650
29868
|
"utf-8"
|
|
29651
29869
|
);
|
|
29652
29870
|
const config = JSON.parse(raw);
|
|
@@ -29679,7 +29897,7 @@ function describePlatform(platform) {
|
|
|
29679
29897
|
|
|
29680
29898
|
// src/commands/manps.ts
|
|
29681
29899
|
import { access as access4, readFile as readFile41 } from "fs/promises";
|
|
29682
|
-
import
|
|
29900
|
+
import path59 from "path";
|
|
29683
29901
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
29684
29902
|
|
|
29685
29903
|
// src/system/preseason.ts
|
|
@@ -29688,14 +29906,14 @@ import { createHash as createHash8 } from "crypto";
|
|
|
29688
29906
|
import { existsSync, readFileSync } from "fs";
|
|
29689
29907
|
import {
|
|
29690
29908
|
access as access3,
|
|
29691
|
-
lstat as
|
|
29909
|
+
lstat as lstat22,
|
|
29692
29910
|
mkdir as mkdir36,
|
|
29693
29911
|
readFile as readFile40,
|
|
29694
29912
|
readdir as readdir18,
|
|
29695
|
-
rename as
|
|
29696
|
-
writeFile as
|
|
29913
|
+
rename as rename13,
|
|
29914
|
+
writeFile as writeFile44
|
|
29697
29915
|
} from "fs/promises";
|
|
29698
|
-
import
|
|
29916
|
+
import path58 from "path";
|
|
29699
29917
|
var PRESEASON_AREAS = [
|
|
29700
29918
|
"all",
|
|
29701
29919
|
"deps",
|
|
@@ -29775,10 +29993,10 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29775
29993
|
const needsFiles = normalizedArea === "all" || normalizedArea === "dead-code" || normalizedArea === "config";
|
|
29776
29994
|
const files = needsFiles ? await listProjectFiles(projectRoot) : [];
|
|
29777
29995
|
const issues = (await scanArea(projectRoot, normalizedArea, pkg, files)).slice(0, 20);
|
|
29778
|
-
const storageRoot = options.storageRoot ??
|
|
29779
|
-
const reportDir =
|
|
29996
|
+
const storageRoot = options.storageRoot ?? path58.join(projectRoot, ".mancode");
|
|
29997
|
+
const reportDir = path58.join(storageRoot, "preseason-reports");
|
|
29780
29998
|
await mkdir36(reportDir, { recursive: true });
|
|
29781
|
-
const issueDbPath =
|
|
29999
|
+
const issueDbPath = path58.join(storageRoot, "preseason-issues.json");
|
|
29782
30000
|
const reportPath = await allocateReportPath(
|
|
29783
30001
|
reportDir,
|
|
29784
30002
|
`${generatedAt.replace(/[:.]/g, "-")}-${normalizedArea}`
|
|
@@ -29792,9 +30010,9 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29792
30010
|
issueDbPath
|
|
29793
30011
|
};
|
|
29794
30012
|
const database = await buildIssueDatabase(projectRoot, report);
|
|
29795
|
-
await
|
|
29796
|
-
await
|
|
29797
|
-
|
|
30013
|
+
await writeFile44(reportPath, renderPreseasonReport(report), "utf-8");
|
|
30014
|
+
await writeFile44(
|
|
30015
|
+
path58.join(storageRoot, "preseason-report.md"),
|
|
29798
30016
|
renderPreseasonReport(report),
|
|
29799
30017
|
"utf-8"
|
|
29800
30018
|
);
|
|
@@ -29802,7 +30020,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
29802
30020
|
return report;
|
|
29803
30021
|
}
|
|
29804
30022
|
async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
29805
|
-
const issueDbPath = options.issueDbPath ??
|
|
30023
|
+
const issueDbPath = options.issueDbPath ?? path58.join(projectRoot, ".mancode", "preseason-issues.json");
|
|
29806
30024
|
const database = await readIssueDatabase(issueDbPath);
|
|
29807
30025
|
const keys = new Set(issues.map((issue) => issueKey(issue)));
|
|
29808
30026
|
const targets = database.issues.filter(
|
|
@@ -29880,7 +30098,7 @@ async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
|
29880
30098
|
write2(" Decision: skipped.");
|
|
29881
30099
|
}
|
|
29882
30100
|
database.updatedAt = now;
|
|
29883
|
-
await
|
|
30101
|
+
await writeFile44(
|
|
29884
30102
|
issueDbPath,
|
|
29885
30103
|
`${JSON.stringify(database, null, 2)}
|
|
29886
30104
|
`,
|
|
@@ -29912,7 +30130,7 @@ async function scanArea(projectRoot, area, pkg, files) {
|
|
|
29912
30130
|
async function allocateReportPath(reportDir, baseName) {
|
|
29913
30131
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
29914
30132
|
const suffix = attempt === 0 ? "" : `-${attempt + 1}`;
|
|
29915
|
-
const candidate =
|
|
30133
|
+
const candidate = path58.join(reportDir, `${baseName}${suffix}.md`);
|
|
29916
30134
|
if (!existsSync(candidate)) return candidate;
|
|
29917
30135
|
}
|
|
29918
30136
|
throw new Error(`unable to allocate preseason report path: ${baseName}`);
|
|
@@ -29961,18 +30179,18 @@ async function walk(root, current, results, depth) {
|
|
|
29961
30179
|
}
|
|
29962
30180
|
for (const entry of entries) {
|
|
29963
30181
|
if (IGNORE_DIRS.has(entry)) continue;
|
|
29964
|
-
const abs =
|
|
29965
|
-
const rel =
|
|
30182
|
+
const abs = path58.join(current, entry);
|
|
30183
|
+
const rel = path58.relative(root, abs);
|
|
29966
30184
|
let info;
|
|
29967
30185
|
try {
|
|
29968
|
-
info = await
|
|
30186
|
+
info = await lstat22(abs);
|
|
29969
30187
|
} catch {
|
|
29970
30188
|
continue;
|
|
29971
30189
|
}
|
|
29972
30190
|
if (info.isSymbolicLink()) continue;
|
|
29973
30191
|
if (info.isDirectory()) {
|
|
29974
30192
|
await walk(root, abs, results, depth + 1);
|
|
29975
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
30193
|
+
} else if (SOURCE_EXTENSIONS.has(path58.extname(entry)) || entry === "package.json") {
|
|
29976
30194
|
results.push(rel);
|
|
29977
30195
|
if (results.length >= MAX_PROJECT_FILES) return;
|
|
29978
30196
|
}
|
|
@@ -29980,7 +30198,7 @@ async function walk(root, current, results, depth) {
|
|
|
29980
30198
|
}
|
|
29981
30199
|
async function readPackageJson(projectRoot) {
|
|
29982
30200
|
try {
|
|
29983
|
-
const raw = await readFile40(
|
|
30201
|
+
const raw = await readFile40(path58.join(projectRoot, "package.json"), "utf-8");
|
|
29984
30202
|
return JSON.parse(raw);
|
|
29985
30203
|
} catch {
|
|
29986
30204
|
return null;
|
|
@@ -30073,7 +30291,7 @@ function scanTodos(projectRoot, files) {
|
|
|
30073
30291
|
const matches = [];
|
|
30074
30292
|
for (const file of files) {
|
|
30075
30293
|
if (matches.length >= 7) break;
|
|
30076
|
-
const abs =
|
|
30294
|
+
const abs = path58.join(projectRoot, file);
|
|
30077
30295
|
matches.push(...readTodoIssues(abs, file, matches.length));
|
|
30078
30296
|
}
|
|
30079
30297
|
return matches.slice(0, 7);
|
|
@@ -30114,7 +30332,7 @@ function scanTestGaps(files) {
|
|
|
30114
30332
|
if (sourceFiles.length === 0) return [];
|
|
30115
30333
|
const tests = new Set(files.filter((file) => file.startsWith("tests/")));
|
|
30116
30334
|
const missing = sourceFiles.filter((file) => {
|
|
30117
|
-
const base =
|
|
30335
|
+
const base = path58.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
30118
30336
|
return !Array.from(tests).some((test) => test.includes(base));
|
|
30119
30337
|
}).slice(0, 4);
|
|
30120
30338
|
return missing.map((file, index) => ({
|
|
@@ -30123,13 +30341,13 @@ function scanTestGaps(files) {
|
|
|
30123
30341
|
type: "tests",
|
|
30124
30342
|
title: "Core source file has no obvious test",
|
|
30125
30343
|
file,
|
|
30126
|
-
detail: `No matching test file was found for ${
|
|
30344
|
+
detail: `No matching test file was found for ${path58.basename(file)}.`,
|
|
30127
30345
|
recommendation: "Add focused coverage for the public behavior or document why this module is exercised indirectly."
|
|
30128
30346
|
}));
|
|
30129
30347
|
}
|
|
30130
30348
|
function scanConfig(projectRoot, files) {
|
|
30131
30349
|
const issues = [];
|
|
30132
|
-
if (!files.includes(".gitignore") && !pathExistsSync(
|
|
30350
|
+
if (!files.includes(".gitignore") && !pathExistsSync(path58.join(projectRoot, ".gitignore"))) {
|
|
30133
30351
|
issues.push({
|
|
30134
30352
|
id: "config-gitignore",
|
|
30135
30353
|
severity: "P1",
|
|
@@ -30140,7 +30358,7 @@ function scanConfig(projectRoot, files) {
|
|
|
30140
30358
|
recommendation: "Add a .gitignore that excludes dependencies, build output, coverage, and local env files."
|
|
30141
30359
|
});
|
|
30142
30360
|
}
|
|
30143
|
-
if (!files.includes(".editorconfig") && !pathExistsSync(
|
|
30361
|
+
if (!files.includes(".editorconfig") && !pathExistsSync(path58.join(projectRoot, ".editorconfig"))) {
|
|
30144
30362
|
issues.push({
|
|
30145
30363
|
id: "config-editorconfig",
|
|
30146
30364
|
severity: "P2",
|
|
@@ -30159,7 +30377,7 @@ function scanAestheticDrift(projectRoot, files, pkg) {
|
|
|
30159
30377
|
for (const file of frontendFiles) {
|
|
30160
30378
|
let content;
|
|
30161
30379
|
try {
|
|
30162
|
-
content = readFileSyncSafe(
|
|
30380
|
+
content = readFileSyncSafe(path58.join(projectRoot, file));
|
|
30163
30381
|
} catch {
|
|
30164
30382
|
continue;
|
|
30165
30383
|
}
|
|
@@ -30210,7 +30428,7 @@ function detectedIconSystems(pkg) {
|
|
|
30210
30428
|
return systems.filter(([, pattern]) => packages.some((name) => pattern.test(name))).map(([name]) => name);
|
|
30211
30429
|
}
|
|
30212
30430
|
async function scanArchitecture(projectRoot) {
|
|
30213
|
-
const localBinary =
|
|
30431
|
+
const localBinary = path58.join(
|
|
30214
30432
|
projectRoot,
|
|
30215
30433
|
"node_modules",
|
|
30216
30434
|
".bin",
|
|
@@ -30258,7 +30476,7 @@ async function hasDependencyCruiserConfig(projectRoot) {
|
|
|
30258
30476
|
"dependency-cruiser.config.mjs"
|
|
30259
30477
|
];
|
|
30260
30478
|
const results = await Promise.all(
|
|
30261
|
-
files.map((file) => pathExists9(
|
|
30479
|
+
files.map((file) => pathExists9(path58.join(projectRoot, file)))
|
|
30262
30480
|
);
|
|
30263
30481
|
return results.some(Boolean);
|
|
30264
30482
|
}
|
|
@@ -30364,9 +30582,9 @@ function inferCommands(pkg) {
|
|
|
30364
30582
|
return ["lint", "test", "build"].filter((name) => scripts[name]).map((name) => `npm run ${name}`);
|
|
30365
30583
|
}
|
|
30366
30584
|
async function buildIssueDatabase(projectRoot, report) {
|
|
30367
|
-
const reportRef =
|
|
30585
|
+
const reportRef = path58.relative(projectRoot, report.reportPath);
|
|
30368
30586
|
const run = {
|
|
30369
|
-
id:
|
|
30587
|
+
id: path58.basename(report.reportPath, ".md"),
|
|
30370
30588
|
generatedAt: report.generatedAt,
|
|
30371
30589
|
area: report.area,
|
|
30372
30590
|
reportPath: reportRef,
|
|
@@ -30410,7 +30628,7 @@ async function readIssueDatabase(issueDbPath) {
|
|
|
30410
30628
|
try {
|
|
30411
30629
|
raw = await readFile40(issueDbPath, "utf-8");
|
|
30412
30630
|
} catch (err) {
|
|
30413
|
-
if (
|
|
30631
|
+
if (isNodeError9(err) && err.code === "ENOENT") {
|
|
30414
30632
|
return emptyIssueDatabase();
|
|
30415
30633
|
}
|
|
30416
30634
|
throw err;
|
|
@@ -30429,9 +30647,9 @@ async function readIssueDatabase(issueDbPath) {
|
|
|
30429
30647
|
}
|
|
30430
30648
|
async function writeJsonAtomic3(file, value) {
|
|
30431
30649
|
const tmp = `${file}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
30432
|
-
await
|
|
30650
|
+
await writeFile44(tmp, `${JSON.stringify(value, null, 2)}
|
|
30433
30651
|
`, "utf-8");
|
|
30434
|
-
await
|
|
30652
|
+
await rename13(tmp, file);
|
|
30435
30653
|
}
|
|
30436
30654
|
function emptyIssueDatabase() {
|
|
30437
30655
|
return {
|
|
@@ -30472,20 +30690,20 @@ function compareIssueRecords(a, b) {
|
|
|
30472
30690
|
}
|
|
30473
30691
|
async function applySafeRemediation(projectRoot, issue) {
|
|
30474
30692
|
if (issue.id === "config-gitignore" && issue.file === ".gitignore") {
|
|
30475
|
-
const gitignorePath =
|
|
30693
|
+
const gitignorePath = path58.join(projectRoot, ".gitignore");
|
|
30476
30694
|
if (pathExistsSync(gitignorePath)) {
|
|
30477
30695
|
return { applied: false };
|
|
30478
30696
|
}
|
|
30479
|
-
await
|
|
30697
|
+
await writeFile44(gitignorePath, `${DEFAULT_GITIGNORE}
|
|
30480
30698
|
`, "utf-8");
|
|
30481
30699
|
return { applied: true, action: "created .gitignore" };
|
|
30482
30700
|
}
|
|
30483
30701
|
if (issue.id === "config-editorconfig" && issue.file === ".editorconfig") {
|
|
30484
|
-
const editorconfigPath =
|
|
30702
|
+
const editorconfigPath = path58.join(projectRoot, ".editorconfig");
|
|
30485
30703
|
if (pathExistsSync(editorconfigPath)) {
|
|
30486
30704
|
return { applied: false };
|
|
30487
30705
|
}
|
|
30488
|
-
await
|
|
30706
|
+
await writeFile44(editorconfigPath, `${DEFAULT_EDITORCONFIG}
|
|
30489
30707
|
`, "utf-8");
|
|
30490
30708
|
return { applied: true, action: "created .editorconfig" };
|
|
30491
30709
|
}
|
|
@@ -30521,7 +30739,7 @@ async function inferSafePackageScript(projectRoot, scriptName) {
|
|
|
30521
30739
|
}
|
|
30522
30740
|
}
|
|
30523
30741
|
async function addPackageScript(projectRoot, scriptName, script) {
|
|
30524
|
-
const packagePath =
|
|
30742
|
+
const packagePath = path58.join(projectRoot, "package.json");
|
|
30525
30743
|
let pkg;
|
|
30526
30744
|
try {
|
|
30527
30745
|
pkg = JSON.parse(await readFile40(packagePath, "utf-8"));
|
|
@@ -30534,7 +30752,7 @@ async function addPackageScript(projectRoot, scriptName, script) {
|
|
|
30534
30752
|
...scripts,
|
|
30535
30753
|
[scriptName]: script
|
|
30536
30754
|
};
|
|
30537
|
-
await
|
|
30755
|
+
await writeFile44(packagePath, `${JSON.stringify(pkg, null, 2)}
|
|
30538
30756
|
`, "utf-8");
|
|
30539
30757
|
return true;
|
|
30540
30758
|
}
|
|
@@ -30621,7 +30839,7 @@ async function pathExists9(file) {
|
|
|
30621
30839
|
return false;
|
|
30622
30840
|
}
|
|
30623
30841
|
}
|
|
30624
|
-
function
|
|
30842
|
+
function isNodeError9(err) {
|
|
30625
30843
|
return err instanceof Error && "code" in err;
|
|
30626
30844
|
}
|
|
30627
30845
|
function isRecord10(value) {
|
|
@@ -30634,7 +30852,7 @@ var EXIT_NOT_INITIALIZED3 = 1;
|
|
|
30634
30852
|
var EXIT_SCAN_FAILED = 2;
|
|
30635
30853
|
var EXIT_INVALID_ARG = 3;
|
|
30636
30854
|
async function manps(rootDir, area = "all", options = {}) {
|
|
30637
|
-
const v3SchemaPath =
|
|
30855
|
+
const v3SchemaPath = path59.join(rootDir, ".mancode", "schema.json");
|
|
30638
30856
|
const v3Activation = await readV3ActivationState(v3SchemaPath);
|
|
30639
30857
|
if (v3Activation !== null && v3Activation !== "v3_active" && v3Activation !== "dual_read") {
|
|
30640
30858
|
const message = `manps is unavailable while mancode activation is ${v3Activation}`;
|
|
@@ -30647,7 +30865,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30647
30865
|
return EXIT_SCAN_FAILED;
|
|
30648
30866
|
}
|
|
30649
30867
|
const v3Initialized = v3Activation === "v3_active";
|
|
30650
|
-
const initialized = v3Initialized || await pathExists10(
|
|
30868
|
+
const initialized = v3Initialized || await pathExists10(path59.join(rootDir, ".mancode", "state.json"));
|
|
30651
30869
|
if (!initialized) {
|
|
30652
30870
|
if (options.json) {
|
|
30653
30871
|
console.log(JSON.stringify({ error: "not initialized" }, null, 2));
|
|
@@ -30660,7 +30878,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30660
30878
|
let report;
|
|
30661
30879
|
try {
|
|
30662
30880
|
report = await runPreseasonScan(rootDir, area, {
|
|
30663
|
-
storageRoot: v3Initialized ?
|
|
30881
|
+
storageRoot: v3Initialized ? path59.join(rootDir, ".mancode", "local") : void 0
|
|
30664
30882
|
});
|
|
30665
30883
|
} catch (err) {
|
|
30666
30884
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -30729,8 +30947,8 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30729
30947
|
console.log(
|
|
30730
30948
|
`Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`
|
|
30731
30949
|
);
|
|
30732
|
-
console.log(`Report: ${
|
|
30733
|
-
console.log(`Issue DB: ${
|
|
30950
|
+
console.log(`Report: ${path59.relative(rootDir, report.reportPath)}`);
|
|
30951
|
+
console.log(`Issue DB: ${path59.relative(rootDir, report.issueDbPath)}`);
|
|
30734
30952
|
if (report.issues.length > 0) {
|
|
30735
30953
|
console.log("");
|
|
30736
30954
|
for (const issue of report.issues.slice(0, 7)) {
|
|
@@ -30746,7 +30964,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
30746
30964
|
console.log(` Skipped: ${remediation.skipped}`);
|
|
30747
30965
|
console.log(` Fixed: ${remediation.fixed}`);
|
|
30748
30966
|
console.log(
|
|
30749
|
-
` Issue DB: ${
|
|
30967
|
+
` Issue DB: ${path59.relative(rootDir, remediation.issueDbPath)}`
|
|
30750
30968
|
);
|
|
30751
30969
|
}
|
|
30752
30970
|
return EXIT_OK5;
|
|
@@ -30817,7 +31035,7 @@ async function readV3ActivationState(schemaPath) {
|
|
|
30817
31035
|
|
|
30818
31036
|
// src/commands/migrate.ts
|
|
30819
31037
|
import { readFile as readFile42 } from "fs/promises";
|
|
30820
|
-
import
|
|
31038
|
+
import path60 from "path";
|
|
30821
31039
|
var EXIT_OK6 = 0;
|
|
30822
31040
|
var EXIT_INVALID_ARG2 = 2;
|
|
30823
31041
|
var EXIT_MIGRATION_BLOCKED = 3;
|
|
@@ -30943,9 +31161,9 @@ async function readScopeFile(rootDir, file) {
|
|
|
30943
31161
|
if (!file.trim() || file.includes("\0")) {
|
|
30944
31162
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30945
31163
|
}
|
|
30946
|
-
const resolved =
|
|
30947
|
-
const relative =
|
|
30948
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
31164
|
+
const resolved = path60.resolve(rootDir, file);
|
|
31165
|
+
const relative = path60.relative(path60.resolve(rootDir), resolved);
|
|
31166
|
+
if (relative === ".." || relative.startsWith(`..${path60.sep}`) || path60.isAbsolute(relative)) {
|
|
30949
31167
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
30950
31168
|
}
|
|
30951
31169
|
try {
|
|
@@ -31050,12 +31268,12 @@ async function runOperationMutation(rootDir, operationId, options, mode) {
|
|
|
31050
31268
|
}
|
|
31051
31269
|
|
|
31052
31270
|
// src/context/project-policy-upgrade.ts
|
|
31053
|
-
import { lstat as
|
|
31054
|
-
import
|
|
31271
|
+
import { lstat as lstat23, mkdir as mkdir37, readFile as readFile43, rm as rm21, writeFile as writeFile45 } from "fs/promises";
|
|
31272
|
+
import path61 from "path";
|
|
31055
31273
|
var UPGRADE_OPERATION = "project_policy_upgrade";
|
|
31056
31274
|
async function dryRunProjectPolicyUpgrade(input) {
|
|
31057
31275
|
assertPolicyVersion(input.policyVersion);
|
|
31058
|
-
const root =
|
|
31276
|
+
const root = path61.resolve(input.projectRoot);
|
|
31059
31277
|
const project = await new V3ContextStore(root).readProjectSnapshot();
|
|
31060
31278
|
const beforeDigest = digestManifest(project.manifest);
|
|
31061
31279
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -31099,7 +31317,7 @@ async function dryRunProjectPolicyUpgrade(input) {
|
|
|
31099
31317
|
async function upgradeProjectPolicy(input) {
|
|
31100
31318
|
assertPolicyVersion(input.policyVersion);
|
|
31101
31319
|
assertUlid(input.sessionId, "project policy upgrade sessionId");
|
|
31102
|
-
const root =
|
|
31320
|
+
const root = path61.resolve(input.projectRoot);
|
|
31103
31321
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
31104
31322
|
const operationId = input.operationId;
|
|
31105
31323
|
if (operationId === void 0) {
|
|
@@ -31353,24 +31571,24 @@ function buildV2Manifest(manifest, operationId) {
|
|
|
31353
31571
|
return candidate;
|
|
31354
31572
|
}
|
|
31355
31573
|
async function readSchemaContent(root) {
|
|
31356
|
-
return readFile43(
|
|
31574
|
+
return readFile43(path61.join(root, ".mancode", "schema.json"), "utf8");
|
|
31357
31575
|
}
|
|
31358
31576
|
async function writeSchemaContent(root, operationId, content) {
|
|
31359
|
-
const directory =
|
|
31360
|
-
const target =
|
|
31361
|
-
const stat5 = await
|
|
31577
|
+
const directory = path61.join(root, ".mancode");
|
|
31578
|
+
const target = path61.join(directory, "schema.json");
|
|
31579
|
+
const stat5 = await lstat23(target);
|
|
31362
31580
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
31363
31581
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
31364
31582
|
}
|
|
31365
|
-
const temporary =
|
|
31583
|
+
const temporary = path61.join(
|
|
31366
31584
|
directory,
|
|
31367
31585
|
`.schema.json.${operationId}.${process.pid}.tmp`
|
|
31368
31586
|
);
|
|
31369
|
-
await
|
|
31587
|
+
await writeFile45(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
31370
31588
|
try {
|
|
31371
31589
|
await replaceFileAtomically(temporary, target);
|
|
31372
31590
|
} catch (error) {
|
|
31373
|
-
await
|
|
31591
|
+
await rm21(temporary, { force: true });
|
|
31374
31592
|
throw error;
|
|
31375
31593
|
}
|
|
31376
31594
|
}
|
|
@@ -31438,13 +31656,13 @@ async function releaseLocks3(locks) {
|
|
|
31438
31656
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
31439
31657
|
}
|
|
31440
31658
|
function projectUpgradePreviewRoot(root, operationId) {
|
|
31441
|
-
return
|
|
31659
|
+
return path61.join(root, ".mancode", "staging", "project-upgrade", operationId);
|
|
31442
31660
|
}
|
|
31443
31661
|
async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
31444
31662
|
const directory = projectUpgradePreviewRoot(root, receipt.operationId);
|
|
31445
|
-
const receiptPath =
|
|
31446
|
-
const manifestPath =
|
|
31447
|
-
await mkdir37(
|
|
31663
|
+
const receiptPath = path61.join(directory, "preview.json");
|
|
31664
|
+
const manifestPath = path61.join(directory, "schema.json");
|
|
31665
|
+
await mkdir37(path61.dirname(directory), { recursive: true });
|
|
31448
31666
|
try {
|
|
31449
31667
|
await mkdir37(directory);
|
|
31450
31668
|
} catch (error) {
|
|
@@ -31454,25 +31672,25 @@ async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
|
31454
31672
|
throw error;
|
|
31455
31673
|
}
|
|
31456
31674
|
try {
|
|
31457
|
-
await
|
|
31675
|
+
await writeFile45(receiptPath, `${JSON.stringify(receipt, null, 2)}
|
|
31458
31676
|
`, {
|
|
31459
31677
|
encoding: "utf8",
|
|
31460
31678
|
flag: "wx"
|
|
31461
31679
|
});
|
|
31462
|
-
await
|
|
31680
|
+
await writeFile45(manifestPath, manifestContent, {
|
|
31463
31681
|
encoding: "utf8",
|
|
31464
31682
|
flag: "wx"
|
|
31465
31683
|
});
|
|
31466
31684
|
} catch (error) {
|
|
31467
|
-
await
|
|
31685
|
+
await rm21(directory, { recursive: true, force: true });
|
|
31468
31686
|
throw error;
|
|
31469
31687
|
}
|
|
31470
31688
|
}
|
|
31471
31689
|
async function assertProjectPolicyUpgradePreview(root, operationId, project) {
|
|
31472
31690
|
const directory = projectUpgradePreviewRoot(root, operationId);
|
|
31473
31691
|
const [receiptContent, manifestContent] = await Promise.all([
|
|
31474
|
-
readSafePreviewFile(
|
|
31475
|
-
readSafePreviewFile(
|
|
31692
|
+
readSafePreviewFile(path61.join(directory, "preview.json")),
|
|
31693
|
+
readSafePreviewFile(path61.join(directory, "schema.json"))
|
|
31476
31694
|
]);
|
|
31477
31695
|
let receipt;
|
|
31478
31696
|
try {
|
|
@@ -31495,7 +31713,7 @@ async function assertProjectPolicyUpgradePreview(root, operationId, project) {
|
|
|
31495
31713
|
}
|
|
31496
31714
|
async function readSafePreviewFile(target) {
|
|
31497
31715
|
try {
|
|
31498
|
-
const stat5 = await
|
|
31716
|
+
const stat5 = await lstat23(target);
|
|
31499
31717
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
31500
31718
|
throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_INVALID");
|
|
31501
31719
|
}
|
|
@@ -31588,16 +31806,16 @@ async function projectUpgrade(rootDir, options) {
|
|
|
31588
31806
|
// src/commands/refresh-project.ts
|
|
31589
31807
|
import { randomUUID } from "crypto";
|
|
31590
31808
|
import { promises as fs7 } from "fs";
|
|
31591
|
-
import
|
|
31809
|
+
import path62 from "path";
|
|
31592
31810
|
import process9 from "process";
|
|
31593
31811
|
var EXIT_OK7 = 0;
|
|
31594
31812
|
var EXIT_NOT_INITIALIZED4 = 1;
|
|
31595
31813
|
var EXIT_CORRUPT_STATE = 2;
|
|
31596
31814
|
var EXIT_REFRESH_FAILED = 3;
|
|
31597
31815
|
async function refreshProject(rootDir = process9.cwd()) {
|
|
31598
|
-
const mancodeDir =
|
|
31599
|
-
const statePath =
|
|
31600
|
-
if (await pathExists11(
|
|
31816
|
+
const mancodeDir = path62.join(rootDir, ".mancode");
|
|
31817
|
+
const statePath = path62.join(mancodeDir, "state.json");
|
|
31818
|
+
if (await pathExists11(path62.join(mancodeDir, "schema.json"))) {
|
|
31601
31819
|
return refreshV3Project(rootDir);
|
|
31602
31820
|
}
|
|
31603
31821
|
if (!await pathExists11(statePath)) {
|
|
@@ -31613,27 +31831,27 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
31613
31831
|
}
|
|
31614
31832
|
let factsWritten = false;
|
|
31615
31833
|
try {
|
|
31616
|
-
const [profile, team, hasGit,
|
|
31834
|
+
const [profile, team, hasGit, hasEvidence] = await Promise.all([
|
|
31617
31835
|
detectProjectProfile(rootDir),
|
|
31618
31836
|
detectTeamStatus(rootDir),
|
|
31619
|
-
pathExists11(
|
|
31620
|
-
|
|
31837
|
+
pathExists11(path62.join(rootDir, ".git")),
|
|
31838
|
+
hasProjectEvidence(rootDir)
|
|
31621
31839
|
]);
|
|
31622
31840
|
const uiLibrary = primaryUiLibrary(profile);
|
|
31623
31841
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
31624
|
-
const config = await readJson2(
|
|
31842
|
+
const config = await readJson2(path62.join(mancodeDir, "config.json"));
|
|
31625
31843
|
const configuredTeam = config.forceTeamMode === true ? true : config.teamMode === "on" ? true : config.teamMode === "off" ? false : team.isTeam;
|
|
31626
31844
|
const nextState = {
|
|
31627
31845
|
...state,
|
|
31628
31846
|
techStack: stack.join(" + ") || profile.projectKind,
|
|
31629
31847
|
uiLibrary: uiLibrary ?? "None",
|
|
31630
|
-
projectMode: hasGit ||
|
|
31848
|
+
projectMode: hasGit || hasEvidence ? "detected" : "generic",
|
|
31631
31849
|
teamModeAutoDetected: configuredTeam,
|
|
31632
31850
|
contributors: team.contributors
|
|
31633
31851
|
};
|
|
31634
31852
|
await writeProjectFacts2(
|
|
31635
31853
|
statePath,
|
|
31636
|
-
|
|
31854
|
+
path62.join(mancodeDir, "project-profile.json"),
|
|
31637
31855
|
`${JSON.stringify(nextState, null, 2)}
|
|
31638
31856
|
`,
|
|
31639
31857
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -31650,7 +31868,7 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
31650
31868
|
);
|
|
31651
31869
|
console.log("\u2713 Project facts refreshed.");
|
|
31652
31870
|
console.log(
|
|
31653
|
-
` ${hasGit ? "Git detected" : "No Git repository"} | ${
|
|
31871
|
+
` ${hasGit ? "Git detected" : "No Git repository"} | ${hasEvidence ? "project source detected" : "generic project"}`
|
|
31654
31872
|
);
|
|
31655
31873
|
console.log(
|
|
31656
31874
|
` Stack: ${nextState.techStack} | UI: ${nextState.uiLibrary}`
|
|
@@ -31698,12 +31916,6 @@ async function refreshV3Project(rootDir) {
|
|
|
31698
31916
|
return EXIT_REFRESH_FAILED;
|
|
31699
31917
|
}
|
|
31700
31918
|
}
|
|
31701
|
-
async function hasProjectManifest2(rootDir) {
|
|
31702
|
-
for (const manifest of PROJECT_MANIFESTS) {
|
|
31703
|
-
if (await pathExists11(path61.join(rootDir, manifest))) return true;
|
|
31704
|
-
}
|
|
31705
|
-
return false;
|
|
31706
|
-
}
|
|
31707
31919
|
async function writeProjectFacts2(statePath, profilePath, stateContent, profileContent) {
|
|
31708
31920
|
await Promise.all([
|
|
31709
31921
|
ensureReplaceableFile(statePath),
|
|
@@ -31744,7 +31956,7 @@ async function ensureReplaceableFile(filePath) {
|
|
|
31744
31956
|
throw new Error(`cannot replace non-file path: ${filePath}`);
|
|
31745
31957
|
}
|
|
31746
31958
|
} catch (error) {
|
|
31747
|
-
if (
|
|
31959
|
+
if (isNodeError10(error) && error.code === "ENOENT") return;
|
|
31748
31960
|
throw error;
|
|
31749
31961
|
}
|
|
31750
31962
|
}
|
|
@@ -31761,14 +31973,14 @@ async function readOptionalText(filePath) {
|
|
|
31761
31973
|
try {
|
|
31762
31974
|
return await fs7.readFile(filePath, "utf-8");
|
|
31763
31975
|
} catch (error) {
|
|
31764
|
-
if (
|
|
31976
|
+
if (isNodeError10(error) && error.code === "ENOENT") return null;
|
|
31765
31977
|
throw error;
|
|
31766
31978
|
}
|
|
31767
31979
|
}
|
|
31768
31980
|
function temporaryPath(filePath) {
|
|
31769
|
-
return
|
|
31770
|
-
|
|
31771
|
-
`.${
|
|
31981
|
+
return path62.join(
|
|
31982
|
+
path62.dirname(filePath),
|
|
31983
|
+
`.${path62.basename(filePath)}.${process9.pid}.${randomUUID()}.tmp`
|
|
31772
31984
|
);
|
|
31773
31985
|
}
|
|
31774
31986
|
async function refreshStaticPlatforms(rootDir, config, fallbackPlatform, stack, uiLibrary, profile) {
|
|
@@ -31824,7 +32036,7 @@ async function readRequiredState(filePath) {
|
|
|
31824
32036
|
function isRecord11(value) {
|
|
31825
32037
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31826
32038
|
}
|
|
31827
|
-
function
|
|
32039
|
+
function isNodeError10(error) {
|
|
31828
32040
|
return error instanceof Error && "code" in error;
|
|
31829
32041
|
}
|
|
31830
32042
|
async function pathExists11(filePath) {
|
|
@@ -31838,7 +32050,7 @@ async function pathExists11(filePath) {
|
|
|
31838
32050
|
|
|
31839
32051
|
// src/commands/refresh-style.ts
|
|
31840
32052
|
import { promises as fs8 } from "fs";
|
|
31841
|
-
import
|
|
32053
|
+
import path63 from "path";
|
|
31842
32054
|
import process10 from "process";
|
|
31843
32055
|
var EXIT_OK8 = 0;
|
|
31844
32056
|
var EXIT_NOT_INITIALIZED5 = 1;
|
|
@@ -31849,8 +32061,8 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31849
32061
|
console.error("\u2717 style scan root must stay inside the project root.");
|
|
31850
32062
|
return EXIT_V3_REFRESH_FAILED;
|
|
31851
32063
|
}
|
|
31852
|
-
const stateFile =
|
|
31853
|
-
if (await pathExists12(
|
|
32064
|
+
const stateFile = path63.join(rootDir, ".mancode", "state.json");
|
|
32065
|
+
if (await pathExists12(path63.join(rootDir, ".mancode", "schema.json"))) {
|
|
31854
32066
|
return refreshV3Style(rootDir, scanTarget.root, scanTarget.scopeRoot);
|
|
31855
32067
|
}
|
|
31856
32068
|
if (!await pathExists12(stateFile)) {
|
|
@@ -31860,7 +32072,7 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31860
32072
|
}
|
|
31861
32073
|
console.log("\u2713 \u5237\u65B0\u9879\u76EE profile...");
|
|
31862
32074
|
const profile = await detectProjectProfile(rootDir);
|
|
31863
|
-
const profilePath =
|
|
32075
|
+
const profilePath = path63.join(rootDir, ".mancode", "project-profile.json");
|
|
31864
32076
|
await fs8.writeFile(
|
|
31865
32077
|
profilePath,
|
|
31866
32078
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -31887,13 +32099,13 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
31887
32099
|
uiLibraryHint,
|
|
31888
32100
|
scanTarget.scopeRoot
|
|
31889
32101
|
);
|
|
31890
|
-
const tokensPath =
|
|
32102
|
+
const tokensPath = path63.join(
|
|
31891
32103
|
rootDir,
|
|
31892
32104
|
".mancode",
|
|
31893
32105
|
"aesthetics",
|
|
31894
32106
|
"style-tokens.json"
|
|
31895
32107
|
);
|
|
31896
|
-
await fs8.mkdir(
|
|
32108
|
+
await fs8.mkdir(path63.dirname(tokensPath), { recursive: true });
|
|
31897
32109
|
await fs8.writeFile(
|
|
31898
32110
|
tokensPath,
|
|
31899
32111
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -31966,7 +32178,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31966
32178
|
console.log(
|
|
31967
32179
|
` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
|
|
31968
32180
|
);
|
|
31969
|
-
const tokensPath =
|
|
32181
|
+
const tokensPath = path63.join(
|
|
31970
32182
|
rootDir,
|
|
31971
32183
|
".mancode",
|
|
31972
32184
|
"local",
|
|
@@ -31983,7 +32195,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
31983
32195
|
}
|
|
31984
32196
|
console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
|
|
31985
32197
|
const tokens = await scanAesthetics(scanRoot, uiLibraryHint, scopeRoot);
|
|
31986
|
-
await fs8.mkdir(
|
|
32198
|
+
await fs8.mkdir(path63.dirname(tokensPath), { recursive: true });
|
|
31987
32199
|
await fs8.writeFile(
|
|
31988
32200
|
tokensPath,
|
|
31989
32201
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -32017,7 +32229,7 @@ async function printStaticPlatformRefreshHint(rootDir) {
|
|
|
32017
32229
|
);
|
|
32018
32230
|
}
|
|
32019
32231
|
async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
32020
|
-
const statePath =
|
|
32232
|
+
const statePath = path63.join(rootDir, ".mancode", "state.json");
|
|
32021
32233
|
try {
|
|
32022
32234
|
const state = JSON.parse(await fs8.readFile(statePath, "utf-8"));
|
|
32023
32235
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
@@ -32041,7 +32253,7 @@ async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
|
32041
32253
|
async function readInstalledPlatforms2(rootDir) {
|
|
32042
32254
|
try {
|
|
32043
32255
|
const raw = await fs8.readFile(
|
|
32044
|
-
|
|
32256
|
+
path63.join(rootDir, ".mancode", "config.json"),
|
|
32045
32257
|
"utf-8"
|
|
32046
32258
|
);
|
|
32047
32259
|
const config = JSON.parse(raw);
|
|
@@ -32061,30 +32273,30 @@ async function pathExists12(p) {
|
|
|
32061
32273
|
}
|
|
32062
32274
|
}
|
|
32063
32275
|
async function resolveScanTarget(rootDir, requestedRoot) {
|
|
32064
|
-
const projectRoot = await fs8.realpath(
|
|
32276
|
+
const projectRoot = await fs8.realpath(path63.resolve(rootDir)).catch(() => null);
|
|
32065
32277
|
if (projectRoot === null) return null;
|
|
32066
32278
|
if (requestedRoot === void 0 || requestedRoot === ".") {
|
|
32067
32279
|
return { root: projectRoot, scopeRoot: "." };
|
|
32068
32280
|
}
|
|
32069
|
-
if (
|
|
32281
|
+
if (path63.isAbsolute(requestedRoot) || requestedRoot.includes("\0") || requestedRoot.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
32070
32282
|
return null;
|
|
32071
32283
|
}
|
|
32072
|
-
const candidate = await fs8.realpath(
|
|
32284
|
+
const candidate = await fs8.realpath(path63.resolve(projectRoot, requestedRoot)).catch(() => null);
|
|
32073
32285
|
if (candidate === null) return null;
|
|
32074
|
-
const relative =
|
|
32075
|
-
if (relative.startsWith(`..${
|
|
32286
|
+
const relative = path63.relative(projectRoot, candidate);
|
|
32287
|
+
if (relative.startsWith(`..${path63.sep}`) || relative === ".." || path63.isAbsolute(relative)) {
|
|
32076
32288
|
return null;
|
|
32077
32289
|
}
|
|
32078
32290
|
return {
|
|
32079
32291
|
root: candidate,
|
|
32080
|
-
scopeRoot: relative.split(
|
|
32292
|
+
scopeRoot: relative.split(path63.sep).join("/") || "."
|
|
32081
32293
|
};
|
|
32082
32294
|
}
|
|
32083
32295
|
|
|
32084
32296
|
// src/commands/status.ts
|
|
32085
32297
|
import { spawn } from "child_process";
|
|
32086
32298
|
import { promises as fs9 } from "fs";
|
|
32087
|
-
import
|
|
32299
|
+
import path64 from "path";
|
|
32088
32300
|
import process11 from "process";
|
|
32089
32301
|
|
|
32090
32302
|
// src/team/assessment.ts
|
|
@@ -32240,8 +32452,8 @@ var EXIT_OK9 = 0;
|
|
|
32240
32452
|
var EXIT_NOT_INITIALIZED6 = 1;
|
|
32241
32453
|
var EXIT_CORRUPT_STATE2 = 2;
|
|
32242
32454
|
async function status(rootDir = process11.cwd(), options = {}) {
|
|
32243
|
-
const stateFile =
|
|
32244
|
-
const v3SchemaFile =
|
|
32455
|
+
const stateFile = path64.join(rootDir, ".mancode", "state.json");
|
|
32456
|
+
const v3SchemaFile = path64.join(rootDir, ".mancode", "schema.json");
|
|
32245
32457
|
if (await pathExists13(v3SchemaFile)) {
|
|
32246
32458
|
return statusV3(rootDir, options);
|
|
32247
32459
|
}
|
|
@@ -32486,12 +32698,9 @@ async function readV3StatusSession(rootDir) {
|
|
|
32486
32698
|
}
|
|
32487
32699
|
async function shouldRefreshProject(rootDir, state) {
|
|
32488
32700
|
if (state.projectMode !== "generic") return false;
|
|
32489
|
-
const hasGit = await pathExists13(
|
|
32701
|
+
const hasGit = await pathExists13(path64.join(rootDir, ".git"));
|
|
32490
32702
|
if (hasGit) return true;
|
|
32491
|
-
|
|
32492
|
-
if (await pathExists13(path63.join(rootDir, manifest))) return true;
|
|
32493
|
-
}
|
|
32494
|
-
return false;
|
|
32703
|
+
return hasProjectEvidence(rootDir);
|
|
32495
32704
|
}
|
|
32496
32705
|
async function checkPlatformStatus2(rootDir, installedPlatforms) {
|
|
32497
32706
|
const installed = new Set(installedPlatforms);
|
|
@@ -32533,19 +32742,19 @@ async function getCurrentWorkflow(rootDir, taskId) {
|
|
|
32533
32742
|
}
|
|
32534
32743
|
async function getProjectName(rootDir) {
|
|
32535
32744
|
try {
|
|
32536
|
-
const raw = await fs9.readFile(
|
|
32745
|
+
const raw = await fs9.readFile(path64.join(rootDir, "package.json"), "utf-8");
|
|
32537
32746
|
const pkg = JSON.parse(raw);
|
|
32538
32747
|
if (pkg.name && typeof pkg.name === "string") {
|
|
32539
32748
|
return pkg.name;
|
|
32540
32749
|
}
|
|
32541
32750
|
} catch {
|
|
32542
32751
|
}
|
|
32543
|
-
return
|
|
32752
|
+
return path64.basename(rootDir);
|
|
32544
32753
|
}
|
|
32545
32754
|
async function readConfig3(rootDir) {
|
|
32546
32755
|
try {
|
|
32547
32756
|
const raw = await fs9.readFile(
|
|
32548
|
-
|
|
32757
|
+
path64.join(rootDir, ".mancode", "config.json"),
|
|
32549
32758
|
"utf-8"
|
|
32550
32759
|
);
|
|
32551
32760
|
return JSON.parse(raw);
|
|
@@ -32573,9 +32782,9 @@ function getEffectiveTeamStatus(state, config, detected) {
|
|
|
32573
32782
|
}
|
|
32574
32783
|
async function checkHooks(rootDir) {
|
|
32575
32784
|
const [sessionStart, userPromptSubmit, registered] = await Promise.all([
|
|
32576
|
-
pathExists13(
|
|
32785
|
+
pathExists13(path64.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
|
|
32577
32786
|
pathExists13(
|
|
32578
|
-
|
|
32787
|
+
path64.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
32579
32788
|
),
|
|
32580
32789
|
isRegistered(rootDir)
|
|
32581
32790
|
]);
|
|
@@ -32584,7 +32793,7 @@ async function checkHooks(rootDir) {
|
|
|
32584
32793
|
async function isRegistered(rootDir) {
|
|
32585
32794
|
try {
|
|
32586
32795
|
const raw = await fs9.readFile(
|
|
32587
|
-
|
|
32796
|
+
path64.join(rootDir, ".claude", "settings.json"),
|
|
32588
32797
|
"utf-8"
|
|
32589
32798
|
);
|
|
32590
32799
|
const settings = JSON.parse(raw);
|
|
@@ -32613,7 +32822,7 @@ function hasHookCommand2(value, needle) {
|
|
|
32613
32822
|
});
|
|
32614
32823
|
}
|
|
32615
32824
|
async function estimateHookInjection(rootDir) {
|
|
32616
|
-
const hookPath =
|
|
32825
|
+
const hookPath = path64.join(
|
|
32617
32826
|
rootDir,
|
|
32618
32827
|
".mancode",
|
|
32619
32828
|
"hooks",
|
|
@@ -34110,8 +34319,8 @@ function assertPositiveRevision2(value, label) {
|
|
|
34110
34319
|
}
|
|
34111
34320
|
|
|
34112
34321
|
// src/team/git-ref-handoff-repair.ts
|
|
34113
|
-
import { lstat as
|
|
34114
|
-
import
|
|
34322
|
+
import { lstat as lstat24, mkdir as mkdir38, readFile as readFile44, readdir as readdir19, writeFile as writeFile46 } from "fs/promises";
|
|
34323
|
+
import path65 from "path";
|
|
34115
34324
|
|
|
34116
34325
|
// src/team/git-ref-operation.ts
|
|
34117
34326
|
import { execFile as execFileCallback6 } from "child_process";
|
|
@@ -36689,7 +36898,7 @@ async function recoverGitRefHandoffRepairs(projectRoot) {
|
|
|
36689
36898
|
}
|
|
36690
36899
|
async function recoverGitRefHandoffRepair(projectRoot, operationId, transportReceipt) {
|
|
36691
36900
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
36692
|
-
const root =
|
|
36901
|
+
const root = path65.resolve(projectRoot);
|
|
36693
36902
|
let journal = await requireJournal2(root, operationId);
|
|
36694
36903
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
36695
36904
|
return recoveryResult2(journal);
|
|
@@ -36768,7 +36977,7 @@ async function recoverGitRefHandoffRepair(projectRoot, operationId, transportRec
|
|
|
36768
36977
|
}
|
|
36769
36978
|
}
|
|
36770
36979
|
async function prepareHandoffRepairWhileTaskLocked(projectRoot, rawPrepared) {
|
|
36771
|
-
const root =
|
|
36980
|
+
const root = path65.resolve(projectRoot);
|
|
36772
36981
|
const prepared2 = parsePrepared2(rawPrepared);
|
|
36773
36982
|
const runtime = await readProjectRuntimeContext(root);
|
|
36774
36983
|
const previousMetadata = bundleMetadata2(prepared2.predecessorBundle);
|
|
@@ -36831,7 +37040,7 @@ async function restorePredecessorMetadata2(projectRoot, journal) {
|
|
|
36831
37040
|
);
|
|
36832
37041
|
}
|
|
36833
37042
|
async function replaceMetadataVerified(projectRoot, expected, targetMetadata, alternateExpected) {
|
|
36834
|
-
const target =
|
|
37043
|
+
const target = path65.join(
|
|
36835
37044
|
taskRootPath(projectRoot, targetMetadata.taskRef),
|
|
36836
37045
|
"metadata.json"
|
|
36837
37046
|
);
|
|
@@ -36957,7 +37166,7 @@ async function createJournal3(projectRoot, journal) {
|
|
|
36957
37166
|
await ensureJournalDirectory2(projectRoot);
|
|
36958
37167
|
const target = journalPath3(projectRoot, journal.operationId);
|
|
36959
37168
|
try {
|
|
36960
|
-
await
|
|
37169
|
+
await writeFile46(target, serialize13(journal), {
|
|
36961
37170
|
encoding: "utf8",
|
|
36962
37171
|
flag: "wx"
|
|
36963
37172
|
});
|
|
@@ -37000,7 +37209,7 @@ async function listJournals2(projectRoot) {
|
|
|
37000
37209
|
parseJournal3(
|
|
37001
37210
|
JSON.parse(
|
|
37002
37211
|
await readFile44(
|
|
37003
|
-
|
|
37212
|
+
path65.join(journalDirectory2(projectRoot), entry),
|
|
37004
37213
|
"utf8"
|
|
37005
37214
|
)
|
|
37006
37215
|
)
|
|
@@ -37010,43 +37219,43 @@ async function listJournals2(projectRoot) {
|
|
|
37010
37219
|
return journals;
|
|
37011
37220
|
}
|
|
37012
37221
|
async function readSafeFile2(target) {
|
|
37013
|
-
const before = await
|
|
37222
|
+
const before = await lstat24(target);
|
|
37014
37223
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
37015
37224
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37016
37225
|
}
|
|
37017
37226
|
const content = await readFile44(target, "utf8");
|
|
37018
|
-
const after = await
|
|
37227
|
+
const after = await lstat24(target);
|
|
37019
37228
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
37020
37229
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37021
37230
|
}
|
|
37022
37231
|
return content;
|
|
37023
37232
|
}
|
|
37024
37233
|
async function atomicWrite2(target, content) {
|
|
37025
|
-
const temporary =
|
|
37026
|
-
|
|
37027
|
-
`.${
|
|
37234
|
+
const temporary = path65.join(
|
|
37235
|
+
path65.dirname(target),
|
|
37236
|
+
`.${path65.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
37028
37237
|
);
|
|
37029
|
-
await
|
|
37238
|
+
await writeFile46(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
37030
37239
|
await replaceFileAtomically(temporary, target);
|
|
37031
37240
|
}
|
|
37032
37241
|
async function ensureJournalDirectory2(projectRoot) {
|
|
37033
|
-
let current =
|
|
37242
|
+
let current = path65.resolve(projectRoot);
|
|
37034
37243
|
for (const segment of [".mancode", "local", "journals", "git-ref-handoff"]) {
|
|
37035
|
-
current =
|
|
37244
|
+
current = path65.join(current, segment);
|
|
37036
37245
|
try {
|
|
37037
37246
|
await mkdir38(current);
|
|
37038
37247
|
} catch (error) {
|
|
37039
37248
|
if (!isAlreadyExists24(error)) throw error;
|
|
37040
37249
|
}
|
|
37041
|
-
const entry = await
|
|
37250
|
+
const entry = await lstat24(current);
|
|
37042
37251
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
37043
37252
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37044
37253
|
}
|
|
37045
37254
|
}
|
|
37046
37255
|
}
|
|
37047
37256
|
function journalDirectory2(projectRoot) {
|
|
37048
|
-
return
|
|
37049
|
-
|
|
37257
|
+
return path65.join(
|
|
37258
|
+
path65.resolve(projectRoot),
|
|
37050
37259
|
".mancode",
|
|
37051
37260
|
"local",
|
|
37052
37261
|
"journals",
|
|
@@ -37055,7 +37264,7 @@ function journalDirectory2(projectRoot) {
|
|
|
37055
37264
|
}
|
|
37056
37265
|
function journalPath3(projectRoot, operationId) {
|
|
37057
37266
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
37058
|
-
return
|
|
37267
|
+
return path65.join(journalDirectory2(projectRoot), `${operationId}.json`);
|
|
37059
37268
|
}
|
|
37060
37269
|
function serialize13(value) {
|
|
37061
37270
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -37154,8 +37363,8 @@ function parseReceipt(value) {
|
|
|
37154
37363
|
}
|
|
37155
37364
|
|
|
37156
37365
|
// src/team/policy-operation.ts
|
|
37157
|
-
import { lstat as
|
|
37158
|
-
import
|
|
37366
|
+
import { lstat as lstat25, mkdir as mkdir39, readdir as readdir20, unlink as unlink3, writeFile as writeFile47 } from "fs/promises";
|
|
37367
|
+
import path66 from "path";
|
|
37159
37368
|
async function updateTeamPolicy(input) {
|
|
37160
37369
|
const operationId = input.operationId ?? createUlid();
|
|
37161
37370
|
const eventId = createUlid();
|
|
@@ -37166,7 +37375,7 @@ async function updateTeamPolicy(input) {
|
|
|
37166
37375
|
throw new Error("MANCODE_TEAM_POLICY_INVALID");
|
|
37167
37376
|
}
|
|
37168
37377
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
37169
|
-
const root =
|
|
37378
|
+
const root = path66.resolve(input.projectRoot);
|
|
37170
37379
|
const runtime = await readProjectRuntimeContext(root);
|
|
37171
37380
|
const store = resolveCoordinationEntityHomeStore(
|
|
37172
37381
|
runtime.entityHomeStoreContext
|
|
@@ -37247,7 +37456,7 @@ async function applyTeamTransportSet(input, write2) {
|
|
|
37247
37456
|
}
|
|
37248
37457
|
const remote = transportRemote(input.mode, input.remote);
|
|
37249
37458
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
37250
|
-
const root =
|
|
37459
|
+
const root = path66.resolve(input.projectRoot);
|
|
37251
37460
|
const runtime = await readProjectRuntimeContext(root);
|
|
37252
37461
|
const store = resolveCoordinationEntityHomeStore(
|
|
37253
37462
|
runtime.entityHomeStoreContext
|
|
@@ -37380,9 +37589,9 @@ async function assertTransportAuthorityEmpty(projectRoot, store) {
|
|
|
37380
37589
|
listClaims(store),
|
|
37381
37590
|
listHandoffs(store),
|
|
37382
37591
|
directoryHasEntries(taskHeadDirectory(store)),
|
|
37383
|
-
directoryHasEntries(
|
|
37592
|
+
directoryHasEntries(path66.join(store.root, "transport-migrations")),
|
|
37384
37593
|
directoryHasEntries(
|
|
37385
|
-
|
|
37594
|
+
path66.join(projectRoot, ".mancode", "shared", "team", "transport")
|
|
37386
37595
|
),
|
|
37387
37596
|
pathExists14(gitRefCachePath(projectRoot))
|
|
37388
37597
|
]);
|
|
@@ -37412,21 +37621,21 @@ function assertPositiveRevision5(value, label) {
|
|
|
37412
37621
|
}
|
|
37413
37622
|
}
|
|
37414
37623
|
function teamPolicyPath(projectRoot) {
|
|
37415
|
-
return
|
|
37624
|
+
return path66.join(projectRoot, ".mancode", "shared", "team", "policy.json");
|
|
37416
37625
|
}
|
|
37417
37626
|
function projectConfigPath(projectRoot) {
|
|
37418
|
-
return
|
|
37627
|
+
return path66.join(projectRoot, ".mancode", "shared", "config.json");
|
|
37419
37628
|
}
|
|
37420
37629
|
async function writeJsonAtomic4(target, value) {
|
|
37421
|
-
await mkdir39(
|
|
37422
|
-
await assertPlainDirectory(
|
|
37630
|
+
await mkdir39(path66.dirname(target), { recursive: true });
|
|
37631
|
+
await assertPlainDirectory(path66.dirname(target));
|
|
37423
37632
|
await assertPlainFileOrMissing(target);
|
|
37424
|
-
const temporary =
|
|
37425
|
-
|
|
37426
|
-
`.${
|
|
37633
|
+
const temporary = path66.join(
|
|
37634
|
+
path66.dirname(target),
|
|
37635
|
+
`.${path66.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
37427
37636
|
);
|
|
37428
37637
|
try {
|
|
37429
|
-
await
|
|
37638
|
+
await writeFile47(temporary, `${JSON.stringify(value, null, 2)}
|
|
37430
37639
|
`, {
|
|
37431
37640
|
encoding: "utf8",
|
|
37432
37641
|
flag: "wx"
|
|
@@ -37438,14 +37647,14 @@ async function writeJsonAtomic4(target, value) {
|
|
|
37438
37647
|
}
|
|
37439
37648
|
}
|
|
37440
37649
|
async function assertPlainDirectory(target) {
|
|
37441
|
-
const entry = await
|
|
37650
|
+
const entry = await lstat25(target);
|
|
37442
37651
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
37443
37652
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37444
37653
|
}
|
|
37445
37654
|
}
|
|
37446
37655
|
async function assertPlainFileOrMissing(target) {
|
|
37447
37656
|
try {
|
|
37448
|
-
const entry = await
|
|
37657
|
+
const entry = await lstat25(target);
|
|
37449
37658
|
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
37450
37659
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37451
37660
|
}
|
|
@@ -37456,7 +37665,7 @@ async function assertPlainFileOrMissing(target) {
|
|
|
37456
37665
|
}
|
|
37457
37666
|
async function directoryHasEntries(target) {
|
|
37458
37667
|
try {
|
|
37459
|
-
const entry = await
|
|
37668
|
+
const entry = await lstat25(target);
|
|
37460
37669
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
37461
37670
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
37462
37671
|
}
|
|
@@ -37468,7 +37677,7 @@ async function directoryHasEntries(target) {
|
|
|
37468
37677
|
}
|
|
37469
37678
|
async function pathExists14(target) {
|
|
37470
37679
|
try {
|
|
37471
|
-
await
|
|
37680
|
+
await lstat25(target);
|
|
37472
37681
|
return true;
|
|
37473
37682
|
} catch (error) {
|
|
37474
37683
|
if (isNotFound32(error)) return false;
|
|
@@ -37484,15 +37693,15 @@ function isNotFound32(error) {
|
|
|
37484
37693
|
|
|
37485
37694
|
// src/team/transport-migration-adapters.ts
|
|
37486
37695
|
import {
|
|
37487
|
-
lstat as
|
|
37696
|
+
lstat as lstat26,
|
|
37488
37697
|
mkdir as mkdir40,
|
|
37489
37698
|
readFile as readFile45,
|
|
37490
37699
|
readdir as readdir21,
|
|
37491
|
-
rename as
|
|
37700
|
+
rename as rename14,
|
|
37492
37701
|
unlink as unlink4,
|
|
37493
|
-
writeFile as
|
|
37702
|
+
writeFile as writeFile48
|
|
37494
37703
|
} from "fs/promises";
|
|
37495
|
-
import
|
|
37704
|
+
import path67 from "path";
|
|
37496
37705
|
|
|
37497
37706
|
// src/team/transport-migration.ts
|
|
37498
37707
|
var DIGEST_PATTERN7 = /^sha256:[a-f0-9]{64}$/;
|
|
@@ -38564,7 +38773,7 @@ function compareUtf813(left, right) {
|
|
|
38564
38773
|
var STAGE_DIRECTORY = "transport-migrations";
|
|
38565
38774
|
var COLLECTIONS = ["claims", "handoffs", "task-heads"];
|
|
38566
38775
|
async function createTransportMigrationFileAdapters(input) {
|
|
38567
|
-
const projectRoot =
|
|
38776
|
+
const projectRoot = path67.resolve(input.projectRoot);
|
|
38568
38777
|
assertUlid(input.actorId, "transport migration adapter actorId");
|
|
38569
38778
|
if (input.operationId !== void 0) {
|
|
38570
38779
|
assertUlid(input.operationId, "transport migration adapter operationId");
|
|
@@ -38616,7 +38825,7 @@ async function createTransportMigrationFileAdapters(input) {
|
|
|
38616
38825
|
var FileSystemTransportMigrationConfigAdapter = class {
|
|
38617
38826
|
constructor(projectRoot, coordinationStore) {
|
|
38618
38827
|
this.coordinationStore = coordinationStore;
|
|
38619
|
-
this.projectRoot =
|
|
38828
|
+
this.projectRoot = path67.resolve(projectRoot);
|
|
38620
38829
|
}
|
|
38621
38830
|
projectRoot;
|
|
38622
38831
|
async read() {
|
|
@@ -39469,7 +39678,7 @@ async function publishMigrationActorProfiles(projectRoot, profiles) {
|
|
|
39469
39678
|
}
|
|
39470
39679
|
}
|
|
39471
39680
|
async function archiveLocalCoordinationCollections(store, operationId) {
|
|
39472
|
-
const archiveRoot =
|
|
39681
|
+
const archiveRoot = path67.join(
|
|
39473
39682
|
store.root,
|
|
39474
39683
|
STAGE_DIRECTORY,
|
|
39475
39684
|
"archive",
|
|
@@ -39482,20 +39691,20 @@ async function archiveLocalCoordinationCollections(store, operationId) {
|
|
|
39482
39691
|
"task-heads": taskHeadDirectory(store)
|
|
39483
39692
|
};
|
|
39484
39693
|
for (const name of COLLECTIONS) {
|
|
39485
|
-
const archived =
|
|
39486
|
-
const absent =
|
|
39694
|
+
const archived = path67.join(archiveRoot, name);
|
|
39695
|
+
const absent = path67.join(archiveRoot, `${name}.absent`);
|
|
39487
39696
|
if (await pathKind(archived) === "directory" || await pathKind(absent) === "file") {
|
|
39488
39697
|
continue;
|
|
39489
39698
|
}
|
|
39490
39699
|
const sourceKind = await pathKind(directories[name]);
|
|
39491
39700
|
if (sourceKind === null) {
|
|
39492
|
-
await
|
|
39701
|
+
await writeFile48(absent, "\n", { encoding: "utf8", flag: "wx" });
|
|
39493
39702
|
continue;
|
|
39494
39703
|
}
|
|
39495
39704
|
if (sourceKind !== "directory") {
|
|
39496
39705
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_LOCAL_AUTHORITY_UNSAFE");
|
|
39497
39706
|
}
|
|
39498
|
-
await
|
|
39707
|
+
await rename14(directories[name], archived);
|
|
39499
39708
|
}
|
|
39500
39709
|
}
|
|
39501
39710
|
async function listActorProfiles(projectRoot) {
|
|
@@ -39521,7 +39730,7 @@ async function listActorProfiles(projectRoot) {
|
|
|
39521
39730
|
return profiles;
|
|
39522
39731
|
}
|
|
39523
39732
|
async function listSharedTaskRefs(projectRoot) {
|
|
39524
|
-
const directory =
|
|
39733
|
+
const directory = path67.join(projectRoot, ".mancode", "shared", "workflows");
|
|
39525
39734
|
let entries;
|
|
39526
39735
|
try {
|
|
39527
39736
|
entries = await readdir21(directory);
|
|
@@ -39532,7 +39741,7 @@ async function listSharedTaskRefs(projectRoot) {
|
|
|
39532
39741
|
const refs = [];
|
|
39533
39742
|
for (const taskId of entries.sort(compareUtf814)) {
|
|
39534
39743
|
assertUlid(taskId, "shared workflow directory");
|
|
39535
|
-
const stat5 = await
|
|
39744
|
+
const stat5 = await lstat26(path67.join(directory, taskId));
|
|
39536
39745
|
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
39537
39746
|
throw new Error("MANCODE_CONTEXT_PATH_UNSAFE");
|
|
39538
39747
|
}
|
|
@@ -39606,7 +39815,7 @@ async function readStagedRecord(store, operationId) {
|
|
|
39606
39815
|
);
|
|
39607
39816
|
}
|
|
39608
39817
|
function stagedPath(store, operationId) {
|
|
39609
|
-
return
|
|
39818
|
+
return path67.join(
|
|
39610
39819
|
store.root,
|
|
39611
39820
|
STAGE_DIRECTORY,
|
|
39612
39821
|
"staged",
|
|
@@ -39614,7 +39823,7 @@ function stagedPath(store, operationId) {
|
|
|
39614
39823
|
);
|
|
39615
39824
|
}
|
|
39616
39825
|
function establishedPath(store, operationId) {
|
|
39617
|
-
return
|
|
39826
|
+
return path67.join(
|
|
39618
39827
|
store.root,
|
|
39619
39828
|
STAGE_DIRECTORY,
|
|
39620
39829
|
"established",
|
|
@@ -39622,7 +39831,7 @@ function establishedPath(store, operationId) {
|
|
|
39622
39831
|
);
|
|
39623
39832
|
}
|
|
39624
39833
|
function projectConfigPath2(projectRoot) {
|
|
39625
|
-
return
|
|
39834
|
+
return path67.join(projectRoot, ".mancode", "shared", "config.json");
|
|
39626
39835
|
}
|
|
39627
39836
|
async function readProjectConfigFile(projectRoot) {
|
|
39628
39837
|
try {
|
|
@@ -39637,14 +39846,14 @@ async function readProjectConfigFile(projectRoot) {
|
|
|
39637
39846
|
}
|
|
39638
39847
|
}
|
|
39639
39848
|
async function writeJsonAtomic5(target, value) {
|
|
39640
|
-
await mkdir40(
|
|
39641
|
-
await assertPlainDirectory2(
|
|
39642
|
-
const temporary =
|
|
39643
|
-
|
|
39644
|
-
`.${
|
|
39849
|
+
await mkdir40(path67.dirname(target), { recursive: true });
|
|
39850
|
+
await assertPlainDirectory2(path67.dirname(target));
|
|
39851
|
+
const temporary = path67.join(
|
|
39852
|
+
path67.dirname(target),
|
|
39853
|
+
`.${path67.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
39645
39854
|
);
|
|
39646
39855
|
try {
|
|
39647
|
-
await
|
|
39856
|
+
await writeFile48(temporary, serialize14(value), {
|
|
39648
39857
|
encoding: "utf8",
|
|
39649
39858
|
flag: "wx"
|
|
39650
39859
|
});
|
|
@@ -39655,10 +39864,10 @@ async function writeJsonAtomic5(target, value) {
|
|
|
39655
39864
|
}
|
|
39656
39865
|
}
|
|
39657
39866
|
async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
|
|
39658
|
-
await mkdir40(
|
|
39659
|
-
await assertPlainDirectory2(
|
|
39867
|
+
await mkdir40(path67.dirname(target), { recursive: true });
|
|
39868
|
+
await assertPlainDirectory2(path67.dirname(target));
|
|
39660
39869
|
try {
|
|
39661
|
-
await
|
|
39870
|
+
await writeFile48(target, serialize14(value), { encoding: "utf8", flag: "wx" });
|
|
39662
39871
|
} catch (error) {
|
|
39663
39872
|
if (!isAlreadyExists25(error)) throw error;
|
|
39664
39873
|
const existing = await readJsonOrNull5(target, parser, conflictCode);
|
|
@@ -39670,12 +39879,12 @@ async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
|
|
|
39670
39879
|
}
|
|
39671
39880
|
async function readJsonOrNull5(target, parser, corruptCode) {
|
|
39672
39881
|
try {
|
|
39673
|
-
const before = await
|
|
39882
|
+
const before = await lstat26(target);
|
|
39674
39883
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
39675
39884
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
39676
39885
|
}
|
|
39677
39886
|
const parsed = parser(JSON.parse(await readFile45(target, "utf8")));
|
|
39678
|
-
const after = await
|
|
39887
|
+
const after = await lstat26(target);
|
|
39679
39888
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
39680
39889
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
39681
39890
|
}
|
|
@@ -39733,7 +39942,7 @@ function requireRemote(value) {
|
|
|
39733
39942
|
}
|
|
39734
39943
|
async function pathKind(target) {
|
|
39735
39944
|
try {
|
|
39736
|
-
const stat5 = await
|
|
39945
|
+
const stat5 = await lstat26(target);
|
|
39737
39946
|
if (stat5.isSymbolicLink()) return "other";
|
|
39738
39947
|
if (stat5.isFile()) return "file";
|
|
39739
39948
|
if (stat5.isDirectory()) return "directory";
|
|
@@ -39744,7 +39953,7 @@ async function pathKind(target) {
|
|
|
39744
39953
|
}
|
|
39745
39954
|
}
|
|
39746
39955
|
async function assertPlainDirectory2(target) {
|
|
39747
|
-
const stat5 = await
|
|
39956
|
+
const stat5 = await lstat26(target);
|
|
39748
39957
|
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
39749
39958
|
throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
|
|
39750
39959
|
}
|
|
@@ -41206,16 +41415,16 @@ function parsePositiveInteger6(value) {
|
|
|
41206
41415
|
}
|
|
41207
41416
|
|
|
41208
41417
|
// src/commands/uninstall.ts
|
|
41209
|
-
import { access as access5, readFile as readFile46, rm as
|
|
41210
|
-
import
|
|
41418
|
+
import { access as access5, readFile as readFile46, rm as rm22, writeFile as writeFile49 } from "fs/promises";
|
|
41419
|
+
import path68 from "path";
|
|
41211
41420
|
import process12 from "process";
|
|
41212
41421
|
var EXIT_OK10 = 0;
|
|
41213
41422
|
var EXIT_NOT_INITIALIZED7 = 1;
|
|
41214
41423
|
var EXIT_UNSUPPORTED_PLATFORM2 = 2;
|
|
41215
41424
|
var EXIT_V3_AUTHORITY_PROTECTED = 3;
|
|
41216
41425
|
async function uninstall(rootDir = process12.cwd(), platform, options = {}) {
|
|
41217
|
-
const stateFile =
|
|
41218
|
-
const v3SchemaFile =
|
|
41426
|
+
const stateFile = path68.join(rootDir, ".mancode", "state.json");
|
|
41427
|
+
const v3SchemaFile = path68.join(rootDir, ".mancode", "schema.json");
|
|
41219
41428
|
if (await pathExists15(v3SchemaFile)) {
|
|
41220
41429
|
return uninstallV3(rootDir, platform, options);
|
|
41221
41430
|
}
|
|
@@ -41301,6 +41510,8 @@ async function uninstallPlatform(rootDir, platform) {
|
|
|
41301
41510
|
await uninstallKimiCode(rootDir);
|
|
41302
41511
|
} else if (platform === "qoder") {
|
|
41303
41512
|
await uninstallQoder(rootDir);
|
|
41513
|
+
} else if (platform === "dsh") {
|
|
41514
|
+
await uninstallDsh(rootDir);
|
|
41304
41515
|
}
|
|
41305
41516
|
await removeFromConfig(rootDir, platform);
|
|
41306
41517
|
}
|
|
@@ -41310,7 +41521,7 @@ async function uninstallAll(rootDir) {
|
|
|
41310
41521
|
await uninstallPlatform(rootDir, p);
|
|
41311
41522
|
}
|
|
41312
41523
|
console.log("\u2713 Removing .mancode/ directory...");
|
|
41313
|
-
await
|
|
41524
|
+
await rm22(path68.join(rootDir, ".mancode"), {
|
|
41314
41525
|
recursive: true,
|
|
41315
41526
|
force: true
|
|
41316
41527
|
});
|
|
@@ -41320,7 +41531,7 @@ async function uninstallClaudeCode(rootDir) {
|
|
|
41320
41531
|
await cleanClaudeSettings(rootDir);
|
|
41321
41532
|
}
|
|
41322
41533
|
async function cleanClaudeSettings(rootDir) {
|
|
41323
|
-
const settingsPath =
|
|
41534
|
+
const settingsPath = path68.join(rootDir, ".claude", "settings.json");
|
|
41324
41535
|
let content;
|
|
41325
41536
|
try {
|
|
41326
41537
|
content = await readFile46(settingsPath, "utf-8");
|
|
@@ -41349,7 +41560,7 @@ async function cleanClaudeSettings(rootDir) {
|
|
|
41349
41560
|
);
|
|
41350
41561
|
settings.skills = Object.keys(retainedSkills).length > 0 ? retainedSkills : void 0;
|
|
41351
41562
|
}
|
|
41352
|
-
await
|
|
41563
|
+
await writeFile49(
|
|
41353
41564
|
settingsPath,
|
|
41354
41565
|
`${JSON.stringify(settings, null, 2)}
|
|
41355
41566
|
`,
|
|
@@ -41398,22 +41609,22 @@ async function uninstallCursor(rootDir) {
|
|
|
41398
41609
|
await removeCursorCommands(rootDir);
|
|
41399
41610
|
}
|
|
41400
41611
|
async function uninstallCodex(rootDir) {
|
|
41401
|
-
const agentsPath =
|
|
41612
|
+
const agentsPath = path68.join(rootDir, "AGENTS.md");
|
|
41402
41613
|
try {
|
|
41403
41614
|
const content = await readFile46(agentsPath, "utf-8");
|
|
41404
41615
|
const cleaned = removeManagedBlock(content);
|
|
41405
41616
|
if (cleaned.trim()) {
|
|
41406
|
-
await
|
|
41617
|
+
await writeFile49(agentsPath, `${cleaned}
|
|
41407
41618
|
`, "utf-8");
|
|
41408
41619
|
} else {
|
|
41409
|
-
await
|
|
41620
|
+
await rm22(agentsPath, { force: true });
|
|
41410
41621
|
}
|
|
41411
41622
|
} catch {
|
|
41412
41623
|
}
|
|
41413
41624
|
await removeCodexSkills(rootDir);
|
|
41414
41625
|
}
|
|
41415
41626
|
async function uninstallCopilot(rootDir) {
|
|
41416
|
-
const instructionsPath =
|
|
41627
|
+
const instructionsPath = path68.join(
|
|
41417
41628
|
rootDir,
|
|
41418
41629
|
".github",
|
|
41419
41630
|
"copilot-instructions.md"
|
|
@@ -41422,17 +41633,17 @@ async function uninstallCopilot(rootDir) {
|
|
|
41422
41633
|
const content = await readFile46(instructionsPath, "utf-8");
|
|
41423
41634
|
const cleaned = removeManagedBlock(content);
|
|
41424
41635
|
if (cleaned.trim()) {
|
|
41425
|
-
await
|
|
41636
|
+
await writeFile49(instructionsPath, `${cleaned}
|
|
41426
41637
|
`, "utf-8");
|
|
41427
41638
|
} else {
|
|
41428
|
-
await
|
|
41639
|
+
await rm22(instructionsPath, { force: true });
|
|
41429
41640
|
}
|
|
41430
41641
|
} catch {
|
|
41431
41642
|
}
|
|
41432
41643
|
await removeCopilotPrompts(rootDir);
|
|
41433
41644
|
}
|
|
41434
41645
|
async function uninstallZcode(rootDir) {
|
|
41435
|
-
const agentsPath =
|
|
41646
|
+
const agentsPath = path68.join(rootDir, "AGENTS.md");
|
|
41436
41647
|
try {
|
|
41437
41648
|
const content = await readFile46(agentsPath, "utf-8");
|
|
41438
41649
|
const cleaned = removeManagedBlock(
|
|
@@ -41441,17 +41652,17 @@ async function uninstallZcode(rootDir) {
|
|
|
41441
41652
|
ZCODE_MANCODE_END_MARKER
|
|
41442
41653
|
);
|
|
41443
41654
|
if (cleaned.trim()) {
|
|
41444
|
-
await
|
|
41655
|
+
await writeFile49(agentsPath, `${cleaned}
|
|
41445
41656
|
`, "utf-8");
|
|
41446
41657
|
} else {
|
|
41447
|
-
await
|
|
41658
|
+
await rm22(agentsPath, { force: true });
|
|
41448
41659
|
}
|
|
41449
41660
|
} catch {
|
|
41450
41661
|
}
|
|
41451
41662
|
await removeZcodeSkills(rootDir);
|
|
41452
41663
|
}
|
|
41453
41664
|
async function uninstallKimiCode(rootDir) {
|
|
41454
|
-
const agentsPath =
|
|
41665
|
+
const agentsPath = path68.join(rootDir, "AGENTS.md");
|
|
41455
41666
|
try {
|
|
41456
41667
|
const content = await readFile46(agentsPath, "utf-8");
|
|
41457
41668
|
const cleaned = removeManagedBlock(
|
|
@@ -41460,17 +41671,17 @@ async function uninstallKimiCode(rootDir) {
|
|
|
41460
41671
|
KIMI_MANCODE_END_MARKER
|
|
41461
41672
|
);
|
|
41462
41673
|
if (cleaned.trim()) {
|
|
41463
|
-
await
|
|
41674
|
+
await writeFile49(agentsPath, `${cleaned}
|
|
41464
41675
|
`, "utf-8");
|
|
41465
41676
|
} else {
|
|
41466
|
-
await
|
|
41677
|
+
await rm22(agentsPath, { force: true });
|
|
41467
41678
|
}
|
|
41468
41679
|
} catch {
|
|
41469
41680
|
}
|
|
41470
41681
|
await removeKimiSkills(rootDir);
|
|
41471
41682
|
}
|
|
41472
41683
|
async function uninstallQoder(rootDir) {
|
|
41473
|
-
const agentsPath =
|
|
41684
|
+
const agentsPath = path68.join(rootDir, "AGENTS.md");
|
|
41474
41685
|
try {
|
|
41475
41686
|
const content = await readFile46(agentsPath, "utf-8");
|
|
41476
41687
|
const cleaned = removeManagedBlock(
|
|
@@ -41479,17 +41690,38 @@ async function uninstallQoder(rootDir) {
|
|
|
41479
41690
|
QODER_MANCODE_END_MARKER
|
|
41480
41691
|
);
|
|
41481
41692
|
if (cleaned.trim()) {
|
|
41482
|
-
await
|
|
41693
|
+
await writeFile49(agentsPath, `${cleaned}
|
|
41483
41694
|
`, "utf-8");
|
|
41484
41695
|
} else {
|
|
41485
|
-
await
|
|
41696
|
+
await rm22(agentsPath, { force: true });
|
|
41486
41697
|
}
|
|
41487
41698
|
} catch {
|
|
41488
41699
|
}
|
|
41489
41700
|
await removeQoderCommands(rootDir);
|
|
41490
41701
|
}
|
|
41702
|
+
async function uninstallDsh(rootDir) {
|
|
41703
|
+
await assertDshAdapterPathsSafe(rootDir);
|
|
41704
|
+
const agentsPath = path68.join(rootDir, "AGENTS.md");
|
|
41705
|
+
try {
|
|
41706
|
+
const content = await readFile46(agentsPath, "utf-8");
|
|
41707
|
+
const cleaned = removeManagedBlock(
|
|
41708
|
+
content,
|
|
41709
|
+
DSH_MANCODE_START_MARKER,
|
|
41710
|
+
DSH_MANCODE_END_MARKER
|
|
41711
|
+
);
|
|
41712
|
+
if (cleaned.trim()) {
|
|
41713
|
+
await writeDshAgentsFile(rootDir, `${cleaned}
|
|
41714
|
+
`);
|
|
41715
|
+
} else {
|
|
41716
|
+
await rm22(agentsPath, { force: true });
|
|
41717
|
+
}
|
|
41718
|
+
} catch {
|
|
41719
|
+
}
|
|
41720
|
+
await assertDshAdapterPathsSafe(rootDir);
|
|
41721
|
+
await removeDshSkills(rootDir);
|
|
41722
|
+
}
|
|
41491
41723
|
async function removeFromConfig(rootDir, platform) {
|
|
41492
|
-
const configPath =
|
|
41724
|
+
const configPath = path68.join(rootDir, ".mancode", "config.json");
|
|
41493
41725
|
try {
|
|
41494
41726
|
const raw = await readFile46(configPath, "utf-8");
|
|
41495
41727
|
const config = JSON.parse(raw);
|
|
@@ -41503,7 +41735,7 @@ async function removeFromConfig(rootDir, platform) {
|
|
|
41503
41735
|
);
|
|
41504
41736
|
config.platformOptions = Object.keys(platformOptions).length > 0 ? platformOptions : void 0;
|
|
41505
41737
|
}
|
|
41506
|
-
await
|
|
41738
|
+
await writeFile49(
|
|
41507
41739
|
configPath,
|
|
41508
41740
|
`${JSON.stringify(config, null, 2)}
|
|
41509
41741
|
`,
|
|
@@ -41560,8 +41792,8 @@ var WORKFLOW_SUBCOMMAND_SET = new Set(
|
|
|
41560
41792
|
var CONTINUITY_COMPATIBILITY_SUBCOMMANDS = /* @__PURE__ */ new Set(["clean"]);
|
|
41561
41793
|
|
|
41562
41794
|
// src/commands/workflow.ts
|
|
41563
|
-
import { access as access6, readFile as readFile48, rm as
|
|
41564
|
-
import
|
|
41795
|
+
import { access as access6, readFile as readFile48, rm as rm24, writeFile as writeFile51 } from "fs/promises";
|
|
41796
|
+
import path70 from "path";
|
|
41565
41797
|
|
|
41566
41798
|
// src/context/child-result-merge.ts
|
|
41567
41799
|
async function mergeV3ChildResult(input) {
|
|
@@ -44753,14 +44985,14 @@ function updateMetadata4(previous, verification, operationId, updatedAt) {
|
|
|
44753
44985
|
|
|
44754
44986
|
// src/context/workflow-create.ts
|
|
44755
44987
|
import {
|
|
44756
|
-
lstat as
|
|
44988
|
+
lstat as lstat27,
|
|
44757
44989
|
mkdir as mkdir41,
|
|
44758
44990
|
readFile as readFile47,
|
|
44759
|
-
rename as
|
|
44760
|
-
rm as
|
|
44761
|
-
writeFile as
|
|
44991
|
+
rename as rename15,
|
|
44992
|
+
rm as rm23,
|
|
44993
|
+
writeFile as writeFile50
|
|
44762
44994
|
} from "fs/promises";
|
|
44763
|
-
import
|
|
44995
|
+
import path69 from "path";
|
|
44764
44996
|
|
|
44765
44997
|
// src/context/creation-resolution.ts
|
|
44766
44998
|
function resolveWorkflowCreation(request) {
|
|
@@ -44870,7 +45102,7 @@ function rejectConflict(provided, expected, label) {
|
|
|
44870
45102
|
|
|
44871
45103
|
// src/context/workflow-create.ts
|
|
44872
45104
|
async function createV3Workflow(input) {
|
|
44873
|
-
const projectRoot =
|
|
45105
|
+
const projectRoot = path69.resolve(requireProjectRoot2(input.projectRoot));
|
|
44874
45106
|
const task = requireText2(input.task, "workflow task");
|
|
44875
45107
|
const client = requireText2(input.client, "workflow client");
|
|
44876
45108
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -45055,8 +45287,8 @@ async function createV3Workflow(input) {
|
|
|
45055
45287
|
throw new Error("MANCODE_REVISION_CONFLICT");
|
|
45056
45288
|
}
|
|
45057
45289
|
const taskParent = await ensureSafeTaskParent3(projectRoot, taskRef);
|
|
45058
|
-
const targetDirectory =
|
|
45059
|
-
stagingDirectory =
|
|
45290
|
+
const targetDirectory = path69.join(taskParent, taskRef.taskId);
|
|
45291
|
+
stagingDirectory = path69.join(
|
|
45060
45292
|
taskParent,
|
|
45061
45293
|
`.${taskRef.taskId}.${operationId}.staging`
|
|
45062
45294
|
);
|
|
@@ -45514,7 +45746,7 @@ async function ensureSafeTaskParent3(projectRoot, taskRef) {
|
|
|
45514
45746
|
const segments = [".mancode", taskRef.namespace, "workflows"];
|
|
45515
45747
|
let current = projectRoot;
|
|
45516
45748
|
for (const segment of segments) {
|
|
45517
|
-
current =
|
|
45749
|
+
current = path69.join(current, segment);
|
|
45518
45750
|
const existing = await lstatOrNull5(current);
|
|
45519
45751
|
if (existing === null) {
|
|
45520
45752
|
await mkdir41(current);
|
|
@@ -45550,13 +45782,13 @@ async function writeStagedEntities(stagingDirectory, entities) {
|
|
|
45550
45782
|
}
|
|
45551
45783
|
async function writeStagedJson(stagingDirectory, fileName, value) {
|
|
45552
45784
|
await assertDirectory(stagingDirectory);
|
|
45553
|
-
const target =
|
|
45554
|
-
await
|
|
45785
|
+
const target = path69.join(stagingDirectory, fileName);
|
|
45786
|
+
await writeFile50(target, `${JSON.stringify(value, null, 2)}
|
|
45555
45787
|
`, {
|
|
45556
45788
|
encoding: "utf8",
|
|
45557
45789
|
flag: "wx"
|
|
45558
45790
|
});
|
|
45559
|
-
const entry = await
|
|
45791
|
+
const entry = await lstat27(target);
|
|
45560
45792
|
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
45561
45793
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
45562
45794
|
}
|
|
@@ -45588,13 +45820,13 @@ async function validateStagedEntities(stagingDirectory) {
|
|
|
45588
45820
|
});
|
|
45589
45821
|
}
|
|
45590
45822
|
async function readStagedJson(stagingDirectory, fileName, parser) {
|
|
45591
|
-
const target =
|
|
45592
|
-
const before = await
|
|
45823
|
+
const target = path69.join(stagingDirectory, fileName);
|
|
45824
|
+
const before = await lstat27(target);
|
|
45593
45825
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
45594
45826
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
45595
45827
|
}
|
|
45596
45828
|
const parsed = parser(JSON.parse(await readFile47(target, "utf8")));
|
|
45597
|
-
const after = await
|
|
45829
|
+
const after = await lstat27(target);
|
|
45598
45830
|
if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
|
|
45599
45831
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
45600
45832
|
}
|
|
@@ -45607,7 +45839,7 @@ async function publishStagedTask(stagingDirectory, targetDirectory) {
|
|
|
45607
45839
|
targetDirectory,
|
|
45608
45840
|
"MANCODE_WORKFLOW_ALREADY_EXISTS"
|
|
45609
45841
|
);
|
|
45610
|
-
await
|
|
45842
|
+
await rename15(stagingDirectory, targetDirectory);
|
|
45611
45843
|
await assertDirectory(targetDirectory);
|
|
45612
45844
|
}
|
|
45613
45845
|
async function advanceJournal(store, previous, stepId, now, canAbort) {
|
|
@@ -45685,18 +45917,18 @@ async function abortPreparedCreate(store, journal, stagingDirectory, now) {
|
|
|
45685
45917
|
{ canAbort: true }
|
|
45686
45918
|
);
|
|
45687
45919
|
} finally {
|
|
45688
|
-
await
|
|
45920
|
+
await rm23(stagingDirectory, { recursive: true, force: true });
|
|
45689
45921
|
}
|
|
45690
45922
|
}
|
|
45691
45923
|
async function assertDirectory(target) {
|
|
45692
|
-
const entry = await
|
|
45924
|
+
const entry = await lstat27(target);
|
|
45693
45925
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
45694
45926
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
45695
45927
|
}
|
|
45696
45928
|
}
|
|
45697
45929
|
async function lstatOrNull5(target) {
|
|
45698
45930
|
try {
|
|
45699
|
-
return await
|
|
45931
|
+
return await lstat27(target);
|
|
45700
45932
|
} catch (error) {
|
|
45701
45933
|
if (isNotFound34(error)) return null;
|
|
45702
45934
|
throw error;
|
|
@@ -46721,7 +46953,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
|
|
|
46721
46953
|
if (v3Activation === "v3_active") {
|
|
46722
46954
|
return workflowV3(rootDir, subcommand, args, options);
|
|
46723
46955
|
}
|
|
46724
|
-
if (!await pathExists16(
|
|
46956
|
+
if (!await pathExists16(path70.join(rootDir, ".mancode", "state.json"))) {
|
|
46725
46957
|
if (v3Activation !== null) {
|
|
46726
46958
|
return printV3Error(
|
|
46727
46959
|
options.json,
|
|
@@ -47804,7 +48036,7 @@ function parseV3ParticipantActorIds(values) {
|
|
|
47804
48036
|
return values;
|
|
47805
48037
|
}
|
|
47806
48038
|
async function readWorkflowInputFile(projectRoot, value) {
|
|
47807
|
-
const inputPath =
|
|
48039
|
+
const inputPath = path70.isAbsolute(value) ? value : path70.resolve(projectRoot, value);
|
|
47808
48040
|
return readFile48(inputPath, "utf8");
|
|
47809
48041
|
}
|
|
47810
48042
|
async function readWorkflowJsonInputFile(projectRoot, value) {
|
|
@@ -47878,12 +48110,12 @@ async function readV3ActivationState2(rootDir) {
|
|
|
47878
48110
|
try {
|
|
47879
48111
|
const manifest = parseSchemaManifest(
|
|
47880
48112
|
JSON.parse(
|
|
47881
|
-
await readFile48(
|
|
48113
|
+
await readFile48(path70.join(rootDir, ".mancode", "schema.json"), "utf8")
|
|
47882
48114
|
)
|
|
47883
48115
|
);
|
|
47884
48116
|
return manifest.activationState === "v3_active" ? "v3_active" : "other";
|
|
47885
48117
|
} catch (error) {
|
|
47886
|
-
if (
|
|
48118
|
+
if (isNodeError11(error) && error.code === "ENOENT") return null;
|
|
47887
48119
|
throw error;
|
|
47888
48120
|
}
|
|
47889
48121
|
}
|
|
@@ -47923,15 +48155,15 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
47923
48155
|
"requirements can only be finalized for an in-progress man or manteam workflow at step 1 or 2"
|
|
47924
48156
|
);
|
|
47925
48157
|
}
|
|
47926
|
-
const workflowPath =
|
|
47927
|
-
const jsonPath =
|
|
47928
|
-
const markdownPath =
|
|
47929
|
-
const metadataPath3 =
|
|
48158
|
+
const workflowPath = path70.join(rootDir, ".mancode", "workflows", taskId);
|
|
48159
|
+
const jsonPath = path70.join(workflowPath, "requirements.json");
|
|
48160
|
+
const markdownPath = path70.join(workflowPath, "requirements.md");
|
|
48161
|
+
const metadataPath3 = path70.join(workflowPath, "metadata.json");
|
|
47930
48162
|
let originalJson;
|
|
47931
48163
|
let originalMarkdown;
|
|
47932
48164
|
let originalMetadata;
|
|
47933
48165
|
try {
|
|
47934
|
-
const inputPath =
|
|
48166
|
+
const inputPath = path70.isAbsolute(options.file) ? options.file : path70.resolve(rootDir, options.file);
|
|
47935
48167
|
const input = await readFile48(inputPath, "utf-8");
|
|
47936
48168
|
const requirements = parseRequirementsLedger2(input);
|
|
47937
48169
|
assertRequirementsScopeConsistent2(requirements);
|
|
@@ -47968,7 +48200,7 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
47968
48200
|
const rollback = await Promise.allSettled([
|
|
47969
48201
|
restoreOptionalText(jsonPath, originalJson),
|
|
47970
48202
|
restoreOptionalText(markdownPath, originalMarkdown),
|
|
47971
|
-
|
|
48203
|
+
writeFile51(metadataPath3, originalMetadata, "utf-8")
|
|
47972
48204
|
]);
|
|
47973
48205
|
rollbackIncomplete = rollback.some(
|
|
47974
48206
|
(result2) => result2.status === "rejected"
|
|
@@ -48056,7 +48288,7 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
48056
48288
|
);
|
|
48057
48289
|
}
|
|
48058
48290
|
if (options.evidenceFile) {
|
|
48059
|
-
const evidencePath =
|
|
48291
|
+
const evidencePath = path70.isAbsolute(options.evidenceFile) ? options.evidenceFile : path70.resolve(rootDir, options.evidenceFile);
|
|
48060
48292
|
if (!await pathExists16(evidencePath)) {
|
|
48061
48293
|
return invalidArg(
|
|
48062
48294
|
options,
|
|
@@ -48116,14 +48348,14 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
48116
48348
|
}
|
|
48117
48349
|
async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
48118
48350
|
const ledgerPath = verificationLedgerPath(rootDir, meta.taskId);
|
|
48119
|
-
const metadataPath3 =
|
|
48351
|
+
const metadataPath3 = path70.join(
|
|
48120
48352
|
rootDir,
|
|
48121
48353
|
".mancode",
|
|
48122
48354
|
"workflows",
|
|
48123
48355
|
meta.taskId,
|
|
48124
48356
|
"metadata.json"
|
|
48125
48357
|
);
|
|
48126
|
-
const specPath =
|
|
48358
|
+
const specPath = path70.join(rootDir, ".mancode", "memory", "spec.md");
|
|
48127
48359
|
const [originalLedger, originalMetadata, originalSpec] = await Promise.all([
|
|
48128
48360
|
readOptionalText2(ledgerPath),
|
|
48129
48361
|
readFile48(metadataPath3, "utf-8"),
|
|
@@ -48155,7 +48387,7 @@ async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
|
48155
48387
|
} catch (error) {
|
|
48156
48388
|
const rollback = await Promise.allSettled([
|
|
48157
48389
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
48158
|
-
|
|
48390
|
+
writeFile51(metadataPath3, originalMetadata, "utf-8"),
|
|
48159
48391
|
restoreOptionalText(specPath, originalSpec)
|
|
48160
48392
|
]);
|
|
48161
48393
|
const message = error instanceof Error ? error.message : "verification transition failed";
|
|
@@ -48287,7 +48519,7 @@ async function workflowReview(rootDir, args, options) {
|
|
|
48287
48519
|
}
|
|
48288
48520
|
async function commitReviewSkip(rootDir, meta, reason) {
|
|
48289
48521
|
const ledgerPath = reviewLedgerPath(rootDir, meta.taskId);
|
|
48290
|
-
const metadataPath3 =
|
|
48522
|
+
const metadataPath3 = path70.join(
|
|
48291
48523
|
rootDir,
|
|
48292
48524
|
".mancode",
|
|
48293
48525
|
"workflows",
|
|
@@ -48307,7 +48539,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
|
|
|
48307
48539
|
} catch (error) {
|
|
48308
48540
|
const rollback = await Promise.allSettled([
|
|
48309
48541
|
restoreOptionalText(ledgerPath, originalLedger),
|
|
48310
|
-
|
|
48542
|
+
writeFile51(metadataPath3, originalMetadata, "utf-8")
|
|
48311
48543
|
]);
|
|
48312
48544
|
const message = error instanceof Error ? error.message : "review skip failed";
|
|
48313
48545
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -48527,14 +48759,14 @@ async function workflowHandoff(rootDir, taskId, options) {
|
|
|
48527
48759
|
"solo handoff requires an undecided in-progress workflow at step 4 with ready requirements"
|
|
48528
48760
|
);
|
|
48529
48761
|
}
|
|
48530
|
-
const workflowPath =
|
|
48531
|
-
if (!await pathExists16(
|
|
48762
|
+
const workflowPath = path70.join(rootDir, ".mancode", "workflows", taskId);
|
|
48763
|
+
if (!await pathExists16(path70.join(workflowPath, "requirements.md")) || !await pathExists16(path70.join(workflowPath, "plan.md"))) {
|
|
48532
48764
|
return invalidArg(
|
|
48533
48765
|
options,
|
|
48534
48766
|
"solo handoff requires requirements.md and plan.md"
|
|
48535
48767
|
);
|
|
48536
48768
|
}
|
|
48537
|
-
const statePath =
|
|
48769
|
+
const statePath = path70.join(rootDir, ".mancode", "state.json");
|
|
48538
48770
|
let originalState;
|
|
48539
48771
|
let state;
|
|
48540
48772
|
try {
|
|
@@ -48609,7 +48841,7 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
|
|
|
48609
48841
|
`workflow is not an active solo handoff: ${taskId}`
|
|
48610
48842
|
);
|
|
48611
48843
|
}
|
|
48612
|
-
const statePath =
|
|
48844
|
+
const statePath = path70.join(rootDir, ".mancode", "state.json");
|
|
48613
48845
|
let originalState;
|
|
48614
48846
|
let state;
|
|
48615
48847
|
try {
|
|
@@ -48676,14 +48908,14 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
48676
48908
|
`workflow is not ready for a plan-only decision: ${taskId}`
|
|
48677
48909
|
);
|
|
48678
48910
|
}
|
|
48679
|
-
const workflowPath =
|
|
48680
|
-
if (!await pathExists16(
|
|
48911
|
+
const workflowPath = path70.join(rootDir, ".mancode", "workflows", taskId);
|
|
48912
|
+
if (!await pathExists16(path70.join(workflowPath, "requirements.md")) || !await pathExists16(path70.join(workflowPath, "plan.md"))) {
|
|
48681
48913
|
return invalidArg(
|
|
48682
48914
|
options,
|
|
48683
48915
|
"plan-only requires requirements.md and plan.md"
|
|
48684
48916
|
);
|
|
48685
48917
|
}
|
|
48686
|
-
const statePath =
|
|
48918
|
+
const statePath = path70.join(rootDir, ".mancode", "state.json");
|
|
48687
48919
|
let originalState;
|
|
48688
48920
|
let state;
|
|
48689
48921
|
try {
|
|
@@ -48739,14 +48971,14 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
48739
48971
|
return EXIT_OK11;
|
|
48740
48972
|
}
|
|
48741
48973
|
async function commitPlanningTransition(args) {
|
|
48742
|
-
const metadataPath3 =
|
|
48974
|
+
const metadataPath3 = path70.join(
|
|
48743
48975
|
args.rootDir,
|
|
48744
48976
|
".mancode",
|
|
48745
48977
|
"workflows",
|
|
48746
48978
|
args.taskId,
|
|
48747
48979
|
"metadata.json"
|
|
48748
48980
|
);
|
|
48749
|
-
const specPath =
|
|
48981
|
+
const specPath = path70.join(args.rootDir, ".mancode", "memory", "spec.md");
|
|
48750
48982
|
let originalMetadata;
|
|
48751
48983
|
let originalSpec;
|
|
48752
48984
|
try {
|
|
@@ -48757,7 +48989,7 @@ async function commitPlanningTransition(args) {
|
|
|
48757
48989
|
}
|
|
48758
48990
|
try {
|
|
48759
48991
|
await updateWorkflow(args.rootDir, args.taskId, args.workflowPatch);
|
|
48760
|
-
await
|
|
48992
|
+
await writeFile51(
|
|
48761
48993
|
args.statePath,
|
|
48762
48994
|
`${JSON.stringify(args.nextState, null, 2)}
|
|
48763
48995
|
`,
|
|
@@ -48771,9 +49003,9 @@ async function commitPlanningTransition(args) {
|
|
|
48771
49003
|
return null;
|
|
48772
49004
|
} catch (error) {
|
|
48773
49005
|
const rollback = await Promise.allSettled([
|
|
48774
|
-
|
|
48775
|
-
|
|
48776
|
-
originalSpec === null ?
|
|
49006
|
+
writeFile51(metadataPath3, originalMetadata, "utf-8"),
|
|
49007
|
+
writeFile51(args.statePath, args.originalState, "utf-8"),
|
|
49008
|
+
originalSpec === null ? rm24(specPath, { force: true }) : writeFile51(specPath, originalSpec, "utf-8")
|
|
48777
49009
|
]);
|
|
48778
49010
|
const message = error instanceof Error ? error.message : "planning transition failed";
|
|
48779
49011
|
return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
|
|
@@ -48783,16 +49015,16 @@ async function readOptionalText2(filePath) {
|
|
|
48783
49015
|
try {
|
|
48784
49016
|
return await readFile48(filePath, "utf-8");
|
|
48785
49017
|
} catch (error) {
|
|
48786
|
-
if (
|
|
49018
|
+
if (isNodeError11(error) && error.code === "ENOENT") return null;
|
|
48787
49019
|
throw error;
|
|
48788
49020
|
}
|
|
48789
49021
|
}
|
|
48790
49022
|
async function restoreOptionalText(filePath, content) {
|
|
48791
49023
|
if (content === null) {
|
|
48792
|
-
await
|
|
49024
|
+
await rm24(filePath, { force: true });
|
|
48793
49025
|
return;
|
|
48794
49026
|
}
|
|
48795
|
-
await
|
|
49027
|
+
await writeFile51(filePath, content, "utf-8");
|
|
48796
49028
|
}
|
|
48797
49029
|
function readActiveSoloPlan(value) {
|
|
48798
49030
|
if (!value || typeof value !== "object") return null;
|
|
@@ -48802,7 +49034,7 @@ function readActiveSoloPlan(value) {
|
|
|
48802
49034
|
}
|
|
48803
49035
|
return { taskId: plan.taskId, planVersion: plan.planVersion };
|
|
48804
49036
|
}
|
|
48805
|
-
function
|
|
49037
|
+
function isNodeError11(error) {
|
|
48806
49038
|
return error instanceof Error && "code" in error;
|
|
48807
49039
|
}
|
|
48808
49040
|
async function workflowList(rootDir, options) {
|
|
@@ -49060,7 +49292,7 @@ function createCliProgram() {
|
|
|
49060
49292
|
process.exitCode = code;
|
|
49061
49293
|
});
|
|
49062
49294
|
program.command("install [platform]").description(
|
|
49063
|
-
"Install platform adapter (claude-code, cursor, codex, copilot, zcode, kimi-code, qoder)"
|
|
49295
|
+
"Install platform adapter (claude-code, cursor, codex, copilot, zcode, kimi-code, qoder, dsh)"
|
|
49064
49296
|
).option("--force", "Reinstall even if already installed").option(
|
|
49065
49297
|
"--minimal",
|
|
49066
49298
|
"Retained for legacy compatibility; Continuity bootstrap is already minimal"
|
|
@@ -49179,7 +49411,7 @@ Public Continuity subcommands:
|
|
|
49179
49411
|
"Record real-host session evidence without persisting host keys"
|
|
49180
49412
|
).requiredOption(
|
|
49181
49413
|
"--platform <platform>",
|
|
49182
|
-
"claude-code, codex, cursor, copilot, zcode, kimi-code, or
|
|
49414
|
+
"claude-code, codex, cursor, copilot, zcode, kimi-code, qoder, or dsh"
|
|
49183
49415
|
).requiredOption("--session-mode <mode>", "Evidence path: host or explicit").requiredOption(
|
|
49184
49416
|
"--host-session-source <source>",
|
|
49185
49417
|
"hook_stdin, environment, api, or none for explicit sessions"
|