@cortexkit/aft-bridge 0.39.3 → 0.40.0

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.
Files changed (56) hide show
  1. package/dist/bash-format.d.ts +0 -1
  2. package/dist/bash-format.d.ts.map +1 -1
  3. package/dist/bash-format.js +0 -3
  4. package/dist/bash-format.js.map +1 -1
  5. package/dist/bash-hints.js +97 -9
  6. package/dist/bash-hints.js.map +1 -1
  7. package/dist/bridge.d.ts +23 -1
  8. package/dist/bridge.d.ts.map +1 -1
  9. package/dist/bridge.js +63 -43
  10. package/dist/bridge.js.map +1 -1
  11. package/dist/callgraph-format.d.ts.map +1 -1
  12. package/dist/callgraph-format.js +27 -14
  13. package/dist/callgraph-format.js.map +1 -1
  14. package/dist/coerce.d.ts +39 -0
  15. package/dist/coerce.d.ts.map +1 -1
  16. package/dist/coerce.js +82 -0
  17. package/dist/coerce.js.map +1 -1
  18. package/dist/command-timeouts.d.ts.map +1 -1
  19. package/dist/command-timeouts.js +1 -0
  20. package/dist/command-timeouts.js.map +1 -1
  21. package/dist/config-tiers.d.ts +19 -0
  22. package/dist/config-tiers.d.ts.map +1 -0
  23. package/dist/config-tiers.js +45 -0
  24. package/dist/config-tiers.js.map +1 -0
  25. package/dist/edit-summary.d.ts +5 -0
  26. package/dist/edit-summary.d.ts.map +1 -1
  27. package/dist/edit-summary.js +12 -2
  28. package/dist/edit-summary.js.map +1 -1
  29. package/dist/index.d.ts +11 -9
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +8 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/migration.d.ts +27 -0
  34. package/dist/migration.d.ts.map +1 -1
  35. package/dist/migration.js +384 -2
  36. package/dist/migration.js.map +1 -1
  37. package/dist/onnx-runtime.d.ts +4 -6
  38. package/dist/onnx-runtime.d.ts.map +1 -1
  39. package/dist/onnx-runtime.js +13 -15
  40. package/dist/onnx-runtime.js.map +1 -1
  41. package/dist/paths.d.ts +17 -0
  42. package/dist/paths.d.ts.map +1 -1
  43. package/dist/paths.js +52 -1
  44. package/dist/paths.js.map +1 -1
  45. package/dist/pool.d.ts.map +1 -1
  46. package/dist/pool.js +15 -16
  47. package/dist/pool.js.map +1 -1
  48. package/dist/project-identity.d.ts +30 -0
  49. package/dist/project-identity.d.ts.map +1 -0
  50. package/dist/project-identity.js +69 -0
  51. package/dist/project-identity.js.map +1 -0
  52. package/package.json +1 -1
  53. package/dist/pipe-strip.d.ts +0 -7
  54. package/dist/pipe-strip.d.ts.map +0 -1
  55. package/dist/pipe-strip.js +0 -688
  56. package/dist/pipe-strip.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"edit-summary.d.ts","sourceRoot":"","sources":["../src/edit-summary.ts"],"names":[],"mappings":"AAeA,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA8ChE"}
1
+ {"version":3,"file":"edit-summary.d.ts","sourceRoot":"","sources":["../src/edit-summary.ts"],"names":[],"mappings":"AAeA,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,uEAAuE;IACvE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA8ChE"}
@@ -51,7 +51,7 @@ export function formatEditSummary(data) {
51
51
  if (data.created === true) {
52
52
  let s = `Created file (${counts}).`;
53
53
  if (data.formatted)
54
- s += " Auto-formatted.";
54
+ s += formatAutoFormattedSuffix(data);
55
55
  return s;
56
56
  }
57
57
  // Batch mode reports edits_applied; replaceAll reports replacements > 1.
@@ -64,7 +64,17 @@ export function formatEditSummary(data) {
64
64
  }
65
65
  let s = `Edited (${detail}).`;
66
66
  if (data.formatted)
67
- s += " Auto-formatted.";
67
+ s += formatAutoFormattedSuffix(data);
68
68
  return s;
69
69
  }
