threadnote 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/post-update-migrations.json +5 -4
- package/dist/mcp_server.cjs +14 -3
- package/dist/threadnote.cjs +237 -36
- package/package.json +1 -1
|
@@ -25,15 +25,16 @@
|
|
|
25
25
|
"title": "Consolidate memories under the git remote project name",
|
|
26
26
|
"description": [
|
|
27
27
|
"Threadnote now uses the git remote repository name as the default project identifier instead of the clone folder name.",
|
|
28
|
-
"This migration scans personal lifecycle-aware memory folders
|
|
29
|
-
"It
|
|
28
|
+
"This migration scans personal lifecycle-aware memory project folders and uses repo_path evidence in memories, plus matching seed manifest paths when present, to resolve git remote names.",
|
|
29
|
+
"It covers every detected personal memory project, not just the workspace where threadnote update was run.",
|
|
30
|
+
"It also renames matching seed manifest projects and workset references so future seeded guidance uses the remote-derived project name.",
|
|
30
31
|
"Matching memories are copied under the remote-derived project name with updated project metadata, then the old copy is removed.",
|
|
31
32
|
"If a destination file already exists with different content, Threadnote keeps both by writing the migrated copy with a -from-<old-project> suffix.",
|
|
32
|
-
"Shared team memories and
|
|
33
|
+
"Shared team memories and projects without repo path evidence are left untouched."
|
|
33
34
|
],
|
|
34
35
|
"commandArgs": ["migrate-project-names", "--apply"],
|
|
35
36
|
"instructions": [
|
|
36
|
-
"Post-update project-name migration finished. Future default handoffs and memories for
|
|
37
|
+
"Post-update project-name migration finished. Future default handoffs and memories for migrated repos will use the git remote repository name as their project.",
|
|
37
38
|
"If the migration updated your seed manifest, run threadnote seed --only <new-project-name> to re-ingest seeded resources under the new project URI.",
|
|
38
39
|
"If Threadnote reported any original files were still being processed, rerun the printed threadnote forget <uri> command later."
|
|
39
40
|
],
|
package/dist/mcp_server.cjs
CHANGED
|
@@ -37023,7 +37023,12 @@ async function loadPendingReindexes(config2, state) {
|
|
|
37023
37023
|
}
|
|
37024
37024
|
const entry = item;
|
|
37025
37025
|
if (typeof entry.path === "string" && typeof entry.relativePath === "string" && (entry.status === "added" || entry.status === "removed" || entry.status === "modified")) {
|
|
37026
|
-
changes.push({
|
|
37026
|
+
changes.push({
|
|
37027
|
+
path: entry.path,
|
|
37028
|
+
previousContent: typeof entry.previousContent === "string" ? entry.previousContent : void 0,
|
|
37029
|
+
relativePath: entry.relativePath,
|
|
37030
|
+
status: entry.status
|
|
37031
|
+
});
|
|
37027
37032
|
}
|
|
37028
37033
|
}
|
|
37029
37034
|
if (changes.length > 0) {
|
|
@@ -39092,7 +39097,7 @@ async function applyChangesToOpenViking(config2, team, changes, options = {}) {
|
|
|
39092
39097
|
const currentContent = await readExistingMemoryContent(config2, ov, uri);
|
|
39093
39098
|
if (currentContent !== void 0) {
|
|
39094
39099
|
if (change.status === "added") {
|
|
39095
|
-
if (currentContent
|
|
39100
|
+
if (sharedMemoryContentsEquivalent(currentContent, content)) {
|
|
39096
39101
|
continue;
|
|
39097
39102
|
}
|
|
39098
39103
|
throw new Error(
|
|
@@ -39131,12 +39136,18 @@ function assertInboundPreviousContentMatches(change, uri, currentContent) {
|
|
|
39131
39136
|
);
|
|
39132
39137
|
}
|
|
39133
39138
|
const expectedContent = prepareSharedInboundContent(uri, change.previousContent);
|
|
39134
|
-
if (currentContent
|
|
39139
|
+
if (!sharedMemoryContentsEquivalent(currentContent, expectedContent)) {
|
|
39135
39140
|
throw new Error(
|
|
39136
39141
|
`Refusing to apply inbound shared change for ${uri}: local OpenViking content differs from the previous shared version. Inspect and resolve the local edit first.`
|
|
39137
39142
|
);
|
|
39138
39143
|
}
|
|
39139
39144
|
}
|
|
39145
|
+
function sharedMemoryContentsEquivalent(left, right) {
|
|
39146
|
+
return normalizeSharedMemoryComparisonContent(left) === normalizeSharedMemoryComparisonContent(right);
|
|
39147
|
+
}
|
|
39148
|
+
function normalizeSharedMemoryComparisonContent(content) {
|
|
39149
|
+
return content.replace(/\r\n?/g, "\n").replace(/\n$/, "");
|
|
39150
|
+
}
|
|
39140
39151
|
function mergeChanges(...lists) {
|
|
39141
39152
|
const map2 = /* @__PURE__ */ new Map();
|
|
39142
39153
|
for (const list of lists) {
|
package/dist/threadnote.cjs
CHANGED
|
@@ -8808,7 +8808,12 @@ async function loadPendingReindexes(config, state) {
|
|
|
8808
8808
|
}
|
|
8809
8809
|
const entry = item;
|
|
8810
8810
|
if (typeof entry.path === "string" && typeof entry.relativePath === "string" && (entry.status === "added" || entry.status === "removed" || entry.status === "modified")) {
|
|
8811
|
-
changes.push({
|
|
8811
|
+
changes.push({
|
|
8812
|
+
path: entry.path,
|
|
8813
|
+
previousContent: typeof entry.previousContent === "string" ? entry.previousContent : void 0,
|
|
8814
|
+
relativePath: entry.relativePath,
|
|
8815
|
+
status: entry.status
|
|
8816
|
+
});
|
|
8812
8817
|
}
|
|
8813
8818
|
}
|
|
8814
8819
|
if (changes.length > 0) {
|
|
@@ -11395,7 +11400,7 @@ async function applyChangesToOpenViking(config, team, changes, options = {}) {
|
|
|
11395
11400
|
const currentContent = await readExistingMemoryContent(config, ov, uri);
|
|
11396
11401
|
if (currentContent !== void 0) {
|
|
11397
11402
|
if (change.status === "added") {
|
|
11398
|
-
if (currentContent
|
|
11403
|
+
if (sharedMemoryContentsEquivalent(currentContent, content)) {
|
|
11399
11404
|
continue;
|
|
11400
11405
|
}
|
|
11401
11406
|
throw new Error(
|
|
@@ -11434,12 +11439,18 @@ function assertInboundPreviousContentMatches(change, uri, currentContent) {
|
|
|
11434
11439
|
);
|
|
11435
11440
|
}
|
|
11436
11441
|
const expectedContent = prepareSharedInboundContent(uri, change.previousContent);
|
|
11437
|
-
if (currentContent
|
|
11442
|
+
if (!sharedMemoryContentsEquivalent(currentContent, expectedContent)) {
|
|
11438
11443
|
throw new Error(
|
|
11439
11444
|
`Refusing to apply inbound shared change for ${uri}: local OpenViking content differs from the previous shared version. Inspect and resolve the local edit first.`
|
|
11440
11445
|
);
|
|
11441
11446
|
}
|
|
11442
11447
|
}
|
|
11448
|
+
function sharedMemoryContentsEquivalent(left, right) {
|
|
11449
|
+
return normalizeSharedMemoryComparisonContent(left) === normalizeSharedMemoryComparisonContent(right);
|
|
11450
|
+
}
|
|
11451
|
+
function normalizeSharedMemoryComparisonContent(content) {
|
|
11452
|
+
return content.replace(/\r\n?/g, "\n").replace(/\n$/, "");
|
|
11453
|
+
}
|
|
11443
11454
|
function mergeChanges(...lists) {
|
|
11444
11455
|
const map = /* @__PURE__ */ new Map();
|
|
11445
11456
|
for (const list of lists) {
|
|
@@ -11633,21 +11644,30 @@ async function runMigrateLifecycle(config, options) {
|
|
|
11633
11644
|
async function runMigrateProjectNames(config, options) {
|
|
11634
11645
|
const dryRun = options.dryRun === true || options.apply !== true;
|
|
11635
11646
|
const limit = options.limit ? parsePositiveInteger(options.limit, "project-name migration limit") : void 0;
|
|
11636
|
-
const
|
|
11637
|
-
if (
|
|
11638
|
-
console.log("No git remote project-name
|
|
11647
|
+
const contexts = await projectNameMigrationContexts(config);
|
|
11648
|
+
if (contexts.length === 0) {
|
|
11649
|
+
console.log("No git remote project-name changes apply across configured projects.");
|
|
11639
11650
|
return;
|
|
11640
11651
|
}
|
|
11641
|
-
const
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11652
|
+
const plans = [];
|
|
11653
|
+
let remaining = limit;
|
|
11654
|
+
for (const context of contexts) {
|
|
11655
|
+
const candidates2 = remaining === 0 ? [] : await projectNameMigrationCandidates(config, context, remaining);
|
|
11656
|
+
plans.push({ candidates: candidates2, context });
|
|
11657
|
+
if (remaining !== void 0) {
|
|
11658
|
+
remaining = Math.max(0, remaining - candidates2.length);
|
|
11659
|
+
}
|
|
11660
|
+
}
|
|
11661
|
+
const seedManifestMigration = await seedManifestProjectNameMigration(config, contexts);
|
|
11662
|
+
if (!plans.some((plan) => plan.candidates.length > 0) && !seedManifestMigration) {
|
|
11663
|
+
console.log("No project-name migration candidates found across configured projects.");
|
|
11645
11664
|
return;
|
|
11646
11665
|
}
|
|
11647
|
-
const seedManifestUpdated = await
|
|
11666
|
+
const seedManifestUpdated = await migrateSeedManifestProjectNames(config, seedManifestMigration, dryRun);
|
|
11648
11667
|
let existingCount = 0;
|
|
11649
11668
|
let migratedCount = 0;
|
|
11650
11669
|
let skippedCount = 0;
|
|
11670
|
+
const candidates = plans.flatMap((plan) => [...plan.candidates]);
|
|
11651
11671
|
if (candidates.length > 0) {
|
|
11652
11672
|
const ov = await openVikingCliForMode(dryRun);
|
|
11653
11673
|
for (const candidate of candidates) {
|
|
@@ -11671,37 +11691,186 @@ async function runMigrateProjectNames(config, options) {
|
|
|
11671
11691
|
migratedCount += 1;
|
|
11672
11692
|
}
|
|
11673
11693
|
}
|
|
11694
|
+
const activeContexts = projectNameMigrationActiveContexts(plans, seedManifestMigration);
|
|
11695
|
+
const newProjectsToSeed = [...new Set(seedManifestMigration?.newProjects ?? [])];
|
|
11674
11696
|
console.log(
|
|
11675
11697
|
[
|
|
11676
|
-
|
|
11698
|
+
projectNameMigrationSummary(migratedCount, dryRun, activeContexts),
|
|
11677
11699
|
seedManifestUpdated ? `seed manifest ${dryRun ? "would be updated" : "updated"}` : "seed manifest unchanged",
|
|
11678
11700
|
`${existingCount} duplicate destination(s) reused`,
|
|
11679
11701
|
`${skippedCount} source(s) still processing`,
|
|
11680
11702
|
dryRun ? "Run with --apply to perform this migration." : void 0,
|
|
11681
|
-
|
|
11703
|
+
...newProjectsToSeed.map(
|
|
11704
|
+
(project) => `Run threadnote seed --only ${project} to re-ingest seeded resources under the new project URI.`
|
|
11705
|
+
)
|
|
11682
11706
|
].filter((part) => part !== void 0).join("; ")
|
|
11683
11707
|
);
|
|
11684
11708
|
}
|
|
11685
11709
|
async function hasProjectNameMigrationCandidates(config) {
|
|
11686
|
-
const
|
|
11687
|
-
|
|
11710
|
+
const contexts = await projectNameMigrationContexts(config);
|
|
11711
|
+
if (contexts.length === 0) {
|
|
11712
|
+
return false;
|
|
11713
|
+
}
|
|
11714
|
+
for (const context of contexts) {
|
|
11715
|
+
if ((await projectNameMigrationCandidates(config, context, 1)).length > 0) {
|
|
11716
|
+
return true;
|
|
11717
|
+
}
|
|
11718
|
+
}
|
|
11719
|
+
return await seedManifestProjectNameMigration(config, contexts) !== void 0;
|
|
11720
|
+
}
|
|
11721
|
+
async function projectNameMigrationContexts(config) {
|
|
11722
|
+
const evidence = await projectNameMigrationMemoryEvidence(config);
|
|
11723
|
+
const contexts = [];
|
|
11724
|
+
let manifest;
|
|
11725
|
+
try {
|
|
11726
|
+
manifest = await readSeedManifest(config.manifestPath);
|
|
11727
|
+
} catch (_err) {
|
|
11728
|
+
manifest = void 0;
|
|
11729
|
+
}
|
|
11730
|
+
if (manifest) {
|
|
11731
|
+
for (const project of manifest.projects) {
|
|
11732
|
+
const projectEvidence = evidence.get(uriSegment(project.name));
|
|
11733
|
+
if (projectEvidence) {
|
|
11734
|
+
projectEvidence.repoPaths.add(expandPath(project.path));
|
|
11735
|
+
}
|
|
11736
|
+
}
|
|
11737
|
+
}
|
|
11738
|
+
for (const projectEvidence of evidence.values()) {
|
|
11739
|
+
for (const repoPath of projectEvidence.repoPaths) {
|
|
11740
|
+
const context = await projectNameMigrationContextForRepoPath(projectEvidence.oldProject, repoPath);
|
|
11741
|
+
if (context) {
|
|
11742
|
+
contexts.push(context);
|
|
11743
|
+
}
|
|
11744
|
+
}
|
|
11745
|
+
}
|
|
11746
|
+
const currentContext = await currentWorkspaceProjectNameMigrationContext(evidence);
|
|
11747
|
+
if (currentContext) {
|
|
11748
|
+
contexts.push(currentContext);
|
|
11749
|
+
}
|
|
11750
|
+
return dedupeProjectNameMigrationContexts(contexts);
|
|
11751
|
+
}
|
|
11752
|
+
async function projectNameMigrationMemoryEvidence(config) {
|
|
11753
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
11754
|
+
for (const location of projectMemoryLocations()) {
|
|
11755
|
+
const locationRoot = (0, import_node_path8.join)(localUserMemoriesRoot(config), ...location.relativePath);
|
|
11756
|
+
let projectEntries;
|
|
11757
|
+
try {
|
|
11758
|
+
projectEntries = await (0, import_promises6.readdir)(locationRoot, { withFileTypes: true });
|
|
11759
|
+
} catch (_err) {
|
|
11760
|
+
continue;
|
|
11761
|
+
}
|
|
11762
|
+
for (const projectEntry of projectEntries) {
|
|
11763
|
+
if (!projectEntry.isDirectory() || projectEntry.name.startsWith(".")) {
|
|
11764
|
+
continue;
|
|
11765
|
+
}
|
|
11766
|
+
const oldSegment = projectEntry.name;
|
|
11767
|
+
const projectEvidence = ensureProjectNameMigrationEvidence(evidence, oldSegment);
|
|
11768
|
+
const projectDirectory = (0, import_node_path8.join)(locationRoot, projectEntry.name);
|
|
11769
|
+
let memoryEntries;
|
|
11770
|
+
try {
|
|
11771
|
+
memoryEntries = await (0, import_promises6.readdir)(projectDirectory, { withFileTypes: true });
|
|
11772
|
+
} catch (_err) {
|
|
11773
|
+
continue;
|
|
11774
|
+
}
|
|
11775
|
+
for (const memoryEntry of memoryEntries) {
|
|
11776
|
+
if (!memoryEntry.isFile() || memoryEntry.name.startsWith(".") || !memoryEntry.name.endsWith(".md")) {
|
|
11777
|
+
continue;
|
|
11778
|
+
}
|
|
11779
|
+
const content = await readTextIfExists((0, import_node_path8.join)(projectDirectory, memoryEntry.name));
|
|
11780
|
+
if (!content) {
|
|
11781
|
+
continue;
|
|
11782
|
+
}
|
|
11783
|
+
const sourceUri = `viking://user/${uriSegment(config.user)}/memories/${location.uriPath}/${oldSegment}/${memoryEntry.name}`;
|
|
11784
|
+
const record = parseMemoryDocument(sourceUri, content);
|
|
11785
|
+
if (record?.metadata.project && uriSegment(record.metadata.project) === oldSegment) {
|
|
11786
|
+
projectEvidence.oldProject = record.metadata.project;
|
|
11787
|
+
}
|
|
11788
|
+
const repoPath = repoPathEvidenceFromMemory(content);
|
|
11789
|
+
if (repoPath) {
|
|
11790
|
+
projectEvidence.repoPaths.add(repoPath);
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11793
|
+
}
|
|
11794
|
+
}
|
|
11795
|
+
return evidence;
|
|
11688
11796
|
}
|
|
11689
|
-
|
|
11797
|
+
function ensureProjectNameMigrationEvidence(evidence, oldSegment) {
|
|
11798
|
+
const existing = evidence.get(oldSegment);
|
|
11799
|
+
if (existing) {
|
|
11800
|
+
return existing;
|
|
11801
|
+
}
|
|
11802
|
+
const created = { oldProject: oldSegment, oldSegment, repoPaths: /* @__PURE__ */ new Set() };
|
|
11803
|
+
evidence.set(oldSegment, created);
|
|
11804
|
+
return created;
|
|
11805
|
+
}
|
|
11806
|
+
function repoPathEvidenceFromMemory(content) {
|
|
11807
|
+
const match = /^repo_path:\s*(.+)$/m.exec(content);
|
|
11808
|
+
if (!match?.[1]) {
|
|
11809
|
+
return void 0;
|
|
11810
|
+
}
|
|
11811
|
+
const cleaned = match[1].trim().replace(/^['"`]+|['"`]+$/g, "").replace(/[.,;]+$/g, "");
|
|
11812
|
+
if (!cleaned.startsWith("/") && !cleaned.startsWith("~/")) {
|
|
11813
|
+
return void 0;
|
|
11814
|
+
}
|
|
11815
|
+
return expandPath(cleaned);
|
|
11816
|
+
}
|
|
11817
|
+
async function projectNameMigrationContextForRepoPath(oldProject, repoPath) {
|
|
11818
|
+
const repoRoot = await gitValue(["rev-parse", "--show-toplevel"], repoPath);
|
|
11819
|
+
if (!repoRoot) {
|
|
11820
|
+
return void 0;
|
|
11821
|
+
}
|
|
11822
|
+
const newProject = await resolveGitRemoteRepoName(repoRoot);
|
|
11823
|
+
if (!newProject) {
|
|
11824
|
+
return void 0;
|
|
11825
|
+
}
|
|
11826
|
+
return projectNameMigrationContextFromParts({
|
|
11827
|
+
newProject,
|
|
11828
|
+
oldProject,
|
|
11829
|
+
repoRoot
|
|
11830
|
+
});
|
|
11831
|
+
}
|
|
11832
|
+
async function currentWorkspaceProjectNameMigrationContext(evidence) {
|
|
11690
11833
|
const repoRoot = await gitValue(["rev-parse", "--show-toplevel"]);
|
|
11691
11834
|
if (!repoRoot) {
|
|
11692
11835
|
return void 0;
|
|
11693
11836
|
}
|
|
11694
|
-
const newProject = await
|
|
11837
|
+
const newProject = await resolveGitRemoteRepoName(repoRoot);
|
|
11695
11838
|
const oldProject = await resolveRepoFolderName(repoRoot);
|
|
11696
11839
|
if (!newProject || !oldProject) {
|
|
11697
11840
|
return void 0;
|
|
11698
11841
|
}
|
|
11699
|
-
const newSegment = uriSegment(newProject);
|
|
11700
11842
|
const oldSegment = uriSegment(oldProject);
|
|
11843
|
+
if (!evidence.has(oldSegment)) {
|
|
11844
|
+
return void 0;
|
|
11845
|
+
}
|
|
11846
|
+
return projectNameMigrationContextFromParts({ newProject, oldProject, repoRoot });
|
|
11847
|
+
}
|
|
11848
|
+
function projectNameMigrationContextFromParts(params) {
|
|
11849
|
+
const newSegment = uriSegment(params.newProject);
|
|
11850
|
+
const oldSegment = uriSegment(params.oldProject);
|
|
11701
11851
|
if (newSegment === oldSegment) {
|
|
11702
11852
|
return void 0;
|
|
11703
11853
|
}
|
|
11704
|
-
return {
|
|
11854
|
+
return {
|
|
11855
|
+
newProject: params.newProject,
|
|
11856
|
+
newSegment,
|
|
11857
|
+
oldProject: params.oldProject,
|
|
11858
|
+
oldSegment,
|
|
11859
|
+
repoRoot: params.repoRoot
|
|
11860
|
+
};
|
|
11861
|
+
}
|
|
11862
|
+
function dedupeProjectNameMigrationContexts(contexts) {
|
|
11863
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11864
|
+
const out = [];
|
|
11865
|
+
for (const context of contexts) {
|
|
11866
|
+
const key = `${context.oldSegment}\0${context.newSegment}\0${context.repoRoot}`;
|
|
11867
|
+
if (seen.has(key)) {
|
|
11868
|
+
continue;
|
|
11869
|
+
}
|
|
11870
|
+
seen.add(key);
|
|
11871
|
+
out.push(context);
|
|
11872
|
+
}
|
|
11873
|
+
return out;
|
|
11705
11874
|
}
|
|
11706
11875
|
async function projectNameMigrationCandidates(config, context, limit) {
|
|
11707
11876
|
const candidates = [];
|
|
@@ -11753,11 +11922,23 @@ async function projectNameMigrationCandidates(config, context, limit) {
|
|
|
11753
11922
|
}
|
|
11754
11923
|
return candidates;
|
|
11755
11924
|
}
|
|
11756
|
-
|
|
11757
|
-
return
|
|
11925
|
+
function projectNameMigrationActiveContexts(plans, seedManifestMigration) {
|
|
11926
|
+
return dedupeProjectNameMigrationContexts([
|
|
11927
|
+
...plans.filter((plan) => plan.candidates.length > 0).map((plan) => plan.context),
|
|
11928
|
+
...seedManifestMigration?.contexts ?? []
|
|
11929
|
+
]);
|
|
11930
|
+
}
|
|
11931
|
+
function projectNameMigrationSummary(migratedCount, dryRun, contexts) {
|
|
11932
|
+
const memoryWord = migratedCount === 1 ? "memory" : "memories";
|
|
11933
|
+
const verb = dryRun ? "would be migrated" : "migrated";
|
|
11934
|
+
if (contexts.length === 1) {
|
|
11935
|
+
const [context] = contexts;
|
|
11936
|
+
return `Project-name migration summary: ${migratedCount} ${memoryWord} ${verb} from ${context.oldProject} to ${context.newProject}`;
|
|
11937
|
+
}
|
|
11938
|
+
const renameSummary = contexts.map((context) => `${context.oldProject} -> ${context.newProject}`).join(", ");
|
|
11939
|
+
return `Project-name migration summary: ${migratedCount} ${memoryWord} ${verb} across ${contexts.length} project rename(s)${renameSummary ? `: ${renameSummary}` : ""}`;
|
|
11758
11940
|
}
|
|
11759
|
-
async function
|
|
11760
|
-
const migration = await seedManifestProjectNameMigration(config, context);
|
|
11941
|
+
async function migrateSeedManifestProjectNames(config, migration, dryRun) {
|
|
11761
11942
|
if (!migration) {
|
|
11762
11943
|
return false;
|
|
11763
11944
|
}
|
|
@@ -11779,33 +11960,45 @@ async function migrateSeedManifestProjectName(config, context, dryRun) {
|
|
|
11779
11960
|
console.log(`Updated seed manifest: ${config.manifestPath}`);
|
|
11780
11961
|
return true;
|
|
11781
11962
|
}
|
|
11782
|
-
async function seedManifestProjectNameMigration(config,
|
|
11963
|
+
async function seedManifestProjectNameMigration(config, contexts) {
|
|
11783
11964
|
let manifest;
|
|
11784
11965
|
try {
|
|
11785
11966
|
manifest = await readSeedManifest(config.manifestPath);
|
|
11786
11967
|
} catch (_err) {
|
|
11787
11968
|
return void 0;
|
|
11788
11969
|
}
|
|
11789
|
-
const
|
|
11790
|
-
const newDefaultUri = `viking://resources/repos/${context.newSegment}`;
|
|
11791
|
-
const newNameExists = manifest.projects.some((project) => uriSegment(project.name) === context.newSegment);
|
|
11970
|
+
const renamed = /* @__PURE__ */ new Map();
|
|
11792
11971
|
let changed = false;
|
|
11793
|
-
let renamedProject = false;
|
|
11794
11972
|
const projects = manifest.projects.map((project) => {
|
|
11795
|
-
|
|
11973
|
+
const context = contexts.find(
|
|
11974
|
+
(candidate) => isSeedManifestProjectNameCandidate(
|
|
11975
|
+
project,
|
|
11976
|
+
candidate,
|
|
11977
|
+
`viking://resources/repos/${candidate.oldSegment}`,
|
|
11978
|
+
`viking://resources/repos/${candidate.newSegment}`
|
|
11979
|
+
)
|
|
11980
|
+
);
|
|
11981
|
+
if (!context) {
|
|
11982
|
+
return project;
|
|
11983
|
+
}
|
|
11984
|
+
const newNameExists = manifest.projects.some(
|
|
11985
|
+
(other) => other !== project && uriSegment(other.name) === context.newSegment
|
|
11986
|
+
);
|
|
11987
|
+
if (newNameExists || [...renamed.values()].some((existing) => existing.newSegment === context.newSegment)) {
|
|
11796
11988
|
return project;
|
|
11797
11989
|
}
|
|
11798
11990
|
changed = true;
|
|
11799
|
-
|
|
11991
|
+
renamed.set(context.oldSegment, context);
|
|
11800
11992
|
return {
|
|
11801
11993
|
...project,
|
|
11802
11994
|
name: context.newProject,
|
|
11803
|
-
uri: trimTrailingSlash(project.uri) ===
|
|
11995
|
+
uri: trimTrailingSlash(project.uri) === `viking://resources/repos/${context.oldSegment}` ? `viking://resources/repos/${context.newSegment}` : project.uri
|
|
11804
11996
|
};
|
|
11805
11997
|
});
|
|
11806
|
-
const worksets =
|
|
11998
|
+
const worksets = renamed.size > 0 ? manifest.worksets?.map((workset) => {
|
|
11807
11999
|
const members = workset.projects.map((projectName) => {
|
|
11808
|
-
|
|
12000
|
+
const context = renamed.get(uriSegment(projectName));
|
|
12001
|
+
if (!context) {
|
|
11809
12002
|
return projectName;
|
|
11810
12003
|
}
|
|
11811
12004
|
changed = true;
|
|
@@ -11817,6 +12010,8 @@ async function seedManifestProjectNameMigration(config, context) {
|
|
|
11817
12010
|
return void 0;
|
|
11818
12011
|
}
|
|
11819
12012
|
return {
|
|
12013
|
+
contexts: [...renamed.values()],
|
|
12014
|
+
newProjects: [...new Set([...renamed.values()].map((context) => context.newProject))],
|
|
11820
12015
|
output: `${index_vite_proxy_tmp_default.dump(
|
|
11821
12016
|
{
|
|
11822
12017
|
version: manifest.version,
|
|
@@ -11844,11 +12039,17 @@ async function seedManifestProjectNameMigration(config, context) {
|
|
|
11844
12039
|
)}`
|
|
11845
12040
|
};
|
|
11846
12041
|
}
|
|
11847
|
-
function isSeedManifestProjectNameCandidate(project, context, oldDefaultUri) {
|
|
11848
|
-
|
|
12042
|
+
function isSeedManifestProjectNameCandidate(project, context, oldDefaultUri, newDefaultUri) {
|
|
12043
|
+
const nameSegment = uriSegment(project.name);
|
|
12044
|
+
const uriMatchesOld = trimTrailingSlash(project.uri) === oldDefaultUri;
|
|
12045
|
+
const pathMatchesRepo = expandPath(project.path) === context.repoRoot;
|
|
12046
|
+
if (nameSegment === context.newSegment && !uriMatchesOld) {
|
|
12047
|
+
return false;
|
|
12048
|
+
}
|
|
12049
|
+
if (nameSegment !== context.oldSegment && !uriMatchesOld && !pathMatchesRepo) {
|
|
11849
12050
|
return false;
|
|
11850
12051
|
}
|
|
11851
|
-
return
|
|
12052
|
+
return nameSegment !== context.newSegment || uriMatchesOld || trimTrailingSlash(project.uri) !== newDefaultUri;
|
|
11852
12053
|
}
|
|
11853
12054
|
function canMigrateProjectName(record, context) {
|
|
11854
12055
|
const projectSegment = record.metadata.project ? uriSegment(record.metadata.project) : context.oldSegment;
|