tanmi-dock 0.9.0 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,OAAO,KAAK,EAAuE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAOzH;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAiC3C;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AA6gCD;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqZ1F;AAuKD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,OAAO,EAClB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC,CA0CvD;AAw+BD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyCnD;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,UAAU,CAAC,CAStB;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,OAAO,KAAK,EAAuE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAOzH;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAiC3C;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AA4+BD;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwZ1F;AAmSD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,OAAO,EAClB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC,CA0CvD;AAwhCD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyCnD;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,UAAU,CAAC,CAStB;AAED,eAAe,iBAAiB,CAAC"}
@@ -7,13 +7,13 @@ import { Command } from 'commander';
7
7
  import { ensureInitialized } from '../core/guard.js';
8
8
  import * as config from '../core/config.js';
9
9
  import { setLogLevel } from '../utils/logger.js';
10
- import { parseProjectDependencies, getRelativeConfigPath, parseCodepacDep, extractActions, parseActionCommand, extractNestedDependencies, normalizeProjectRoot, findAllCodepacConfigs, extractDependencies, } from '../core/parser.js';
10
+ import { parseProjectDependencies, getRelativeConfigPath, parseCodepacDep, extractActions, parseActionCommand, extractNestedDependencies, findAllCodepacConfigs, extractDependencies, resolveProjectRootPath, } from '../core/parser.js';
11
11
  import { getRegistry } from '../core/registry.js';
12
12
  import * as store from '../core/store.js';
13
13
  import * as linker from '../core/linker.js';
14
14
  import * as codepac from '../core/codepac.js';
15
15
  import { setProxyConfig } from '../core/codepac.js';
16
- import { resolvePath, getPlatformHelpText, GENERAL_PLATFORM, SHARED_PLATFORM, pathsEqual, isSparseOnlyCommon, KNOWN_PLATFORM_VALUES } from '../core/platform.js';
16
+ import { getPlatformHelpText, GENERAL_PLATFORM, SHARED_PLATFORM, pathsEqual, isSparseOnlyCommon, KNOWN_PLATFORM_VALUES } from '../core/platform.js';
17
17
  import { Transaction } from '../core/transaction.js';
18
18
  import { formatSize, checkDiskSpace } from '../utils/disk.js';
19
19
  import { getDirSize } from '../utils/fs-utils.js';
@@ -289,13 +289,11 @@ async function linkScope(params) {
289
289
  const { existing: allExisting } = await store.checkPlatformCompleteness(dependency.libName, dependency.commit, platforms);
290
290
  tx.recordOp('link', localPath, linkedCommitPath);
291
291
  await linker.linkLib(localPath, linkedCommitPath, allExisting);
292
- for (const platform of allExisting) {
293
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
294
- registry.addStoreReference(storeKey, projectHash);
295
- }
292
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, allExisting, projectHash, false);
296
293
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - 已补充平台 [${supplementResult.downloaded.join(', ')}]`);
297
294
  }
298
295
  }
296
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, isLinkedGeneral ? [GENERAL_PLATFORM] : platforms, projectHash, isLinkedGeneral);
299
297
  break;
300
298
  }
301
299
  case DependencyStatus.RELINK: {
@@ -307,6 +305,7 @@ async function linkScope(params) {
307
305
  const sharedPath = path.join(relinkCommitPath, '_shared');
308
306
  tx.recordOp('link', localPath, sharedPath);
309
307
  await linker.linkGeneral(localPath, sharedPath);
308
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, [GENERAL_PLATFORM], projectHash, true);
310
309
  generalLibs.add(dependency.libName);
311
310
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - General 库,重建链接`);
312
311
  }
@@ -337,10 +336,7 @@ async function linkScope(params) {
337
336
  await linker.unlink(localPath);
338
337
  tx.recordOp('link', localPath, relinkCommitPath);
339
338
  await linker.linkLib(localPath, relinkCommitPath, relinkExisting);
340
- for (const platform of relinkExisting) {
341
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
342
- registry.addStoreReference(storeKey, projectHash);
343
- }
339
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, relinkExisting, projectHash, false);
344
340
  if (relinkSupplementResult.downloaded.length > 0) {
345
341
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - 重建链接并补充平台 [${relinkExisting.join(', ')}]`);
346
342
  }
@@ -359,6 +355,7 @@ async function linkScope(params) {
359
355
  tx.recordOp('replace', localPath, sharedPath);
360
356
  await linker.linkGeneral(localPath, sharedPath);
361
357
  savedBytes += replaceSize;
358
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, [GENERAL_PLATFORM], projectHash, true);
362
359
  generalLibs.add(dependency.libName);
363
360
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - General 库,创建链接`);
364
361
  }
