mancode 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +3 -3
- package/README.md +3 -3
- package/dist/{chunk-NG72XZ3R.js → chunk-7HPP3KYG.js} +1 -11
- package/dist/{chunk-NG72XZ3R.js.map → chunk-7HPP3KYG.js.map} +1 -1
- package/dist/{chunk-RDPFQODS.js → chunk-WJ6WARGG.js} +495 -250
- package/dist/chunk-WJ6WARGG.js.map +1 -0
- package/dist/cli.js +2709 -1004
- package/dist/cli.js.map +1 -1
- package/dist/{store-C3G3HN3N.js → store-LN63OL66.js} +2 -2
- package/dist/{v3-adapter-7KIOYYWS.js → v3-adapter-T3IKK3LU.js} +4 -2
- package/package.json +1 -1
- package/dist/chunk-RDPFQODS.js.map +0 -1
- /package/dist/{store-C3G3HN3N.js.map → store-LN63OL66.js.map} +0 -0
- /package/dist/{v3-adapter-7KIOYYWS.js.map → v3-adapter-T3IKK3LU.js.map} +0 -0
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
lstat,
|
|
5
5
|
mkdir,
|
|
6
6
|
readFile,
|
|
7
|
+
readlink,
|
|
7
8
|
realpath,
|
|
8
9
|
rename,
|
|
9
10
|
rm,
|
|
@@ -289,17 +290,348 @@ function adapterManagedContentDigest(targetIdentity, managedContent) {
|
|
|
289
290
|
return `sha256:${digest}`;
|
|
290
291
|
}
|
|
291
292
|
async function planV3AdapterFiles(projectRoot) {
|
|
293
|
+
return planPhysicalAdapterTargets(
|
|
294
|
+
path.resolve(projectRoot),
|
|
295
|
+
V3_ADAPTER_FILE_TARGETS,
|
|
296
|
+
V3_ADAPTER_PLATFORMS
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
async function planV3AdapterUpgradeFiles(projectRoot, platforms) {
|
|
292
300
|
const root = path.resolve(projectRoot);
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
301
|
+
const selected = normalizeUpgradePlatforms(platforms);
|
|
302
|
+
const targets = /* @__PURE__ */ new Set();
|
|
303
|
+
for (const platform of selected) {
|
|
304
|
+
targets.add(primaryFileTarget(platform));
|
|
305
|
+
for (const mode of V3_MODE_NAMES) {
|
|
306
|
+
targets.add(modeEntryFileTarget(platform, mode));
|
|
307
|
+
}
|
|
308
|
+
for (const target of legacyAdapterTargetsForPlatform(platform, true)) {
|
|
309
|
+
targets.add(target);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return planPhysicalAdapterTargets(root, [...targets], selected);
|
|
313
|
+
}
|
|
314
|
+
async function planPhysicalAdapterTargets(root, targets, platforms) {
|
|
315
|
+
const ordered = orderAdapterTargets(targets);
|
|
316
|
+
const observations = await Promise.all(
|
|
317
|
+
ordered.map((target) => observeAdapterPhysicalTarget(root, target))
|
|
318
|
+
);
|
|
319
|
+
const groups = /* @__PURE__ */ new Map();
|
|
320
|
+
for (const observation of observations) {
|
|
321
|
+
const group = groups.get(observation.physicalKey) ?? [];
|
|
322
|
+
group.push(observation);
|
|
323
|
+
groups.set(observation.physicalKey, group);
|
|
324
|
+
}
|
|
325
|
+
const plans = [];
|
|
326
|
+
for (const group of groups.values()) {
|
|
327
|
+
const members = group.sort(
|
|
328
|
+
(left, right) => adapterTargetOrder(left.target) - adapterTargetOrder(right.target)
|
|
329
|
+
);
|
|
330
|
+
assertPhysicalGroupComposable(members);
|
|
331
|
+
const beforeContent = members[0]?.beforeContent ?? null;
|
|
332
|
+
if (members.some((member) => member.beforeContent !== beforeContent)) {
|
|
333
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
334
|
+
}
|
|
335
|
+
const targetContent = composePhysicalAdapterContent(
|
|
336
|
+
beforeContent,
|
|
337
|
+
members,
|
|
338
|
+
platforms
|
|
339
|
+
);
|
|
340
|
+
if (targetContent === null || targetContent === beforeContent) continue;
|
|
341
|
+
const representative = members.find((member) => member.target === "agents") ?? members[0];
|
|
342
|
+
if (representative === void 0) continue;
|
|
343
|
+
const links = uniqueLinkIdentities(
|
|
344
|
+
members.flatMap((member) => member.linkIdentities)
|
|
345
|
+
);
|
|
346
|
+
plans.push({
|
|
347
|
+
target: representative.target,
|
|
348
|
+
beforeContent,
|
|
349
|
+
targetContent,
|
|
350
|
+
...links.length > 0 ? {
|
|
351
|
+
resolvedTarget: representative.physicalRelative,
|
|
352
|
+
linkIdentities: links
|
|
353
|
+
} : {}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return plans.sort(
|
|
357
|
+
(left, right) => adapterTargetOrder(left.target) - adapterTargetOrder(right.target)
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
function orderAdapterTargets(targets) {
|
|
361
|
+
return [...new Set(targets)].sort(
|
|
362
|
+
(left, right) => adapterTargetOrder(left) - adapterTargetOrder(right)
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
function adapterTargetOrder(target) {
|
|
366
|
+
const index = V3_ADAPTER_FILE_TARGETS.indexOf(target);
|
|
367
|
+
return index < 0 ? Number.MAX_SAFE_INTEGER : index;
|
|
368
|
+
}
|
|
369
|
+
async function observeAdapterPhysicalTarget(root, target) {
|
|
370
|
+
const logicalPath = v3AdapterTargetPath(root, target);
|
|
371
|
+
const entry = await lstatOrNullAdapter(logicalPath);
|
|
372
|
+
if (entry === null) {
|
|
373
|
+
await assertAdapterPathSafe(root, logicalPath);
|
|
374
|
+
return {
|
|
375
|
+
target,
|
|
376
|
+
logicalPath,
|
|
377
|
+
physicalRelative: relativeAdapterPath(root, logicalPath),
|
|
378
|
+
physicalKey: `path:${relativeAdapterPath(root, logicalPath)}`,
|
|
379
|
+
beforeContent: null,
|
|
380
|
+
linkIdentities: []
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
if (entry.isSymbolicLink()) {
|
|
384
|
+
const resolved2 = await resolveObservedAdapterSymlinkChain(
|
|
385
|
+
root,
|
|
386
|
+
logicalPath
|
|
387
|
+
);
|
|
388
|
+
const physicalRelative2 = normalizeAdapterRelativePath(resolved2.relative);
|
|
389
|
+
return {
|
|
390
|
+
target,
|
|
391
|
+
logicalPath,
|
|
392
|
+
physicalRelative: physicalRelative2,
|
|
393
|
+
physicalKey: physicalFileKey(resolved2.entry),
|
|
394
|
+
beforeContent: await readFile(resolved2.path, "utf8"),
|
|
395
|
+
linkIdentities: resolved2.linkIdentities
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
if (!entry.isFile()) {
|
|
399
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
400
|
+
}
|
|
401
|
+
const resolved = await realpath(logicalPath);
|
|
402
|
+
const resolvedRelative = await relativeWithinRealRoot(root, resolved);
|
|
403
|
+
if (resolvedRelative === null) {
|
|
404
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
405
|
+
}
|
|
406
|
+
const resolvedEntry = await lstat(resolved);
|
|
407
|
+
if (!resolvedEntry.isFile() || resolvedEntry.isSymbolicLink()) {
|
|
408
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
409
|
+
}
|
|
410
|
+
const physicalRelative = normalizeAdapterRelativePath(resolvedRelative);
|
|
411
|
+
return {
|
|
412
|
+
target,
|
|
413
|
+
logicalPath,
|
|
414
|
+
physicalRelative,
|
|
415
|
+
physicalKey: physicalFileKey(resolvedEntry),
|
|
416
|
+
beforeContent: await readFile(resolved, "utf8"),
|
|
417
|
+
linkIdentities: []
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
async function resolveObservedAdapterSymlinkChain(root, logicalPath) {
|
|
421
|
+
let current = path.resolve(logicalPath);
|
|
422
|
+
const seen = /* @__PURE__ */ new Set();
|
|
423
|
+
const linkIdentities = [];
|
|
424
|
+
for (let depth = 0; depth < 40; depth += 1) {
|
|
425
|
+
if (!isPathInsideRoot(root, current) || seen.has(current)) {
|
|
426
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
427
|
+
}
|
|
428
|
+
seen.add(current);
|
|
429
|
+
const entry = await lstatOrNullAdapter(current);
|
|
430
|
+
if (entry === null) throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
431
|
+
if (!entry.isSymbolicLink()) {
|
|
432
|
+
if (!entry.isFile()) throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
433
|
+
const resolved = await realpath(current);
|
|
434
|
+
const relative = await relativeWithinRealRoot(root, resolved);
|
|
435
|
+
if (relative === null || entry.nlink > 1) {
|
|
436
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
437
|
+
}
|
|
438
|
+
return { path: resolved, relative, entry, linkIdentities };
|
|
439
|
+
}
|
|
440
|
+
const linkTarget = await readlink(current, "utf8");
|
|
441
|
+
linkIdentities.push({
|
|
442
|
+
linkPath: relativeAdapterPath(root, current),
|
|
443
|
+
linkTarget
|
|
444
|
+
});
|
|
445
|
+
current = path.resolve(path.dirname(current), linkTarget);
|
|
446
|
+
}
|
|
447
|
+
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
448
|
+
}
|
|
449
|
+
function physicalFileKey(entry) {
|
|
450
|
+
if (entry.nlink > 1) {
|
|
451
|
+
throw new Error("MANCODE_V3_ADAPTER_HARDLINK_UNSAFE");
|
|
452
|
+
}
|
|
453
|
+
return `inode:${entry.dev}:${entry.ino}`;
|
|
454
|
+
}
|
|
455
|
+
function uniqueLinkIdentities(identities) {
|
|
456
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
457
|
+
for (const identity of identities) {
|
|
458
|
+
const previous = byPath.get(identity.linkPath);
|
|
459
|
+
if (previous !== void 0 && previous.linkTarget !== identity.linkTarget) {
|
|
460
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
461
|
+
}
|
|
462
|
+
byPath.set(identity.linkPath, identity);
|
|
463
|
+
}
|
|
464
|
+
return [...byPath.values()].sort(
|
|
465
|
+
(left, right) => compareUtf8(left.linkPath, right.linkPath)
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
function isPathInsideRoot(root, candidate) {
|
|
469
|
+
const relative = path.relative(root, candidate);
|
|
470
|
+
return Boolean(relative) && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
471
|
+
}
|
|
472
|
+
function normalizeAdapterRelativePath(value) {
|
|
473
|
+
return value.split(path.sep).join("/");
|
|
474
|
+
}
|
|
475
|
+
function compareUtf8(left, right) {
|
|
476
|
+
return Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"));
|
|
477
|
+
}
|
|
478
|
+
async function lstatOrNullAdapter(target) {
|
|
479
|
+
try {
|
|
480
|
+
return await lstat(target);
|
|
481
|
+
} catch (error) {
|
|
482
|
+
if (isNodeError(error) && error.code === "ENOENT") return null;
|
|
483
|
+
throw error;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function assertPhysicalGroupComposable(group) {
|
|
487
|
+
if (group.length <= 1) return;
|
|
488
|
+
if (group.every((member) => isComposableEmbeddedAdapterTarget(member.target))) {
|
|
489
|
+
return;
|
|
296
490
|
}
|
|
491
|
+
throw new Error("MANCODE_V3_ADAPTER_SHARED_TARGET_CONFLICT");
|
|
492
|
+
}
|
|
493
|
+
function composePhysicalAdapterContent(beforeContent, members, platforms) {
|
|
494
|
+
const memberTargets = new Set(members.map((member) => member.target));
|
|
495
|
+
let content = beforeContent;
|
|
496
|
+
for (const platform of platforms) {
|
|
497
|
+
const primary = primaryFileTarget(platform);
|
|
498
|
+
if (!memberTargets.has(primary)) continue;
|
|
499
|
+
content = applyPrimaryBootstrapContent(content, platform);
|
|
500
|
+
}
|
|
501
|
+
for (const member of members) {
|
|
502
|
+
if (isPrimaryAdapterTarget(member.target)) continue;
|
|
503
|
+
content = desiredAdapterTargetContent(member.target, content);
|
|
504
|
+
}
|
|
505
|
+
return content;
|
|
506
|
+
}
|
|
507
|
+
function isPrimaryAdapterTarget(target) {
|
|
508
|
+
return target === "claude-skill" || target === "cursor-rule" || target === "agents" || target === "copilot-instructions";
|
|
509
|
+
}
|
|
510
|
+
function applyPrimaryBootstrapContent(current, platform) {
|
|
511
|
+
switch (platform) {
|
|
512
|
+
case "claude-code":
|
|
513
|
+
return replaceManagedV3BlockText(
|
|
514
|
+
current ?? "",
|
|
515
|
+
CONTINUITY_CLAUDE_START_MARKER,
|
|
516
|
+
CONTINUITY_CLAUDE_END_MARKER,
|
|
517
|
+
renderV3Bootstrap(platform)
|
|
518
|
+
);
|
|
519
|
+
case "cursor":
|
|
520
|
+
return managedFilePlan(
|
|
521
|
+
"cursor-rule",
|
|
522
|
+
current,
|
|
523
|
+
renderCursorRule(renderV3Bootstrap(platform))
|
|
524
|
+
).targetContent;
|
|
525
|
+
case "codex":
|
|
526
|
+
return replaceManagedV3BlockText(
|
|
527
|
+
removeLegacyV3Block(
|
|
528
|
+
removeLegacyAgentsBlocks(current ?? ""),
|
|
529
|
+
LEGACY_V3_CODEX_MARKERS
|
|
530
|
+
),
|
|
531
|
+
V3_CODEX_START_MARKER,
|
|
532
|
+
V3_CODEX_END_MARKER,
|
|
533
|
+
renderV3Bootstrap(platform)
|
|
534
|
+
);
|
|
535
|
+
case "zcode":
|
|
536
|
+
return replaceManagedV3BlockText(
|
|
537
|
+
removeLegacyV3Block(
|
|
538
|
+
removeLegacyAgentsBlocks(current ?? ""),
|
|
539
|
+
LEGACY_V3_ZCODE_MARKERS
|
|
540
|
+
),
|
|
541
|
+
V3_ZCODE_START_MARKER,
|
|
542
|
+
V3_ZCODE_END_MARKER,
|
|
543
|
+
renderV3Bootstrap(platform)
|
|
544
|
+
);
|
|
545
|
+
case "kimi-code":
|
|
546
|
+
return replaceManagedV3BlockText(
|
|
547
|
+
removeLegacyV3Block(
|
|
548
|
+
removeLegacyAgentsBlocks(current ?? ""),
|
|
549
|
+
LEGACY_KIMI_MARKERS
|
|
550
|
+
),
|
|
551
|
+
V3_KIMI_START_MARKER,
|
|
552
|
+
V3_KIMI_END_MARKER,
|
|
553
|
+
renderV3Bootstrap(platform)
|
|
554
|
+
);
|
|
555
|
+
case "qoder":
|
|
556
|
+
return replaceManagedV3BlockText(
|
|
557
|
+
removeLegacyV3Block(current ?? "", LEGACY_QODER_MARKERS),
|
|
558
|
+
V3_QODER_START_MARKER,
|
|
559
|
+
V3_QODER_END_MARKER,
|
|
560
|
+
renderV3Bootstrap(platform)
|
|
561
|
+
);
|
|
562
|
+
case "dsh":
|
|
563
|
+
return replaceManagedV3BlockText(
|
|
564
|
+
removeLegacyV3Block(current ?? "", LEGACY_DSH_MARKERS),
|
|
565
|
+
V3_DSH_START_MARKER,
|
|
566
|
+
V3_DSH_END_MARKER,
|
|
567
|
+
renderV3Bootstrap(platform)
|
|
568
|
+
);
|
|
569
|
+
case "copilot":
|
|
570
|
+
return replaceManagedV3BlockText(
|
|
571
|
+
removeLegacyV3Block(
|
|
572
|
+
removeManagedBlock(current ?? ""),
|
|
573
|
+
LEGACY_V3_COPILOT_MARKERS
|
|
574
|
+
),
|
|
575
|
+
V3_COPILOT_START_MARKER,
|
|
576
|
+
V3_COPILOT_END_MARKER,
|
|
577
|
+
renderV3Bootstrap(platform)
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
function isComposableEmbeddedAdapterTarget(target) {
|
|
582
|
+
return target === "claude-skill" || target === "agents" || target === "copilot-instructions";
|
|
583
|
+
}
|
|
584
|
+
function desiredAdapterTargetContent(target, current) {
|
|
585
|
+
switch (target) {
|
|
586
|
+
case "claude-skill":
|
|
587
|
+
return replaceManagedV3BlockText(
|
|
588
|
+
current ?? "",
|
|
589
|
+
CONTINUITY_CLAUDE_START_MARKER,
|
|
590
|
+
CONTINUITY_CLAUDE_END_MARKER,
|
|
591
|
+
renderV3Bootstrap("claude-code")
|
|
592
|
+
);
|
|
593
|
+
case "cursor-rule":
|
|
594
|
+
return managedFilePlan(
|
|
595
|
+
target,
|
|
596
|
+
current,
|
|
597
|
+
renderCursorRule(renderV3Bootstrap("cursor"))
|
|
598
|
+
).targetContent;
|
|
599
|
+
case "agents":
|
|
600
|
+
return renderAgentsBootstrapTarget(current ?? "");
|
|
601
|
+
case "copilot-instructions":
|
|
602
|
+
return replaceManagedV3BlockText(
|
|
603
|
+
removeLegacyV3Block(
|
|
604
|
+
removeManagedBlock(current ?? ""),
|
|
605
|
+
LEGACY_V3_COPILOT_MARKERS
|
|
606
|
+
),
|
|
607
|
+
V3_COPILOT_START_MARKER,
|
|
608
|
+
V3_COPILOT_END_MARKER,
|
|
609
|
+
renderV3Bootstrap("copilot")
|
|
610
|
+
);
|
|
611
|
+
default: {
|
|
612
|
+
const modeTarget = parseModeEntryFileTarget(target);
|
|
613
|
+
if (modeTarget !== null) {
|
|
614
|
+
const modeFileTarget = target;
|
|
615
|
+
return managedModeEntryPlan(
|
|
616
|
+
modeFileTarget,
|
|
617
|
+
current,
|
|
618
|
+
renderModeEntryForFileTarget(modeFileTarget)
|
|
619
|
+
).targetContent;
|
|
620
|
+
}
|
|
621
|
+
const retirement = planLegacyAdapterRetirement(
|
|
622
|
+
/* @__PURE__ */ new Map([[target, current]])
|
|
623
|
+
).find((plan) => plan.target === target);
|
|
624
|
+
return retirement?.targetContent ?? current;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function renderAgentsBootstrapTarget(existing) {
|
|
297
629
|
const agents = removeLegacyV3Block(
|
|
298
630
|
removeLegacyV3Block(
|
|
299
631
|
removeLegacyV3Block(
|
|
300
632
|
removeLegacyV3Block(
|
|
301
633
|
removeLegacyV3Block(
|
|
302
|
-
removeLegacyAgentsBlocks(existing
|
|
634
|
+
removeLegacyAgentsBlocks(existing),
|
|
303
635
|
LEGACY_V3_CODEX_MARKERS
|
|
304
636
|
),
|
|
305
637
|
LEGACY_V3_ZCODE_MARKERS
|
|
@@ -310,7 +642,7 @@ async function planV3AdapterFiles(projectRoot) {
|
|
|
310
642
|
),
|
|
311
643
|
LEGACY_DSH_MARKERS
|
|
312
644
|
);
|
|
313
|
-
|
|
645
|
+
return replaceManagedV3BlockText(
|
|
314
646
|
replaceManagedV3BlockText(
|
|
315
647
|
replaceManagedV3BlockText(
|
|
316
648
|
replaceManagedV3BlockText(
|
|
@@ -336,125 +668,6 @@ async function planV3AdapterFiles(projectRoot) {
|
|
|
336
668
|
V3_DSH_END_MARKER,
|
|
337
669
|
renderV3Bootstrap("dsh")
|
|
338
670
|
);
|
|
339
|
-
const legacyAdapterPlans = planLegacyAdapterRetirement(existing);
|
|
340
|
-
const plans = [
|
|
341
|
-
{
|
|
342
|
-
target: "claude-skill",
|
|
343
|
-
beforeContent: existing.get("claude-skill") ?? null,
|
|
344
|
-
targetContent: replaceManagedV3BlockText(
|
|
345
|
-
existing.get("claude-skill") ?? "",
|
|
346
|
-
CONTINUITY_CLAUDE_START_MARKER,
|
|
347
|
-
CONTINUITY_CLAUDE_END_MARKER,
|
|
348
|
-
renderV3Bootstrap("claude-code")
|
|
349
|
-
)
|
|
350
|
-
},
|
|
351
|
-
managedFilePlan(
|
|
352
|
-
"cursor-rule",
|
|
353
|
-
existing.get("cursor-rule") ?? null,
|
|
354
|
-
renderCursorRule(renderV3Bootstrap("cursor"))
|
|
355
|
-
),
|
|
356
|
-
{
|
|
357
|
-
target: "agents",
|
|
358
|
-
beforeContent: existing.get("agents") ?? null,
|
|
359
|
-
targetContent: nextAgents
|
|
360
|
-
},
|
|
361
|
-
{
|
|
362
|
-
target: "copilot-instructions",
|
|
363
|
-
beforeContent: existing.get("copilot-instructions") ?? null,
|
|
364
|
-
targetContent: replaceManagedV3BlockText(
|
|
365
|
-
removeLegacyV3Block(
|
|
366
|
-
removeManagedBlock(existing.get("copilot-instructions") ?? ""),
|
|
367
|
-
LEGACY_V3_COPILOT_MARKERS
|
|
368
|
-
),
|
|
369
|
-
V3_COPILOT_START_MARKER,
|
|
370
|
-
V3_COPILOT_END_MARKER,
|
|
371
|
-
renderV3Bootstrap("copilot")
|
|
372
|
-
)
|
|
373
|
-
},
|
|
374
|
-
...V3_MODE_ENTRY_FILE_TARGETS.map(
|
|
375
|
-
(target) => managedModeEntryPlan(
|
|
376
|
-
target,
|
|
377
|
-
existing.get(target) ?? null,
|
|
378
|
-
renderModeEntryForFileTarget(target)
|
|
379
|
-
)
|
|
380
|
-
),
|
|
381
|
-
...legacyAdapterPlans
|
|
382
|
-
];
|
|
383
|
-
return annotateWriteThroughPlans(root, plans);
|
|
384
|
-
}
|
|
385
|
-
async function annotateWriteThroughPlans(root, plans) {
|
|
386
|
-
return Promise.all(
|
|
387
|
-
plans.map(async (plan) => {
|
|
388
|
-
const resolved = await writeThroughResolvedPath(
|
|
389
|
-
root,
|
|
390
|
-
v3AdapterTargetPath(root, plan.target)
|
|
391
|
-
);
|
|
392
|
-
if (resolved === null) return plan;
|
|
393
|
-
const relative = await relativeWithinRealRoot(root, resolved);
|
|
394
|
-
if (relative === null) return plan;
|
|
395
|
-
return { ...plan, resolvedTarget: relative };
|
|
396
|
-
})
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
async function effectivePrimaryTarget(root, platform) {
|
|
400
|
-
const primary = primaryFileTarget(platform);
|
|
401
|
-
const resolved = await writeThroughResolvedPath(
|
|
402
|
-
root,
|
|
403
|
-
v3AdapterTargetPath(root, primary)
|
|
404
|
-
);
|
|
405
|
-
if (resolved === null) return primary;
|
|
406
|
-
const agentsPath = v3AdapterTargetPath(root, "agents");
|
|
407
|
-
const realAgents = await resolveAdapterSymlink(agentsPath);
|
|
408
|
-
if (realAgents !== null && path.resolve(resolved) === path.resolve(realAgents)) {
|
|
409
|
-
return "agents";
|
|
410
|
-
}
|
|
411
|
-
return primary;
|
|
412
|
-
}
|
|
413
|
-
async function planV3AdapterUpgradeFiles(projectRoot, platforms) {
|
|
414
|
-
const root = path.resolve(projectRoot);
|
|
415
|
-
const selected = normalizeUpgradePlatforms(platforms);
|
|
416
|
-
const targetSet = /* @__PURE__ */ new Set();
|
|
417
|
-
const effectivePrimary = /* @__PURE__ */ new Map();
|
|
418
|
-
for (const platform of selected) {
|
|
419
|
-
const primary = await effectivePrimaryTarget(root, platform);
|
|
420
|
-
effectivePrimary.set(platform, primary);
|
|
421
|
-
targetSet.add(primary);
|
|
422
|
-
for (const mode of V3_MODE_NAMES) {
|
|
423
|
-
targetSet.add(modeEntryFileTarget(platform, mode));
|
|
424
|
-
}
|
|
425
|
-
for (const target of legacyAdapterTargetsForPlatform(platform, true)) {
|
|
426
|
-
targetSet.add(target);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
const existing = /* @__PURE__ */ new Map();
|
|
430
|
-
for (const target of targetSet) {
|
|
431
|
-
existing.set(target, await readAdapterTarget(root, target));
|
|
432
|
-
}
|
|
433
|
-
const desired = new Map(existing);
|
|
434
|
-
for (const platform of selected) {
|
|
435
|
-
planPlatformBootstrapUpgrade(
|
|
436
|
-
desired,
|
|
437
|
-
platform,
|
|
438
|
-
effectivePrimary.get(platform)
|
|
439
|
-
);
|
|
440
|
-
for (const mode of V3_MODE_NAMES) {
|
|
441
|
-
const target = modeEntryFileTarget(platform, mode);
|
|
442
|
-
const current = desired.get(target) ?? null;
|
|
443
|
-
desired.set(
|
|
444
|
-
target,
|
|
445
|
-
managedModeEntryPlan(target, current, renderV3ModeEntry(mode, platform)).targetContent
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
const plans = [...desired.entries()].filter(([target, targetContent]) => existing.get(target) !== targetContent).map(([target, targetContent]) => ({
|
|
450
|
-
target,
|
|
451
|
-
beforeContent: existing.get(target) ?? null,
|
|
452
|
-
targetContent: targetContent ?? ""
|
|
453
|
-
}));
|
|
454
|
-
const legacyPlans = planLegacyAdapterRetirement(existing).filter(
|
|
455
|
-
(legacyPlan) => !plans.some((candidate) => candidate.target === legacyPlan.target)
|
|
456
|
-
);
|
|
457
|
-
return annotateWriteThroughPlans(root, [...plans, ...legacyPlans]);
|
|
458
671
|
}
|
|
459
672
|
async function stageV3AdapterUpgradeFiles(projectRoot, operationId, plans) {
|
|
460
673
|
if (!/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/.test(operationId)) {
|
|
@@ -493,18 +706,7 @@ async function applyV3AdapterFilePlan(projectRoot, plan) {
|
|
|
493
706
|
throw new Error("MANCODE_V3_ADAPTER_TARGET_INVALID");
|
|
494
707
|
}
|
|
495
708
|
const target = v3AdapterTargetPath(root, plan.target);
|
|
496
|
-
const writePath =
|
|
497
|
-
if (plan.resolvedTarget !== void 0) {
|
|
498
|
-
const entry = await lstat(target).catch(() => null);
|
|
499
|
-
const resolved = entry?.isSymbolicLink() === true ? await resolveAdapterSymlink(target) : null;
|
|
500
|
-
const realWrite = await resolveAdapterSymlink(writePath);
|
|
501
|
-
if (resolved === null || realWrite === null || resolved !== realWrite) {
|
|
502
|
-
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
503
|
-
}
|
|
504
|
-
await assertAdapterPathSafe(root, writePath);
|
|
505
|
-
} else {
|
|
506
|
-
await assertAdapterPathSafe(root, target);
|
|
507
|
-
}
|
|
709
|
+
const writePath = await resolvePlannedAdapterWritePath(root, target, plan);
|
|
508
710
|
const retiredBootstrapPlatform = retiredBootstrapPlatformFor(plan.target);
|
|
509
711
|
if (retiredBootstrapPlatform !== null) {
|
|
510
712
|
for (const retired of retiredBootstrapSpecs(
|
|
@@ -514,7 +716,10 @@ async function applyV3AdapterFilePlan(projectRoot, plan) {
|
|
|
514
716
|
await assertAdapterPathSafe(root, retired.filePath);
|
|
515
717
|
}
|
|
516
718
|
}
|
|
517
|
-
const current = await
|
|
719
|
+
const current = await readFile(writePath, "utf8").catch((error) => {
|
|
720
|
+
if (isNodeError(error) && error.code === "ENOENT") return null;
|
|
721
|
+
throw error;
|
|
722
|
+
});
|
|
518
723
|
if (current === plan.targetContent) {
|
|
519
724
|
if (retiredBootstrapPlatform !== null) {
|
|
520
725
|
await removeRetiredBootstrapFiles(root, retiredBootstrapPlatform);
|
|
@@ -524,12 +729,123 @@ async function applyV3AdapterFilePlan(projectRoot, plan) {
|
|
|
524
729
|
if (current !== plan.beforeContent) {
|
|
525
730
|
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
526
731
|
}
|
|
732
|
+
const verifiedWritePath = await resolvePlannedAdapterWritePath(
|
|
733
|
+
root,
|
|
734
|
+
target,
|
|
735
|
+
plan
|
|
736
|
+
);
|
|
737
|
+
if (!await sameResolvedPath(verifiedWritePath, writePath)) {
|
|
738
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
739
|
+
}
|
|
527
740
|
await mkdir(path.dirname(writePath), { recursive: true });
|
|
528
741
|
await atomicWrite(writePath, plan.targetContent);
|
|
529
742
|
if (retiredBootstrapPlatform !== null) {
|
|
530
743
|
await removeRetiredBootstrapFiles(root, retiredBootstrapPlatform);
|
|
531
744
|
}
|
|
532
745
|
}
|
|
746
|
+
async function resolvePlannedAdapterWritePath(root, logicalTarget, plan) {
|
|
747
|
+
await assertAdapterPathSafe(root, logicalTarget);
|
|
748
|
+
if (plan.resolvedTarget === void 0) {
|
|
749
|
+
if (plan.linkIdentities !== void 0 && plan.linkIdentities.length > 0) {
|
|
750
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
751
|
+
}
|
|
752
|
+
const entry = await lstatOrNullAdapter(logicalTarget);
|
|
753
|
+
if (entry?.isSymbolicLink()) {
|
|
754
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
755
|
+
}
|
|
756
|
+
if (entry !== null && (!entry.isFile() || entry.nlink > 1)) {
|
|
757
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
758
|
+
}
|
|
759
|
+
return logicalTarget;
|
|
760
|
+
}
|
|
761
|
+
if (plan.linkIdentities !== void 0 && plan.linkIdentities.length === 0) {
|
|
762
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
763
|
+
}
|
|
764
|
+
const resolvedTarget = safePlannedRelativePath(root, plan.resolvedTarget);
|
|
765
|
+
await assertAdapterPathSafe(root, resolvedTarget);
|
|
766
|
+
const resolvedEntry = await lstatOrNullAdapter(resolvedTarget);
|
|
767
|
+
if (resolvedEntry === null || !resolvedEntry.isFile() || resolvedEntry.isSymbolicLink() || resolvedEntry.nlink > 1) {
|
|
768
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
769
|
+
}
|
|
770
|
+
if (plan.linkIdentities === void 0) {
|
|
771
|
+
const logicalEntry2 = await lstatOrNullAdapter(logicalTarget);
|
|
772
|
+
if (!logicalEntry2?.isSymbolicLink() || !await sameResolvedPath(logicalTarget, resolvedTarget)) {
|
|
773
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
774
|
+
}
|
|
775
|
+
return resolvedTarget;
|
|
776
|
+
}
|
|
777
|
+
await assertLinkIdentities(root, plan.linkIdentities, resolvedTarget);
|
|
778
|
+
const logicalEntry = await lstatOrNullAdapter(logicalTarget);
|
|
779
|
+
if (logicalEntry === null)
|
|
780
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
781
|
+
if (logicalEntry.isSymbolicLink()) {
|
|
782
|
+
const logicalRelative = relativeAdapterPath(root, logicalTarget);
|
|
783
|
+
if (!plan.linkIdentities?.some(
|
|
784
|
+
(identity) => identity.linkPath === logicalRelative
|
|
785
|
+
)) {
|
|
786
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
787
|
+
}
|
|
788
|
+
} else if (!logicalEntry.isFile()) {
|
|
789
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
790
|
+
} else if (!await sameResolvedPath(logicalTarget, resolvedTarget)) {
|
|
791
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
792
|
+
}
|
|
793
|
+
return resolvedTarget;
|
|
794
|
+
}
|
|
795
|
+
function safePlannedRelativePath(root, relative) {
|
|
796
|
+
if (typeof relative !== "string" || !relative.trim() || path.isAbsolute(relative) || relative.split(/[\\/]/u).some((segment) => segment === ".." || !segment)) {
|
|
797
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
798
|
+
}
|
|
799
|
+
const resolved = path.resolve(root, relative);
|
|
800
|
+
if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {
|
|
801
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
802
|
+
}
|
|
803
|
+
return resolved;
|
|
804
|
+
}
|
|
805
|
+
async function readV3AdapterFilePlanContent(projectRoot, plan) {
|
|
806
|
+
const root = path.resolve(projectRoot);
|
|
807
|
+
const logicalTarget = v3AdapterTargetPath(root, plan.target);
|
|
808
|
+
const readPath = await resolvePlannedAdapterWritePath(
|
|
809
|
+
root,
|
|
810
|
+
logicalTarget,
|
|
811
|
+
plan
|
|
812
|
+
);
|
|
813
|
+
try {
|
|
814
|
+
const entry = await lstat(readPath);
|
|
815
|
+
if (!entry.isFile() || entry.isSymbolicLink() || entry.nlink > 1) {
|
|
816
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
817
|
+
}
|
|
818
|
+
return await readFile(readPath, "utf8");
|
|
819
|
+
} catch (error) {
|
|
820
|
+
if (isNodeError(error) && error.code === "ENOENT") return null;
|
|
821
|
+
throw error;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
async function assertLinkIdentities(root, identities, resolvedTarget) {
|
|
825
|
+
for (const identity of identities) {
|
|
826
|
+
const linkPath = safePlannedRelativePath(root, identity.linkPath);
|
|
827
|
+
await assertAdapterPathSafe(root, linkPath);
|
|
828
|
+
const entry = await lstatOrNullAdapter(linkPath);
|
|
829
|
+
if (entry === null || !entry.isSymbolicLink()) {
|
|
830
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
831
|
+
}
|
|
832
|
+
const linkTarget = await readlink(linkPath, "utf8");
|
|
833
|
+
if (linkTarget !== identity.linkTarget) {
|
|
834
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
835
|
+
}
|
|
836
|
+
const actual = await resolveAdapterSymlink(linkPath);
|
|
837
|
+
if (actual === null || !await sameResolvedPath(actual, resolvedTarget)) {
|
|
838
|
+
throw new Error("MANCODE_V3_ADAPTER_TARGET_CONFLICT");
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
async function sameResolvedPath(left, right) {
|
|
843
|
+
const [leftReal, rightReal] = await Promise.all([
|
|
844
|
+
realpath(left).catch(() => path.resolve(left)),
|
|
845
|
+
realpath(right).catch(() => path.resolve(right))
|
|
846
|
+
]);
|
|
847
|
+
return path.resolve(leftReal) === path.resolve(rightReal);
|
|
848
|
+
}
|
|
533
849
|
async function stageV3Adapter(projectRoot, platform) {
|
|
534
850
|
const root = path.resolve(projectRoot);
|
|
535
851
|
await assertPlatformAdapterPathsSafe(root, platform);
|
|
@@ -1248,110 +1564,6 @@ function primaryFileTarget(platform) {
|
|
|
1248
1564
|
return "copilot-instructions";
|
|
1249
1565
|
}
|
|
1250
1566
|
}
|
|
1251
|
-
function planPlatformBootstrapUpgrade(desired, platform, targetOverride) {
|
|
1252
|
-
const target = targetOverride ?? primaryFileTarget(platform);
|
|
1253
|
-
const current = desired.get(target) ?? null;
|
|
1254
|
-
switch (platform) {
|
|
1255
|
-
case "claude-code":
|
|
1256
|
-
desired.set(
|
|
1257
|
-
target,
|
|
1258
|
-
replaceManagedV3BlockText(
|
|
1259
|
-
current ?? "",
|
|
1260
|
-
CONTINUITY_CLAUDE_START_MARKER,
|
|
1261
|
-
CONTINUITY_CLAUDE_END_MARKER,
|
|
1262
|
-
renderV3Bootstrap(platform)
|
|
1263
|
-
)
|
|
1264
|
-
);
|
|
1265
|
-
return;
|
|
1266
|
-
case "cursor":
|
|
1267
|
-
desired.set(
|
|
1268
|
-
target,
|
|
1269
|
-
managedFilePlan(
|
|
1270
|
-
target,
|
|
1271
|
-
current,
|
|
1272
|
-
renderCursorRule(renderV3Bootstrap(platform))
|
|
1273
|
-
).targetContent
|
|
1274
|
-
);
|
|
1275
|
-
return;
|
|
1276
|
-
case "codex":
|
|
1277
|
-
desired.set(
|
|
1278
|
-
target,
|
|
1279
|
-
replaceManagedV3BlockText(
|
|
1280
|
-
removeLegacyV3Block(
|
|
1281
|
-
removeLegacyAgentsBlocks(current ?? ""),
|
|
1282
|
-
LEGACY_V3_CODEX_MARKERS
|
|
1283
|
-
),
|
|
1284
|
-
V3_CODEX_START_MARKER,
|
|
1285
|
-
V3_CODEX_END_MARKER,
|
|
1286
|
-
renderV3Bootstrap(platform)
|
|
1287
|
-
)
|
|
1288
|
-
);
|
|
1289
|
-
return;
|
|
1290
|
-
case "zcode":
|
|
1291
|
-
desired.set(
|
|
1292
|
-
target,
|
|
1293
|
-
replaceManagedV3BlockText(
|
|
1294
|
-
removeLegacyV3Block(
|
|
1295
|
-
removeLegacyAgentsBlocks(current ?? ""),
|
|
1296
|
-
LEGACY_V3_ZCODE_MARKERS
|
|
1297
|
-
),
|
|
1298
|
-
V3_ZCODE_START_MARKER,
|
|
1299
|
-
V3_ZCODE_END_MARKER,
|
|
1300
|
-
renderV3Bootstrap(platform)
|
|
1301
|
-
)
|
|
1302
|
-
);
|
|
1303
|
-
return;
|
|
1304
|
-
case "kimi-code":
|
|
1305
|
-
desired.set(
|
|
1306
|
-
target,
|
|
1307
|
-
replaceManagedV3BlockText(
|
|
1308
|
-
removeLegacyV3Block(
|
|
1309
|
-
removeLegacyAgentsBlocks(current ?? ""),
|
|
1310
|
-
LEGACY_KIMI_MARKERS
|
|
1311
|
-
),
|
|
1312
|
-
V3_KIMI_START_MARKER,
|
|
1313
|
-
V3_KIMI_END_MARKER,
|
|
1314
|
-
renderV3Bootstrap(platform)
|
|
1315
|
-
)
|
|
1316
|
-
);
|
|
1317
|
-
return;
|
|
1318
|
-
case "qoder":
|
|
1319
|
-
desired.set(
|
|
1320
|
-
target,
|
|
1321
|
-
replaceManagedV3BlockText(
|
|
1322
|
-
removeLegacyV3Block(current ?? "", LEGACY_QODER_MARKERS),
|
|
1323
|
-
V3_QODER_START_MARKER,
|
|
1324
|
-
V3_QODER_END_MARKER,
|
|
1325
|
-
renderV3Bootstrap(platform)
|
|
1326
|
-
)
|
|
1327
|
-
);
|
|
1328
|
-
return;
|
|
1329
|
-
case "dsh":
|
|
1330
|
-
desired.set(
|
|
1331
|
-
target,
|
|
1332
|
-
replaceManagedV3BlockText(
|
|
1333
|
-
removeLegacyV3Block(current ?? "", LEGACY_DSH_MARKERS),
|
|
1334
|
-
V3_DSH_START_MARKER,
|
|
1335
|
-
V3_DSH_END_MARKER,
|
|
1336
|
-
renderV3Bootstrap(platform)
|
|
1337
|
-
)
|
|
1338
|
-
);
|
|
1339
|
-
return;
|
|
1340
|
-
case "copilot":
|
|
1341
|
-
desired.set(
|
|
1342
|
-
target,
|
|
1343
|
-
replaceManagedV3BlockText(
|
|
1344
|
-
removeLegacyV3Block(
|
|
1345
|
-
removeManagedBlock(current ?? ""),
|
|
1346
|
-
LEGACY_V3_COPILOT_MARKERS
|
|
1347
|
-
),
|
|
1348
|
-
V3_COPILOT_START_MARKER,
|
|
1349
|
-
V3_COPILOT_END_MARKER,
|
|
1350
|
-
renderV3Bootstrap(platform)
|
|
1351
|
-
)
|
|
1352
|
-
);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
1567
|
function primaryManagedTargetSpec(platform) {
|
|
1356
1568
|
const target = targetFor(platform);
|
|
1357
1569
|
switch (platform) {
|
|
@@ -2014,8 +2226,13 @@ async function replaceUnsafeV3AdapterSymlinks(entries) {
|
|
|
2014
2226
|
if (entry.kind !== "symlink" || !entry.finalTarget || entry.resolvedTo === null) {
|
|
2015
2227
|
continue;
|
|
2016
2228
|
}
|
|
2229
|
+
const projectRoot = entry.projectRoot;
|
|
2230
|
+
if (projectRoot === void 0 || await relativeWithinRealRoot(projectRoot, entry.resolvedTo) === null) {
|
|
2231
|
+
continue;
|
|
2232
|
+
}
|
|
2017
2233
|
const resolvedEntry = await lstat(entry.resolvedTo).catch(() => null);
|
|
2018
|
-
if (resolvedEntry === null || !resolvedEntry.isFile())
|
|
2234
|
+
if (resolvedEntry === null || !resolvedEntry.isFile() || resolvedEntry.isSymbolicLink())
|
|
2235
|
+
continue;
|
|
2019
2236
|
const content = await readFile(entry.resolvedTo);
|
|
2020
2237
|
await rm(entry.target, { force: true });
|
|
2021
2238
|
await writeFile(entry.target, content);
|
|
@@ -2056,7 +2273,8 @@ async function findUnsafeAdapterPathEntry(root, target) {
|
|
|
2056
2273
|
relative,
|
|
2057
2274
|
kind: "outside-root",
|
|
2058
2275
|
finalTarget: false,
|
|
2059
|
-
resolvedTo: null
|
|
2276
|
+
resolvedTo: null,
|
|
2277
|
+
projectRoot: root
|
|
2060
2278
|
};
|
|
2061
2279
|
}
|
|
2062
2280
|
const rootEntry = await lstat(root);
|
|
@@ -2066,7 +2284,8 @@ async function findUnsafeAdapterPathEntry(root, target) {
|
|
|
2066
2284
|
relative,
|
|
2067
2285
|
kind: "root-symlink",
|
|
2068
2286
|
finalTarget: false,
|
|
2069
|
-
resolvedTo: null
|
|
2287
|
+
resolvedTo: null,
|
|
2288
|
+
projectRoot: root
|
|
2070
2289
|
};
|
|
2071
2290
|
}
|
|
2072
2291
|
const segments = relative.split(path.sep);
|
|
@@ -2081,7 +2300,8 @@ async function findUnsafeAdapterPathEntry(root, target) {
|
|
|
2081
2300
|
relative,
|
|
2082
2301
|
kind: "symlink",
|
|
2083
2302
|
finalTarget: index === segments.length - 1,
|
|
2084
|
-
resolvedTo: await
|
|
2303
|
+
resolvedTo: await resolveAdapterSymlinkForInspection(current),
|
|
2304
|
+
projectRoot: root
|
|
2085
2305
|
};
|
|
2086
2306
|
}
|
|
2087
2307
|
if (index < segments.length - 1 && !entry.isDirectory()) {
|
|
@@ -2090,7 +2310,8 @@ async function findUnsafeAdapterPathEntry(root, target) {
|
|
|
2090
2310
|
relative,
|
|
2091
2311
|
kind: "not-directory",
|
|
2092
2312
|
finalTarget: false,
|
|
2093
|
-
resolvedTo: null
|
|
2313
|
+
resolvedTo: null,
|
|
2314
|
+
projectRoot: root
|
|
2094
2315
|
};
|
|
2095
2316
|
}
|
|
2096
2317
|
} catch (error) {
|
|
@@ -2107,6 +2328,29 @@ async function resolveAdapterSymlink(linkPath) {
|
|
|
2107
2328
|
return null;
|
|
2108
2329
|
}
|
|
2109
2330
|
}
|
|
2331
|
+
async function resolveAdapterSymlinkForInspection(linkPath) {
|
|
2332
|
+
let current = path.resolve(linkPath);
|
|
2333
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2334
|
+
for (let depth = 0; depth < 40; depth += 1) {
|
|
2335
|
+
if (seen.has(current)) return null;
|
|
2336
|
+
seen.add(current);
|
|
2337
|
+
const entry = await lstatOrNullAdapter(current);
|
|
2338
|
+
if (entry === null) return current;
|
|
2339
|
+
if (!entry.isSymbolicLink()) {
|
|
2340
|
+
return await realpath(current).catch(() => null) ?? current;
|
|
2341
|
+
}
|
|
2342
|
+
let target;
|
|
2343
|
+
try {
|
|
2344
|
+
target = await readlink(current, "utf8");
|
|
2345
|
+
} catch {
|
|
2346
|
+
return null;
|
|
2347
|
+
}
|
|
2348
|
+
current = path.resolve(
|
|
2349
|
+
path.isAbsolute(target) ? target : path.join(path.dirname(current), target)
|
|
2350
|
+
);
|
|
2351
|
+
}
|
|
2352
|
+
return null;
|
|
2353
|
+
}
|
|
2110
2354
|
async function writeThroughResolvedPath(root, target) {
|
|
2111
2355
|
const entry = await lstat(target).catch((error) => {
|
|
2112
2356
|
if (isNodeError(error) && error.code === "ENOENT") return null;
|
|
@@ -2303,14 +2547,14 @@ async function delay(milliseconds) {
|
|
|
2303
2547
|
}
|
|
2304
2548
|
|
|
2305
2549
|
export {
|
|
2306
|
-
ACCEPTED_STATE_NARRATIVE_GUIDANCE,
|
|
2307
|
-
INTERFACE_EMOJI_ICON_GUIDANCE,
|
|
2308
|
-
VISUAL_DIRECTION_SELECTION_GUIDANCE,
|
|
2309
2550
|
DEFAULT_MANCODE_START_MARKER,
|
|
2310
2551
|
DEFAULT_MANCODE_END_MARKER,
|
|
2311
2552
|
removeManagedBlock,
|
|
2312
2553
|
hasManagedBlock,
|
|
2313
2554
|
replaceManagedBlock,
|
|
2555
|
+
ACCEPTED_STATE_NARRATIVE_GUIDANCE,
|
|
2556
|
+
INTERFACE_EMOJI_ICON_GUIDANCE,
|
|
2557
|
+
VISUAL_DIRECTION_SELECTION_GUIDANCE,
|
|
2314
2558
|
V3_ADAPTER_VERSION,
|
|
2315
2559
|
V3_ADAPTER_MANAGED_MARKER,
|
|
2316
2560
|
V3_MODE_ENTRY_MANAGED_MARKER,
|
|
@@ -2323,6 +2567,7 @@ export {
|
|
|
2323
2567
|
planV3AdapterUpgradeFiles,
|
|
2324
2568
|
stageV3AdapterUpgradeFiles,
|
|
2325
2569
|
applyV3AdapterFilePlan,
|
|
2570
|
+
readV3AdapterFilePlanContent,
|
|
2326
2571
|
stageV3Adapter,
|
|
2327
2572
|
v3AdapterTargetPath,
|
|
2328
2573
|
assertV3AdapterTargetSafe,
|
|
@@ -2339,4 +2584,4 @@ export {
|
|
|
2339
2584
|
replaceUnsafeV3AdapterSymlinks,
|
|
2340
2585
|
writeThroughResolvedPath
|
|
2341
2586
|
};
|
|
2342
|
-
//# sourceMappingURL=chunk-
|
|
2587
|
+
//# sourceMappingURL=chunk-WJ6WARGG.js.map
|