@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.
- package/dist/bash-format.d.ts +0 -1
- package/dist/bash-format.d.ts.map +1 -1
- package/dist/bash-format.js +0 -3
- package/dist/bash-format.js.map +1 -1
- package/dist/bash-hints.js +97 -9
- package/dist/bash-hints.js.map +1 -1
- package/dist/bridge.d.ts +23 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +63 -43
- package/dist/bridge.js.map +1 -1
- package/dist/callgraph-format.d.ts.map +1 -1
- package/dist/callgraph-format.js +27 -14
- package/dist/callgraph-format.js.map +1 -1
- package/dist/coerce.d.ts +39 -0
- package/dist/coerce.d.ts.map +1 -1
- package/dist/coerce.js +82 -0
- package/dist/coerce.js.map +1 -1
- package/dist/command-timeouts.d.ts.map +1 -1
- package/dist/command-timeouts.js +1 -0
- package/dist/command-timeouts.js.map +1 -1
- package/dist/config-tiers.d.ts +19 -0
- package/dist/config-tiers.d.ts.map +1 -0
- package/dist/config-tiers.js +45 -0
- package/dist/config-tiers.js.map +1 -0
- package/dist/edit-summary.d.ts +5 -0
- package/dist/edit-summary.d.ts.map +1 -1
- package/dist/edit-summary.js +12 -2
- package/dist/edit-summary.js.map +1 -1
- package/dist/index.d.ts +11 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/migration.d.ts +27 -0
- package/dist/migration.d.ts.map +1 -1
- package/dist/migration.js +384 -2
- package/dist/migration.js.map +1 -1
- package/dist/onnx-runtime.d.ts +4 -6
- package/dist/onnx-runtime.d.ts.map +1 -1
- package/dist/onnx-runtime.js +13 -15
- package/dist/onnx-runtime.js.map +1 -1
- package/dist/paths.d.ts +17 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +52 -1
- package/dist/paths.js.map +1 -1
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +15 -16
- package/dist/pool.js.map +1 -1
- package/dist/project-identity.d.ts +30 -0
- package/dist/project-identity.d.ts.map +1 -0
- package/dist/project-identity.js +69 -0
- package/dist/project-identity.js.map +1 -0
- package/package.json +1 -1
- package/dist/pipe-strip.d.ts +0 -7
- package/dist/pipe-strip.d.ts.map +0 -1
- package/dist/pipe-strip.js +0 -688
- 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"}
|
package/dist/edit-summary.js
CHANGED
|
@@ -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 +=
|
|
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 +=
|
|
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
|
package/dist/edit-summary.js.map
CHANGED
|
@@ -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;
|
|
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 {
|
|
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 {
|
|
31
|
-
export
|
|
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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EACL,
|
|
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 {
|
|
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,
|
|
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"}
|
package/dist/migration.d.ts
CHANGED
|
@@ -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.
|
package/dist/migration.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
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 "";
|