70
+ function formatAutoFormattedSuffix(data) {
71
+ const reflowText = data.reformatted?.text;
72
+ if (typeof reflowText === "string" && reflowText.length > 0) {
73
+ return `\nAuto-formatted — the formatter reflowed your edit. On disk now:\n${reflowText}`;
74
+ }
75
+ if (data.reformatted?.extensive === true) {
76
+ return " Auto-formatted — extensive reflow; re-read the file before your next anchored edit.";
77
+ }
78
+ return " Auto-formatted.";
79
+ }
70
80
  //# sourceMappingURL=edit-summary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit-summary.js","sourceRoot":"","sources":["../src/edit-summary.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,iEAAiE;AACjE,+EAA+E;AAC/E,aAAa;AACb,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,8DAA8D;AAC9D,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AA0B5E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAsB;IACtD,yEAAyE;IACzE,2EAA2E;IAC3E,0DAA0D;IAC1D,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,uFAAuF,CAAC;IACjG,CAAC;IAED,4EAA4E;IAC5E,gBAAgB;IAChB,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;QAC9B,OAAO,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5D,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,0EAA0E;IAC1E,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC;QAC1C,OAAO,UAAU,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,eAAe,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACxG,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;IAE7C,4BAA4B;IAC5B,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,iBAAiB,MAAM,IAAI,CAAC;QACpC,IAAI,IAAI,CAAC,SAAS;YAAE,CAAC,IAAI,kBAAkB,CAAC;QAC5C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,yEAAyE;IACzE,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,aAAa,QAAQ,CAAC;IACpD,CAAC;SAAM,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,YAAY,eAAe,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,GAAG,WAAW,MAAM,IAAI,CAAC;IAC9B,IAAI,IAAI,CAAC,SAAS;QAAE,CAAC,IAAI,kBAAkB,CAAC;IAC5C,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"edit-summary.js","sourceRoot":"","sources":["../src/edit-summary.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,32 +7,34 @@
7
7
  * each host plugin.
8
8
  */
9
9
  export { setActiveLogger } from "./active-logger.js";
10
- export { appendPipeStripNote, formatForegroundResult, formatSeconds, isTerminalStatus, sleep, } from "./bash-format.js";
10
+ export { formatForegroundResult, formatSeconds, isTerminalStatus, sleep, } from "./bash-format.js";
11
11
  export { commandInvokesCodeSearch, maybeAppendConflictsHint, maybeAppendGrepSearchHint, } from "./bash-hints.js";
12
12
  export { resolveBashKillTimeout } from "./bash-timeout.js";
13
- export type { BashCompletedPayload, BashLongRunningPayload, BridgeOptions, BridgeRequestOptions, ConfigureWarning, ConfigureWarningsContext, StatusSnapshot, } from "./bridge.js";
14
- export { BinaryBridge, compareSemver, tagStderrLine } from "./bridge.js";
13
+ export type { BashCompletedPayload, BashLongRunningPayload, BridgeOptions, BridgeRequestOptions, ConfigureDroppedKey, ConfigureWarning, ConfigureWarningsContext, StatusSnapshot, } from "./bridge.js";
14
+ export { BinaryBridge, BridgeTransportTimeoutError, compareSemver, isBridgeTransportTimeout, tagStderrLine, } from "./bridge.js";
15
15
  export type { CallgraphTheme } from "./callgraph-format.js";
16
16
  export { formatCallgraphSections, PLAIN_CALLGRAPH_THEME } from "./callgraph-format.js";
17
- export { coerceOptionalInt, coerceStringArray, isEmptyParam } from "./coerce.js";
17
+ export { coerceBoolean, coerceOptionalInt, coerceStringArray, coerceTargetParam, isEmptyParam, } from "./coerce.js";
18
18
  export { LONG_RUNNING_COMMAND_TIMEOUT_MS, timeoutForCommand } from "./command-timeouts.js";
19
+ export type { ConfigTier } from "./config-tiers.js";
20
+ export { formatDroppedKeyWarnings, inlineUserConfigTier, readConfigTiers } from "./config-tiers.js";
19
21
  export { downloadBinary, ensureBinary, getBinaryName, getCacheDir, getCachedBinaryPath, } from "./downloader.js";
20
22
  export type { EditSummaryInput } from "./edit-summary.js";
21
23
  export { formatEditSummary } from "./edit-summary.js";
22
24
  export { compressionSavingsPercent, formatTokenCount } from "./format.js";
23
25
  export { stripJsoncSymbols } from "./jsonc.js";
24
26
  export type { Logger, LogMeta } from "./logger.js";
25
- export type { MigrationHarness, MigrationOptions, MigrationStatus } from "./migration.js";
26
- export { ensureStorageMigrated, getMigrationStatus, resolveCortexKitStorageRoot, resolveLegacyStorageRoot, } from "./migration.js";
27
+ export type { AftConfigFileMigrationOptions, AftConfigFileMigrationResult, MigrationHarness, MigrationOptions, MigrationStatus, } from "./migration.js";
28
+ export { ensureStorageMigrated, getMigrationStatus, migrateAftConfigFile, resolveCortexKitStorageRoot, resolveLegacyStorageRoot, } from "./migration.js";
27
29
  export type { ResolvedNpm } from "./npm-resolver.js";
