@cortexkit/aft-opencode 0.49.4 → 0.50.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.
@@ -177,9 +177,12 @@ export declare function handleIdleBgCompletions(drainContext: DrainContext & {
177
177
  * `forcedDrainCompleted` is set and nothing is locally outstanding, it skips the
178
178
  * drain. A subc completion can be for a task this process never tracked (a prior
179
179
  * session, or one whose outstanding entry was already cleared), so the gated
180
- * drain would skip it and the module would re-arm and nudge forever. This path
181
- * forces an UNCONDITIONAL drain so the completion is fetched, delivered, and
182
- * acked (which makes the module's CLEAR fire and the nudges stop).
180
+ * drain would skip it and the module would re-arm and nudge forever. The
181
+ * module-side loop is
182
+ * `crates/aft/src/subc/push.rs::{emit_bg_event_wakes,clear_stale_bg_wakes_for_empty_sessions}`:
183
+ * it re-emits pending wakes until ack empties the queue, so coalescing a duplicate
184
+ * while this handler is in flight is safe. This path forces an UNCONDITIONAL drain
185
+ * so the completion is fetched, delivered, and acked.
183
186
  */
184
187
  export declare function handleSubcBgEventsNudge(drainContext: DrainContext & {
185
188
  client: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -10,6 +10,10 @@ export type ConfigureWarningsDelivery = z.infer<typeof ConfigureWarningsDelivery
10
10
  export declare const AftConfigSchema: z.ZodPreprocess<z.ZodObject<{
11
11
  $schema: z.ZodOptional<z.ZodString>;
12
12
  enabled: z.ZodOptional<z.ZodBoolean>;
13
+ edit_mode: z.ZodOptional<z.ZodEnum<{
14
+ default: "default";
15
+ hashline: "hashline";
16
+ }>>;
13
17
  format_on_edit: z.ZodOptional<z.ZodBoolean>;
14
18
  formatter_timeout_secs: z.ZodOptional<z.ZodNumber>;
15
19
  validate_on_edit: z.ZodOptional<z.ZodEnum<{
@@ -271,6 +275,8 @@ export interface ResolvedAftConfigPaths {
271
275
  }
272
276
  export declare function migrateAftConfigLocations(projectDirectory: string, logger?: Logger): AftConfigFileMigrationResult[];
273
277
  export declare function resolveAftConfigPaths(projectDirectory: string): ResolvedAftConfigPaths;
278
+ /** Resolve the checkout whose project config controls OpenCode's registered tool schema. */
279
+ export declare function resolveOpenCodeRegistrationRoot(directory: string, worktree?: string): string;
274
280
  export declare function buildConfigTierConfigureParams(projectDirectory: string, processState?: Record<string, unknown>): Record<string, unknown> & {
275
281
  config: ConfigTier[];
276
282
  cortexkit_user_config_path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,UAAU,EAQhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB,oGAAoG;AACpG,eAAO,MAAM,6BAA6B;;;;EAAmC,CAAC;AAC9E,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAsNtF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAsH3B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,8BAA8B;IAC7C,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,kCAAkC,CAAC,EAAE,OAAO,CAAC;IAC7C,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAMD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,qBAAqB,CAuDrF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiC9F;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,mBAAmB,EAAE,OAAO,CAAC;IAC7B,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C;;;OAGG;IACH,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED,iEAAiE;AACjE,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,kBAAkB,CA0FvE;AAED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,SAAS,GAChB,8BAA8B,CAsBhC;AAED,KAAK,MAAM,GAAG;IACZ,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAoMF,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAsB,GAC7B;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAwD1C;AA4DD,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAIhE,oFAAoF;AACpF,wBAAgB,mBAAmB,IAAI,SAAS,eAAe,EAAE,CAEhE;AAED,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKhG;AAsWD,8DAA8D;AAC9D,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,oKAAoK;AACpK,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAGhD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAElE;AAED,8EAA8E;AAC9E,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,SAAS,GAAG;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB,CAKA;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,yBAAyB,CACvC,gBAAgB,EAAE,MAAM,EACxB,MAAM,GAAE,MAAsB,GAC7B,4BAA4B,EAAE,CAmBhC;AAED,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,sBAAsB,CAKtF;AAED,4FAA4F;AAC5F,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5F;AAED,wBAAgB,8BAA8B,CAC5C,gBAAgB,EAAE,MAAM,EACxB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACzC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC3B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,0BAA0B,EAAE,MAAM,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAkBA;AAMD,wBAAgB,aAAa,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAoCjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAoMlD;;;;;;;;;;;;;;;;GAgBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AAyhC5E,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAyMlD;;;;;;;;;;;;;;;;GAgBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AA8jC5E,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -8334,6 +8334,8 @@ var DEFAULT_BRIDGE_TIMEOUT_MS = 30000;
8334
8334
  var BRIDGE_HANG_TIMEOUT_THRESHOLD = 2;
8335
8335
  var MAX_STDOUT_BUFFER = 64 * 1024 * 1024;
8336
8336
  var STDOUT_BUFFER_COMPACT_THRESHOLD = 64 * 1024;
8337
+ var HASHLINE_REGISTRATION_LOG_INTERVAL_MS = 60000;
8338
+ var HASHLINE_REGISTRATION_LOG_STATE_LIMIT = 256;
8337
8339
  var TERMINAL_BASH_STATUSES = new Set([
8338
8340
  "completed",
8339
8341
  "failed",
@@ -8483,6 +8485,9 @@ class BinaryBridge {
8483
8485
  configured = false;
8484
8486
  _configurePromise = null;
8485
8487
  configOverrides;
8488
+ editSlotSurvives;
8489
+ editSlotSurvivesCaptured = false;
8490
+ hashlineRegistrationLogState = new Map;
8486
8491
  minVersion;
8487
8492
  onVersionMismatch;
8488
8493
  onConfigureWarnings;
@@ -8499,20 +8504,33 @@ class BinaryBridge {
8499
8504
  errorPrefix;
8500
8505
  logger;
8501
8506
  childEnv;
8502
- constructor(binaryPath, cwd, options, configOverrides) {
8507
+ constructor(binaryPath, cwd, options, configOverrides, editSlotSurvives) {
8503
8508
  this.binaryPath = binaryPath;
8504
8509
  this.cwd = cwd;
8505
8510
  this.timeoutMs = options?.timeoutMs ?? DEFAULT_BRIDGE_TIMEOUT_MS;
8506
8511
  this.hangThreshold = options?.hangThreshold ?? BRIDGE_HANG_TIMEOUT_THRESHOLD;
8507
8512
  this.maxRestarts = options?.maxRestarts ?? 3;
8508
- this.configOverrides = configOverrides ?? {};
8513
+ this.errorPrefix = options?.errorPrefix ?? "[aft-bridge]";
8514
+ this.configOverrides = { ...configOverrides ?? {} };
8515
+ const legacyEditSlotSurvives = this.configOverrides.edit_slot_survives;
8516
+ delete this.configOverrides.edit_slot_survives;
8517
+ if (legacyEditSlotSurvives !== undefined && typeof legacyEditSlotSurvives !== "boolean") {
8518
+ throw new Error(`${this.errorPrefix} edit_slot_survives must be a boolean`);
8519
+ }
8520
+ if (editSlotSurvives !== undefined && legacyEditSlotSurvives !== undefined && editSlotSurvives !== legacyEditSlotSurvives) {
8521
+ throw new Error(`${this.errorPrefix} conflicting edit_slot_survives construction values`);
8522
+ }
8523
+ const capturedEditSlotSurvives = editSlotSurvives ?? legacyEditSlotSurvives;
8524
+ if (typeof capturedEditSlotSurvives === "boolean") {
8525
+ this.editSlotSurvives = capturedEditSlotSurvives;
8526
+ this.editSlotSurvivesCaptured = true;
8527
+ }
8509
8528
  this.minVersion = options?.minVersion;
8510
8529
  this.onVersionMismatch = options?.onVersionMismatch;
8511
8530
  this.onConfigureWarnings = options?.onConfigureWarnings;
8512
8531
  this.onBashCompletion = options?.onBashCompletion;
8513
8532
  this.onBashLongRunning = options?.onBashLongRunning;
8514
8533
  this.onBashPatternMatch = options?.onBashPatternMatch;
8515
- this.errorPrefix = options?.errorPrefix ?? "[aft-bridge]";
8516
8534
  this.logger = options?.logger;
8517
8535
  this.childEnv = options?.childEnv;
8518
8536
  }
@@ -8623,13 +8641,54 @@ class BinaryBridge {
8623
8641
  cacheStatusSnapshot(snapshot) {
8624
8642
  this.cachedStatus = snapshot;
8625
8643
  }
8644
+ setEditSlotSurvives(value) {
8645
+ if (this.editSlotSurvivesCaptured) {
8646
+ throw new Error(`${this.errorPrefix} edit_slot_survives is write-once and was already captured`);
8647
+ }
8648
+ this.editSlotSurvives = value;
8649
+ this.editSlotSurvivesCaptured = true;
8650
+ }
8651
+ logHashlineRegistrationCarrier(phase, sessionId, editSlotSurvives) {
8652
+ const session = sessionId && sessionId.length > 0 ? sessionId : "__default__";
8653
+ const key = `${phase}\x00${session}\x00${String(editSlotSurvives)}`;
8654
+ const now = Date.now();
8655
+ const state = this.hashlineRegistrationLogState.get(key);
8656
+ if (state && now - state.lastEmittedAt < HASHLINE_REGISTRATION_LOG_INTERVAL_MS) {
8657
+ state.suppressed += 1;
8658
+ return;
8659
+ }
8660
+ const repeated = state && state.suppressed > 0 ? ` repeated=${state.suppressed + 1}` : "";
8661
+ if (!state && this.hashlineRegistrationLogState.size >= HASHLINE_REGISTRATION_LOG_STATE_LIMIT) {
8662
+ const oldest = this.hashlineRegistrationLogState.keys().next().value;
8663
+ if (oldest !== undefined)
8664
+ this.hashlineRegistrationLogState.delete(oldest);
8665
+ }
8666
+ this.hashlineRegistrationLogState.set(key, { lastEmittedAt: now, suppressed: 0 });
8667
+ this.sessionLogVia(sessionId, `hashline registration carrier transport=ndjson phase=${phase} edit_slot_survives=${editSlotSurvives}${repeated}`);
8668
+ }
8626
8669
  async send(command, params = {}, options) {
8627
- return this.sendWithVersionMismatchRetry(command, params, options, true);
8670
+ let dispatchParams = params;
8671
+ if (command === "configure") {
8672
+ dispatchParams = { ...params };
8673
+ delete dispatchParams.edit_slot_survives;
8674
+ const editSlotSurvives = this.editSlotSurvives;
8675
+ if (this.editSlotSurvivesCaptured && typeof editSlotSurvives === "boolean") {
8676
+ dispatchParams.edit_slot_survives = editSlotSurvives;
8677
+ const sessionId = typeof dispatchParams.session_id === "string" ? dispatchParams.session_id : undefined;
8678
+ this.logHashlineRegistrationCarrier("configure", sessionId, editSlotSurvives);
8679
+ }
8680
+ }
8681
+ return this.sendWithVersionMismatchRetry(command, dispatchParams, options, true);
8628
8682
  }
8629
8683
  async toolCall(sessionId, name, rawArgs = {}, options) {
8630
8684
  const params = { name, arguments: rawArgs };
8631
8685
  if (sessionId)
8632
8686
  params.session_id = sessionId;
8687
+ const editSlotSurvives = this.editSlotSurvives;
8688
+ if (this.editSlotSurvivesCaptured && typeof editSlotSurvives === "boolean") {
8689
+ params.edit_slot_survives = editSlotSurvives;
8690
+ this.logHashlineRegistrationCarrier("tool_call", sessionId, editSlotSurvives);
8691
+ }
8633
8692
  const { preview, ...sendOptions } = options ?? {};
8634
8693
  if (preview === true)
8635
8694
  params.preview = true;
@@ -12483,6 +12542,8 @@ function projectRootKeyHash(dir) {
12483
12542
  var AFT_MODULE_ID = "aft";
12484
12543
  var MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3;
12485
12544
  var BG_STABLE_MS = 5000;
12545
+ var BG_LIFECYCLE_LOG_INTERVAL_MS = 60000;
12546
+ var BG_DISPATCH_PROBE_INTERVAL_MS = 60000;
12486
12547
  var DEFAULT_SESSION_ID = "__default__";
12487
12548
  var LOCALLY_SATISFIED_COMMANDS = new Set(["configure"]);
12488
12549
 
@@ -12545,12 +12606,15 @@ class BgSubscription {
12545
12606
  canAttach;
12546
12607
  onRootAttachFailure;
12547
12608
  onDormant;
12609
+ dispatchProbeIntervalMs;
12548
12610
  nudgeRef;
12549
12611
  isCurrent;
12550
12612
  stopped = false;
12551
12613
  current = null;
12552
12614
  loop;
12553
- constructor(identity, acquireClient, dropClient, consumerIdentity, onNudge, sleep2, canAttach, onRootAttachFailure, onDormant, nudgeRef, isCurrent = () => true) {
12615
+ lifecycleLogState = new Map;
12616
+ nudgeReceiptLogState = null;
12617
+ constructor(identity, acquireClient, dropClient, consumerIdentity, onNudge, sleep2, canAttach, onRootAttachFailure, onDormant, dispatchProbeIntervalMs, nudgeRef, isCurrent = () => true) {
12554
12618
  this.identity = identity;
12555
12619
  this.acquireClient = acquireClient;
12556
12620
  this.dropClient = dropClient;
@@ -12560,6 +12624,7 @@ class BgSubscription {
12560
12624
  this.canAttach = canAttach;
12561
12625
  this.onRootAttachFailure = onRootAttachFailure;
12562
12626
  this.onDormant = onDormant;
12627
+ this.dispatchProbeIntervalMs = dispatchProbeIntervalMs;
12563
12628
  this.nudgeRef = nudgeRef;
12564
12629
  this.isCurrent = isCurrent;
12565
12630
  this.loop = this.run();
@@ -12576,25 +12641,106 @@ class BgSubscription {
12576
12641
  return;
12577
12642
  });
12578
12643
  }
12644
+ info(kind, message) {
12645
+ const now = Date.now();
12646
+ const state = this.lifecycleLogState.get(kind);
12647
+ if (state && now - state.lastEmittedAt < BG_LIFECYCLE_LOG_INTERVAL_MS) {
12648
+ state.suppressed += 1;
12649
+ return;
12650
+ }
12651
+ const suppressed = state?.suppressed ?? 0;
12652
+ this.lifecycleLogState.set(kind, { lastEmittedAt: now, suppressed: 0 });
12653
+ const suffix = suppressed > 0 ? ` suppressed=${suppressed}` : "";
12654
+ log(`subc bg_events: ${message}${suffix}`, { sessionId: this.identity.session });
12655
+ }
12656
+ routeId(route) {
12657
+ return `${route.channel}@${route.epoch}`;
12658
+ }
12659
+ recordNudgeReceipt(routeId) {
12660
+ const now = Date.now();
12661
+ const state = this.nudgeReceiptLogState;
12662
+ if (state && now - state.lastEmittedAt < BG_LIFECYCLE_LOG_INTERVAL_MS) {
12663
+ state.count += 1;
12664
+ return;
12665
+ }
12666
+ const count = (state?.count ?? 0) + 1;
12667
+ this.nudgeReceiptLogState = { lastEmittedAt: now, count: 0 };
12668
+ log(`subc bg_events: nudge received channel=${routeId} count=${count}`, {
12669
+ sessionId: this.identity.session
12670
+ });
12671
+ }
12672
+ errorText(error2) {
12673
+ return error2 instanceof Error ? `${error2.name}: ${error2.message}` : String(error2);
12674
+ }
12675
+ startDispatchProbe(client, routeId) {
12676
+ const initial = client.droppedIngressFrames;
12677
+ if (typeof initial !== "number")
12678
+ return () => {
12679
+ return;
12680
+ };
12681
+ let previous = initial;
12682
+ const timer = setInterval(() => {
12683
+ const total = client.droppedIngressFrames;
12684
+ if (typeof total !== "number" || total <= previous)
12685
+ return;
12686
+ const delta = total - previous;
12687
+ previous = total;
12688
+ this.info("dispatch-epoch-drop", `client ingress epoch drops scope=client observed_while_channel=${routeId} delta=${delta} total=${total}`);
12689
+ }, this.dispatchProbeIntervalMs);
12690
+ timer.unref?.();
12691
+ return () => clearInterval(timer);
12692
+ }
12579
12693
  async run() {
12580
- let attempt = 0;
12694
+ let backoffAttempt = 0;
12695
+ let reconnectAttempt = 0;
12696
+ let reconnecting = false;
12697
+ const beginReconnect = () => {
12698
+ reconnecting = true;
12699
+ reconnectAttempt = reconnectAttempt === 0 ? 1 : reconnectAttempt + 1;
12700
+ };
12701
+ const giveUp = (reason) => {
12702
+ this.info("reconnect-gave-up", `reconnect gave-up attempt=${reconnectAttempt} reason=${reason}`);
12703
+ };
12581
12704
  while (!this.stopped) {
12582
- if (!this.isCurrent())
12705
+ if (!this.isCurrent()) {
12706
+ if (reconnecting)
12707
+ giveUp("stale-session");
12583
12708
  return;
12709
+ }
12584
12710
  if (!this.canAttach()) {
12711
+ if (reconnecting)
12712
+ giveUp("root-dormant");
12585
12713
  this.onDormant();
12586
12714
  return;
12587
12715
  }
12716
+ if (reconnecting) {
12717
+ this.info("reconnect-attempt", `reconnect attempt=${reconnectAttempt}`);
12718
+ }
12588
12719
  let client;
12589
12720
  try {
12590
12721
  client = await this.acquireClient();
12591
- } catch {
12592
- await this.backoff(attempt++);
12722
+ } catch (err) {
12723
+ if (!reconnecting)
12724
+ beginReconnect();
12725
+ this.info("reconnect-error", `reconnect error attempt=${reconnectAttempt} error=${this.errorText(err)}`);
12726
+ await this.backoff(backoffAttempt++);
12727
+ if (reconnecting)
12728
+ reconnectAttempt += 1;
12593
12729
  continue;
12594
12730
  }
12595
- if (this.stopped || !this.isCurrent())
12731
+ if (this.stopped) {
12732
+ if (reconnecting)
12733
+ giveUp("stopped");
12734
+ return;
12735
+ }
12736
+ if (!this.isCurrent()) {
12737
+ if (reconnecting)
12738
+ giveUp("stale-session");
12596
12739
  return;
12740
+ }
12597
12741
  if (!this.canAttach()) {
12742
+ if (reconnecting)
12743
+ giveUp("root-dormant");
12598
12744
  this.onDormant();
12599
12745
  return;
12600
12746
  }
@@ -12603,44 +12749,84 @@ class BgSubscription {
12603
12749
  route = await client.routeOpen({ kind: "tool_provider", module_id: AFT_MODULE_ID }, this.identity, { consumerIdentity: this.consumerIdentity });
12604
12750
  } catch (err) {
12605
12751
  if (this.isCurrent() && this.onRootAttachFailure(err)) {
12752
+ if (reconnecting)
12753
+ giveUp("root-dormant");
12606
12754
  this.onDormant();
12607
12755
  return;
12608
12756
  }
12609
12757
  if (isConsumerReconnectTransient(err))
12610
12758
  this.dropClient(client);
12611
- await this.backoff(attempt++);
12759
+ if (!reconnecting)
12760
+ beginReconnect();
12761
+ this.info("reconnect-error", `reconnect error attempt=${reconnectAttempt} error=${this.errorText(err)}`);
12762
+ await this.backoff(backoffAttempt++);
12763
+ if (reconnecting)
12764
+ reconnectAttempt += 1;
12612
12765
  continue;
12613
12766
  }
12614
12767
  if (this.stopped || !this.isCurrent()) {
12615
12768
  safeCloseRoute(client, route);
12769
+ if (reconnecting)
12770
+ giveUp(this.stopped ? "stopped" : "stale-session");
12616
12771
  return;
12617
12772
  }
12618
12773
  const subscribedAt = Date.now();
12774
+ const routeId = this.routeId(route);
12775
+ let stopDispatchProbe = () => {
12776
+ return;
12777
+ };
12619
12778
  try {
12620
12779
  const sub = client.subscribe(route, { op: "bg_events" }, () => {
12621
- if (!this.stopped && this.isCurrent())
12622
- this.onNudge();
12780
+ if (this.stopped) {
12781
+ this.info("nudge-drop-stopped", `nudge dropped cause=subscription-stopped channel=${routeId}`);
12782
+ return;
12783
+ }
12784
+ this.recordNudgeReceipt(routeId);
12785
+ if (!this.isCurrent()) {
12786
+ this.info("nudge-stale-carrier", `nudge carried by stale subscription; checking current session channel=${routeId}`);
12787
+ }
12788
+ this.onNudge();
12623
12789
  });
12624
12790
  this.current = sub;
12791
+ stopDispatchProbe = this.startDispatchProbe(client, routeId);
12792
+ this.info("subscription-open", `subscription open channel=${routeId}`);
12793
+ if (reconnecting) {
12794
+ this.info("reconnect-success", `reconnect success attempt=${reconnectAttempt} channel=${routeId}`);
12795
+ reconnecting = false;
12796
+ reconnectAttempt = 0;
12797
+ }
12625
12798
  if (this.stopped)
12626
12799
  sub.unsubscribe();
12627
12800
  if (!this.stopped && this.isCurrent())
12628
12801
  this.onNudge();
12629
12802
  await sub.closed;
12630
- return;
12803
+ this.info("stream-end", `stream ended channel=${routeId}`);
12804
+ if (this.stopped) {
12805
+ giveUp("stopped");
12806
+ return;
12807
+ }
12808
+ beginReconnect();
12631
12809
  } catch (err) {
12632
- if (this.stopped)
12810
+ const routeId2 = this.routeId(route);
12811
+ this.info("stream-error", `stream error channel=${routeId2} error=${this.errorText(err)}`);
12812
+ if (this.stopped) {
12813
+ giveUp("stopped");
12633
12814
  return;
12815
+ }
12634
12816
  if (isConsumerReconnectTransient(err))
12635
12817
  this.dropClient(client);
12636
12818
  if (Date.now() - subscribedAt >= BG_STABLE_MS)
12637
- attempt = 0;
12819
+ backoffAttempt = 0;
12820
+ beginReconnect();
12638
12821
  } finally {
12822
+ stopDispatchProbe();
12639
12823
  this.current = null;
12640
12824
  safeCloseRoute(client, route);
12641
12825
  }
12642
- await this.backoff(attempt++);
12826
+ await this.backoff(backoffAttempt++);
12643
12827
  }
12828
+ if (reconnecting)
12829
+ giveUp("stopped");
12644
12830
  }
12645
12831
  async backoff(attempt) {
12646
12832
  const ms = Math.min(100 * 2 ** Math.min(attempt, 6), 2000);
@@ -12738,6 +12924,9 @@ class SubcTransport {
12738
12924
  this.assertCurrent();
12739
12925
  const { preview, timeoutMs, onProgress } = this.splitOptions(options);
12740
12926
  const body = { name, arguments: rawArgs };
12927
+ const editSlotSurvives = this.pool.getEditSlotSurvives();
12928
+ if (editSlotSurvives !== undefined)
12929
+ body.edit_slot_survives = editSlotSurvives;
12741
12930
  if (preview === true)
12742
12931
  body.preview = true;
12743
12932
  const reply = await this.pool.routeRequest(this.identityFor(sessionId), body, timeoutMs, onProgress, this.generation);
@@ -12752,7 +12941,11 @@ class SubcTransport {
12752
12941
  }
12753
12942
  const { timeoutMs, onProgress } = this.splitOptions(options);
12754
12943
  const session = typeof params.session_id === "string" ? params.session_id : undefined;
12755
- const reply = await this.pool.routeRequest(this.identityFor(session), { name: command, arguments: params }, timeoutMs, onProgress, this.generation);
12944
+ const body = { name: command, arguments: params };
12945
+ const editSlotSurvives = this.pool.getEditSlotSurvives();
12946
+ if (editSlotSurvives !== undefined)
12947
+ body.edit_slot_survives = editSlotSurvives;
12948
+ const reply = await this.pool.routeRequest(this.identityFor(session), body, timeoutMs, onProgress, this.generation);
12756
12949
  const response = reliftReply(reply);
12757
12950
  this.captureStatusBar(response);
12758
12951
  return response;
@@ -12776,6 +12969,7 @@ class SubcTransportPool {
12776
12969
  onBgEventsNudge;
12777
12970
  onBgEventsNudgeRef;
12778
12971
  bgBackoffSleep;
12972
+ bgDispatchProbeIntervalMs;
12779
12973
  lifecycleDemandCheck;
12780
12974
  onLifecycleEvent;
12781
12975
  onBgNudgeRejected;
@@ -12791,8 +12985,11 @@ class SubcTransportPool {
12791
12985
  transportFailures = 0;
12792
12986
  transports = new Map;
12793
12987
  generationRejections = new Set;
12988
+ nudgeDeliveryLogState = new Map;
12794
12989
  pendingRootCleanups = new Set;
12795
12990
  shuttingDown = false;
12991
+ editSlotSurvives;
12992
+ editSlotSurvivesCaptured = false;
12796
12993
  constructor(options) {
12797
12994
  this.connectionFile = options.connectionFile;
12798
12995
  this.harness = options.harness;
@@ -12802,6 +12999,7 @@ class SubcTransportPool {
12802
12999
  this.onBgEventsNudge = options.onBgEventsNudge;
12803
13000
  this.onBgEventsNudgeRef = options.onBgEventsNudgeRef;
12804
13001
  this.bgBackoffSleep = options.bgBackoffSleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
13002
+ this.bgDispatchProbeIntervalMs = options.bgDispatchProbeIntervalMs ?? BG_DISPATCH_PROBE_INTERVAL_MS;
12805
13003
  const lifecycle = options.lifecycle;
12806
13004
  const demandCheck = options.lifecycleDemandCheck ?? options.demandCheck ?? lifecycle?.demandCheck;
12807
13005
  this.lifecycleDemandCheck = demandCheck;
@@ -13118,6 +13316,35 @@ class SubcTransportPool {
13118
13316
  isCurrentSession(key, record) {
13119
13317
  return this.sessions.get(key) === record && !record.closed;
13120
13318
  }
13319
+ currentSessionForNudge(identity) {
13320
+ const current = this.sessions.get(identityKey(identity));
13321
+ return current && !current.closed ? current : null;
13322
+ }
13323
+ nudgeRefFor(record) {
13324
+ const poolId = this.currentPoolId();
13325
+ const generation = record.generation;
13326
+ if (poolId === undefined || generation === undefined)
13327
+ return;
13328
+ return {
13329
+ canonicalRoot: record.canonicalRoot,
13330
+ session: record.identity.session,
13331
+ concretePoolId: poolId,
13332
+ generation
13333
+ };
13334
+ }
13335
+ logNudgeDelivery(kind, record, message) {
13336
+ const key = `${kind}\x00${record.identityKey}`;
13337
+ const now = Date.now();
13338
+ const state = this.nudgeDeliveryLogState.get(key);
13339
+ if (state && now - state.lastEmittedAt < BG_LIFECYCLE_LOG_INTERVAL_MS) {
13340
+ state.suppressed += 1;
13341
+ return;
13342
+ }
13343
+ const suppressed = state?.suppressed ?? 0;
13344
+ this.nudgeDeliveryLogState.set(key, { lastEmittedAt: now, suppressed: 0 });
13345
+ const suffix = suppressed > 0 ? ` suppressed=${suppressed}` : "";
13346
+ log(`subc bg_events: ${message}${suffix}`, { sessionId: record.identity.session });
13347
+ }
13121
13348
  removeIndexMembership(record) {
13122
13349
  const keys = this.rootIndex.get(record.canonicalRoot);
13123
13350
  if (!keys)
@@ -13371,20 +13598,32 @@ class SubcTransportPool {
13371
13598
  return;
13372
13599
  if (record.bgSub)
13373
13600
  return;
13374
- const poolId = this.currentPoolId();
13375
- const generation = record.generation;
13376
- const nudgeRef = poolId !== undefined && generation !== undefined ? {
13377
- canonicalRoot: record.canonicalRoot,
13378
- session: identity.session,
13379
- concretePoolId: poolId,
13380
- generation
13381
- } : undefined;
13601
+ const nudgeRef = this.nudgeRefFor(record);
13382
13602
  const onNudge = () => {
13383
- if (!this.isCurrentSession(record.identityKey, record))
13603
+ const currentRecord = this.currentSessionForNudge(identity);
13604
+ if (!currentRecord) {
13605
+ this.logNudgeDelivery("drop-no-current-session", record, `nudge dropped cause=no-current-session root=${record.canonicalRoot}`);
13384
13606
  return;
13385
- this.onBgEventsNudge?.(identity.project_root, identity.session);
13386
- if (nudgeRef)
13387
- this.onBgEventsNudgeRef?.(nudgeRef);
13607
+ }
13608
+ if (currentRecord !== record) {
13609
+ this.logNudgeDelivery("forward-superseded-carrier", currentRecord, `nudge forwarding cause=superseded-carrying-record root=${currentRecord.canonicalRoot}`);
13610
+ }
13611
+ const currentRef = this.nudgeRefFor(currentRecord);
13612
+ let delivered = false;
13613
+ if (currentRef && this.onBgEventsNudgeRef) {
13614
+ this.onBgEventsNudgeRef(currentRef);
13615
+ delivered = true;
13616
+ }
13617
+ if (this.onBgEventsNudge) {
13618
+ if (!currentRef && this.onBgEventsNudgeRef) {
13619
+ this.logNudgeDelivery("fallback-missing-generation", currentRecord, `nudge dispatch fallback=root-session-handler cause=generation-provenance-unavailable root=${currentRecord.canonicalRoot}`);
13620
+ }
13621
+ this.onBgEventsNudge(currentRecord.identity.project_root, currentRecord.identity.session);
13622
+ delivered = true;
13623
+ }
13624
+ if (delivered)
13625
+ return;
13626
+ this.logNudgeDelivery("drop-no-compatible-handler", currentRecord, `nudge dropped cause=generation-provenance-unavailable-and-root-session-handler-unwired root=${currentRecord.canonicalRoot}`);
13388
13627
  };
13389
13628
  let sub = null;
13390
13629
  const clearDormantSubscription = () => {
@@ -13396,7 +13635,7 @@ class SubcTransportPool {
13396
13635
  return false;
13397
13636
  this.markRootDormant(record.canonicalRoot, error2);
13398
13637
  return true;
13399
- }, clearDormantSubscription, nudgeRef, () => this.isCurrentSession(record.identityKey, record) && this.isCurrentLiveGeneration(record.canonicalRoot, record.generation));
13638
+ }, clearDormantSubscription, this.bgDispatchProbeIntervalMs, nudgeRef, () => this.isCurrentSession(record.identityKey, record) && this.isCurrentLiveGeneration(record.canonicalRoot, record.generation));
13400
13639
  record.bgSub = sub;
13401
13640
  if (!this.rootCanAttach(record.canonicalRoot)) {
13402
13641
  record.bgSub = null;
@@ -13458,7 +13697,21 @@ class SubcTransportPool {
13458
13697
  return Promise.resolve();
13459
13698
  return registry.requestProjectRootClose(registration.concretePoolId, root, generation, cause);
13460
13699
  }
13461
- setConfigureOverride(_key, _value) {}
13700
+ setConfigureOverride(key, value) {
13701
+ if (key !== "edit_slot_survives")
13702
+ return;
13703
+ if (typeof value !== "boolean") {
13704
+ throw new Error("edit_slot_survives must be set once to a boolean");
13705
+ }
13706
+ if (this.editSlotSurvivesCaptured) {
13707
+ throw new Error("edit_slot_survives is write-once and was already captured");
13708
+ }
13709
+ this.editSlotSurvives = value;
13710
+ this.editSlotSurvivesCaptured = true;
13711
+ }
13712
+ getEditSlotSurvives() {
13713
+ return this.editSlotSurvives;
13714
+ }
13462
13715
  async reconfigure(_projectRoot, _overrides) {}
13463
13716
  async replaceBinary(path2) {
13464
13717
  return path2;
@@ -13536,14 +13789,29 @@ function toolErrorFromResponse(command, response) {
13536
13789
  return new AftToolError(message, code, response);
13537
13790
  }
13538
13791
  var BASH_TRANSPORT_DISPOSITION = "The transport to the AFT daemon was interrupted; no background task was created for this command and no task ID exists. Re-run the command. Do not poll bash_status for it.";
13792
+ var SUBC_MODULE_RESTART_DISPOSITION = "The AFT daemon module restarted while this call was in flight, so its outcome is UNKNOWN: it may or may not have executed. Verify actual state before re-running, and never blind-retry a mutation.";
13793
+ function isRouteGoodbyeError(error2) {
13794
+ if (!(error2 instanceof SubcError))
13795
+ return false;
13796
+ if (error2.code === undefined) {
13797
+ return error2.message.includes("route closed by subc");
13798
+ }
13799
+ return error2.code === "route_closed" && error2.message.includes("route closed by subc");
13800
+ }
13539
13801
  function isTransportClassError(error2) {
13540
13802
  return isBridgeTransportTimeout(error2) || isConsumerReconnectTransient(error2) || error2 instanceof StaleRouteHandleError || error2 instanceof SubcRootGenerationExpiredError || error2 instanceof SubcRootReapedError;
13541
13803
  }
13542
13804
  function adaptToolError(command, error2) {
13543
- if (command !== "bash" || !isTransportClassError(error2))
13544
- return error2;
13545
13805
  if (!(error2 instanceof Error))
13546
13806
  return error2;
13807
+ if (isRouteGoodbyeError(error2)) {
13808
+ if (error2.message.includes(SUBC_MODULE_RESTART_DISPOSITION))
13809
+ return error2;
13810
+ error2.message = error2.message ? `${error2.message} ${SUBC_MODULE_RESTART_DISPOSITION}` : SUBC_MODULE_RESTART_DISPOSITION;
13811
+ return error2;
13812
+ }
13813
+ if (command !== "bash" || !isTransportClassError(error2))
13814
+ return error2;
13547
13815
  if (error2.message.includes(BASH_TRANSPORT_DISPOSITION))
13548
13816
  return error2;
13549
13817
  error2.message = error2.message ? `${error2.message} ${BASH_TRANSPORT_DISPOSITION}` : BASH_TRANSPORT_DISPOSITION;
@@ -15656,6 +15924,8 @@ class BridgePool {
15656
15924
  idleTimeoutMs;
15657
15925
  bridgeOptions;
15658
15926
  configOverrides;
15927
+ editSlotSurvives;
15928
+ editSlotSurvivesCaptured = false;
15659
15929
  projectConfigLoader;
15660
15930
  logger;
15661
15931
  cleanupTimer = null;
@@ -15680,7 +15950,16 @@ class BridgePool {
15680
15950
  logger: options.logger,
15681
15951
  childEnv: options.childEnv
15682
15952
  };
15683
- this.configOverrides = configOverrides;
15953
+ this.configOverrides = { ...configOverrides };
15954
+ const initialEditSlotSurvives = this.configOverrides.edit_slot_survives;
15955
+ delete this.configOverrides.edit_slot_survives;
15956
+ if (initialEditSlotSurvives !== undefined) {
15957
+ if (typeof initialEditSlotSurvives !== "boolean") {
15958
+ throw new Error("edit_slot_survives must be a boolean");
15959
+ }
15960
+ this.editSlotSurvives = initialEditSlotSurvives;
15961
+ this.editSlotSurvivesCaptured = true;
15962
+ }
15684
15963
  this.startCleanupTimer();
15685
15964
  }
15686
15965
  getActiveBridgeForRoot(projectRoot) {
@@ -15719,7 +15998,8 @@ class BridgePool {
15719
15998
  }
15720
15999
  const projectOverrides = this.loadProjectOverrides(key);
15721
16000
  const mergedOverrides = { ...this.configOverrides, ...projectOverrides };
15722
- const bridge = new BinaryBridge(this.binaryPath, key, this.bridgeOptions, mergedOverrides);
16001
+ delete mergedOverrides.edit_slot_survives;
16002
+ const bridge = new BinaryBridge(this.binaryPath, key, this.bridgeOptions, mergedOverrides, this.editSlotSurvivesCaptured ? this.editSlotSurvives : undefined);
15723
16003
  this.bridges.set(key, { bridge, lastUsed: Date.now() });
15724
16004
  return bridge;
15725
16005
  }
@@ -15823,6 +16103,23 @@ class BridgePool {
15823
16103
  error(message, meta);
15824
16104
  }
15825
16105
  setConfigureOverride(key, value) {
16106
+ if (key === "edit_slot_survives") {
16107
+ if (typeof value !== "boolean") {
16108
+ throw new Error("edit_slot_survives must be set once to a boolean");
16109
+ }
16110
+ if (this.editSlotSurvivesCaptured) {
16111
+ throw new Error("edit_slot_survives is write-once and was already captured");
16112
+ }
16113
+ this.editSlotSurvives = value;
16114
+ this.editSlotSurvivesCaptured = true;
16115
+ for (const entry of this.bridges.values()) {
16116
+ entry.bridge.setEditSlotSurvives(value);
16117
+ }
16118
+ for (const bridge of this.staleBridges) {
16119
+ bridge.setEditSlotSurvives(value);
16120
+ }
16121
+ return;
16122
+ }
15826
16123
  if (value === undefined) {
15827
16124
  delete this.configOverrides[key];
15828
16125
  } else {
@@ -15880,6 +16177,7 @@ class RevivableTransportPool {
15880
16177
  revival = null;
15881
16178
  transports = new Map;
15882
16179
  configureOverrides = new Map;
16180
+ editSlotSurvivesCaptured = false;
15883
16181
  constructor(initialPool, createPool, onBinaryReplaced) {
15884
16182
  this.createPool = createPool;
15885
16183
  this.onBinaryReplaced = onBinaryReplaced;
@@ -15910,6 +16208,18 @@ class RevivableTransportPool {
15910
16208
  return this.getBridge(projectRoot).toolCall(runtime.sessionID, name, rawArgs, options);
15911
16209
  }
15912
16210
  setConfigureOverride(key, value) {
16211
+ if (key === "edit_slot_survives") {
16212
+ if (typeof value !== "boolean") {
16213
+ throw new Error("edit_slot_survives must be set once to a boolean");
16214
+ }
16215
+ if (this.editSlotSurvivesCaptured) {
16216
+ throw new Error("edit_slot_survives is write-once and was already captured");
16217
+ }
16218
+ this.activePool.setConfigureOverride(key, value);
16219
+ this.editSlotSurvivesCaptured = true;
16220
+ this.configureOverrides.set(key, value);
16221
+ return;
16222
+ }
15913
16223
  if (value === undefined)
15914
16224
  this.configureOverrides.delete(key);
15915
16225
  else
@@ -15917,14 +16227,20 @@ class RevivableTransportPool {
15917
16227
  this.activePool.setConfigureOverride(key, value);
15918
16228
  }
15919
16229
  async reconfigure(projectRoot, overrides) {
16230
+ const pool = await this.ensureActivePool();
16231
+ const runtimeOverrides = {};
15920
16232
  for (const [key, value] of Object.entries(overrides)) {
16233
+ if (key === "edit_slot_survives") {
16234
+ this.setConfigureOverride(key, value);
16235
+ continue;
16236
+ }
15921
16237
  if (value === undefined)
15922
16238
  this.configureOverrides.delete(key);
15923
16239
  else
15924
16240
  this.configureOverrides.set(key, value);
16241
+ runtimeOverrides[key] = value;
15925
16242
  }
15926
- const pool = await this.ensureActivePool();
15927
- await pool.reconfigure(projectRoot, overrides);
16243
+ await pool.reconfigure(projectRoot, runtimeOverrides);
15928
16244
  }
15929
16245
  async replaceBinary(path2) {
15930
16246
  const replaced = await this.activePool.replaceBinary(path2);
@@ -16336,6 +16652,9 @@ var UNKNOWN_COMPLETION_TTL_MS = 5000;
16336
16652
  var UNKNOWN_COMPLETION_CAP = 32;
16337
16653
  var DEFAULT_SESSION_ID2 = "__default__";
16338
16654
  var LOG_PREFIX = "[aft-plugin] bg-notifications:";
16655
+ var SUBC_NUDGE_LOG_INTERVAL_MS = 60000;
16656
+ var subcNudgesInFlight = new Map;
16657
+ var subcNudgeLogState = new Map;
16339
16658
  function consumeBgCompletion(sessionID, taskId) {
16340
16659
  const state = stateFor(sessionID);
16341
16660
  state.pendingCompletions = state.pendingCompletions.filter((c) => c.task_id !== taskId);
@@ -16542,11 +16861,45 @@ async function handleIdleBgCompletions(drainContext) {
16542
16861
  stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
16543
16862
  await triggerWakeIfPending(drainContext, false, true);
16544
16863
  }
16545
- async function handleSubcBgEventsNudge(drainContext) {
16864
+ function handleSubcBgEventsNudge(drainContext) {
16865
+ const key = `${drainContext.directory}\x00${drainContext.sessionID}`;
16866
+ const inFlight = subcNudgesInFlight.get(key);
16867
+ if (inFlight) {
16868
+ logSubcNudgeLifecycle(drainContext, "coalesced-in-flight", "nudge coalesced cause=handler-already-in-flight");
16869
+ return inFlight;
16870
+ }
16871
+ logSubcNudgeLifecycle(drainContext, "handler-entry", "nudge handler entered");
16872
+ const handling = handleSubcBgEventsNudgeOnce(drainContext);
16873
+ subcNudgesInFlight.set(key, handling);
16874
+ const clear = () => {
16875
+ if (subcNudgesInFlight.get(key) === handling)
16876
+ subcNudgesInFlight.delete(key);
16877
+ };
16878
+ handling.then(clear, clear);
16879
+ return handling;
16880
+ }
16881
+ async function handleSubcBgEventsNudgeOnce(drainContext) {
16546
16882
  bridgeForDrain(drainContext);
16547
16883
  stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
16548
16884
  await triggerWakeIfPending(drainContext, false, true, true);
16549
16885
  }
16886
+ function logSubcNudgeLifecycle(drainContext, kind, message) {
16887
+ const key = `${kind}\x00${drainContext.directory}\x00${drainContext.sessionID}`;
16888
+ const now = Date.now();
16889
+ const state = subcNudgeLogState.get(key);
16890
+ if (state && now - state.lastEmittedAt < SUBC_NUDGE_LOG_INTERVAL_MS) {
16891
+ state.suppressed += 1;
16892
+ return;
16893
+ }
16894
+ const suppressed = state?.suppressed ?? 0;
16895
+ subcNudgeLogState.set(key, { lastEmittedAt: now, suppressed: 0 });
16896
+ sessionLog(drainContext.sessionID, `${LOG_PREFIX} ${message}`, {
16897
+ event: "subc_bg_nudge_delivery",
16898
+ cause: kind,
16899
+ canonical_root: drainContext.directory,
16900
+ suppressed
16901
+ });
16902
+ }
16550
16903
  async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false) {
16551
16904
  const state = stateFor(drainContext.sessionID);
16552
16905
  if (!skipDrain && (forceDrain || state.outstandingTaskIds.size > 0 || !state.forcedDrainCompleted)) {
@@ -17412,6 +17765,7 @@ async function signalBashWaitDetachForProject(pool, projectRoot, sessionID) {
17412
17765
 
17413
17766
  // src/config.ts
17414
17767
  import { existsSync as existsSync10, readFileSync as readFileSync7, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
17768
+ import { parse as parsePath, resolve as resolvePath } from "node:path";
17415
17769
  var import_comment_json = __toESM(require_src2(), 1);
17416
17770
 
17417
17771
  // ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
@@ -31798,6 +32152,7 @@ var BackupConfigSchema = exports_external.object({
31798
32152
  var AftConfigSchema = exports_external.preprocess((value) => stripHarnessSpecificConfigKeys(value, PI_ONLY_KEYS), exports_external.object({
31799
32153
  $schema: exports_external.string().optional(),
31800
32154
  enabled: exports_external.boolean().optional(),
32155
+ edit_mode: exports_external.enum(["default", "hashline"]).optional(),
31801
32156
  format_on_edit: exports_external.boolean().optional(),
31802
32157
  formatter_timeout_secs: exports_external.number().int().min(1).max(600).optional(),
31803
32158
  validate_on_edit: exports_external.enum(["syntax", "full"]).optional(),
@@ -32035,14 +32390,19 @@ ${serialized}` : serialized;
32035
32390
  }
32036
32391
  }
32037
32392
  function parseConfigPartially(rawConfig) {
32038
- const fullResult = AftConfigSchema.safeParse(rawConfig);
32393
+ let configForParsing = rawConfig;
32394
+ if (Object.hasOwn(rawConfig, "edit_mode") && rawConfig.edit_mode !== "default" && rawConfig.edit_mode !== "hashline") {
32395
+ warn2(`Unknown edit_mode value ${JSON.stringify(rawConfig.edit_mode)}; falling back to "default"`);
32396
+ configForParsing = { ...rawConfig, edit_mode: "default" };
32397
+ }
32398
+ const fullResult = AftConfigSchema.safeParse(configForParsing);
32039
32399
  if (fullResult.success) {
32040
32400
  return fullResult.data;
32041
32401
  }
32042
32402
  const partialConfig = {};
32043
32403
  const invalidSections = [];
32044
- for (const key of Object.keys(rawConfig)) {
32045
- const sectionResult = AftConfigSchema.safeParse({ [key]: rawConfig[key] });
32404
+ for (const key of Object.keys(configForParsing)) {
32405
+ const sectionResult = AftConfigSchema.safeParse({ [key]: configForParsing[key] });
32046
32406
  if (sectionResult.success) {
32047
32407
  const parsed = sectionResult.data;
32048
32408
  if (parsed[key] !== undefined) {
@@ -32211,6 +32571,7 @@ function getProjectLspStrippedKeys(lsp) {
32211
32571
  }
32212
32572
  var PROJECT_SAFE_TOP_LEVEL_FIELDS = new Set([
32213
32573
  "enabled",
32574
+ "edit_mode",
32214
32575
  "tool_surface",
32215
32576
  "hoist_builtin_tools",
32216
32577
  "format_on_edit",
@@ -32326,6 +32687,12 @@ function resolveAftConfigPaths(projectDirectory) {
32326
32687
  migrateAftConfigFile2(paths.projectConfigPath);
32327
32688
  return paths;
32328
32689
  }
32690
+ function resolveOpenCodeRegistrationRoot(directory, worktree) {
32691
+ if (!worktree)
32692
+ return directory;
32693
+ const resolvedWorktree = resolvePath(worktree);
32694
+ return parsePath(resolvedWorktree).root === resolvedWorktree ? directory : resolvedWorktree;
32695
+ }
32329
32696
  function buildConfigTierConfigureParams(projectDirectory, processState = {}) {
32330
32697
  const paths = resolveAftConfigPaths(projectDirectory);
32331
32698
  const initialPluginState = Object.keys(processState).length > 0;
@@ -35359,14 +35726,18 @@ function normalizeToolArgSchemas(toolDefinition) {
35359
35726
  function bareToolName2(toolName) {
35360
35727
  return toolName.startsWith("aft_") ? toolName.slice(4) : toolName;
35361
35728
  }
35362
- function prepareOpenCodeArguments(toolName, rawArguments) {
35729
+ function prepareOpenCodeArguments(toolName, rawArguments, preparation = {}) {
35363
35730
  const bare = bareToolName2(toolName);
35731
+ if (bare === "edit" && preparation.hashlineEffective === true) {
35732
+ return rawArguments;
35733
+ }
35364
35734
  if (bare === "edit") {
35365
35735
  return prepareCanonicalEditArguments(toolName, rawArguments);
35366
35736
  }
35367
35737
  return prepareCanonicalPathArguments(toolName, rawArguments);
35368
35738
  }
35369
35739
  var DISPLAY_FILE_PATH_TOOLS = new Set(["read", "write", "edit"]);
35740
+ var PREPARED_EXECUTORS = new WeakSet;
35370
35741
  function preserveDisplayFilePathAlias(toolName, rawArguments, prepared) {
35371
35742
  if (!DISPLAY_FILE_PATH_TOOLS.has(toolName))
35372
35743
  return;
@@ -35377,21 +35748,25 @@ function preserveDisplayFilePathAlias(toolName, rawArguments, prepared) {
35377
35748
  raw.filePath = prepared.path;
35378
35749
  }
35379
35750
  }
35380
- function prepareToolMap(tools) {
35751
+ function prepareToolMap(tools, preparation = {}) {
35381
35752
  for (const [toolName, def] of Object.entries(tools)) {
35753
+ if (PREPARED_EXECUTORS.has(def.execute))
35754
+ continue;
35382
35755
  const execute = def.execute;
35383
- def.execute = async (args, context) => {
35384
- const prepared = prepareOpenCodeArguments(toolName, args);
35756
+ const preparedExecute = async (args, context) => {
35757
+ const prepared = prepareOpenCodeArguments(toolName, args, preparation);
35385
35758
  preserveDisplayFilePathAlias(toolName, args, prepared);
35386
35759
  return execute(prepared, context);
35387
35760
  };
35761
+ PREPARED_EXECUTORS.add(preparedExecute);
35762
+ def.execute = preparedExecute;
35388
35763
  }
35389
35764
  return tools;
35390
35765
  }
35391
- function normalizeToolMap(tools) {
35766
+ function normalizeToolMap(tools, preparation = {}) {
35392
35767
  for (const def of Object.values(tools))
35393
35768
  normalizeToolArgSchemas(def);
35394
- return prepareToolMap(tools);
35769
+ return prepareToolMap(tools, preparation);
35395
35770
  }
35396
35771
  // src/shared/ignored-message.ts
35397
35772
  async function sendIgnoredMessage2(client, sessionID, text) {
@@ -37901,7 +38276,56 @@ ${backupBehavior}
37901
38276
  - Symbol replace includes decorators, attributes, and doc comments in range
37902
38277
  - Response is a compact server-rendered summary; before/after diff details are attached as UI metadata when available.`;
37903
38278
  }
38279
+ function createHashlineEditTool(ctx) {
38280
+ return {
38281
+ description: "Apply a hashline patch. Arguments are exactly `{patch}` where `patch` is a non-empty string of one or more `[path#TAG]` sections with PUT/CUT/REM/MV operations. Paths and tags come from section headers; obtain tags from tagged reads. Server-owned preview control is outside this schema.",
38282
+ args: {
38283
+ patch: z8.string().min(1).describe("Hashline patch text with one or more [path#TAG] sections and PUT/CUT/REM/MV operations")
38284
+ },
38285
+ execute: async (args, context) => {
38286
+ const patch = args.patch;
38287
+ const projectRoot = await resolveProjectRoot(ctx, context);
38288
+ const rawArgs = { patch };
38289
+ const preflight = await callToolCall(ctx, context, "hashline_preflight", rawArgs);
38290
+ if (preflight.success === false)
38291
+ throw toolErrorFromResponse("edit", preflight);
38292
+ const permissionPatterns = [
38293
+ ...coerceStringArray(preflight.affected_paths),
38294
+ ...coerceStringArray(preflight.affected_rel_paths),
38295
+ ...coerceStringArray(preflight.mv_destinations)
38296
+ ].filter((value, index, all) => all.indexOf(value) === index);
38297
+ for (const target of [
38298
+ ...coerceStringArray(preflight.affected_paths),
38299
+ ...coerceStringArray(preflight.mv_destinations)
38300
+ ]) {
38301
+ const absolute = resolvePathFromProjectRoot(projectRoot, target);
38302
+ const denial2 = await assertExternalDirectoryPermission(ctx, context, absolute);
38303
+ if (denial2)
38304
+ return permissionDeniedResponse(denial2);
38305
+ }
38306
+ const denial = await askEditPermission(context, permissionPatterns, {
38307
+ surface: "hashline"
38308
+ });
38309
+ if (denial)
38310
+ return permissionDeniedResponse(denial);
38311
+ const preview2 = await callToolCall(ctx, context, "edit", rawArgs, { preview: true });
38312
+ if (preview2.success === false)
38313
+ throw toolErrorFromResponse("edit", preview2);
38314
+ const data = await callToolCall(ctx, context, "edit", rawArgs);
38315
+ if (data.success === false)
38316
+ throw toolErrorFromResponse("edit", data);
38317
+ const firstPath = typeof data.filePath === "string" ? resolvePathFromProjectRoot(projectRoot, data.filePath) : "";
38318
+ return {
38319
+ output: data.text,
38320
+ title: firstPath ? relativeToWorktree(firstPath, projectRoot) : "edit",
38321
+ metadata: data.metadata && typeof data.metadata === "object" ? data.metadata : {}
38322
+ };
38323
+ }
38324
+ };
38325
+ }
37904
38326
  function createEditTool(ctx, writeToolName = "write") {
38327
+ if (ctx.hashlineEffective === true)
38328
+ return createHashlineEditTool(ctx);
37905
38329
  return {
37906
38330
  description: getEditDescription(ctx, writeToolName),
37907
38331
  args: {
@@ -38209,7 +38633,7 @@ function hoistedTools(ctx) {
38209
38633
  tools.bash_kill = createBashKillTool(ctx);
38210
38634
  }
38211
38635
  }
38212
- return prepareToolMap(tools);
38636
+ return prepareToolMap(tools, { hashlineEffective: ctx.hashlineEffective });
38213
38637
  }
38214
38638
  function aftPrefixedTools(ctx) {
38215
38639
  const aftEditTool = createEditTool(ctx, "aft_write");
@@ -38231,7 +38655,7 @@ function aftPrefixedTools(ctx) {
38231
38655
  tools.bash_kill = createBashKillTool(ctx);
38232
38656
  }
38233
38657
  }
38234
- return prepareToolMap(tools);
38658
+ return prepareToolMap(tools, { hashlineEffective: ctx.hashlineEffective });
38235
38659
  }
38236
38660
 
38237
38661
  // src/tools/imports.ts
@@ -39240,6 +39664,15 @@ function semanticTools(ctx) {
39240
39664
 
39241
39665
  // src/tool-registration.ts
39242
39666
  var ALL_ONLY_TOOLS = ["aft_callgraph", "aft_delete", "aft_move", "aft_refactor"];
39667
+ function openCodeEditSlotSurvives(config2) {
39668
+ return (config2.tool_surface ?? "recommended") !== "minimal" && config2.hoist_builtin_tools !== false && !(config2.disabled_tools ?? []).includes("edit");
39669
+ }
39670
+ function openCodeHashlineEffective(config2) {
39671
+ return config2.edit_mode === "hashline" && openCodeEditSlotSurvives(config2);
39672
+ }
39673
+ function openCodeHashlineEditRegistered(config2, registeredTools) {
39674
+ return openCodeHashlineEffective(config2) && registeredTools.has("edit");
39675
+ }
39243
39676
  function buildOpenCodeToolMap(ctx, config2, onUnknownDisabled) {
39244
39677
  const surface = config2.tool_surface ?? "recommended";
39245
39678
  const allTools = normalizeToolMap({
@@ -39254,7 +39687,7 @@ function buildOpenCodeToolMap(ctx, config2, onUnknownDisabled) {
39254
39687
  ...surface !== "minimal" && config2.search_index === true && searchTools(ctx),
39255
39688
  ...refactoringTools(ctx),
39256
39689
  ...surface !== "minimal" && conflictTools(ctx)
39257
- });
39690
+ }, { hashlineEffective: ctx.hashlineEffective });
39258
39691
  if (surface !== "all") {
39259
39692
  for (const name of ALL_ONLY_TOOLS)
39260
39693
  delete allTools[name];
@@ -39395,7 +39828,7 @@ var PLUGIN_VERSION = (() => {
39395
39828
  return "0.0.0";
39396
39829
  }
39397
39830
  })();
39398
- var ANNOUNCEMENT_VERSION = "0.49.4";
39831
+ var ANNOUNCEMENT_VERSION = "0.50.0";
39399
39832
  var ANNOUNCEMENT_FEATURES = [
39400
39833
  "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
39401
39834
  "aft_zoom handles real-world .jsonc: files with comment banners above the opening brace now resolve, and not-found errors point at the segment that actually failed (thanks @iceteaSA).",
@@ -39411,22 +39844,23 @@ async function initializePluginForDirectory(input) {
39411
39844
  });
39412
39845
  }
39413
39846
  };
39414
- let aftConfig = loadAftConfig(input.directory);
39847
+ const registrationRoot = resolveOpenCodeRegistrationRoot(input.directory, input.worktree);
39848
+ let aftConfig = loadAftConfig(registrationRoot);
39415
39849
  if (aftConfig.enabled === false) {
39416
- log2(`AFT disabled by config for ${input.directory}`);
39850
+ log2(`AFT disabled by config for ${registrationRoot}`);
39417
39851
  return { tool: {} };
39418
39852
  }
39419
- deliverConfigMigrationWarnings(input.directory, migrateAftConfigLocations(input.directory, bridgeLogger).flatMap((result) => result.warnings));
39420
- aftConfig = loadAftConfig(input.directory);
39421
- enqueueConfigParseWarnings(input.directory, getConfigLoadErrors());
39853
+ deliverConfigMigrationWarnings(registrationRoot, migrateAftConfigLocations(registrationRoot, bridgeLogger).flatMap((result) => result.warnings));
39854
+ aftConfig = loadAftConfig(registrationRoot);
39855
+ enqueueConfigParseWarnings(registrationRoot, getConfigLoadErrors());
39422
39856
  if (aftConfig.enabled === false) {
39423
- log2(`AFT disabled by config for ${input.directory}`);
39857
+ log2(`AFT disabled by config for ${registrationRoot}`);
39424
39858
  return { tool: {} };
39425
39859
  }
39426
39860
  const binaryPath = await findBinary(PLUGIN_VERSION);
39427
39861
  await ensureStorageMigrated({ harness: "opencode", binaryPath, logger: bridgeLogger });
39428
39862
  const autoUpdateAbort = new AbortController;
39429
- const projectEnabledCache = new Map([[input.directory, true]]);
39863
+ const projectEnabledCache = new Map([[registrationRoot, true]]);
39430
39864
  const loggedDisabledProjects = new Set;
39431
39865
  const isProjectEnabled = (projectRoot) => {
39432
39866
  const cached2 = projectEnabledCache.get(projectRoot);
@@ -39442,10 +39876,11 @@ async function initializePluginForDirectory(input) {
39442
39876
  return enabled;
39443
39877
  };
39444
39878
  const storageDir = resolveCortexKitStorageRoot();
39445
- const configOverrides = buildConfigTierConfigureParams(input.directory, {
39879
+ const configOverrides = buildConfigTierConfigureParams(registrationRoot, {
39446
39880
  bash_permissions: true,
39447
39881
  storage_dir: storageDir
39448
39882
  });
39883
+ const hashlineEffective = openCodeHashlineEffective(aftConfig);
39449
39884
  let lspInstallCompletion = null;
39450
39885
  const isFastembedSemanticBackend = (aftConfig.semantic?.backend ?? "fastembed") === "fastembed";
39451
39886
  let onnxRuntimePromise = null;
@@ -39635,6 +40070,16 @@ ${lines}
39635
40070
  poolOptions,
39636
40071
  configOverrides,
39637
40072
  subcConnectionFile: aftConfig.subc?.connection_file,
40073
+ onBgEventsNudge: (directory, sessionID) => {
40074
+ handleSubcBgEventsNudge({
40075
+ ctx,
40076
+ directory,
40077
+ sessionID,
40078
+ client: input.client
40079
+ }).catch((err) => {
40080
+ warn2(`[aft-plugin] bg nudge rejected: ${err instanceof Error ? err.message : String(err)}`);
40081
+ });
40082
+ },
39638
40083
  onBgEventsNudgeRef: (ref) => {
39639
40084
  handleSubcBgEventsNudge({
39640
40085
  ctx,
@@ -39664,6 +40109,7 @@ ${lines}
39664
40109
  client: input.client,
39665
40110
  plugin: input.plugin,
39666
40111
  config: aftConfig,
40112
+ hashlineEffective,
39667
40113
  storageDir: configOverrides.storage_dir,
39668
40114
  isProjectEnabled
39669
40115
  };
@@ -39865,6 +40311,10 @@ Install: ${getManualInstallHint()}`).catch(() => {});
39865
40311
  "bash_status"
39866
40312
  ];
39867
40313
  const registeredTools = new Set(Object.keys(allTools));
40314
+ const hashlineEditRegistered = openCodeHashlineEditRegistered(aftConfig, registeredTools);
40315
+ ctx.hashlineEffective = hashlineEditRegistered;
40316
+ pool.setConfigureOverride("edit_slot_survives", hashlineEditRegistered);
40317
+ log2(`hashline activation decision requested=${aftConfig.edit_mode === "hashline"} ` + `edit_slot_survives=${hashlineEditRegistered} effective=${ctx.hashlineEffective}`);
39868
40318
  const aftSearchRegistered = registeredTools.has("aft_search");
39869
40319
  pool.setConfigureOverride("aft_search_registered", aftSearchRegistered);
39870
40320
  ctx.aftSearchRegistered = aftSearchRegistered;
@@ -39959,7 +40409,9 @@ Install: ${getManualInstallHint()}`).catch(() => {});
39959
40409
  signalBashWaitDetachForProject(pool, sessionDir, sid);
39960
40410
  },
39961
40411
  "tool.execute.before": async (toolInput, output) => {
39962
- output.args = prepareOpenCodeArguments(toolInput.tool, output.args);
40412
+ output.args = prepareOpenCodeArguments(toolInput.tool, output.args, {
40413
+ hashlineEffective: ctx.hashlineEffective
40414
+ });
39963
40415
  if (toolInput.sessionID)
39964
40416
  inspectTier2Idle.clear(toolInput.sessionID);
39965
40417
  },
@@ -8,11 +8,14 @@ import type { ToolDefinition } from "@opencode-ai/plugin";
8
8
  * `tool.schema.toJSONSchema`, which preserves all metadata.
9
9
  */
10
10
  export declare function normalizeToolArgSchemas<T extends Pick<ToolDefinition, "args">>(toolDefinition: T): T;
11
- /** Prepare raw OpenCode arguments and retain legacy fields for old schemas. */
12
- export declare function prepareOpenCodeArguments(toolName: string, rawArguments: unknown): Record<string, unknown>;
13
- declare function prepareToolMap(tools: Record<string, ToolDefinition>): Record<string, ToolDefinition>;
11
+ export interface OpenCodeArgumentPreparation {
12
+ hashlineEffective?: boolean;
13
+ }
14
+ /** Prepare raw OpenCode arguments against the schema arm registered for this session. */
15
+ export declare function prepareOpenCodeArguments(toolName: string, rawArguments: unknown, preparation?: OpenCodeArgumentPreparation): Record<string, unknown>;
16
+ declare function prepareToolMap(tools: Record<string, ToolDefinition>, preparation?: OpenCodeArgumentPreparation): Record<string, ToolDefinition>;
14
17
  /** Normalize tool definitions and attach raw-argument preparation. */
15
- export declare function normalizeToolMap(tools: Record<string, ToolDefinition>): Record<string, ToolDefinition>;
18
+ export declare function normalizeToolMap(tools: Record<string, ToolDefinition>, preparation?: OpenCodeArgumentPreparation): Record<string, ToolDefinition>;
16
19
  /** Attach argument preparation without changing emitted schema metadata. */
17
20
  export { prepareToolMap };
18
21
  //# sourceMappingURL=normalize-schemas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-schemas.d.ts","sourceRoot":"","sources":["../src/normalize-schemas.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAiC1D;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EAC5E,cAAc,EAAE,CAAC,GAChB,CAAC,CAKH;AAMD,+EAA+E;AAC/E,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,OAAO,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAwBD,iBAAS,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAU7F;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAGhC;AAED,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"normalize-schemas.d.ts","sourceRoot":"","sources":["../src/normalize-schemas.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAiC1D;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EAC5E,cAAc,EAAE,CAAC,GAChB,CAAC,CAKH;AAMD,MAAM,WAAW,2BAA2B;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,yFAAyF;AACzF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,OAAO,EACrB,WAAW,GAAE,2BAAgC,GAC5C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB;AAyBD,iBAAS,cAAc,CACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACrC,WAAW,GAAE,2BAAgC,GAC5C,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAchC;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACrC,WAAW,GAAE,2BAAgC,GAC5C,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAGhC;AAED,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -1,6 +1,12 @@
1
1
  import type { ToolDefinition } from "@opencode-ai/plugin";
2
2
  import type { AftConfig } from "./config.js";
3
3
  import type { PluginContext } from "./types.js";
4
+ /** Returns true when bare `edit` remains available after surface, hoisting, and disable filters. */
5
+ export declare function openCodeEditSlotSurvives(config: AftConfig): boolean;
6
+ /** Select the hashline schema only when the host's final edit slot can survive. */
7
+ export declare function openCodeHashlineEffective(config: AftConfig): boolean;
8
+ /** Return the process-state flag Rust uses to select the same edit schema arm. */
9
+ export declare function openCodeHashlineEditRegistered(config: AftConfig, registeredTools: ReadonlySet<string>): boolean;
4
10
  /**
5
11
  * Build the exact OpenCode registration map without starting a bridge.
6
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../src/tool-registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAa7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,SAAS,EACjB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,GACvE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA8BhC"}
1
+ {"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../src/tool-registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAa7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,oGAAoG;AACpG,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAMnE;AAED,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAEpE;AAED,kFAAkF;AAClF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,EACjB,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,GACnC,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,SAAS,EACjB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,GACvE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiChC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAInF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiDjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA+OtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAoIjE;AA6mBD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4BnF"}
1
+ {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAInF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiDjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA+OtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAoIjE;AAyqBD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4BnF"}
package/dist/types.d.ts CHANGED
@@ -23,6 +23,8 @@ export interface PluginContext {
23
23
  client: PluginInput["client"];
24
24
  plugin?: ShellEnvPluginHost;
25
25
  config: AftConfig;
26
+ /** Whether hashline edit/read mode is active for this plugin registration. */
27
+ hashlineEffective?: boolean;
26
28
  /** Absolute path to AFT's storage dir (e.g. ~/.local/share/opencode/storage/plugin/aft) */
27
29
  storageDir: string;
28
30
  /** Returns false when user and project config merge to `enabled: false` for this project. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,CACR,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC7D,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KACnC,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CACnF;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CACrD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,CACR,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC7D,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KACnC,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CACnF;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CACrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.49.4",
3
+ "version": "0.50.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
6
6
  "main": "dist/index.js",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@clack/prompts": "^1.6.0",
37
- "@cortexkit/aft-bridge": "0.49.4",
37
+ "@cortexkit/aft-bridge": "0.50.0",
38
38
  "@opentui/core": "0.4.3",
39
39
  "@opentui/solid": "0.4.3",
40
40
  "comment-json": "^4.6.2",
@@ -43,12 +43,12 @@
43
43
  "zod": "^4.4.3"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@cortexkit/aft-darwin-arm64": "0.49.4",
47
- "@cortexkit/aft-darwin-x64": "0.49.4",
48
- "@cortexkit/aft-linux-arm64": "0.49.4",
49
- "@cortexkit/aft-linux-x64": "0.49.4",
50
- "@cortexkit/aft-win32-arm64": "0.49.4",
51
- "@cortexkit/aft-win32-x64": "0.49.4"
46
+ "@cortexkit/aft-darwin-arm64": "0.50.0",
47
+ "@cortexkit/aft-darwin-x64": "0.50.0",
48
+ "@cortexkit/aft-linux-arm64": "0.50.0",
49
+ "@cortexkit/aft-linux-x64": "0.50.0",
50
+ "@cortexkit/aft-win32-arm64": "0.50.0",
51
+ "@cortexkit/aft-win32-x64": "0.50.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@opencode-ai/plugin": "^1.17.11",