@@ -388,10 +385,7 @@ async function linkScope(params) {
388
385
  tx.recordOp('replace', localPath, replaceCommitPath);
389
386
  await linker.linkLib(localPath, replaceCommitPath, replaceExisting);
390
387
  savedBytes += replaceSize;
391
- for (const platform of replaceExisting) {
392
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
393
- registry.addStoreReference(storeKey, projectHash);
394
- }
388
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, replaceExisting, projectHash, false);
395
389
  if (replaceSupplementResult.downloaded.length > 0) {
396
390
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - Store 已有,创建链接并补充平台 [${replaceExisting.join(', ')}]`);
397
391
  }
@@ -569,21 +563,7 @@ async function linkScope(params) {
569
563
  const sharedPath = path.join(linkNewCommitPath, '_shared');
570
564
  tx.recordOp('link', localPath, sharedPath);
571
565
  await linker.linkGeneral(localPath, sharedPath);
572
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
573
- const existingEntry = registry.getStore(storeKey);
574
- if (!existingEntry) {
575
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
576
- registry.addStore({
577
- libName: dependency.libName, commit: dependency.commit, platform: GENERAL_PLATFORM,
578
- branch: dependency.branch, url: dependency.url, ...integrity,
579
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
580
- });
581
- }
582
- else if (existingEntry.fileCount == null) {
583
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
584
- registry.updateStore(storeKey, integrity);
585
- }
586
- registry.addStoreReference(storeKey, projectHash);
566
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, [GENERAL_PLATFORM], projectHash, true);
587
567
  generalLibs.add(dependency.libName);
588
568
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - General 库,创建链接`);
589
569
  }
@@ -609,29 +589,14 @@ async function linkScope(params) {
609
589
  else {
610
590
  tx.recordOp('link', localPath, linkNewCommitPath);
611
591
  await linker.linkLib(localPath, linkNewCommitPath, linkNewExisting);
612
- for (const platform of linkNewExisting) {
613
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
614
- const existingPlatformEntry = registry.getStore(storeKey);
615
- if (!existingPlatformEntry) {
616
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
617
- registry.addStore({
618
- libName: dependency.libName, commit: dependency.commit, platform,
619
- branch: dependency.branch, url: dependency.url, ...integrity,
620
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
621
- });
622
- }
623
- else if (existingPlatformEntry.fileCount == null) {
624
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
625
- registry.updateStore(storeKey, integrity);
626
- }
627
- registry.addStoreReference(storeKey, projectHash);
628
- }
629
- await registerSharedStore(dependency.libName, dependency.commit, dependency.branch, dependency.url);
592
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, linkNewExisting, projectHash, false);
630
593
  success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - 创建链接 [${linkNewExisting.join(', ')}]`);
631
594
  }
632
595
  break;
633
596
  }
634
597
  }
598
+ // 无论当前是跳过、补平台还是重建链接,都要把本地残留的平台目录清理到最终平台集合
599
+ await linker.cleanupLocalExtraPlatforms(localPath, finalLinkPlatforms);
635
600
  await tx.save();
636
601
  }
637
602
  // 8. 并行处理 MISSING 依赖
@@ -663,31 +628,7 @@ async function linkScope(params) {
663
628
  pLog.info(`${dependency.libName} 所有平台已存在,直接链接...`);
664
629
  tx.recordOp('link', localPath, storeCommitPath);
665
630
  await linker.linkLib(localPath, storeCommitPath, platforms);
666
- for (const platform of platforms) {
667
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
668
- if (!registry.getStore(storeKey)) {
669
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
670
- registry.addStore({
671
- libName: dependency.libName, commit: dependency.commit, platform,
672
- branch: dependency.branch, url: dependency.url, ...integrity,
673
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
674
- });
675
- }
676
- registry.addStoreReference(storeKey, projectHash);
677
- }
678
- await registerSharedStore(dependency.libName, dependency.commit, dependency.branch, dependency.url);
679
- const dlLibKey = registry.getLibraryKey(dependency.libName, dependency.commit);
680
- if (!registry.getLibrary(dlLibKey)) {
681
- let totalSize = 0;
682
- for (const platform of platforms) {
683
- totalSize += await store.getSize(dependency.libName, dependency.commit, platform);
684
- }
685
- registry.addLibrary({
686
- libName: dependency.libName, commit: dependency.commit, branch: dependency.branch,
687
- url: dependency.url, platforms, size: totalSize, referencedBy: [],
688
- createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
689
- });
690
- }
631
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, platforms, projectHash, false);
691
632
  pLog.success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - 链接完成 [${platforms.join(', ')}]`);