28
30
  export { isNpmAvailable, npmSpawnEnv, probeNpmVersion, resolveNpm, } from "./npm-resolver.js";
29
31
  export { __test__ as __onnxTest__, cleanupOnnxRuntime, ensureOnnxRuntime, getManualInstallHint, isOrtAutoDownloadSupported, } from "./onnx-runtime.js";
30
- export { markAnnouncementSeen, repairRootScopedStorageFile, resolveHarnessStoragePath, shouldShowAnnouncement, } from "./paths.js";
31
- export type { PipeStripResult } from "./pipe-strip.js";
32
- export { maybeStripCompressorPipe } from "./pipe-strip.js";
32
+ export type { LegacyAftConfigSource, ResolvedAftConfigPaths } from "./paths.js";
33
+ export { markAnnouncementSeen, repairRootScopedStorageFile, resolveCortexKitConfigPaths, resolveCortexKitProjectConfigPath, resolveCortexKitUserConfigPath, resolveHarnessStoragePath, resolveLegacyAftConfigSources, shouldShowAnnouncement, } from "./paths.js";
33
34
  export { PLATFORM_ARCH_MAP, PLATFORM_ASSET_MAP } from "./platform.js";
34
35
  export type { PoolOptions } from "./pool.js";
35
36
  export { BridgePool, HomeProjectRootError, isHomeDirectoryRoot } from "./pool.js";
37
+ export { canonicalizeProjectRoot, projectRootKeyHash } from "./project-identity.js";
36
38
  export type { AftErrorResponse, AftPushFrame, AftRequestEnvelope, AftResponse, AftSuccessResponse, BashCompletedFrame, BgCompletion, ConfigureWarningFrame, PermissionAskFrame, ProgressFrame, StatusCompression, StatusCompressionAggregate, StatusResponse, } from "./protocol.js";
37
39
  export { findBinary, findBinarySync, isNativeExecutable, platformKey } from "./resolver.js";
38
40
  export type { StatusBarCounts, StatusBarEmitState } from "./status-bar.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,14 +9,15 @@
9
9
  // --- logger contract ---
10
10
  export { setActiveLogger } from "./active-logger.js";
11
11
  // --- bash output hints (shared by both plugin hosts) ---
12
- export { appendPipeStripNote, formatForegroundResult, formatSeconds, isTerminalStatus, sleep, } from "./bash-format.js";
12
+ export { formatForegroundResult, formatSeconds, isTerminalStatus, sleep, } from "./bash-format.js";
13
13
  export { commandInvokesCodeSearch, maybeAppendConflictsHint, maybeAppendGrepSearchHint, } from "./bash-hints.js";
14
14
  export { resolveBashKillTimeout } from "./bash-timeout.js";
15
15
  // --- transport ---
16
- export { BinaryBridge, compareSemver, tagStderrLine } from "./bridge.js";
16
+ export { BinaryBridge, BridgeTransportTimeoutError, compareSemver, isBridgeTransportTimeout, tagStderrLine, } from "./bridge.js";
17
17
  export { formatCallgraphSections, PLAIN_CALLGRAPH_THEME } from "./callgraph-format.js";
18
- export { coerceOptionalInt, coerceStringArray, isEmptyParam } from "./coerce.js";
18
+ export { coerceBoolean, coerceOptionalInt, coerceStringArray, coerceTargetParam, isEmptyParam, } from "./coerce.js";
19
19
  export { LONG_RUNNING_COMMAND_TIMEOUT_MS, timeoutForCommand } from "./command-timeouts.js";
20
+ export { formatDroppedKeyWarnings, inlineUserConfigTier, readConfigTiers } from "./config-tiers.js";
20
21
  // --- binary resolution ---
21
22
  export { downloadBinary, ensureBinary, getBinaryName, getCacheDir, getCachedBinaryPath, } from "./downloader.js";
22
23
  export { formatEditSummary } from "./edit-summary.js";
@@ -25,15 +26,16 @@ export { compressionSavingsPercent, formatTokenCount } from "./format.js";
25
26
  // --- jsonc helpers ---
26
27
  export { stripJsoncSymbols } from "./jsonc.js";
27
28
  // --- storage migration ---
