@cortexkit/aft-opencode 0.43.1 → 0.44.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/config.d.ts CHANGED
@@ -75,6 +75,7 @@ export declare const AftConfigSchema: z.ZodObject<{
75
75
  duplicates: z.ZodOptional<z.ZodObject<{
76
76
  lower_bound: z.ZodOptional<z.ZodNumber>;
77
77
  discard_cost: z.ZodOptional<z.ZodNumber>;
78
+ expected_mirrors: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>>>;
78
79
  anonymize: z.ZodOptional<z.ZodObject<{
79
80
  variables: z.ZodOptional<z.ZodBoolean>;
80
81
  fields: z.ZodOptional<z.ZodBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,UAAU,EAMhB,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;AA4CtF,eAAO,MAAM,eAAe;;;;;;;;;iBAE1B,CAAC;AAkKH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA+GjB,CAAC;AAEZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,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,CA+B9F;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;AAgDD,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,iCAAiC;AACjC,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKhG;AA2VD,8DAA8D;AAC9D,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,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,wBAAgB,8BAA8B,CAC5C,gBAAgB,EAAE,MAAM,EACxB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACzC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,0BAA0B,EAAE,MAAM,CAAA;CAAE,CAOxF;AAMD,wBAAgB,aAAa,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAoCjE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -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;AA6MlD;;;;;;;;;;;;;;;;GAgBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AAsgC5E,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;AA8MlD;;;;;;;;;;;;;;;;GAgBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AAsgC5E,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -11382,10 +11382,10 @@ class BridgePool {
11382
11382
  function normalizeKey(projectRoot) {
11383
11383
  return canonicalizeProjectRoot(projectRoot);
11384
11384
  }
11385
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/client.ts
11385
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
11386
11386
  import { promises as fs2 } from "node:fs";
11387
11387
 
11388
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/auth.ts
11388
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/auth.ts
11389
11389
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
11390
11390
  var NONCE_LEN = 32;
11391
11391
  var MAX_AUTH_MESSAGE_LEN = 4096;
@@ -11449,7 +11449,7 @@ async function authenticateClient(sock, conn, deadlineMs) {
11449
11449
  await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
11450
11450
  }
11451
11451
 
11452
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/connection-file.ts
11452
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/connection-file.ts
11453
11453
  import { promises as fs } from "node:fs";
11454
11454
  var SCHEMA_VERSION = 1;
11455
11455
  var MIN_KEY_LEN = 32;
@@ -11518,7 +11518,7 @@ async function readConnectionFile(path2) {
11518
11518
  return info;
11519
11519
  }
11520
11520
 
11521
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/envelope.ts
11521
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/envelope.ts
11522
11522
  var PROTOCOL_VERSION = 1;
11523
11523
  var HEADER_LEN = 17;
11524
11524
  var FROZEN_PREFIX_LEN = 5;
@@ -11625,7 +11625,7 @@ function encodeFrame(frame) {
11625
11625
  return out;
11626
11626
  }
11627
11627
 
11628
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/socket.ts
11628
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/socket.ts
11629
11629
  import net from "node:net";
11630
11630
 
11631
11631
  class SocketClosedError extends Error {
@@ -11672,6 +11672,9 @@ class SubcSocket {
11672
11672
  sock.on("end", () => fail(new SocketClosedError("subc closed the connection")));
11673
11673
  sock.on("close", () => fail(new SocketClosedError("subc connection closed")));
11674
11674
  }
11675
+ localPort() {
11676
+ return this.sock.localPort ?? null;
11677
+ }
11675
11678
  static connect(host, port, deadlineMs) {
11676
11679
  return new Promise((resolve7, reject) => {
11677
11680
  const sock = net.connect({ host, port });
@@ -11811,7 +11814,7 @@ class SubcSocket {
11811
11814
  }
11812
11815
  }
11813
11816
 
11814
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/client.ts
11817
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
11815
11818
  var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
11816
11819
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
11817
11820
  var BODY_READ_TIMEOUT_MS = 30000;
@@ -12038,7 +12041,7 @@ class SubcClient {
12038
12041
  timer: null
12039
12042
  };
12040
12043
  pending.timer = setTimeout(() => {
12041
- this.rejectPending(key, pending, new SubcError(`request on channel ${channel} timed out after ${ms}ms`));
12044
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12042
12045
  }, ms);
12043
12046
  this.pending.set(key, pending);
12044
12047
  this.sock.write(encodeFrame(frame), Date.now() + ms).catch((err) => {
@@ -12085,7 +12088,7 @@ class SubcClient {
12085
12088
  classifyFailure
12086
12089
  };
12087
12090
  pending.timer = setTimeout(() => {
12088
- this.rejectPending(key, pending, new SubcError(`request on channel ${channel} timed out after ${ms}ms`));
12091
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12089
12092
  }, ms);
12090
12093
  this.pending.set(key, pending);
12091
12094
  const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
@@ -12233,7 +12236,9 @@ class SubcClient {
12233
12236
  for (const cached of this.routes.values()) {
12234
12237
  if (cached.closed)
12235
12238
  continue;
12236
- const channel = await this.routeOpen(cached.target, cached.identity);
12239
+ const channel = await this.routeOpen(cached.target, cached.identity, {
12240
+ consumerIdentity: cached.consumerIdentity ?? null
12241
+ });
12237
12242
  if (cached.closed) {
12238
12243
  this.sendRouteGoodbye(channel);
12239
12244
  continue;
@@ -12242,6 +12247,11 @@ class SubcClient {
12242
12247
  cached.generation = this.generation;
12243
12248
  }
12244
12249
  }
12250
+ timeoutMessage(channel, corr, ms) {
12251
+ const port = this.sock.localPort();
12252
+ const where = port === null ? "channel" : `local_port=${port} channel`;
12253
+ return `request on ${where} ${channel} corr ${corr} timed out after ${ms}ms`;
12254
+ }
12245
12255
  routeClosedDuringOpen() {
12246
12256
  return new SubcCallError("not_sent", "route was closed before route.open completed", "route_closed");
12247
12257
  }
@@ -12397,7 +12407,7 @@ function causeMessage(cause) {
12397
12407
  return "";
12398
12408
  return `: ${cause instanceof Error ? cause.message : String(cause)}`;
12399
12409
  }
12400
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/provider.ts
12410
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/provider.ts
12401
12411
  import { Buffer as Buffer2 } from "node:buffer";
12402
12412
  var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4;
12403
12413
  var BODY_READ_TIMEOUT_MS2 = 30000;
@@ -28728,6 +28738,7 @@ var InspectConfigSchema = exports_external.object({
28728
28738
  duplicates: exports_external.object({
28729
28739
  lower_bound: exports_external.number().int().positive().optional(),
28730
28740
  discard_cost: exports_external.number().int().min(0).optional(),
28741
+ expected_mirrors: exports_external.array(exports_external.tuple([exports_external.string().trim().min(1), exports_external.string().trim().min(1)])).optional(),
28731
28742
  anonymize: exports_external.object({
28732
28743
  variables: exports_external.boolean().optional(),
28733
28744
  fields: exports_external.boolean().optional(),
@@ -33561,17 +33572,18 @@ var SUPPORTED_LANGS = [
33561
33572
  "rust",
33562
33573
  "go",
33563
33574
  "pascal",
33564
- "r"
33575
+ "r",
33576
+ "objc"
33565
33577
  ];
33566
33578
  function astTools(ctx) {
33567
33579
  const searchTool = {
33568
- description: `Search code patterns across filesystem using AST-aware matching. Supports 8 languages.
33580
+ description: `Search code patterns across filesystem using AST-aware matching. Supports 9 languages.
33569
33581
 
33570
33582
  ` + `Use meta-variables: $VAR matches a single AST node, $$$ matches multiple nodes (variadic).
33571
33583
  ` + `IMPORTANT: Patterns must be complete AST nodes (valid code fragments).
33572
33584
  ` + `For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not just 'export async function $NAME'.
33573
33585
 
33574
- ` + "Examples: pattern='console.log($MSG)' lang='typescript', pattern='async function $NAME($$$) { $$$ }' lang='javascript', pattern='def $FUNC($$$): $$$' lang='python', pattern='Writeln($MSG);' lang='pascal', pattern='$X <- $Y' lang='r'",
33586
+ ` + "Examples: pattern='console.log($MSG)' lang='typescript', pattern='async function $NAME($$$) { $$$ }' lang='javascript', pattern='def $FUNC($$$): $$$' lang='python', pattern='Writeln($MSG);' lang='pascal', pattern='$X <- $Y' lang='r', pattern='[obj foo:$ARG]' lang='objc'",
33575
33587
  args: {
33576
33588
  pattern: z3.string().describe("AST pattern with meta-variables ($VAR, $$$). Must be complete AST node."),
33577
33589
  lang: z3.enum(SUPPORTED_LANGS).describe("Target language"),
@@ -33734,14 +33746,14 @@ function resolveForegroundWaitMs(configured) {
33734
33746
  }
33735
33747
  return configured;
33736
33748
  }
33737
- function orchestratedTransportTimeoutMs(blockToCompletion, effectiveTimeout, foregroundWaitMs) {
33738
- const waitBudget = blockToCompletion ? effectiveTimeout ?? DEFAULT_HARD_TIMEOUT_MS : foregroundWaitMs;
33749
+ function orchestratedTransportTimeoutMs(blockToCompletion, wait, effectiveTimeout, foregroundWaitMs) {
33750
+ const waitBudget = blockToCompletion || wait ? effectiveTimeout ?? DEFAULT_HARD_TIMEOUT_MS : foregroundWaitMs;
33739
33751
  return waitBudget + BASH_TRANSPORT_MARGIN_MS;
33740
33752
  }
33741
33753
  function bashToolDescription(aftSearchRegistered, compressionOn, backgroundOn) {
33742
33754
  const searchSteer = aftSearchRegistered ? "use aft_search (concepts, identifiers, regex, literals), read, aft_outline, or aft_zoom instead" : "use the grep tool, read, aft_outline, or aft_zoom instead";
33743
33755
  const compression = compressionOn ? " Output is compressed by default; pass compressed: false for raw output. Piped commands run verbatim and show the pipeline's output; for AFT's test/build summary, run the runner without | head, | tail, or | grep." : "";
33744
- const tasks = backgroundOn ? ' Commands run in the foreground and return inline; a long-running one auto-promotes to background and delivers a completion reminder when it finishes so for the common "I am waiting on this result" case, just run it and wait, no flags needed. Use background: true yourself ONLY when you have other useful work to do while it runs; then bash_watch waits on the task (sync blocks until exit/pattern, async notifies) and bash_status peeks at it — never background a command and immediately bash_watch it (that wastes a turn for what foreground returns in one), and never loop bash_status to wait. pty: true runs interactive programs (REPLs, TUIs), implies background, and is driven with bash_status({ outputMode: "screen" }) plus bash_write.' : " Commands run in the foreground to completion; timeout is the hard kill cap (default 30 minutes).";
33756
+ const tasks = backgroundOn ? ' Commands run in the foreground and return inline; wait: true blocks until a long command finishes instead of auto-promoting use it when you need the result before doing anything else; keep it off otherwise so auto-promote can remind you while you work. Use background: true yourself ONLY when you have other useful work to do while it runs; then bash_watch waits on the task (sync blocks until exit/pattern, async notifies) and bash_status peeks at it — never background a command and immediately bash_watch it (that wastes a turn for what foreground returns in one), and never loop bash_status to wait. pty: true runs interactive programs (REPLs, TUIs), implies background, and is driven with bash_status({ outputMode: "screen" }) plus bash_write.' : " Commands run in the foreground to completion; timeout is the hard kill cap (default 30 minutes).";
33745
33757
  return `Execute shell commands.${compression}${tasks}
33746
33758
 
33747
33759
  DO NOT use bash for code search or code exploration. If you are about to run grep, rg, sed, awk, find, or cat through bash to locate or read code: STOP — ${searchSteer}.`;
@@ -33807,6 +33819,7 @@ function createBashTool(ctx, aftSearchRegisteredOverride) {
33807
33819
  timeout: optionalInt(1, Number.MAX_SAFE_INTEGER).describe(initialBashCfg.background ? "Hard kill cap in milliseconds (positive integer). When omitted, the task can run up to 30 minutes. Foreground bash returns inline if the command finishes within ~8s (configurable via bash.foreground_wait_window_ms); otherwise it's automatically promoted to background and a completion reminder is delivered when the task actually finishes." : "Hard kill cap in milliseconds (positive integer). When omitted, the foreground command can run up to 30 minutes and returns inline when it finishes."),
33808
33820
  workdir: z4.string().optional().describe("Working directory for command execution. Relative paths resolve through the bridge; defaults to the current tool context/project root when omitted."),
33809
33821
  description: z4.string().optional().describe("Short 5-10 word human-readable summary shown in OpenCode UI metadata instead of raw shell syntax."),
33822
+ wait: z4.boolean().optional().describe("When true, run in the foreground without auto-promoting and wait until the command finishes or reaches its timeout. Use only when you know the result is required before doing anything else."),
33810
33823
  ...backgroundFlagArg,
33811
33824
  compressed: z4.boolean().optional().describe("When true or omitted, return compressed output with noisy terminal control sequences reduced. Set to false for raw output."),
33812
33825
  ...ptyArgs
@@ -33826,21 +33839,30 @@ function createBashTool(ctx, aftSearchRegisteredOverride) {
33826
33839
  const cwd = args2.workdir ?? context.directory;
33827
33840
  const isSubagent = await resolveIsSubagent(ctx.client, context.sessionID, context.directory);
33828
33841
  const backgroundDisabled = !bashCfg.background;
33829
- const requestedPty = !backgroundDisabled && coerceBoolean(args2.pty);
33830
- const requestedBackground = !backgroundDisabled && (coerceBoolean(args2.background) || requestedPty);
33842
+ const requestedWait = coerceBoolean(args2.wait);
33843
+ const rawRequestedPty = coerceBoolean(args2.pty);
33844
+ const rawRequestedBackground = coerceBoolean(args2.background);
33845
+ if (requestedWait && rawRequestedPty) {
33846
+ throw new Error("wait:true cannot be used with pty:true because PTY sessions run in background.");
33847
+ }
33848
+ if (requestedWait && rawRequestedBackground) {
33849
+ throw new Error("wait:true cannot be used with background:true.");
33850
+ }
33851
+ const requestedPty = !backgroundDisabled && rawRequestedPty;
33852
+ const requestedBackground = !backgroundDisabled && (rawRequestedBackground || requestedPty);
33831
33853
  if (requestedPty && isSubagent) {
33832
33854
  throw new Error("PTY mode is not available in subagent sessions; subagents cannot drive interactive terminals.");
33833
33855
  }
33834
33856
  const allowSubagentBg = bashCfg.subagent_background;
33835
33857
  const subagentForcedForeground = isSubagent && !allowSubagentBg;
33836
- const blockToCompletion = subagentForcedForeground || backgroundDisabled;
33858
+ const blockToCompletion = subagentForcedForeground || backgroundDisabled || requestedWait;
33837
33859
  const effectiveBackground = blockToCompletion ? false : requestedBackground;
33838
33860
  const rawTimeout = coerceOptionalInt(args2.timeout, "timeout", 1, Number.MAX_SAFE_INTEGER);
33839
33861
  const ptyRows = coerceOptionalInt(args2.ptyRows, "ptyRows", 1, 60);
33840
33862
  const ptyCols = coerceOptionalInt(args2.ptyCols, "ptyCols", 1, 140);
33841
33863
  const compressed = coerceBoolean(args2.compressed, true);
33842
33864
  const foregroundWaitMs = resolveForegroundWaitMs(bashCfg.foreground_wait_window_ms);
33843
- const effectiveTimeout = effectiveBackground || backgroundDisabled ? rawTimeout : resolveBashKillTimeout(rawTimeout, foregroundWaitMs);
33865
+ const effectiveTimeout = requestedWait || effectiveBackground || backgroundDisabled ? rawTimeout : resolveBashKillTimeout(rawTimeout, foregroundWaitMs);
33844
33866
  if (subagentForcedForeground && requestedBackground) {
33845
33867
  sessionLog(context.sessionID, "[bash] subagent + background:true → converting to foreground (subagent would lose task_id)");
33846
33868
  }
@@ -33859,9 +33881,10 @@ function createBashTool(ctx, aftSearchRegisteredOverride) {
33859
33881
  pty_cols: ptyCols,
33860
33882
  permissions_requested: true,
33861
33883
  foreground_orchestrate: true,
33862
- block_to_completion: blockToCompletion
33884
+ block_to_completion: blockToCompletion,
33885
+ wait: requestedWait
33863
33886
  }, callBashBridge, {
33864
- transportTimeoutMs: orchestratedTransportTimeoutMs(blockToCompletion, effectiveTimeout, foregroundWaitMs),
33887
+ transportTimeoutMs: orchestratedTransportTimeoutMs(blockToCompletion, requestedWait, effectiveTimeout, foregroundWaitMs),
33865
33888
  onProgress: ({ text }) => {
33866
33889
  accumulatedOutput = preview(accumulatedOutput + text);
33867
33890
  metadata?.({ output: accumulatedOutput, description });
@@ -35319,11 +35342,11 @@ function createInspectTier2IdleScheduler(options) {
35319
35342
  }
35320
35343
  function inspectTools(ctx) {
35321
35344
  const inspectTool = {
35322
- description: "Codebase health snapshot. One call returns summary stats for: TODOs, diagnostics, file/symbol metrics, dead code, unused exports, code duplicates. Pass `sections` for per-category drill-down details.\n\n" + "Categories run in tiers — Tier 1 (todos, metrics) return synchronously from cache. Tier 2 (dead_code, unused_exports, duplicates) waits for a fresh reuse scan up to a short deadline; if a category is still scanning the response reports `complete: false` with `pending_categories: [...]` rather than a fabricated clean count.\n\n" + `Use when: starting work on unfamiliar code, after multi-edit batches to check diagnostics, before a refactor, before review, or to verify cleanup completeness.
35345
+ description: "Codebase health snapshot. One call returns summary stats for: TODOs, diagnostics, file/symbol metrics, dead code, unused exports, code duplicates, and TS/JS import cycles. Pass `sections` for per-category drill-down details.\n\n" + "Categories run in tiers — Tier 1 (todos, metrics) return synchronously from cache. Tier 2 (dead_code, unused_exports, duplicates, cycles) waits for a fresh reuse scan up to a short deadline; if a category is still scanning the response reports `complete: false` with `pending_categories: [...]` rather than a fabricated clean count. Rust module cycles are out of scope for `cycles`.\n\n" + `Use when: starting work on unfamiliar code, after multi-edit batches to check diagnostics, before a refactor, before review, or to verify cleanup completeness.
35323
35346
 
35324
35347
  ` + "Treat `dead_code` as a hint, not proof: reachability is call-based, so symbols reached only via method dispatch or referenced only in type position may be false positives — verify before deleting.",
35325
35348
  args: {
35326
- sections: arg(z10.union([z10.string(), z10.array(z10.string())]).optional().describe("Categories to include in detailed drill-down (e.g. 'todos' or ['todos', 'dead_code']). Use 'all' for every active category. Omit for summary-only mode.")),
35349
+ sections: arg(z10.union([z10.string(), z10.array(z10.string())]).optional().describe("Categories to include in detailed drill-down (e.g. 'todos' or ['todos', 'dead_code', 'cycles']). Use 'all' for every active category. Omit for summary-only mode.")),
35327
35350
  scope: arg(z10.union([z10.string(), z10.array(z10.string())]).optional().describe("Restrict scan/results to paths under this scope (file or directory, absolute or relative to project root). Tier 1 scopes the scan; Tier 2 scans project-wide and applies scope as a result filter.")),
35328
35351
  topK: arg(z10.number().int().positive().max(100).optional().describe("Max drill-down items per category. Default 20, max 100."))
35329
35352
  },
@@ -36235,7 +36258,7 @@ function buildWorkflowHints(opts) {
36235
36258
  }
36236
36259
  if (hasBash && hasBgBash) {
36237
36260
  sections.push([
36238
- `**Long-running commands** (builds, installs, full test suites): run them in the FOREGROUND — \`${bashName}({ command })\` waits and returns the result in ONE step, and if it outlives the short wait window it auto-promotes to background and delivers a completion reminder when it finishes. Don't reach for \`background: true\` for the common "I'm waiting on this result" case — that costs an extra turn.`,
36261
+ `**Long-running commands** (builds, installs, full test suites): run them in the FOREGROUND — use \`${bashName}({ command, wait: true })\` when you know it is long and need the result before anything else; otherwise omit \`wait\` so auto-promote can hand you a reminder while you work.`,
36239
36262
  "- `background: true` is ONLY for when you have OTHER useful work to do while it runs: start it, do the other work, and the completion reminder delivers the result (or spawn a subagent for the side work). Do NOT background a command and then immediately `bash_watch` it — that spends a whole extra turn waiting for something foreground returns in one.",
36240
36263
  "- `bash_watch` is for blocking on an ALREADY-backgrounded task once you've run out of parallel work (sync — the user can interrupt), or reacting to a specific early output line (async: background:true + pattern). Never loop `bash_status` to wait — it's a one-shot inspector."
36241
36264
  ].join(`
@@ -36292,12 +36315,13 @@ var PLUGIN_VERSION = (() => {
36292
36315
  return "0.0.0";
36293
36316
  }
36294
36317
  })();
36295
- var ANNOUNCEMENT_VERSION = "0.43.0";
36318
+ var ANNOUNCEMENT_VERSION = "0.44.0";
36296
36319
  var ANNOUNCEMENT_FEATURES = [
36297
- "Fewer permission prompts: system temp paths (/tmp and friends) no longer trigger external-directory asks, and aft_search now has its own permission id so a grep deny rule can't block it.",
36298
- `New enabled config toggle: set "enabled": false in a project's .cortexkit/aft.jsonc (or your user config) to turn AFT off there entirely.`,
36299
- "Bash compression honesty fix: empty successful output stays empty instead of being replaced with synthesized text like 'kubectl: no resources found'.",
36300
- "TUI sidebar now updates over a push channel instead of polling (lower idle CPU), and AFT no longer re-adds itself to tui.json if you remove it (aft setup re-registers)."
36320
+ "Code Health accuracy overhaul: framework entry points (Tauri commands, Next.js/Nuxt/SvelteKit/Remix/Astro routes, NestJS decorators) are no longer flagged dead, barrel re-exports collapse to their real definition, and test-only usage moves out of the headline counts into its own tier.",
36321
+ "New: import cycle detection for TS/JS (aft_inspect sections: cycles), and expected_mirrors config to suppress intentional duplicate pairs like plugin/pi-plugin parity trees.",
36322
+ "Stale diagnostics fixed: files edited outside AFT (scripts, git) no longer show outdated errors in aft_inspect or the status bar.",
36323
+ "bash wait: true blocks until a long command finishes instead of promoting it to background.",
36324
+ "Objective-C support (.m/.mm): outline, zoom, AST search, and semantic indexing."
36301
36325
  ];
36302
36326
  var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
36303
36327
  var plugin = async (input) => initializePluginForDirectory(input);
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiDjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0H3E"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkDjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0H3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuCjD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,OAAO,EAC5B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,GACpB,MAAM,CAaR;AA6ED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,aAAa,EAClB,2BAA2B,CAAC,EAAE,OAAO,GACpC,cAAc,CAwMhB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA2BvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAwBrE"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuCjD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,OAAO,EAC5B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,GACpB,MAAM,CAaR;AA6ED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,aAAa,EAClB,2BAA2B,CAAC,EAAE,OAAO,GACpC,cAAc,CA2NhB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA2BvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAwBrE"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Pick the text color for a sidebar badge label drawn on a theme accent.
3
+ * Keep this logic in sync with Magic Context so both sidebars make the same
4
+ * contrast decision for shared themes.
5
+ */
6
+ type Color = {
7
+ r: number;
8
+ g: number;
9
+ b: number;
10
+ a?: number;
11
+ };
12
+ export declare function readableTextColorOn(bg: Color): string;
13
+ export declare function badgeTextColor<T extends Color>(accent: T, background: T): T | string;
14
+ export {};
15
+ //# sourceMappingURL=badge-contrast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-contrast.d.ts","sourceRoot":"","sources":["../../src/tui/badge-contrast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,KAAK,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA0B7D,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,KAAK,GAAG,MAAM,CAErD;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAMpF"}
package/dist/tui.js CHANGED
@@ -7790,7 +7790,7 @@ var require_src2 = __commonJS((exports, module) => {
7790
7790
  // src/tui/index.tsx
7791
7791
  import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
7792
7792
  // package.json
7793
- var version = "0.43.1";
7793
+ var version = "0.44.0";
7794
7794
 
7795
7795
  // src/shared/rpc-client.ts
7796
7796
  import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
@@ -9030,10 +9030,10 @@ class BridgePool {
9030
9030
  function normalizeKey(projectRoot) {
9031
9031
  return canonicalizeProjectRoot(projectRoot);
9032
9032
  }
9033
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/client.ts
9033
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
9034
9034
  import { promises as fs2 } from "node:fs";
9035
9035
 
9036
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/auth.ts
9036
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/auth.ts
9037
9037
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
9038
9038
  var NONCE_LEN = 32;
9039
9039
  var MAX_AUTH_MESSAGE_LEN = 4096;
@@ -9097,7 +9097,7 @@ async function authenticateClient(sock, conn, deadlineMs) {
9097
9097
  await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
9098
9098
  }
9099
9099
 
9100
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/connection-file.ts
9100
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/connection-file.ts
9101
9101
  import { promises as fs } from "node:fs";
9102
9102
  var SCHEMA_VERSION = 1;
9103
9103
  var MIN_KEY_LEN = 32;
@@ -9166,7 +9166,7 @@ async function readConnectionFile(path) {
9166
9166
  return info;
9167
9167
  }
9168
9168
 
9169
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/envelope.ts
9169
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/envelope.ts
9170
9170
  var PROTOCOL_VERSION = 1;
9171
9171
  var HEADER_LEN = 17;
9172
9172
  var FROZEN_PREFIX_LEN = 5;
@@ -9273,7 +9273,7 @@ function encodeFrame(frame) {
9273
9273
  return out;
9274
9274
  }
9275
9275
 
9276
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/socket.ts
9276
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/socket.ts
9277
9277
  import net from "node:net";
9278
9278
 
9279
9279
  class SocketClosedError extends Error {
@@ -9320,6 +9320,9 @@ class SubcSocket {
9320
9320
  sock.on("end", () => fail(new SocketClosedError("subc closed the connection")));
9321
9321
  sock.on("close", () => fail(new SocketClosedError("subc connection closed")));
9322
9322
  }
9323
+ localPort() {
9324
+ return this.sock.localPort ?? null;
9325
+ }
9323
9326
  static connect(host, port, deadlineMs) {
9324
9327
  return new Promise((resolve2, reject) => {
9325
9328
  const sock = net.connect({ host, port });
@@ -9459,7 +9462,7 @@ class SubcSocket {
9459
9462
  }
9460
9463
  }
9461
9464
 
9462
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/client.ts
9465
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
9463
9466
  var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
9464
9467
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
9465
9468
  var BODY_READ_TIMEOUT_MS = 30000;
@@ -9686,7 +9689,7 @@ class SubcClient {
9686
9689
  timer: null
9687
9690
  };
9688
9691
  pending.timer = setTimeout(() => {
9689
- this.rejectPending(key, pending, new SubcError(`request on channel ${channel} timed out after ${ms}ms`));
9692
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
9690
9693
  }, ms);
9691
9694
  this.pending.set(key, pending);
9692
9695
  this.sock.write(encodeFrame(frame), Date.now() + ms).catch((err) => {
@@ -9733,7 +9736,7 @@ class SubcClient {
9733
9736
  classifyFailure
9734
9737
  };
9735
9738
  pending.timer = setTimeout(() => {
9736
- this.rejectPending(key, pending, new SubcError(`request on channel ${channel} timed out after ${ms}ms`));
9739
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
9737
9740
  }, ms);
9738
9741
  this.pending.set(key, pending);
9739
9742
  const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
@@ -9881,7 +9884,9 @@ class SubcClient {
9881
9884
  for (const cached of this.routes.values()) {
9882
9885
  if (cached.closed)
9883
9886
  continue;
9884
- const channel = await this.routeOpen(cached.target, cached.identity);
9887
+ const channel = await this.routeOpen(cached.target, cached.identity, {
9888
+ consumerIdentity: cached.consumerIdentity ?? null
9889
+ });
9885
9890
  if (cached.closed) {
9886
9891
  this.sendRouteGoodbye(channel);
9887
9892
  continue;
@@ -9890,6 +9895,11 @@ class SubcClient {
9890
9895
  cached.generation = this.generation;
9891
9896
  }
9892
9897
  }
9898
+ timeoutMessage(channel, corr, ms) {
9899
+ const port = this.sock.localPort();
9900
+ const where = port === null ? "channel" : `local_port=${port} channel`;
9901
+ return `request on ${where} ${channel} corr ${corr} timed out after ${ms}ms`;
9902
+ }
9893
9903
  routeClosedDuringOpen() {
9894
9904
  return new SubcCallError("not_sent", "route was closed before route.open completed", "route_closed");
9895
9905
  }
@@ -10045,7 +10055,7 @@ function causeMessage(cause) {
10045
10055
  return "";
10046
10056
  return `: ${cause instanceof Error ? cause.message : String(cause)}`;
10047
10057
  }
10048
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.0/node_modules/@cortexkit/subc-client/src/provider.ts
10058
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/provider.ts
10049
10059
  import { Buffer as Buffer2 } from "node:buffer";
10050
10060
  var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4;
10051
10061
  var BODY_READ_TIMEOUT_MS2 = 30000;
@@ -11799,6 +11809,30 @@ async function handleSocketMessage(ws, raw, messageGeneration) {
11799
11809
  // src/tui/sidebar.tsx
11800
11810
  import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js";
11801
11811
 
11812
+ // src/tui/badge-contrast.ts
11813
+ var MIN_OPAQUE_ALPHA = 0.5;
11814
+ var MIN_CHANNEL_DISTANCE = 0.06;
11815
+ var LIGHT_ACCENT_LUMINANCE = 0.5;
11816
+ function srgbChannelToLinear(c) {
11817
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
11818
+ }
11819
+ function relativeLuminance(bg) {
11820
+ return 0.2126 * srgbChannelToLinear(bg.r) + 0.7152 * srgbChannelToLinear(bg.g) + 0.0722 * srgbChannelToLinear(bg.b);
11821
+ }
11822
+ function nearlyEqual(a, b) {
11823
+ return Math.abs(a.r - b.r) < MIN_CHANNEL_DISTANCE && Math.abs(a.g - b.g) < MIN_CHANNEL_DISTANCE && Math.abs(a.b - b.b) < MIN_CHANNEL_DISTANCE;
11824
+ }
11825
+ function readableTextColorOn(bg) {
11826
+ return relativeLuminance(bg) < LIGHT_ACCENT_LUMINANCE ? "#ffffff" : "#000000";
11827
+ }
11828
+ function badgeTextColor(accent, background) {
11829
+ const alpha = background.a ?? 1;
11830
+ if (alpha >= MIN_OPAQUE_ALPHA && !nearlyEqual(accent, background)) {
11831
+ return background;
11832
+ }
11833
+ return readableTextColorOn(accent);
11834
+ }
11835
+
11802
11836
  // src/tui/preferences.ts
11803
11837
  var import_comment_json = __toESM(require_src2(), 1);
11804
11838
  import { watch } from "node:fs";
@@ -12369,7 +12403,7 @@ var SidebarContent = (props) => {
12369
12403
  paddingRight: 1,
12370
12404
  backgroundColor: props.theme.accent,
12371
12405
  children: /* @__PURE__ */ jsxDEV("text", {
12372
- fg: props.theme.background,
12406
+ fg: badgeTextColor(props.theme.accent, props.theme.background),
12373
12407
  children: /* @__PURE__ */ jsxDEV("b", {
12374
12408
  children: [
12375
12409
  notInitialized() ? "" : collapsed() ? "▶ " : "▼ ",
@@ -12384,7 +12418,7 @@ var SidebarContent = (props) => {
12384
12418
  marginLeft: 1,
12385
12419
  backgroundColor: props.theme.warning,
12386
12420
  children: /* @__PURE__ */ jsxDEV("text", {
12387
- fg: props.theme.background,
12421
+ fg: badgeTextColor(props.theme.warning, props.theme.background),
12388
12422
  children: /* @__PURE__ */ jsxDEV("b", {
12389
12423
  children: "DEGRADED"
12390
12424
  }, undefined, false, undefined, this)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.43.1",
3
+ "version": "0.44.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",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@clack/prompts": "^1.6.0",
34
- "@cortexkit/aft-bridge": "0.43.1",
34
+ "@cortexkit/aft-bridge": "0.44.0",
35
35
  "@opentui/core": "^0.4.2",
36
36
  "@opentui/solid": "^0.4.2",
37
37
  "comment-json": "^4.6.2",
@@ -40,12 +40,12 @@
40
40
  "zod": "^4.4.3"
41
41
  },
42
42
  "optionalDependencies": {
43
- "@cortexkit/aft-darwin-arm64": "0.43.1",
44
- "@cortexkit/aft-darwin-x64": "0.43.1",
45
- "@cortexkit/aft-linux-arm64": "0.43.1",
46
- "@cortexkit/aft-linux-x64": "0.43.1",
47
- "@cortexkit/aft-win32-arm64": "0.43.1",
48
- "@cortexkit/aft-win32-x64": "0.43.1"
43
+ "@cortexkit/aft-darwin-arm64": "0.44.0",
44
+ "@cortexkit/aft-darwin-x64": "0.44.0",
45
+ "@cortexkit/aft-linux-arm64": "0.44.0",
46
+ "@cortexkit/aft-linux-x64": "0.44.0",
47
+ "@cortexkit/aft-win32-arm64": "0.44.0",
48
+ "@cortexkit/aft-win32-x64": "0.44.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@opencode-ai/plugin": "^1.17.11",
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Pick the text color for a sidebar badge label drawn on a theme accent.
3
+ * Keep this logic in sync with Magic Context so both sidebars make the same
4
+ * contrast decision for shared themes.
5
+ */
6
+
7
+ type Color = { r: number; g: number; b: number; a?: number };
8
+
9
+ const MIN_OPAQUE_ALPHA = 0.5;
10
+ const MIN_CHANNEL_DISTANCE = 0.06;
11
+ const LIGHT_ACCENT_LUMINANCE = 0.5;
12
+
13
+ function srgbChannelToLinear(c: number): number {
14
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
15
+ }
16
+
17
+ function relativeLuminance(bg: Color): number {
18
+ return (
19
+ 0.2126 * srgbChannelToLinear(bg.r) +
20
+ 0.7152 * srgbChannelToLinear(bg.g) +
21
+ 0.0722 * srgbChannelToLinear(bg.b)
22
+ );
23
+ }
24
+
25
+ function nearlyEqual(a: Color, b: Color): boolean {
26
+ return (
27
+ Math.abs(a.r - b.r) < MIN_CHANNEL_DISTANCE &&
28
+ Math.abs(a.g - b.g) < MIN_CHANNEL_DISTANCE &&
29
+ Math.abs(a.b - b.b) < MIN_CHANNEL_DISTANCE
30
+ );
31
+ }
32
+
33
+ export function readableTextColorOn(bg: Color): string {
34
+ return relativeLuminance(bg) < LIGHT_ACCENT_LUMINANCE ? "#ffffff" : "#000000";
35
+ }
36
+
37
+ export function badgeTextColor<T extends Color>(accent: T, background: T): T | string {
38
+ const alpha = background.a ?? 1;
39
+ if (alpha >= MIN_OPAQUE_ALPHA && !nearlyEqual(accent, background)) {
40
+ return background;
41
+ }
42
+ return readableTextColorOn(accent);
43
+ }
@@ -19,6 +19,7 @@ import {
19
19
  type StatusCompression,
20
20
  } from "../shared/status";
21
21
  import { resolveCortexKitStorageRoot } from "../shared/storage-paths";
22
+ import { badgeTextColor } from "./badge-contrast";
22
23
  import {
23
24
  createDebouncedStatusRefresh,
24
25
  refreshAftTuiSocketScope,
@@ -592,7 +593,7 @@ const SidebarContent = (props: {
592
593
  {/* Triangle lives inside the accent badge so the toggle reads as one
593
594
  unit: "▶ AFT" / "▼ AFT". Hidden pre-init (nothing to collapse). */}
594
595
  <box paddingLeft={1} paddingRight={1} backgroundColor={props.theme.accent}>
595
- <text fg={props.theme.background}>
596
+ <text fg={badgeTextColor(props.theme.accent, props.theme.background)}>
596
597
  <b>
597
598
  {notInitialized() ? "" : collapsed() ? "▶ " : "▼ "}
598
599
  {prefs().header.label}
@@ -606,7 +607,7 @@ const SidebarContent = (props: {
606
607
  marginLeft={1}
607
608
  backgroundColor={props.theme.warning}
608
609
  >
609
- <text fg={props.theme.background}>
610
+ <text fg={badgeTextColor(props.theme.warning, props.theme.background)}>
610
611
  <b>DEGRADED</b>
611
612
  </text>
612
613
  </box>