692
633
  return { success: true, name: dependency.libName, downloadedPlatforms: platforms, skippedPlatforms: [] };
693
634
  }
@@ -732,25 +673,7 @@ async function linkScope(params) {
732
673
  const sharedPath = path.join(storeCommitPath, '_shared');
733
674
  tx.recordOp('link', localPath, sharedPath);
734
675
  await linker.linkGeneral(localPath, sharedPath);
735
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
736
- if (!registry.getStore(storeKey)) {
737
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
738
- registry.addStore({
739
- libName: dependency.libName, commit: dependency.commit, platform: GENERAL_PLATFORM,
740
- branch: dependency.branch, url: dependency.url, ...integrity,
741
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
742
- });
743
- }
744
- registry.addStoreReference(storeKey, projectHash);
745
- const genLibKey = registry.getLibraryKey(dependency.libName, dependency.commit);
746
- if (!registry.getLibrary(genLibKey)) {
747
- const sharedSize = await getDirSize(sharedPath);
748
- registry.addLibrary({
749
- libName: dependency.libName, commit: dependency.commit, branch: dependency.branch,
750
- url: dependency.url, platforms: [GENERAL_PLATFORM], size: sharedSize,
751
- referencedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
752
- });
753
- }
676
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, [GENERAL_PLATFORM], projectHash, true);
754
677
  generalLibs.add(dependency.libName);
755
678
  pLog.success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - General 库,下载完成`);
756
679
  return { success: true, name: dependency.libName, downloadedPlatforms: [GENERAL_PLATFORM], skippedPlatforms: [], isGeneral: true };
@@ -784,25 +707,7 @@ async function linkScope(params) {
784
707
  const sharedPath = path.join(storeCommitPath, '_shared');
785
708
  tx.recordOp('link', localPath, sharedPath);
786
709
  await linker.linkGeneral(localPath, sharedPath);
787
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
788
- if (!registry.getStore(storeKey)) {
789
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
790
- registry.addStore({
791
- libName: dependency.libName, commit: dependency.commit, platform: GENERAL_PLATFORM,
792
- branch: dependency.branch, url: dependency.url, ...integrity,
793
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
794
- });
795
- }
796
- registry.addStoreReference(storeKey, projectHash);
797
- const genLibKey2 = registry.getLibraryKey(dependency.libName, dependency.commit);
798
- if (!registry.getLibrary(genLibKey2)) {
799
- const sharedSize = await getDirSize(sharedPath);
800
- registry.addLibrary({
801
- libName: dependency.libName, commit: dependency.commit, branch: dependency.branch,
802
- url: dependency.url, platforms: [GENERAL_PLATFORM], size: sharedSize,
803
- referencedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
804
- });
805
- }
710
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, [GENERAL_PLATFORM], projectHash, true);
806
711
  generalLibs.add(dependency.libName);
807
712
  pLog.success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - General 库,下载完成`);
808
713
  return { success: true, name: dependency.libName, downloadedPlatforms: [GENERAL_PLATFORM], skippedPlatforms: [], isGeneral: true };
@@ -812,31 +717,7 @@ async function linkScope(params) {
812
717
  }
813
718
  tx.recordOp('link', localPath, storeCommitPath);
814
719
  await linker.linkLib(localPath, storeCommitPath, linkPlatforms);
815
- for (const platform of linkPlatforms) {
816
- const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
817
- if (!registry.getStore(storeKey)) {
818
- const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
819
- registry.addStore({
820
- libName: dependency.libName, commit: dependency.commit, platform,
821
- branch: dependency.branch, url: dependency.url, ...integrity,
822
- usedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
823
- });
824
- }
825
- registry.addStoreReference(storeKey, projectHash);
826
- }
827
- await registerSharedStore(dependency.libName, dependency.commit, dependency.branch, dependency.url);
828
- const finalLibKey = registry.getLibraryKey(dependency.libName, dependency.commit);
829
- if (!registry.getLibrary(finalLibKey)) {
830
- let totalSize = 0;
831
- for (const platform of linkPlatforms) {
832
- totalSize += await store.getSize(dependency.libName, dependency.commit, platform);
833
- }
834
- registry.addLibrary({
835
- libName: dependency.libName, commit: dependency.commit, branch: dependency.branch,
836
- url: dependency.url, platforms: linkPlatforms, size: totalSize,
837
- referencedBy: [], createdAt: new Date().toISOString(), lastAccess: new Date().toISOString(),
838
- });
839
- }
720
+ await ensureLinkedRegistryState(dependency.libName, dependency.commit, dependency.branch, dependency.url, linkPlatforms, projectHash, false);
840
721
  const notLinkedPlatforms = platforms.filter((p) => !linkPlatforms.includes(p));