28
- export { ensureStorageMigrated, getMigrationStatus, resolveCortexKitStorageRoot, resolveLegacyStorageRoot, } from "./migration.js";
29
+ export { ensureStorageMigrated, getMigrationStatus, migrateAftConfigFile, resolveCortexKitStorageRoot, resolveLegacyStorageRoot, } from "./migration.js";
29
30
  export { isNpmAvailable, npmSpawnEnv, probeNpmVersion, resolveNpm, } from "./npm-resolver.js";
30
31
  // --- ONNX runtime ---
31
32
  export { __test__ as __onnxTest__, cleanupOnnxRuntime, ensureOnnxRuntime, getManualInstallHint, isOrtAutoDownloadSupported, } from "./onnx-runtime.js";
32
- export { markAnnouncementSeen, repairRootScopedStorageFile, resolveHarnessStoragePath, shouldShowAnnouncement, } from "./paths.js";
33
- export { maybeStripCompressorPipe } from "./pipe-strip.js";
33
+ export { markAnnouncementSeen, repairRootScopedStorageFile, resolveCortexKitConfigPaths, resolveCortexKitProjectConfigPath, resolveCortexKitUserConfigPath, resolveHarnessStoragePath, resolveLegacyAftConfigSources, shouldShowAnnouncement, } from "./paths.js";
34
34
  // --- platform helpers ---
35
35
  export { PLATFORM_ARCH_MAP, PLATFORM_ASSET_MAP } from "./platform.js";
36
36
  export { BridgePool, HomeProjectRootError, isHomeDirectoryRoot } from "./pool.js";
37
+ // --- project-root identity (single canonicalizer; mirrors cortexkit-paths) ---
38
+ export { canonicalizeProjectRoot, projectRootKeyHash } from "./project-identity.js";
37
39
  export { findBinary, findBinarySync, isNativeExecutable, platformKey } from "./resolver.js";
38
40
  export { createStatusBarEmitState, formatStatusBar, parseStatusBarCounts, STATUS_BAR_HEARTBEAT_CALLS, shouldEmitStatusBar, statusBarLine, } from "./status-bar.js";
39
41
  export { formatBridgeErrorMessage, formatReadFooter } from "./tool-format.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,0DAA0D;AAC1D,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,KAAK,GACN,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAU3D,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzE,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,+BAA+B,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC3F,4BAA4B;AAC5B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,gCAAgC;AAChC,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,4BAA4B;AAC5B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,uBAAuB;AACvB,OAAO,EACL,QAAQ,IAAI,YAAY,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAiBlF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5F,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAS9E,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,0DAA0D;AAC1D,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,KAAK,GACN,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAW3D,oBAAoB;AACpB,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,aAAa,EACb,wBAAwB,EACxB,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,+BAA+B,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG3F,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpG,4BAA4B;AAC5B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,gCAAgC;AAChC,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAS/C,4BAA4B;AAC5B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,uBAAuB;AACvB,OAAO,EACL,QAAQ,IAAI,YAAY,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,iCAAiC,EACjC,8BAA8B,EAC9B,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAClF,gFAAgF;AAChF,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAiBpF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5F,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAS9E,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from "node:child_process";
2
+ import { type LegacyAftConfigSource } from "./paths.js";
2
3
  type SpawnSyncForMigration = typeof spawnSync;
3
4
  export declare function __setSpawnSyncForTests(impl: SpawnSyncForMigration | null): void;
4
5
  export type MigrationHarness = "opencode" | "pi";
@@ -12,6 +13,31 @@ export interface MigrationOptions {
12
13
  };
13
14
  timeoutMs?: number;
14
15
  }