841
722
  pLog.success(`${dependency.libName} (${dependency.commit.slice(0, 7)}) - 下载完成 [${linkPlatforms.join(', ')}]`);
842
723
  return { success: true, name: dependency.libName, downloadedPlatforms: linkPlatforms, skippedPlatforms: notLinkedPlatforms };
@@ -929,7 +810,7 @@ async function linkScope(params) {
929
810
  * 执行链接操作
930
811
  */
931
812
  export async function linkProject(projectPath, options) {
932
- const absolutePath = resolvePath(projectPath);
813
+ const { absolutePath, normalizedPath, configPath: discoveredConfigPath, } = await resolveProjectRootPath(projectPath);
933
814
  // === 阶段 1: 初始化 ===
934
815
  const cfg = await config.load();
935
816
  if (cfg?.logLevel)
@@ -939,7 +820,7 @@ export async function linkProject(projectPath, options) {
939
820
  const concurrency = cfg?.concurrency ?? 5;
940
821
  const registry = getRegistry();
941
822
  await registry.load();
942
- const existingProject = registry.getProjectByPath(absolutePath);
823
+ const existingProject = registry.getProjectByPath(normalizedPath);
943
824
  const rememberedPlatforms = existingProject?.platforms;
944
825
  // 确定平台列表
945
826
  let platforms;
@@ -976,7 +857,7 @@ export async function linkProject(projectPath, options) {
976
857
  process.exit(EXIT_CODES.NOINPUT);
977
858
  }
978
859
  // 发现可选配置文件
979
- const thirdpartyDir = path.join(absolutePath, '3rdparty');
860
+ const thirdpartyDir = path.join(normalizedPath, '3rdparty');
980
861
  const configDiscovery = await findAllCodepacConfigs(thirdpartyDir);
981
862
  let selectedOptionalConfigs = [];
982
863
  if (configDiscovery && configDiscovery.optionalConfigs.length > 0) {
@@ -1016,8 +897,7 @@ export async function linkProject(projectPath, options) {
1016
897
  }
1017
898
  }
1018
899
  // 查找主配置文件
1019
- const { findCodepacConfig } = await import('../core/parser.js');
1020
- const mainConfigPath = await findCodepacConfig(absolutePath);
900
+ const mainConfigPath = discoveredConfigPath;
1021
901
  if (!mainConfigPath) {
1022
902
  error(`找不到 codepac-dep.json 配置文件,已搜索: 3rdparty, .`);
1023
903
  process.exit(EXIT_CODES.DATAERR);
@@ -1025,7 +905,7 @@ export async function linkProject(projectPath, options) {
1025
905
  // === 阶段 2: Submodule 检测 ===
1026
906
  let selectedSubmodules = [];
1027
907
  if (options.submodules !== false) {
1028
- const submoduleConfigs = await findSubmoduleConfigs(absolutePath);
908
+ const submoduleConfigs = await findSubmoduleConfigs(normalizedPath);
1029
909
  if (submoduleConfigs.length > 0) {
1030
910
  selectedSubmodules = await selectSubmodules(submoduleConfigs, options, existingProject?.submodules);
1031
911
  // 为选中的 submodule 处理可选配置
@@ -1041,7 +921,7 @@ export async function linkProject(projectPath, options) {
1041
921
  }
1042
922
  }
1043
923
  // === 阶段 3: 规范化 + 事务准备 ===
1044
- const normalizedRoot = normalizeProjectRoot(absolutePath, mainConfigPath);
924
+ const normalizedRoot = normalizedPath;
1045
925
  const wasNormalized = normalizedRoot !== absolutePath;
1046
926
  if (wasNormalized) {
1047
927
  info(`项目根目录规范化: ${absolutePath} → ${normalizedRoot}`);
@@ -1365,6 +1245,93 @@ async function registerSharedStore(libName, commit, branch = '', url = '') {
1365
1245
  debug(`注册 _shared: ${libName}:${commit.slice(0, 8)} (${formatSize(integrity.size)})`);
1366
1246
  return true;
1367
1247
  }
1248
+ async function ensureStoreInfo(libName, commit, platform, branch, url, projectHash) {
1249
+ const registry = getRegistry();
1250
+ const storeKey = registry.getStoreKey(libName, commit, platform);
1251
+ const existingEntry = registry.getStore(storeKey);
1252
+ if (!existingEntry) {
1253
+ const integrity = await store.captureIntegrity(libName, commit, platform);
1254
+ registry.addStore({
1255
+ libName,
1256
+ commit,
1257
+ platform,
1258
+ branch,
1259
+ url,
1260
+ ...integrity,
1261
+ usedBy: [],
1262
+ createdAt: new Date().toISOString(),
1263
+ lastAccess: new Date().toISOString(),
1264
+ });
1265
+ }
1266
+ else if (existingEntry.fileCount == null) {
1267
+ const integrity = await store.captureIntegrity(libName, commit, platform);
1268
+ registry.updateStore(storeKey, integrity);
1269
+ }
1270
+ if (projectHash) {
1271
+ registry.addStoreReference(storeKey, projectHash);
1272
+ }
1273
+ }
1274
+ async function syncLibraryInfo(libName, commit, branch, url, platforms) {
1275
+ const registry = getRegistry();
1276
+ const libKey = registry.getLibraryKey(libName, commit);
1277
+ const existingLibrary = registry.getLibrary(libKey);
1278
+ const normalizedPlatforms = [...new Set(platforms)];
1279
+ let totalSize = 0;
1280
+ for (const platform of normalizedPlatforms) {
1281
+ totalSize += await store.getSize(libName, commit, platform);
1282
+ }
1283
+ if (!existingLibrary) {
1284
+ registry.addLibrary({
1285
+ libName,
1286
+ commit,
1287
+ branch,
1288
+ url,
1289
+ platforms: normalizedPlatforms,
1290
+ size: totalSize,
1291
+ referencedBy: [],
1292
+ createdAt: new Date().toISOString(),
1293
+ lastAccess: new Date().toISOString(),
1294
+ });
1295
+ return;
1296
+ }
1297
+ registry.updateLibrary(libKey, {
1298
+ branch: branch || existingLibrary.branch,
1299
+ url: url || existingLibrary.url,
1300
+ platforms: normalizedPlatforms,
1301
+ size: totalSize,
1302
+ lastAccess: new Date().toISOString(),
1303
+ });
1304
+ }
1305
+ async function resolveStoredPlatforms(libName, commit, fallbackPlatforms) {
1306
+ const storePath = await config.getStorePath();
1307
+ if (!storePath) {
1308
+ return [...new Set(fallbackPlatforms)];
1309
+ }
1310
+ const commitPath = path.join(storePath, libName, commit);
1311
+ try {
1312
+ const entries = await fs.readdir(commitPath, { withFileTypes: true });
1313
+ const storedPlatforms = entries
1314
+ .filter(entry => entry.isDirectory() && KNOWN_PLATFORM_VALUES.includes(entry.name))
1315
+ .map(entry => entry.name);
1316
+ return storedPlatforms.length > 0 ? storedPlatforms : [...new Set(fallbackPlatforms)];
1317
+ }
1318
+ catch {
1319
+ return [...new Set(fallbackPlatforms)];
1320
+ }
1321
+ }
1322
+ async function ensureLinkedRegistryState(libName, commit, branch, url, platforms, projectHash, isGeneral) {
1323
+ const linkedPlatforms = isGeneral ? [GENERAL_PLATFORM] : [...new Set(platforms)];
1324
+ const libraryPlatforms = isGeneral
1325
+ ? [GENERAL_PLATFORM]
1326
+ : await resolveStoredPlatforms(libName, commit, linkedPlatforms);
1327
+ for (const platform of linkedPlatforms) {
1328
+ await ensureStoreInfo(libName, commit, platform, branch, url, projectHash);
1329
+ }
1330
+ if (!isGeneral) {
1331
+ await registerSharedStore(libName, commit, branch, url);
1332
+ }
1333
+ await syncLibraryInfo(libName, commit, branch, url, libraryPlatforms);
1334
+ }
1368
1335
  /**
1369
1336
  * 注册嵌套依赖到 Registry
1370
1337
  * absorbLib 递归吸收嵌套依赖时只做文件操作,此函数负责 Registry 注册
@@ -2036,6 +2003,7 @@ async function linkNestedDependencies(dependencies, params) {
2036
2003
  if (localExists && (storeHas || isGeneral)) {
2037
2004
  const linkStatus = await classifyLinkStatus(localPath, storeCommitPath, isGeneral, existingPlatforms);
2038
2005
  if (linkStatus === 'linked') {
2006
+ let linkedPlatforms = isGeneral ? [GENERAL_PLATFORM] : [...existingPlatforms];
2039
2007
  // 已链接,但需要检查是否需要补充缺失平台(与顶层依赖逻辑一致)
2040
2008
  if (!isGeneral) {
2041
2009
  const supplementResult = await supplementMissingPlatforms(dep, platforms, registry, tx, { vars });
@@ -2052,6 +2020,7 @@ async function linkNestedDependencies(dependencies, params) {
2052
2020
  }
2053
2021
  // 合并所有平台并重新链接
2054
2022
  const allPlatforms = [...existingPlatforms, ...supplementResult.downloaded];
2023
+ linkedPlatforms = allPlatforms;
2055
2024
  if (!dryRun) {
2056
2025
  tx.recordOp('link', localPath, storeCommitPath);
2057
2026
  await linker.linkLib(localPath, storeCommitPath, allPlatforms);
@@ -2059,6 +2028,7 @@ async function linkNestedDependencies(dependencies, params) {
2059
2028
  success(`${indent} ${dep.libName} - 重新链接完成 [${allPlatforms.join(', ')}]`);
2060
2029
  }
2061
2030
  }
2031
+ await ensureLinkedRegistryState(dep.libName, dep.commit, dep.branch, dep.url, linkedPlatforms, projectHash, isGeneral);
2062
2032
  nestedLinkedDeps.push({
2063
2033
  libName: dep.libName,
2064
2034
  commit: dep.commit,
@@ -2094,6 +2064,7 @@ async function linkNestedDependencies(dependencies, params) {
2094
2064
  const sharedPath = path.join(storeCommitPath, '_shared');
2095
2065
  tx.recordOp('link', localPath, sharedPath);
2096
2066
  await linker.linkGeneral(localPath, sharedPath);
2067
+ await ensureLinkedRegistryState(dep.libName, dep.commit, dep.branch, dep.url, [GENERAL_PLATFORM], projectHash, true);
2097
2068
  generalLibs.add(dep.libName);
2098
2069
  // 记录到 nestedLinkedDeps
2099
2070
  nestedLinkedDeps.push({
@@ -2119,6 +2090,7 @@ async function linkNestedDependencies(dependencies, params) {
2119
2090
  }
2120
2091
  tx.recordOp('link', localPath, storeCommitPath);
2121
2092
  await linker.linkLib(localPath, storeCommitPath, allPlatforms);
2093
+ await ensureLinkedRegistryState(dep.libName, dep.commit, dep.branch, dep.url, allPlatforms, projectHash, false);
2122
2094
  // 记录到 nestedLinkedDeps
2123
2095
  nestedLinkedDeps.push({
2124
2096
  libName: dep.libName,
@@ -2174,6 +2146,7 @@ async function linkNestedDependencies(dependencies, params) {
2174
2146
  const sharedPath = path.join(storeCommitPath, '_shared');
2175
2147
  tx.recordOp('link', localPath, sharedPath);
2176
2148
  await linker.linkGeneral(localPath, sharedPath);
2149
+ await ensureLinkedRegistryState(dep.libName, dep.commit, dep.branch, dep.url, [GENERAL_PLATFORM], projectHash, true);
2177
2150
  generalLibs.add(dep.libName);
2178
2151
  downloadedLibs.push(dep.libName);
2179
2152
  // 记录到 nestedLinkedDeps
@@ -2192,6 +2165,7 @@ async function linkNestedDependencies(dependencies, params) {
2192
2165
  await registerNestedLibraries(nestedAbsorbResult.nestedLibraries, projectHash);
2193
2166
  tx.recordOp('link', localPath, storeCommitPath);
2194
2167
  await linker.linkLib(localPath, storeCommitPath, downloadResult.platformDirs);
2168
+ await ensureLinkedRegistryState(dep.libName, dep.commit, dep.branch, dep.url, downloadResult.platformDirs, projectHash, false);
2195
2169
  downloadedLibs.push(dep.libName);
2196
2170
  // 记录到 nestedLinkedDeps
2197
2171
  nestedLinkedDeps.push({