16
+ export interface AftConfigFileMigrationOptions {
17
+ scope: "user" | "project";
18
+ targetPath: string;
19
+ legacySources: readonly LegacyAftConfigSource[];
20
+ /**
21
+ * The harness whose plugin is running this migration. When two harnesses
22
+ * (OpenCode + Pi) have DIFFERENT legacy configs, this one wins: its config
23
+ * becomes the shared CortexKit target, and the other's is preserved beside it
24
+ * as `<target>.<harness>_OLD` for manual merge. Without it, the first source
25
+ * by list order wins (back-compat for callers that don't pass it).
26
+ */
27
+ operatingHarness?: MigrationHarness;
28
+ logger?: {
29
+ warn?: (msg: string) => void;
30
+ info?: (msg: string) => void;
31
+ log?: (msg: string) => void;
32
+ };
33
+ }
34
+ export interface AftConfigFileMigrationResult {
35
+ migrated: boolean;
36
+ conflict: boolean;
37
+ sourcePath?: string;
38
+ targetPath: string;
39
+ warnings: string[];
40
+ }
15
41
  export interface MigrationStatus {
16
42
  harness: MigrationHarness;
17
43
  target_root: string;
@@ -26,6 +52,7 @@ export interface MigrationStatus {
26
52
  }
27
53
  export declare function resolveLegacyStorageRoot(harness: MigrationHarness): string;
28
54
  export declare function resolveCortexKitStorageRoot(): string;
55
+ export declare function migrateAftConfigFile(opts: AftConfigFileMigrationOptions): AftConfigFileMigrationResult;
29
56
  export declare function ensureStorageMigrated(opts: MigrationOptions): Promise<void>;
30
57
  /**
31
58
  * Query the migration status without performing any migration.
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAO/C,KAAK,qBAAqB,GAAG,OAAO,SAAS,CAAC;AAI9C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAE/E;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyBD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAG1E;AAED,wBAAgB,2BAA2B,IAAI,MAAM,CAEpD;AA+BD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiGjF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8C3B"}
1
+ {"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAe/C,OAAO,EAAE,KAAK,qBAAqB,EAA6B,MAAM,YAAY,CAAC;AAGnF,KAAK,qBAAqB,GAAG,OAAO,SAAS,CAAC;AAI9C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAE/E;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAChD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyBD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAG1E;AAED,wBAAgB,2BAA2B,IAAI,MAAM,CAEpD;AAiWD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,6BAA6B,GAClC,4BAA4B,CAuF9B;AA+BD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiGjF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8C3B"}
package/dist/migration.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { spawnSync } from "node:child_process";
2
- import { existsSync, mkdirSync } from "node:fs";
2
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
3
  import { homedir, tmpdir } from "node:os";
4
- import { dirname, join } from "node:path";
4
+ import { basename, dirname, join, resolve } from "node:path";
5
5
  import { resolveHarnessStoragePath } from "./paths.js";
6
6
  import { findBinary } from "./resolver.js";
7
7
  let spawnSyncForMigration = spawnSync;
@@ -38,6 +38,388 @@ export function resolveLegacyStorageRoot(harness) {
38
38
  export function resolveCortexKitStorageRoot() {
39
39
  return join(dataHome(), "cortexkit", "aft");
40
40
  }
41
+ function stripJsoncForParse(input) {
42
+ let out = "";
43
+ let inString = false;
44
+ let escaped = false;
45
+ for (let i = 0; i < input.length; i++) {
46
+ const ch = input[i];
47
+ const next = input[i + 1];
48
+ if (inString) {
49
+ out += ch;
50
+ if (escaped) {
51
+ escaped = false;
52
+ }
53
+ else if (ch === "\\") {
54
+ escaped = true;
55
+ }
56
+ else if (ch === '"') {
57
+ inString = false;
58
+ }
59
+ continue;
60
+ }
61
+ if (ch === '"') {
62
+ inString = true;
63
+ out += ch;
64
+ continue;
65
+ }
66
+ if (ch === "/" && next === "/") {
67
+ while (i < input.length && input[i] !== "\n")
68
+ i++;
69
+ out += "\n";
70
+ continue;
71
+ }
72
+ if (ch === "/" && next === "*") {
73
+ i += 2;
74
+ while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
75
+ i++;
76
+ i++;
77
+ out += " ";
78
+ continue;
79
+ }
80
+ out += ch;
81
+ }
82
+ let withoutTrailingCommas = "";
83
+ inString = false;
84
+ escaped = false;
85
+ for (let i = 0; i < out.length; i++) {
86
+ const ch = out[i];
87
+ if (inString) {
88
+ withoutTrailingCommas += ch;
89
+ if (escaped) {
90
+ escaped = false;
91
+ }
92
+ else if (ch === "\\") {
93
+ escaped = true;
94
+ }
95
+ else if (ch === '"') {
96
+ inString = false;
97
+ }
98
+ continue;
99
+ }
100
+ if (ch === '"') {
101
+ inString = true;
102
+ withoutTrailingCommas += ch;
103
+ continue;
104
+ }
105
+ if (ch === ",") {
106
+ let j = i + 1;
107
+ while (j < out.length && /\s/.test(out[j]))
108
+ j++;
109
+ if (out[j] === "}" || out[j] === "]")
110
+ continue;
111
+ }
112
+ withoutTrailingCommas += ch;
113
+ }
114
+ return withoutTrailingCommas;
115
+ }
116
+ function sortJson(value) {
117
+ if (Array.isArray(value))
118
+ return value.map(sortJson);
119
+ if (value && typeof value === "object") {
120
+ const sorted = {};
121
+ for (const key of Object.keys(value).sort()) {
122
+ sorted[key] = sortJson(value[key]);
123
+ }
124
+ return sorted;
125
+ }
126
+ return value;
127
+ }
128
+ function normalizedJsoncSemantics(content) {
129
+ return JSON.stringify(sortJson(JSON.parse(stripJsoncForParse(content))));
130
+ }
131
+ function fileSemanticsMatch(a, b) {
132
+ try {
133
+ return normalizedJsoncSemantics(a) === normalizedJsoncSemantics(b);
134
+ }
135
+ catch {
136
+ return a === b;
137
+ }
138
+ }
139
+ function sleepSync(ms) {
140
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
141
+ }
142
+ function acquireConfigMigrationLock(lockDir) {
143
+ const deadline = Date.now() + 30_000;
144
+ while (true) {
145
+ try {
146
+ mkdirSync(lockDir, { recursive: false });
147
+ return () => {
148
+ try {
149
+ rmSync(lockDir, { recursive: true, force: true });
150
+ }
151
+ catch {
152
+ // best-effort lock cleanup
153
+ }
154
+ };
155
+ }
156
+ catch (err) {
157
+ const code = err?.code;
158
+ if (code !== "EEXIST")
159
+ throw err;
160
+ try {
161
+ const ageMs = Date.now() - statSync(lockDir).mtimeMs;
162
+ if (ageMs > 60_000) {
163
+ rmSync(lockDir, { recursive: true, force: true });
164
+ continue;
165
+ }
166
+ }
167
+ catch {
168
+ // If the lock disappeared between mkdir attempts, retry immediately.
169
+ }
170
+ if (Date.now() >= deadline) {
171
+ throw new Error(`timed out waiting for config migration lock ${lockDir}`);
172
+ }
173
+ sleepSync(25);
174
+ }
175
+ }
176
+ }
177
+ function atomicCopyConfigFile(sourcePath, targetPath) {
178
+ mkdirSync(dirname(targetPath), { recursive: true });
179
+ const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
180
+ let fd = null;
181
+ try {
182
+ fd = openSync(tmpPath, "wx", 0o600);
183
+ writeFileSync(fd, readFileSync(sourcePath));
184
+ closeSync(fd);
185
+ fd = null;
186
+ renameSync(tmpPath, targetPath);
187
+ }
188
+ catch (err) {
189
+ if (fd !== null) {
190
+ try {
191
+ closeSync(fd);
192
+ }
193
+ catch {
194
+ // best-effort close before cleanup
195
+ }
196
+ }
197
+ try {
198
+ unlinkSync(tmpPath);
199
+ }
200
+ catch {
201
+ // best-effort temp cleanup
202
+ }
203
+ throw err;
204
+ }
205
+ }
206
+ function atomicWriteConfigFile(targetPath, content) {
207
+ mkdirSync(dirname(targetPath), { recursive: true });
208
+ const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
209
+ let fd = null;
210
+ try {
211
+ fd = openSync(tmpPath, "wx", 0o600);
212
+ writeFileSync(fd, content);
213
+ closeSync(fd);
214
+ fd = null;
215
+ renameSync(tmpPath, targetPath);
216
+ }
217
+ catch (err) {
218
+ if (fd !== null) {
219
+ try {
220
+ closeSync(fd);
221
+ }
222
+ catch {
223
+ // best-effort close before cleanup
224
+ }
225
+ }
226
+ try {
227
+ unlinkSync(tmpPath);
228
+ }
229
+ catch {
230
+ // best-effort temp cleanup
231
+ }
232
+ throw err;
233
+ }
234
+ }
235
+ const MOVED_MARKER_SUFFIX = ".MOVED_READPLEASE";
236
+ function nonClobberingSidecarPath(desiredPath) {
237
+ if (!existsSync(desiredPath))
238
+ return desiredPath;
239
+ for (let index = 1; index < Number.MAX_SAFE_INTEGER; index++) {
240
+ const candidate = `${desiredPath}.${index}`;
241
+ if (!existsSync(candidate))
242
+ return candidate;
243
+ }
244
+ throw new Error(`could not find available preservation sidecar path for ${desiredPath}`);
245
+ }
246
+ function movedMarkerContent(targetPath, originalName, originalContent) {
247
+ const header = [
248
+ "// AFT configuration moved.",
249
+ "//",
250
+ "// AFT now reads its configuration from one shared CortexKit location",
251
+ "// instead of a per-agent path. The settings that were in this file have",
252
+ "// been moved to:",
253
+ "//",
254
+ `// ${targetPath}`,
255
+ "//",
256
+ "// Edit that file to change AFT settings. This location is no longer read",
257
+ "// by AFT.",
258
+ "//",
259
+ `// To undo, rename this file back to "${originalName}" (and remove the`,
260
+ "// CortexKit copy above if you want this location to take precedence).",
261
+ "//",
262
+ "// Your original settings are preserved below for reference.",
263
+ "",
264
+ "",
265
+ ].join("\n");
266
+ return `${header}${originalContent}`;
267
+ }
268
+ // After the live config is safely at the CortexKit target, rename each legacy
269
+ // source aside to a "<name>.MOVED_READPLEASE" marker so a user editing the old
270
+ // path notices it is no longer read (a copy-in-place leaves a silent stale-edit
271
+ // trap). The marker preserves the original settings and documents how to undo.
272
+ // A failure here is non-fatal: the content is already at the target, so we warn
273
+ // and leave the legacy file in place rather than failing the migration.
274
+ function markLegacySourcesMovedAside(sources, targetPath, logger) {
275
+ const warnings = [];
276
+ const info = logger?.info ?? logger?.log;
277
+ for (const source of sources) {
278
+ const desiredMarkerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
279
+ const markerPath = nonClobberingSidecarPath(desiredMarkerPath);
280
+ try {
281
+ const original = readFileSync(source.path, "utf-8");
282
+ if (markerPath !== desiredMarkerPath) {
283
+ logger?.warn?.(`Preserving existing legacy AFT marker ${desiredMarkerPath}; writing new marker to ${markerPath}`);
284
+ }
285
+ atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename(source.path), original));
286
+ unlinkSync(source.path);
287
+ info?.(`Moved legacy AFT config ${source.path} aside to ${markerPath}; AFT now reads ${targetPath}`);
288
+ }
289
+ catch (err) {
290
+ const msg = err instanceof Error ? err.message : String(err);
291
+ warnings.push(`AFT could not move legacy config ${source.path} aside (${msg}); it is now stale and ignored. Delete it manually — AFT reads ${targetPath}.`);
292
+ logger?.warn?.(`Could not move legacy AFT config ${source.path} aside (${msg}); AFT reads ${targetPath}`);
293
+ }
294
+ }
295
+ return warnings;
296
+ }
297
+ const PRESERVED_OLD_SUFFIX = "_OLD";
298
+ function preservedOldContent(losingHarness, winningHarness, targetPath, originalContent) {
299
+ const winnerLine = winningHarness
300
+ ? `// configs differed, so ${winningHarness}'s config won (first harness to run the`
301
+ : "// configs differed, so the config that was migrated first won and is the";
302
+ const header = [
303
+ `// AFT config from ${losingHarness} — preserved, NOT read.`,
304
+ "//",
305
+ "// AFT now reads one shared config for all harnesses. Your OpenCode and Pi",
306
+ winnerLine,
307
+ winningHarness ? "// migration) and is now the active config at:" : "// active config at:",
308
+ "//",
309
+ `// ${targetPath}`,
310
+ "//",
311
+ `// This file holds ${losingHarness}'s previous settings. Merge anything you`,
312
+ "// want to keep into the active config above, then delete this file. AFT does",
313
+ "// not read this path.",
314
+ "",
315
+ "",
316
+ ].join("\n");
317
+ return `${header}${originalContent}`;
318
+ }
319
+ // When two harnesses have DIFFERENT legacy configs, the operating harness's
320
+ // config wins (becomes the shared target) and the other's is preserved beside
321
+ // the target as `<target>.<harness>_OLD` so the user can merge it. This replaces
322
+ // the old refuse-and-write-nothing behavior, which dropped the plugin to default
323
+ // config and could wipe a fingerprint-keyed semantic index. `winningHarness` is
324
+ // undefined when the target already existed (we don't know which harness wrote
325
+ // it first), in which case the message describes the existing shared config.
326
+ function preserveDifferingSourceAsOld(source, winningHarness, targetPath, logger) {
327
+ const losingHarness = source.harness ?? "pi";
328
+ const desiredOldPath = `${targetPath}.${losingHarness}${PRESERVED_OLD_SUFFIX}`;
329
+ const oldPath = nonClobberingSidecarPath(desiredOldPath);
330
+ try {
331
+ if (oldPath !== desiredOldPath) {
332
+ logger?.warn?.(`Preserving existing ${losingHarness} config sidecar ${desiredOldPath}; writing new preserved config to ${oldPath}`);
333
+ }
334
+ atomicWriteConfigFile(oldPath, preservedOldContent(losingHarness, winningHarness, targetPath, source.content));
335
+ }
336
+ catch (err) {
337
+ const msg = err instanceof Error ? err.message : String(err);
338
+ logger?.warn?.(`Could not preserve ${losingHarness} config as ${oldPath} (${msg})`);
339
+ }
340
+ const usingDesc = winningHarness ? `${winningHarness}'s config` : "the existing shared config";
341
+ return (`AFT found different OpenCode and Pi configs during config unification. ` +
342
+ `Using ${usingDesc} at ${targetPath}; preserved ${losingHarness}'s previous ` +
343
+ `config at ${oldPath} — merge any settings you want to keep, then delete it.`);
344
+ }
345
+ function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
346
+ const uniquePaths = [...new Set([targetPath, ...paths])];
347
+ return (`AFT ${scope} config migration refused: ${reason}. ` +
348
+ `Legacy and CortexKit config paths collapse to one file, but AFT will not overwrite or merge them automatically. ` +
349
+ `Please consolidate manually into ${targetPath}. Paths: ${uniquePaths.join(" ; ")}`);
350
+ }
351
+ export function migrateAftConfigFile(opts) {
352
+ const warnings = [];
353
+ // A legacy source path can resolve to the SAME file as the CortexKit target
354
+ // (e.g. OPENCODE_CONFIG_DIR pointed at ~/.config/cortexkit, so the legacy
355
+ // `<opencode-config>/aft.jsonc` IS `~/.config/cortexkit/aft.jsonc`). That file
356
+ // is the live, already-migrated config — never a legacy source to copy from,
357
+ // preserve, or (critically) `unlinkSync` aside. Dropping it here prevents the
358
+ // active config from being deleted, which would fall the plugin back to
359
+ // defaults and wipe the fingerprint-keyed semantic index (the MC incident).
360
+ const resolvedTarget = resolve(opts.targetPath);
361
+ const existingSources = opts.legacySources.filter((source) => existsSync(source.path) && resolve(source.path) !== resolvedTarget);
362
+ const info = opts.logger?.info ?? opts.logger?.log;
363
+ if (existingSources.length === 0) {
364
+ return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
365
+ }
366
+ mkdirSync(dirname(opts.targetPath), { recursive: true });
367
+ const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
368
+ try {
369
+ const sources = existingSources.map((source) => ({
370
+ ...source,
371
+ content: readFileSync(source.path, "utf-8"),
372
+ }));
373
+ // Target already exists: first-opened wins permanently. We never overwrite
374
+ // it (whichever harness migrated first owns the shared config). Any legacy
375
+ // source that DIFFERS from it is preserved beside the target as
376
+ // `<target>.<harness>_OLD` for manual merge; matching ones are just cleared.
377
+ if (existsSync(opts.targetPath)) {
378
+ const targetContent = readFileSync(opts.targetPath, "utf-8");
379
+ for (const source of sources) {
380
+ if (fileSemanticsMatch(source.content, targetContent))
381
+ continue;
382
+ warnings.push(preserveDifferingSourceAsOld(source, undefined, opts.targetPath, opts.logger));
383
+ }
384
+ info?.(`AFT ${opts.scope} config already present at ${opts.targetPath}; reconciled ${sources.length} legacy source(s)`);
385
+ warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
386
+ return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
387
+ }
388
+ // Target does not exist yet. Pick the winner: the operating harness's source
389
+ // if present, else the first source by list order (back-compat for callers
390
+ // that don't pass operatingHarness). The winner's config becomes the shared
391
+ // target; any OTHER source that differs is preserved as `<target>.<harness>_OLD`.
392
+ const winner = (opts.operatingHarness
393
+ ? sources.find((source) => source.harness === opts.operatingHarness)
394
+ : undefined) ?? sources[0];
395
+ atomicCopyConfigFile(winner.path, opts.targetPath);
396
+ info?.(`Migrated AFT ${opts.scope} config from ${winner.path} to ${opts.targetPath}`);
397
+ for (const source of sources) {
398
+ if (source.path === winner.path)
399
+ continue;
400
+ if (fileSemanticsMatch(source.content, winner.content))
401
+ continue;
402
+ warnings.push(preserveDifferingSourceAsOld(source, winner.harness, opts.targetPath, opts.logger));
403
+ }
404
+ warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
405
+ return {
406
+ migrated: true,
407
+ conflict: false,
408
+ sourcePath: winner.path,
409
+ targetPath: opts.targetPath,
410
+ warnings,
411
+ };
412
+ }
413
+ catch (err) {
414
+ const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, existingSources.map((source) => source.path), `migration failed (${err instanceof Error ? err.message : String(err)})`);
415
+ warnings.push(message);
416
+ opts.logger?.warn?.(message);
417
+ return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
418
+ }
419
+ finally {
420
+ release();
421
+ }
422
+ }
41
423
  function tail(value) {
42
424
  if (!value)
43
425
  return "";