@p4code/cli 0.6.27 → 0.6.32

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/bin.mjs CHANGED
@@ -19,11 +19,8 @@ import "effect/LogLevel";
19
19
  import * as Path$1 from "effect/Path";
20
20
  import * as Schema$1 from "effect/Schema";
21
21
  import * as NodePath from "node:path";
22
- import { isAbsolute } from "node:path";
23
22
  import * as NodeChildProcess from "node:child_process";
24
- import { spawn } from "node:child_process";
25
23
  import * as NodeFS from "node:fs";
26
- import { constants } from "node:fs";
27
24
  import * as DateTime from "effect/DateTime";
28
25
  import * as Duration from "effect/Duration";
29
26
  import * as Option from "effect/Option";
@@ -45,7 +42,6 @@ import * as Config from "effect/Config";
45
42
  import * as References from "effect/References";
46
43
  import * as HttpServerRequest$1 from "effect/unstable/http/HttpServerRequest";
47
44
  import * as NodeCrypto from "node:crypto";
48
- import { createHash, randomUUID } from "node:crypto";
49
45
  import * as Encoding from "effect/Encoding";
50
46
  import * as Result$1 from "effect/Result";
51
47
  import * as Crypto from "effect/Crypto";
@@ -61,7 +57,6 @@ import * as Cause from "effect/Cause";
61
57
  import * as Exit from "effect/Exit";
62
58
  import * as NodeReadline from "node:readline";
63
59
  import * as NodeFSP from "node:fs/promises";
64
- import { access } from "node:fs/promises";
65
60
  import * as Clock from "effect/Clock";
66
61
  import * as Headers$1 from "effect/unstable/http/Headers";
67
62
  import * as HttpRouter$1 from "effect/unstable/http/HttpRouter";
@@ -268,7 +263,7 @@ const make$123 = () => {
268
263
  const layer$124 = Layer.sync(NetService, make$123);
269
264
  //#endregion
270
265
  //#region package.json
271
- var version$1 = "0.6.27";
266
+ var version$1 = "0.6.32";
272
267
  //#endregion
273
268
  //#region ../../packages/shared/src/serverInstance.ts
274
269
  /**
@@ -25782,7 +25777,7 @@ const queryHubAnalyticsFacts = Effect.fn("HubAnalytics.query")(function* (princi
25782
25777
  environmentId: row.environment_id,
25783
25778
  kind: row.kind,
25784
25779
  version: row.version,
25785
- occurredAt: new Date(row.occurred_at).toISOString(),
25780
+ occurredAt: DateTime.formatIso(DateTime.makeUnsafe(row.occurred_at)),
25786
25781
  payload: yield* decodePayload$1(row.payload)
25787
25782
  });
25788
25783
  const last = page[page.length - 1];
@@ -49301,12 +49296,12 @@ var XcodeMcpClient = class XcodeMcpClient {
49301
49296
  child.stdin.on("error", () => this.close(/* @__PURE__ */ new Error("Device MCP input disconnected.")));
49302
49297
  }
49303
49298
  static async start(executable, cwd, environment, signal, kind = "legacy") {
49304
- if (!isAbsolute(executable)) throw new Error("Device MCP requires an absolute executable path.");
49305
- await access(executable, constants.X_OK).catch(() => {
49299
+ if (!NodePath.isAbsolute(executable)) throw new Error("Device MCP requires an absolute executable path.");
49300
+ await NodeFSP.access(executable, NodeFS.constants.X_OK).catch(() => {
49306
49301
  throw new Error(kind === "apple" ? "Selected Xcode bridge is missing or not executable. Check the selected Xcode installation." : "Configured XcodeBuildMCP executable is missing or not executable. Install 2.7.0 explicitly.");
49307
49302
  });
49308
49303
  signal.throwIfAborted();
49309
- const client = new XcodeMcpClient(spawn(executable, kind === "apple" ? ["mcpbridge"] : ["mcp"], {
49304
+ const client = new XcodeMcpClient(NodeChildProcess.spawn(executable, kind === "apple" ? ["mcpbridge"] : ["mcp"], {
49310
49305
  cwd,
49311
49306
  shell: false,
49312
49307
  stdio: "pipe",
@@ -49577,7 +49572,7 @@ function createXcodeDeviceAdapter(executable, cwd, environment) {
49577
49572
  const key = session.leaseId;
49578
49573
  if (action === "start" && recordings.has(key)) throw new Error("This device session is already recording.");
49579
49574
  if (action === "stop" && !recordings.has(key)) throw new Error("This device session has no active recording.");
49580
- const outputFile = recordings.get(key)?.outputFile ?? `${cwd}/device-recording-${randomUUID()}.mp4`;
49575
+ const outputFile = recordings.get(key)?.outputFile ?? `${cwd}/device-recording-${NodeCrypto.randomUUID()}.mp4`;
49581
49576
  const result = xcodeResultData(await client.call("record_sim_video", {
49582
49577
  simulatorId: session.deviceId,
49583
49578
  ...action === "start" ? { start: true } : {
@@ -49678,7 +49673,7 @@ function appleHierarchySnapshot(text, sequence) {
49678
49673
  }];
49679
49674
  });
49680
49675
  return {
49681
- screenHash: createHash("sha256").update(text).digest("hex"),
49676
+ screenHash: NodeCrypto.createHash("sha256").update(text).digest("hex"),
49682
49677
  seq: sequence,
49683
49678
  elements
49684
49679
  };
@@ -49748,7 +49743,7 @@ function createAppleDeviceAdapter(input) {
49748
49743
  pending = (async () => {
49749
49744
  const client = await XcodeMcpClient.start("/usr/bin/xcrun", input.cwd, {
49750
49745
  ...input.environment,
49751
- MCP_XCODE_SESSION_ID: randomUUID()
49746
+ MCP_XCODE_SESSION_ID: NodeCrypto.randomUUID()
49752
49747
  }, signal, "apple");
49753
49748
  try {
49754
49749
  const missing = REQUIRED_DEVICE_TOOLS.filter((tool) => !client.tools.has(tool));
@@ -64523,16 +64518,7 @@ var ProviderSessionDirectoryPersistenceError = class extends Schema$1.TaggedErro
64523
64518
  //#endregion
64524
64519
  //#region src/mcp/ComputerUseInstallation.ts
64525
64520
  /** P4-owned host discovery. Native Codex tools are never injected or inspected here. */
64526
- const COMPUTER_USE_MCP_SERVER_NAME = "cua_repl";
64527
- /**
64528
- * The same P4 server as Codex sees it. Codex bundles its own Computer Use
64529
- * servers (`computer-use`, and the unified plugin's `cua_repl`), so P4's is
64530
- * registered beside them under this name rather than over `cua_repl`: native
64531
- * tools stay native, and P4's work when native ones are disabled.
64532
- */
64533
- const CODEX_COMPUTER_USE_MCP_SERVER_NAME = "p4_cua_repl";
64534
- /** The P4 Computer Use server's name as the given provider driver sees it. */
64535
- const computerUseMcpServerName = (driverKind) => driverKind === "codex" ? CODEX_COMPUTER_USE_MCP_SERVER_NAME : COMPUTER_USE_MCP_SERVER_NAME;
64521
+ const COMPUTER_USE_MCP_SERVER_NAME = "p4_cua_repl";
64536
64522
  //#endregion
64537
64523
  //#region src/mcp/McpProviderSession.ts
64538
64524
  /**
@@ -92224,8 +92210,6 @@ const CODEX_P4CODE_BEARER_TOKEN_ENV_VAR = "P4_MCP_BEARER_TOKEN";
92224
92210
  * TOML float. An hour, because `ask_user_question` blocks until a person answers.
92225
92211
  */
92226
92212
  const CODEX_P4CODE_TOOL_TIMEOUT_SEC = "3600.0";
92227
- /** Its own variable, so the Computer Use credential never rides on p4-code's. */
92228
- const CODEX_P4_COMPUTER_USE_BEARER_TOKEN_ENV_VAR = "P4_COMPUTER_USE_BEARER_TOKEN";
92229
92213
  /** Prefix for the per-server variables the registered servers get. */
92230
92214
  const BEARER_TOKEN_ENV_VAR_PREFIX = "P4_MCP_BEARER_TOKEN_";
92231
92215
  /** TOML bare keys; anything else has to be quoted inside the dotted path. */
@@ -92257,7 +92241,7 @@ const toCodexMcpConfig = (resolved, exclude = /* @__PURE__ */ new Set()) => {
92257
92241
  };
92258
92242
  let index = 0;
92259
92243
  for (const [name, server] of Object.entries(resolved)) {
92260
- if (name === "cua_repl" || name === mcpUserScopeSessionName("cua_repl")) continue;
92244
+ if (["cua_repl", "p4_cua_repl"].some((reserved) => name === reserved || name === mcpUserScopeSessionName(reserved))) continue;
92261
92245
  if (exclude.has(name)) continue;
92262
92246
  if (server.type === "stdio") {
92263
92247
  push(name, "command", JSON.stringify(server.command));
@@ -94321,7 +94305,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
94321
94305
  const externalMcp = toCodexMcpConfig(fusionExternalMcpServers(options?.resolveMcpServers === void 0 ? {} : yield* options.resolveMcpServers, {
94322
94306
  role: input.fusionRole,
94323
94307
  optimizedContext: resolvedFusionPromptSettings?.optimizedContext ?? DEFAULT_FUSION_PROMPT_SETTINGS.optimizedContext
94324
- }), /* @__PURE__ */ new Set([...P4CODE_MCP_SERVER_NAMES, CODEX_COMPUTER_USE_MCP_SERVER_NAME]));
94308
+ }), P4CODE_MCP_SERVER_NAMES);
94325
94309
  for (const dropped of externalMcp.skipped) yield* Effect.logWarning("codex cannot express an mcp registration", {
94326
94310
  server: dropped.name,
94327
94311
  reason: dropped.reason
@@ -94350,26 +94334,16 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
94350
94334
  environment: {
94351
94335
  ...options?.environment ?? process.env,
94352
94336
  ...externalMcp.env,
94353
- ...mcpSession ? { [CODEX_P4CODE_BEARER_TOKEN_ENV_VAR]: mcpSession.authorizationHeader.replace(/^Bearer\s+/, "") } : {},
94354
- ...mcpSession?.computerUse ? { [CODEX_P4_COMPUTER_USE_BEARER_TOKEN_ENV_VAR]: mcpSession.computerUse.authorizationHeader.replace(/^Bearer\s+/, "") } : {}
94337
+ ...mcpSession ? { [CODEX_P4CODE_BEARER_TOKEN_ENV_VAR]: mcpSession.authorizationHeader.replace(/^Bearer\s+/, "") } : {}
94355
94338
  },
94356
- appServerArgs: [
94357
- ...externalMcp.args,
94358
- ...mcpSession ? [
94359
- "-c",
94360
- `mcp_servers.${P4CODE_MCP_SERVER_NAME}.url=${mcpSession.endpoint}`,
94361
- "-c",
94362
- `mcp_servers.${P4CODE_MCP_SERVER_NAME}.bearer_token_env_var="${CODEX_P4CODE_BEARER_TOKEN_ENV_VAR}"`,
94363
- "-c",
94364
- `mcp_servers.${P4CODE_MCP_SERVER_NAME}.tool_timeout_sec=${CODEX_P4CODE_TOOL_TIMEOUT_SEC}`
94365
- ] : [],
94366
- ...mcpSession?.computerUse ? [
94367
- "-c",
94368
- `mcp_servers.${CODEX_COMPUTER_USE_MCP_SERVER_NAME}.url=${mcpSession.computerUse.endpoint}`,
94369
- "-c",
94370
- `mcp_servers.${CODEX_COMPUTER_USE_MCP_SERVER_NAME}.bearer_token_env_var="${CODEX_P4_COMPUTER_USE_BEARER_TOKEN_ENV_VAR}"`
94371
- ] : []
94372
- ]
94339
+ appServerArgs: [...externalMcp.args, ...mcpSession ? [
94340
+ "-c",
94341
+ `mcp_servers.${P4CODE_MCP_SERVER_NAME}.url=${mcpSession.endpoint}`,
94342
+ "-c",
94343
+ `mcp_servers.${P4CODE_MCP_SERVER_NAME}.bearer_token_env_var="${CODEX_P4CODE_BEARER_TOKEN_ENV_VAR}"`,
94344
+ "-c",
94345
+ `mcp_servers.${P4CODE_MCP_SERVER_NAME}.tool_timeout_sec=${CODEX_P4CODE_TOOL_TIMEOUT_SEC}`
94346
+ ] : []]
94373
94347
  } : {}
94374
94348
  };
94375
94349
  const sessionScope = yield* Scope.make("sequential");
@@ -123833,7 +123807,8 @@ const make$36 = Effect.gen(function* () {
123833
123807
  cwd: project.workspaceRoot,
123834
123808
  path: worktreePath
123835
123809
  });
123836
- const detail = input.cleanup && !input.cleanup.worktree ? "Thread assets removed; workspace preserved." : "Detached worktree removed; thread context preserved.";
123810
+ const removedDetail = input.cleanup && !input.cleanup.worktree ? "Thread assets removed; workspace preserved." : "Detached worktree removed; thread context preserved.";
123811
+ const detail = input.cleanup?.localBranch || input.cleanup?.remoteBranch ? `${removedDetail} No feature branch was checked out, so branch cleanup was skipped.` : removedDetail;
123837
123812
  yield* record({
123838
123813
  threadIds,
123839
123814
  lifecycle: {
@@ -123959,7 +123934,7 @@ const make$36 = Effect.gen(function* () {
123959
123934
  });
123960
123935
  const branch = localStatus.isDefaultBranch ? null : localStatus.branch;
123961
123936
  if (branch === null) {
123962
- if (cleanup?.localBranch || cleanup?.remoteBranch) return yield* refusal("Cleanup refused because this worktree has no removable feature branch.");
123937
+ if (cleanup && !cleanup.worktree && !cleanup.assets) return yield* refusal("Cleanup refused because this worktree has no removable feature branch.");
123963
123938
  return yield* cleanupDetachedWorktree({
123964
123939
  threadIds,
123965
123940
  project,
@@ -132002,6 +131977,7 @@ const layer$8 = Layer.effect(SourceControlRepositoryService, make$15);
132002
131977
  /** Matches `p4c hub token add`, so a token minted here and one minted there are the same thing. */
132003
131978
  const HUB_TOKEN_BYTES = 32;
132004
131979
  const isOrchestrationDispatchCommandError = Schema$1.is(OrchestrationDispatchCommandError);
131980
+ const isHubLinkError = Schema$1.is(HubLinkError);
132005
131981
  const nowIso$2 = Effect.map(DateTime.now, DateTime.formatIso);
132006
131982
  const EDITOR_DISCOVERY_TIMEOUT = Duration.seconds(5);
132007
131983
  const resolveAvailableEditorsForConfig = (discovery) => discovery.pipe(Effect.timeoutOption(EDITOR_DISCOVERY_TIMEOUT), Effect.map(Option.getOrElse(() => [])));
@@ -133345,7 +133321,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
133345
133321
  const transport = yield* makeHubActivityTransport(state.settings.value);
133346
133322
  const membership = yield* transport.identity();
133347
133323
  return yield* transport.queryFacts(query, membership);
133348
- }).pipe(Effect.mapError((cause) => new HubLinkError({ detail: cause instanceof HubLinkError ? cause.detail : "The hub could not be reached." }))), { "rpc.aggregate": "hub" }),
133324
+ }).pipe(Effect.mapError((cause) => new HubLinkError({ detail: isHubLinkError(cause) ? cause.detail : "The hub could not be reached." }))), { "rpc.aggregate": "hub" }),
133349
133325
  [WS_METHODS.hubGetSyncStatus]: (_input) => observeRpcEffect$1(WS_METHODS.hubGetSyncStatus, assetSync.status, { "rpc.aggregate": "hub" }),
133350
133326
  [WS_METHODS.hubConnect]: (input) => observeRpcEffect$1(WS_METHODS.hubConnect, hubLink.connect(input).pipe(Effect.mapError((cause) => new HubLinkError({ detail: cause.message })), Effect.andThen(assetSync.status)), { "rpc.aggregate": "hub" }),
133351
133327
  [WS_METHODS.hubDisconnect]: (_input) => observeRpcEffect$1(WS_METHODS.hubDisconnect, hubLink.disconnect.pipe(Effect.mapError((cause) => new HubLinkError({ detail: cause.message })), Effect.andThen(assetSync.status)), { "rpc.aggregate": "hub" }),
@@ -134000,11 +133976,9 @@ const ProviderAdapterRegistryLive = Layer.effect(ProviderAdapterRegistry, makePr
134000
133976
  //#endregion
134001
133977
  //#region src/provider/ComputerUsePrompts.ts
134002
133978
  /** Routing guidance is injected only when the session has P4's Computer Use endpoint. */
134003
- const COMPUTER_USE_ROUTING_PROMPT = "P4 Computer Use is available for this session through the cua_repl MCP server. When you use it for a native desktop app, do not substitute AppleScript or shell automation unless the user explicitly requests that path. For a named app, start directly with const app = await cua.getApp(exactNameOrBundleId); read the automatically returned state/image and stop if it answers the request. Reuse the handle and batch safe actions; do not repeat selection or unchanged state. For Device Hub, simulator, emulator, or connected-device requests, use cua.listDevices() once, then cua.getDevice({hostId,deviceId,platform}) with exact discovered IDs, unless the user explicitly requested a different route such as simctl. Selection already emits initial device state. Reuse its handle; do not print the handle or repeat that state before acting. Never substitute macOS getApp('Simulator'). Device hosts are scoped to this provider environment and can differ from the desktop host. If device discovery, opening, inspection, or interaction reports missing permission or unavailable control, stop P4 device interaction and report the exact limitation. Do not silently retry through screenshots, shell simctl, Xcode tools, or another MCP server; an explicit user request for one of those routes, including a standing fallback authorization in the user's global or project instructions, is separate authorization to use it; report the P4 error and the fallback you used. Do not call getState/getApp, control the P4 desktop app, or open device settings to work around a device API failure. Missing consent, unavailable devices, or unsupported operations are P4 limitations to report, never on their own permission to switch P4 hosts or bypass the tool.";
134004
- /** The routing note, naming the server the way this session's provider sees it. */
134005
- function withComputerUseRouting(input, enabled, serverName = "cua_repl") {
134006
- const prompt = serverName === "cua_repl" ? COMPUTER_USE_ROUTING_PROMPT : COMPUTER_USE_ROUTING_PROMPT.replace("the cua_repl MCP server", `the ${serverName} MCP server`);
134007
- return enabled ? `<p4-computer-use>\n${prompt}\n</p4-computer-use>\n\n${input ?? ""}` : input;
133979
+ const COMPUTER_USE_ROUTING_PROMPT = "P4 Computer Use is available for this session through the p4_cua_repl MCP server. When you use it for a native desktop app, do not substitute AppleScript or shell automation unless the user explicitly requests that path. For a named app, start directly with const app = await cua.getApp(exactNameOrBundleId); read the automatically returned state/image and stop if it answers the request. Reuse the handle and batch safe actions; do not repeat selection or unchanged state. For Device Hub, simulator, emulator, or connected-device requests, use cua.listDevices() once, then cua.getDevice({hostId,deviceId,platform}) with exact discovered IDs, unless the user explicitly requested a different route such as simctl. Selection already emits initial device state. Reuse its handle; do not print the handle or repeat that state before acting. Never substitute macOS getApp('Simulator'). Device hosts are scoped to this provider environment and can differ from the desktop host. If device discovery, opening, inspection, or interaction reports missing permission or unavailable control, stop P4 device interaction and report the exact limitation. Do not silently retry through screenshots, shell simctl, Xcode tools, or another MCP server; an explicit user request for one of those routes, including a standing fallback authorization in the user's global or project instructions, is separate authorization to use it; report the P4 error and the fallback you used. Do not call getState/getApp, control the P4 desktop app, or open device settings to work around a device API failure. Missing consent, unavailable devices, or unsupported operations are P4 limitations to report, never on their own permission to switch P4 hosts or bypass the tool.";
133980
+ function withComputerUseRouting(input, enabled) {
133981
+ return enabled ? `<p4-computer-use>\n${COMPUTER_USE_ROUTING_PROMPT}\n</p4-computer-use>\n\n${input ?? ""}` : input;
134008
133982
  }
134009
133983
  //#endregion
134010
133984
  //#region src/mcp/McpSessionRegistry.ts
@@ -134502,7 +134476,7 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
134502
134476
  const thread = yield* projectionQuery.value.getThreadShellById(threadId);
134503
134477
  return Option.isSome(thread) ? resolveProjectAgentBrowserAccess(settings, thread.value.projectId) : false;
134504
134478
  })), Effect.catch((cause) => Effect.logWarning("Could not read settings; withholding agent browser access.", { cause }).pipe(Effect.as(false))));
134505
- const computerUseAccess = yield* registry.getInstanceInfo(providerInstanceId).pipe(Effect.as(true), Effect.orElseSucceed(() => false));
134479
+ const computerUseAccess = yield* registry.getInstanceInfo(providerInstanceId).pipe(Effect.map((info) => info.driverKind !== "codex"), Effect.orElseSucceed(() => false));
134506
134480
  const fusionRole = Option.isSome(projectionQuery) ? yield* projectionQuery.value.getActiveThreadPairs().pipe(Effect.map((pairs) => {
134507
134481
  const pair = pairs.find((entry) => entry.watcherThreadId === threadId || entry.implementerThreadId === threadId);
134508
134482
  if (pair === void 0) return void 0;
@@ -134875,7 +134849,7 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
134875
134849
  else if (sendComputerUseNote && mcpSession !== void 0) computerUseNoteSessions.set(input.threadId, mcpSession.providerSessionId);
134876
134850
  const turn = yield* routed.adapter.sendTurn({
134877
134851
  ...input,
134878
- input: withComputerUseRouting(input.input, sendComputerUseNote, computerUseMcpServerName(routed.adapter.provider))
134852
+ input: withComputerUseRouting(input.input, sendComputerUseNote)
134879
134853
  });
134880
134854
  yield* directory.upsert({
134881
134855
  threadId: input.threadId,
@@ -135412,7 +135386,7 @@ const mcpToolkit = (toolkit) => Layer.effectDiscard(Effect.gen(function* () {
135412
135386
  //#endregion
135413
135387
  //#region src/mcp/toolkits/computerUse/tools.ts
135414
135388
  const ComputerUseJsTool = Tool.make("js", {
135415
- description: "P4 Code Computer Use: control native apps through P4Code's signed helper. Run JavaScript in a persistent REPL. On the first call, execute exactly one entry-point operation and read its automatic output before continuing. When the user names an app, execute only const app = await cua.getApp(exactNameBundleIdOrPath); this already prints its state and includes a screenshot when AX exposes no app content. Use await cua.getState() only when discovery is needed. Use cua.createBrowserTab('iab', url, {visible:true}) or cua.getTab(tabId) for P4 browser tabs. Tab methods: getState(), goto(url), click({locator}), type({text,locator?,clear?}), press({key,modifiers?}), scroll({deltaY,deltaX?}), upload({locator,files}). Use upload with absolute browser-host file paths to attach files to a file input; clicking or typing a file input opens the system file dialog and cannot attach files. Print results with nodeRepl.write(value); emit PNG/JPEG with nodeRepl.emitImage({mimeType,data}) using base64 data. Top-level await and persistent let bindings are supported. Await each operation. Bindings disappear after helper restart, host disconnect, reset, or tray Stop. When resuming a task, guard a remembered binding within the same js call: if (typeof app === 'undefined') { globalThis.app = await cua.getApp('Spotify'); } else { await app.getScreenshot(); }. Substitute the named app and intended operation. The missing-binding branch selects only and prints fresh state; decide the next action after reading it. Never spend a separate tool call checking whether a binding exists. Reset after timeout or host disconnect. For available native apps, use cua.getApp(exactNameBundleIdOrPath), then getAXState(), click(elementIndex), or setValue(elementIndex,text) to replace a field value in the background. click(elementIndex) sends a real pointer click to the element's center in the background, falling back to its accessibility press when that point is hidden or not visible. click([x,y]) clicks pixels from the latest getScreenshot() of that app. pressKey(chord) such as 'cmd+shift+g', 'Return' or 'Escape', and typeText(text) up to 200 characters, go to the app's frontmost window, including its Open and Save panels. Selection already prints numbered accessibility state; reuse the app handle without selecting or reading it again before the first action. Snapshot text is bounded; use getAXState({filter:'Pause'}) for case-insensitive text filtering across the snapshot, including controls omitted from the initial output. Use {emit:false} on getApp(name, options), getAXState(options), or getScreenshot(options) when processing the returned value yourself; do not print auto-emitted output again. Several deterministic actions against distinct unchanged elements may share one snapshot. Each used element index expires after one action. To click the same control again, refresh with getAXState({filter: controlLabel}) first, even inside a batch; never reuse its old index. The host revalidates remaining native handles and rejects changed elements. Read fresh state after the action batch before deciding the next action. If selection includes a screenshot because AX exposes only window controls or menus, read that image immediately and finish if it answers the request. If no image is included, use getScreenshot() to read visual content; do not repeat unchanged snapshots hoping for missing accessibility content. getScreenshot() emits the selected app window; getAXStateAndScreenshot() emits both. Legacy getState(), click({elementId}), type({elementId,text}), windows(), and screenshot(windowId) remain supported. Native control preserves foreground focus and the system pointer. When a [jev] note follows your output, Jev already ran those app steps; element indexes printed before it are expired, so act on the state in the note. Drag, scroll, paste, and activation input are unsupported; do not use global input or activate the app as a fallback. P4Code shows the controlled native window in its embedded live view. A persistent independent black pointer marks actions on the host window, outside the preview. Hide closes only the view; use Show live view in the Computer Use control to reopen it. Stop ends thread control; reset clears the view and handles. Google Chrome can be controlled as a native app using cua.getApp('Google Chrome'); Chrome extension/CDP tab APIs are not exposed by this host. Native app availability and macOS permission states are reported by the host; never assume native apps are supported. The host may be a different machine from the provider server. Device hub simulators are scoped to the provider environment: await cua.listDevices(), then await cua.getDevice({hostId,deviceId,platform}) using exact discovered IDs. Selection automatically emits initial AX state (or a screenshot on other platforms); reuse the handle without repeating that capture or printing the handle. A permission or unavailable-control error requires stopping and reporting it, never shell or alternative-tool fallback. The device handle supports getAXState() (raw iOS accessibility state), getScreenshot(), getAXStateAndScreenshot(), click([x,y]) in device coordinates from fresh AX state, typeText(text), and close(). When getAXState() reports adapter apple-xcode or xcodebuildmcp, use semantic refs from capture.elements and only advertised capabilities: click(elementRef), typeText(text,{elementRef,replaceExisting:true}), swipe({withinElementRef,direction}), drag({elementRef,direction}), batch([{action:\"tap\",elementRef},...]), and recordVideo(\"start\"|\"stop\") only when advertised in capabilities. getAXState({sinceScreenHash}) avoids unchanged snapshots. Batch only same-screen taps; action output includes updated capture. On stale-ref errors inspect fresh state and choose a current ref; never replay an action automatically. Physical-device UI control and device key input are unavailable. Device consent must already be enabled in P4 Settings. Use timeout_ms:60000 for initial device startup. Reset invalidates device handles; device viewer sessions remain under Devices until explicitly closed. Never substitute macOS Simulator.app AX for simulated-app state.",
135389
+ description: "P4 Code Computer Use: control native apps through P4Code's signed helper. Run JavaScript in a persistent REPL. On the first call, execute exactly one entry-point operation and read its automatic output before continuing. When the user names an app, execute only const app = await cua.getApp(exactNameBundleIdOrPath); this already prints its state and includes a screenshot when AX exposes no app content. Use await cua.getState() only when discovery is needed. Use cua.createBrowserTab('iab', url, {visible:true}) or cua.getTab(tabId) for P4 browser tabs. Tab methods: getState(), goto(url), click({locator}), type({text,locator?,clear?}), press({key,modifiers?}), scroll({deltaY,deltaX?}), upload({locator,files}). Use upload with absolute browser-host file paths to attach files to a file input; clicking or typing a file input opens the system file dialog and cannot attach files. Print results with nodeRepl.write(value); emit PNG/JPEG with nodeRepl.emitImage({mimeType,data}) using base64 data. Top-level await and persistent let bindings are supported. Await each operation. Bindings disappear after helper restart, host disconnect, reset, or tray Stop. When resuming a task, guard a remembered binding within the same js call: if (typeof app === 'undefined') { globalThis.app = await cua.getApp('Spotify'); } else { await app.getScreenshot(); }. Substitute the named app and intended operation. The missing-binding branch selects only and prints fresh state; decide the next action after reading it. Never spend a separate tool call checking whether a binding exists. Reset after timeout or host disconnect. For available native apps, use cua.getApp(exactNameBundleIdOrPath), then getAXState(), click(elementIndex), or setValue(elementIndex,text) to replace a field value in the background. click(elementIndex) uses the element's accessibility press, falling back to a real pointer click at its center only when the element has no press action. click([x,y]) sends a real pointer click on pixels from the latest getScreenshot() of that app; use it only when a web page needs a real click, such as opening a file picker, because some apps briefly come forward on pointer clicks. pressKey(chord) such as 'cmd+shift+g', 'Return' or 'Escape', and typeText(text) up to 200 characters, go to the app's frontmost window, including its Open and Save panels. Selection already prints numbered accessibility state; reuse the app handle without selecting or reading it again before the first action. Snapshot text is bounded; use getAXState({filter:'Pause'}) for case-insensitive text filtering across the snapshot, including controls omitted from the initial output. Use {emit:false} on getApp(name, options), getAXState(options), or getScreenshot(options) when processing the returned value yourself; do not print auto-emitted output again. Several deterministic actions against distinct unchanged elements may share one snapshot. Each used element index expires after one action. To click the same control again, refresh with getAXState({filter: controlLabel}) first, even inside a batch; never reuse its old index. The host revalidates remaining native handles and rejects changed elements. Read fresh state after the action batch before deciding the next action. If selection includes a screenshot because AX exposes only window controls or menus, read that image immediately and finish if it answers the request. If no image is included, use getScreenshot() to read visual content; do not repeat unchanged snapshots hoping for missing accessibility content. getScreenshot() emits the selected app window; getAXStateAndScreenshot() emits both. Legacy getState(), click({elementId}), type({elementId,text}), windows(), and screenshot(windowId) remain supported. Native control preserves foreground focus and the system pointer. When a [jev] note follows your output, Jev already ran those app steps; element indexes printed before it are expired, so act on the state in the note. Drag, scroll, paste, and activation input are unsupported; do not use global input or activate the app as a fallback. P4Code shows the controlled native window in its embedded live view. A persistent independent black pointer marks actions on the host window, outside the preview. Hide closes only the view; use Show live view in the Computer Use control to reopen it. Stop ends thread control; reset clears the view and handles. Google Chrome can be controlled as a native app using cua.getApp('Google Chrome'); Chrome extension/CDP tab APIs are not exposed by this host. Native app availability and macOS permission states are reported by the host; never assume native apps are supported. The host may be a different machine from the provider server. Device hub simulators are scoped to the provider environment: await cua.listDevices(), then await cua.getDevice({hostId,deviceId,platform}) using exact discovered IDs. Selection automatically emits initial AX state (or a screenshot on other platforms); reuse the handle without repeating that capture or printing the handle. A permission or unavailable-control error requires stopping and reporting it, never shell or alternative-tool fallback. The device handle supports getAXState() (raw iOS accessibility state), getScreenshot(), getAXStateAndScreenshot(), click([x,y]) in device coordinates from fresh AX state, typeText(text), and close(). When getAXState() reports adapter apple-xcode or xcodebuildmcp, use semantic refs from capture.elements and only advertised capabilities: click(elementRef), typeText(text,{elementRef,replaceExisting:true}), swipe({withinElementRef,direction}), drag({elementRef,direction}), batch([{action:\"tap\",elementRef},...]), and recordVideo(\"start\"|\"stop\") only when advertised in capabilities. getAXState({sinceScreenHash}) avoids unchanged snapshots. Batch only same-screen taps; action output includes updated capture. On stale-ref errors inspect fresh state and choose a current ref; never replay an action automatically. Physical-device UI control and device key input are unavailable. Device consent must already be enabled in P4 Settings. Use timeout_ms:60000 for initial device startup. Reset invalidates device handles; device viewer sessions remain under Devices until explicitly closed. Never substitute macOS Simulator.app AX for simulated-app state.",
135416
135390
  parameters: Schema$1.Struct({
135417
135391
  ...ComputerUseJsInput.fields,
135418
135392
  hostId: Schema$1.optional(TrimmedNonEmptyString).annotate({ description: "Select an available host when more than one is connected. Reset before changing hosts." })
@@ -139521,7 +139495,7 @@ const McpTransportLive = McpServer.layerHttp({
139521
139495
  }).pipe(Layer.provide(McpAuthMiddlewareLive));
139522
139496
  const StandardMcpLive = Layer.mergeAll(PreviewToolkitRegistrationLive, TaskToolkitRegistrationLive, ThreadToolkitRegistrationLive, WatchToolkitRegistrationLive, AdviseToolkitRegistrationLive, TypeSafeToolkitRegistrationLive, DeviceToolkitRegistrationLive).pipe(Layer.provideMerge(McpTransportLive));
139523
139497
  const ComputerUseMcpLive = ComputerUseToolkitRegistrationLive.pipe(Layer.provide(TypeSafeClientLive), Layer.provideMerge(McpServer.layerHttp({
139524
- name: "cua_repl",
139498
+ name: COMPUTER_USE_MCP_SERVER_NAME,
139525
139499
  version: version$1,
139526
139500
  path: "/mcp/computer-use"
139527
139501
  }).pipe(Layer.provide(McpAuthMiddlewareLive))));
@@ -1,4 +1,4 @@
1
- import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}from"./compiler-runtime-CLAvuQ-D.js";import{$a as i,$r as a,Hr as o,Ia as s,Ot as c,Qa as l,Sl as u,Ua as d,Wa as ee,Wl as te,Xa as f,Ya as p,Za as m,Zu as h,_t as g,b as ne,bl as _,bt as v,h as y,lt as b,pu as x,qr as re,su as S,vt as C,vu as ie,wn as w,wu as ae,xl as oe,yl as T,yn as E,za as se}from"./previewAssetResource-CGmfO5X4.js";import{a as D,c as ce,i as O,n as k,o as A,r as j,s as le,t as M}from"./toggle-group-DP_7wZXj.js";import{F as N,Lr as ue,M as de,N as fe,P as pe,Q as me,Rr as he,Sr as ge,Ur as _e,Vr as ve,Wr as ye,Z as be,ar as xe,b as Se,cr as Ce,dr as we,dt as Te,fi as Ee,fr as De,ft as Oe,gr as ke,ht as P,lr as Ae,lt as je,mr as Me,mt as Ne,or as Pe,pi as Fe,pt as Ie,sr as Le,ur as Re,ut as ze,v as Be,zr as Ve}from"./index-BwOkNK7W.js";import{a as He,n as Ue}from"./fileCommentAnnotations-BnBaaKaI.js";var We=u(`pilcrow`,[[`path`,{d:`M13 4v16`,key:`8vvj80`}],[`path`,{d:`M17 4v16`,key:`7dpous`}],[`path`,{d:`M19 4H9.5a4.5 4.5 0 0 0 0 9H13`,key:`sh4n9v`}]]),F=e(n(),1);function Ge({threadRef:e,filePath:t,activeCwd:n,openInEditor:r,openFileSurface:i}){if(e){if(i){i(t);return}b.getState().openFile(e,t);return}r(n?y(t,n):t)}var I=r();function Ke(e,t){let n=(0,I.c)(4),r=Me(e,t),i;return n[0]!==r.data||n[1]!==r.error||n[2]!==r.isPending?(i={data:r.data,error:r.error,isPending:r.isPending},n[0]=r.data,n[1]=r.error,n[2]=r.isPending,n[3]=i):i=n[3],i}var L=t(),qe=[];function Je(e){return(e.endSide??e.side)===`deletions`?`deletions`:`additions`}function R(e,t,n){let r=Je(t),i=e.findIndex(e=>e.side===r&&e.lineNumber===t.end);return i<0?[...e,{side:r,lineNumber:t.end,metadata:{entries:[n]}}]:e.map((e,t)=>t===i?{...e,metadata:{entries:[...e.metadata.entries,n]}}:e)}function Ye(e){let t=(0,I.c)(50),{files:n,sectionId:r,sectionTitle:i,composerDraftTarget:s,options:c,viewerRef:l,className:u,renderHeaderPrefix:d}=e,ee=o(Qe),te=o(B),f;t[0]===s?f=t[1]:(f=e=>e.getComposerDraft(s)?.reviewComments??qe,t[0]=s,t[1]=f);let p=o(f),[m,h]=(0,F.useState)(null),[g,ne]=(0,F.useState)(null),_;t[2]===n?_=t[3]:(_=new Map(n.map(Ze)),t[2]=n,t[3]=_);let v=_,y;if(t[4]!==g||t[5]!==n||t[6]!==p||t[7]!==r){let e;t[9]!==g||t[10]!==p||t[11]!==r?(e=e=>{let{fileDiff:t,filePath:n,fileKey:i,collapsed:o}=e,s=p.filter(e=>e.sectionId===r&&e.filePath===n&&(e.fenceLanguage??`diff`)===`diff`).reduce((e,n)=>{let r=a(t,n);return r?R(e,r,{id:n.id,kind:`comment`,range:r,rangeLabel:n.rangeLabel,text:n.text}):e},[]),c=g?.fileKey===i?[...s,g.annotation]:s;return{id:i,type:`diff`,fileDiff:t,annotations:c,collapsed:o,version:ze(`${o?`1`:`0`}:${c.flatMap(z).join(`:`)}`)}},t[9]=g,t[10]=p,t[11]=r,t[12]=e):e=t[12],y=n.map(e),t[4]=g,t[5]=n,t[6]=p,t[7]=r,t[8]=y}else y=t[8];let b=y,x;t[13]!==s||t[14]!==g?.annotation||t[15]!==te?(x=e=>{h(null),g?.annotation.metadata.entries.some(t=>t.id===e)?ne(null):te(s,e)},t[13]=s,t[14]=g?.annotation,t[15]=te,t[16]=x):x=t[16];let S=x,C;t[17]!==ee||t[18]!==s||t[19]!==g||t[20]!==v||t[21]!==r||t[22]!==i?(C=(e,t)=>{let n=g?.annotation.metadata.entries.find(t=>t.id===e),a=g?v.get(g.fileKey):void 0;if(!n||!a)return;let o=re({id:n.id,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:n.range,text:t});o&&ee(s,o),h(null),ne(null)},t[17]=ee,t[18]=s,t[19]=g,t[20]=v,t[21]=r,t[22]=i,t[23]=C):C=t[23];let ie=C,w;t[24]!==v||t[25]!==r||t[26]!==i?(w=(e,t)=>{if(!e)return;let n=t.item;if(n.type!==`diff`)return;let a=v.get(n.id);if(!a)return;let o=Ue(),s=re({id:o,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:e,text:``});s&&ne({fileKey:n.id,annotation:{side:Je(e),lineNumber:e.end,metadata:{entries:[{id:o,kind:`draft`,range:e,rangeLabel:s.rangeLabel,text:``}]}}})},t[24]=v,t[25]=r,t[26]=i,t[27]=w):w=t[27];let ae=w,oe=g!==null,T;t[28]===l?T=t[29]:(T=l?{ref:l}:{},t[28]=l,t[29]=T);let E;t[30]===u?E=t[31]:(E=u?{className:u}:{},t[30]=u,t[31]=E);let se=!oe,ce=!oe,O;t[32]!==ae||t[33]!==c||t[34]!==ce||t[35]!==se?(O={...c,enableGutterUtility:se,enableLineSelection:ce,onLineSelectionEnd:ae},t[32]=ae,t[33]=c,t[34]=ce,t[35]=se,t[36]=O):O=t[36];let k;t[37]===d?k=t[38]:(k=e=>e.type===`diff`?d(e.fileDiff,e.id,e.collapsed===!0):null,t[37]=d,t[38]=k);let A;t[39]!==S||t[40]!==ie?(A=e=>(0,L.jsx)(`div`,{className:`py-1`,children:e.metadata.entries.map(e=>(0,L.jsx)(He,{kind:e.kind,rangeLabel:e.rangeLabel,text:e.text,onCancel:()=>S(e.id),onComment:t=>ie(e.id,t),onDelete:()=>S(e.id)},e.id))}),t[39]=S,t[40]=ie,t[41]=A):A=t[41];let j;return t[42]!==b||t[43]!==m||t[44]!==O||t[45]!==k||t[46]!==A||t[47]!==T||t[48]!==E?(j=(0,L.jsx)(D,{...T,...E,items:b,selectedLines:m,onSelectedLinesChange:h,options:O,renderHeaderPrefix:k,renderAnnotation:A}),t[42]=b,t[43]=m,t[44]=O,t[45]=k,t[46]=A,t[47]=T,t[48]=E,t[49]=j):j=t[49],j}function z(e){return e.metadata.entries.map(Xe)}function Xe(e){return`${e.id}:${e.rangeLabel}:${e.text}`}function Ze(e){return[e.fileKey,e]}function B(e){return e.removeReviewComment}function Qe(e){return e.addReviewComment}function $e(e){return{diffPreview:S(e,{label:`environment-data:review:diff-preview`,tag:h.reviewGetDiffPreview,staleTimeMs:5e3})}}var et=$e(w);function V(e){return e.remoteName&&e.name.startsWith(`${e.remoteName}/`)?e.name.slice(e.remoteName.length+1):e.name}function tt(e,t){let n=new Set(t),r=e.map(e=>{let r=t.filter(t=>n.has(t)&&V(t)===e.name),i=r.find(e=>e.remoteName===`origin`)??r[0]??null;return i&&n.delete(i),{id:`local:${e.name}`,label:e.name,local:e,remote:i}}),i=t.filter(e=>n.has(e)).map(e=>({id:`remote:${e.name}`,label:e.name,local:null,remote:e}));return[...r,...i]}function nt(e,t){let n=t.trim().toLocaleLowerCase();return n.length===0?e:e.filter(e=>e.label.toLocaleLowerCase().includes(n)||e.local?.name.toLocaleLowerCase().includes(n)===!0||e.remote?.name.toLocaleLowerCase().includes(n)===!0)}var H=`__automatic_base_ref__`,rt=new Set,it=`
1
+ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}from"./compiler-runtime-CLAvuQ-D.js";import{$a as i,$r as a,Hr as o,Ia as s,Ot as c,Qa as l,Sl as u,Ua as d,Wa as ee,Wl as te,Xa as f,Ya as p,Za as m,Zu as h,_t as g,b as ne,bl as _,bt as v,h as y,lt as b,pu as x,qr as re,su as S,vt as C,vu as ie,wn as w,wu as ae,xl as oe,yl as T,yn as E,za as se}from"./previewAssetResource-DnRvGKTL.js";import{a as D,c as ce,i as O,n as k,o as A,r as j,s as le,t as M}from"./toggle-group-OYeWFpKu.js";import{F as N,Lr as ue,M as de,N as fe,P as pe,Q as me,Rr as he,Sr as ge,Ur as _e,Vr as ve,Wr as ye,Z as be,ar as xe,b as Se,cr as Ce,dr as we,dt as Te,fi as Ee,fr as De,ft as Oe,gr as ke,ht as P,lr as Ae,lt as je,mr as Me,mt as Ne,or as Pe,pi as Fe,pt as Ie,sr as Le,ur as Re,ut as ze,v as Be,zr as Ve}from"./index-onaAsCHe.js";import{a as He,n as Ue}from"./fileCommentAnnotations-FiOzhHWj.js";var We=u(`pilcrow`,[[`path`,{d:`M13 4v16`,key:`8vvj80`}],[`path`,{d:`M17 4v16`,key:`7dpous`}],[`path`,{d:`M19 4H9.5a4.5 4.5 0 0 0 0 9H13`,key:`sh4n9v`}]]),F=e(n(),1);function Ge({threadRef:e,filePath:t,activeCwd:n,openInEditor:r,openFileSurface:i}){if(e){if(i){i(t);return}b.getState().openFile(e,t);return}r(n?y(t,n):t)}var I=r();function Ke(e,t){let n=(0,I.c)(4),r=Me(e,t),i;return n[0]!==r.data||n[1]!==r.error||n[2]!==r.isPending?(i={data:r.data,error:r.error,isPending:r.isPending},n[0]=r.data,n[1]=r.error,n[2]=r.isPending,n[3]=i):i=n[3],i}var L=t(),qe=[];function Je(e){return(e.endSide??e.side)===`deletions`?`deletions`:`additions`}function R(e,t,n){let r=Je(t),i=e.findIndex(e=>e.side===r&&e.lineNumber===t.end);return i<0?[...e,{side:r,lineNumber:t.end,metadata:{entries:[n]}}]:e.map((e,t)=>t===i?{...e,metadata:{entries:[...e.metadata.entries,n]}}:e)}function Ye(e){let t=(0,I.c)(50),{files:n,sectionId:r,sectionTitle:i,composerDraftTarget:s,options:c,viewerRef:l,className:u,renderHeaderPrefix:d}=e,ee=o(Qe),te=o(B),f;t[0]===s?f=t[1]:(f=e=>e.getComposerDraft(s)?.reviewComments??qe,t[0]=s,t[1]=f);let p=o(f),[m,h]=(0,F.useState)(null),[g,ne]=(0,F.useState)(null),_;t[2]===n?_=t[3]:(_=new Map(n.map(Ze)),t[2]=n,t[3]=_);let v=_,y;if(t[4]!==g||t[5]!==n||t[6]!==p||t[7]!==r){let e;t[9]!==g||t[10]!==p||t[11]!==r?(e=e=>{let{fileDiff:t,filePath:n,fileKey:i,collapsed:o}=e,s=p.filter(e=>e.sectionId===r&&e.filePath===n&&(e.fenceLanguage??`diff`)===`diff`).reduce((e,n)=>{let r=a(t,n);return r?R(e,r,{id:n.id,kind:`comment`,range:r,rangeLabel:n.rangeLabel,text:n.text}):e},[]),c=g?.fileKey===i?[...s,g.annotation]:s;return{id:i,type:`diff`,fileDiff:t,annotations:c,collapsed:o,version:ze(`${o?`1`:`0`}:${c.flatMap(z).join(`:`)}`)}},t[9]=g,t[10]=p,t[11]=r,t[12]=e):e=t[12],y=n.map(e),t[4]=g,t[5]=n,t[6]=p,t[7]=r,t[8]=y}else y=t[8];let b=y,x;t[13]!==s||t[14]!==g?.annotation||t[15]!==te?(x=e=>{h(null),g?.annotation.metadata.entries.some(t=>t.id===e)?ne(null):te(s,e)},t[13]=s,t[14]=g?.annotation,t[15]=te,t[16]=x):x=t[16];let S=x,C;t[17]!==ee||t[18]!==s||t[19]!==g||t[20]!==v||t[21]!==r||t[22]!==i?(C=(e,t)=>{let n=g?.annotation.metadata.entries.find(t=>t.id===e),a=g?v.get(g.fileKey):void 0;if(!n||!a)return;let o=re({id:n.id,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:n.range,text:t});o&&ee(s,o),h(null),ne(null)},t[17]=ee,t[18]=s,t[19]=g,t[20]=v,t[21]=r,t[22]=i,t[23]=C):C=t[23];let ie=C,w;t[24]!==v||t[25]!==r||t[26]!==i?(w=(e,t)=>{if(!e)return;let n=t.item;if(n.type!==`diff`)return;let a=v.get(n.id);if(!a)return;let o=Ue(),s=re({id:o,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:e,text:``});s&&ne({fileKey:n.id,annotation:{side:Je(e),lineNumber:e.end,metadata:{entries:[{id:o,kind:`draft`,range:e,rangeLabel:s.rangeLabel,text:``}]}}})},t[24]=v,t[25]=r,t[26]=i,t[27]=w):w=t[27];let ae=w,oe=g!==null,T;t[28]===l?T=t[29]:(T=l?{ref:l}:{},t[28]=l,t[29]=T);let E;t[30]===u?E=t[31]:(E=u?{className:u}:{},t[30]=u,t[31]=E);let se=!oe,ce=!oe,O;t[32]!==ae||t[33]!==c||t[34]!==ce||t[35]!==se?(O={...c,enableGutterUtility:se,enableLineSelection:ce,onLineSelectionEnd:ae},t[32]=ae,t[33]=c,t[34]=ce,t[35]=se,t[36]=O):O=t[36];let k;t[37]===d?k=t[38]:(k=e=>e.type===`diff`?d(e.fileDiff,e.id,e.collapsed===!0):null,t[37]=d,t[38]=k);let A;t[39]!==S||t[40]!==ie?(A=e=>(0,L.jsx)(`div`,{className:`py-1`,children:e.metadata.entries.map(e=>(0,L.jsx)(He,{kind:e.kind,rangeLabel:e.rangeLabel,text:e.text,onCancel:()=>S(e.id),onComment:t=>ie(e.id,t),onDelete:()=>S(e.id)},e.id))}),t[39]=S,t[40]=ie,t[41]=A):A=t[41];let j;return t[42]!==b||t[43]!==m||t[44]!==O||t[45]!==k||t[46]!==A||t[47]!==T||t[48]!==E?(j=(0,L.jsx)(D,{...T,...E,items:b,selectedLines:m,onSelectedLinesChange:h,options:O,renderHeaderPrefix:k,renderAnnotation:A}),t[42]=b,t[43]=m,t[44]=O,t[45]=k,t[46]=A,t[47]=T,t[48]=E,t[49]=j):j=t[49],j}function z(e){return e.metadata.entries.map(Xe)}function Xe(e){return`${e.id}:${e.rangeLabel}:${e.text}`}function Ze(e){return[e.fileKey,e]}function B(e){return e.removeReviewComment}function Qe(e){return e.addReviewComment}function $e(e){return{diffPreview:S(e,{label:`environment-data:review:diff-preview`,tag:h.reviewGetDiffPreview,staleTimeMs:5e3})}}var et=$e(w);function V(e){return e.remoteName&&e.name.startsWith(`${e.remoteName}/`)?e.name.slice(e.remoteName.length+1):e.name}function tt(e,t){let n=new Set(t),r=e.map(e=>{let r=t.filter(t=>n.has(t)&&V(t)===e.name),i=r.find(e=>e.remoteName===`origin`)??r[0]??null;return i&&n.delete(i),{id:`local:${e.name}`,label:e.name,local:e,remote:i}}),i=t.filter(e=>n.has(e)).map(e=>({id:`remote:${e.name}`,label:e.name,local:null,remote:e}));return[...r,...i]}function nt(e,t){let n=t.trim().toLocaleLowerCase();return n.length===0?e:e.filter(e=>e.label.toLocaleLowerCase().includes(n)||e.local?.name.toLocaleLowerCase().includes(n)===!0||e.remote?.name.toLocaleLowerCase().includes(n)===!0)}var H=`__automatic_base_ref__`,rt=new Set,it=`
2
2
  [data-diffs-header],
3
3
  [data-diff],
4
4
  [data-file],
@@ -95,4 +95,4 @@ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}f
95
95
  text-decoration-color: currentColor;
96
96
  }
97
97
  `;function U({mode:e=`inline`,composerDraftTarget:t,initialGitScope:n,threadRef:r}){let{resolvedTheme:a}=ne(),o=ve(),[u]=(0,F.useState)(n),[h,y]=(0,F.useState)(`stacked`),[b,re]=(0,F.useState)(o.wordWrap),[S,w]=(0,F.useState)(o.diffIgnoreWhitespace),[D,Se]=(0,F.useState)(``),[Me,ze]=(0,F.useState)(()=>({scopeKey:null,fileKeys:rt})),He=(0,F.useRef)(null),Ue=r.threadId,I=Ve(r),qe=I?.projectId??null,Je=he(I&&qe?{environmentId:I.environmentId,projectId:qe}:null),R=I?.worktreePath??Je?.workspaceRoot,z=te(E.configValueAtom(I?.environmentId??null)),Xe=ke(I?.environmentId??null,z?.availableEditors??[]),Ze=c(I!=null&&R!=null?ue.status({environmentId:I.environmentId,input:{cwd:R}}):null),B=N(e=>pe(e.byThreadKey,r,u===`unstaged`)),Qe=Ze.data?.isRepo??!0,{turnDiffSummaries:$e,inferredCheckpointTurnCountByTurnId:V}=fe(I),U=(0,F.useMemo)(()=>[...$e].toSorted((e,t)=>{let n=e.checkpointTurnCount??V[e.turnId]??0,r=t.checkpointTurnCount??V[t.turnId]??0;return n===r?t.completedAt.localeCompare(e.completedAt):r-n}),[V,$e]);(0,F.useEffect)(()=>{B.kind===`turn`&&N.getState().reconcileTurnSelection(r,U.map(e=>e.turnId))},[B,U,r]);let W=B.kind===`turn`?B.turnId:null,G=B.kind===`unstaged`?`unstaged`:`branch`,K=B.kind===`branch`?B.baseRef:null,at=B.kind===`turn`?B.filePath:null,ot=B.kind===`turn`?B.revealRequestId:0,q=W===null?void 0:U.find(e=>e.turnId===W)??U[0],J=q&&(q.checkpointTurnCount??V[q.turnId]),st=U[0],ct=W===null?G===`unstaged`?`Working tree`:`Branch changes`:q?.turnId===st?.turnId?`Latest turn`:`Turn ${J??`?`}`,lt=q?`turn:${q.turnId}`:G,Y=`${r.environmentId}:${r.threadId}:${lt}`,ut=Me.scopeKey===Y?Me.fileKeys:rt,dt=q?`Turn ${J??`?`}`:G===`unstaged`?`Working tree`:`Branch changes`,ft=(0,F.useMemo)(()=>typeof J==`number`?{fromTurnCount:Math.max(0,J-1),toTurnCount:J}:null,[J]),pt=Ke({environmentId:I?.environmentId??null,threadId:Ue,fromTurnCount:ft?.fromTurnCount??null,toTurnCount:ft?.toTurnCount??null,ignoreWhitespace:S,cacheScope:q?`turn:${q.turnId}`:null},{enabled:Qe&&q!==void 0}),mt=c(W===null&&I&&R?et.diffPreview({environmentId:I.environmentId,input:{cwd:R,...K?{baseRef:K}:{},ignoreWhitespace:S}}):null),ht=W===null&&mt.error?.includes(`configured workspace root`)===!0&&z?.cwd!==void 0&&z.cwd!==R,gt=c(ht&&I&&z?et.diffPreview({environmentId:I.environmentId,input:{cwd:z.cwd,...K?{baseRef:K}:{},ignoreWhitespace:S}}):null),X=ht?gt:mt,Z=X.data?.sources.find(e=>e.kind===(G===`unstaged`?`working-tree`:`branch-range`)),_t=c(W===null&&G===`branch`&&I&&X.data?.cwd?ue.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`local`,...D.trim().length>0?{query:D.trim()}:{},limit:100}}):null),vt=c(W===null&&G===`branch`&&I&&X.data?.cwd?ue.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`remote`,...D.trim().length>0?{query:D.trim()}:{},limit:100}}):null),yt=tt(_t.data?.refs.filter(e=>e.name!==Z?.headRef)??[],vt.data?.refs??[]),bt=nt(yt,D),xt=e=>K&&K===e.remote?.name?K:e.local?.name??e.remote?.name??e.id,St=[H,...yt.map(xt)],Ct=[...D.trim().length===0?[H]:[],...bt.map(xt)],wt=Z?.diff,Tt=q?pt.data?.diff:wt,Et=!q&&Z?.truncated===!0,Dt=q?pt.isPending:X.isPending,Ot=q?pt.error:X.error,kt=typeof Tt==`string`&&Tt.trim().length===0,Q=(0,F.useMemo)(()=>Ie(Tt,`diff-panel:${a}`,{compactPartialHunkOffsets:W===null}),[a,Tt,W]),At=(0,F.useMemo)(()=>!Q||Q.kind!==`files`?[]:Q.files.toSorted((e,t)=>P(e).localeCompare(P(t),void 0,{numeric:!0,sensitivity:`base`})),[Q]),$=(0,F.useMemo)(()=>At.map(e=>{let t=je(e);return{fileDiff:e,filePath:P(e),fileKey:t,collapsed:ut.has(t)}}),[ut,At]),jt=(0,F.useMemo)(()=>$.map(e=>e.fileKey),[$]),Mt=j(jt,ut),Nt=(0,F.useMemo)(()=>Oe(At),[At]);(0,F.useEffect)(()=>{if(!at)return;let e=$.find(e=>e.filePath===at);e&&He.current?.scrollTo({type:`item`,id:e.fileKey,align:`start`})},[$,at,ot]);let Pt=de({threadRef:r,workspaceRoot:R??null}),Ft=(0,F.useCallback)(e=>{Ge({threadRef:r,filePath:e,activeCwd:R,openFileSurface:Pt,openInEditor:e=>{(async()=>{let t=await Xe(e);t._tag===`Failure`&&!x(t)&&console.warn(`Failed to open diff file in editor.`,{operation:`open-diff-file`,environmentId:r.environmentId,threadId:r.threadId,...ae(ie(t))})})()}})},[R,Pt,Xe,r]),It=(0,F.useCallback)(e=>{ze(t=>{let n=new Set(t.scopeKey===Y?t.fileKeys:[]);return n.has(e)?n.delete(e):n.add(e),{scopeKey:Y,fileKeys:n}})},[Y]),Lt=(0,F.useCallback)(()=>{ze(e=>{let t=e.scopeKey===Y?e.fileKeys:rt;return{scopeKey:Y,fileKeys:O(jt,t)}})},[Y,jt]),Rt=e=>{N.getState().selectTurn(r,e)},zt=e=>{N.getState().selectGitScope(r,e)},Bt=e=>{N.getState().selectBranchBaseRef(r,e)};return(0,L.jsx)(me,{mode:e,header:(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-center gap-3 [-webkit-app-region:no-drag]`,children:[(0,L.jsxs)(se,{children:[(0,L.jsxs)(l,{className:`inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted/70 px-2 text-xs font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring`,"aria-label":`Diff scope: ${ct}`,children:[(0,L.jsx)(`span`,{className:`truncate`,children:ct}),(0,L.jsx)(_,{className:`size-3.5 shrink-0 text-muted-foreground`})]}),(0,L.jsxs)(ee,{align:`start`,className:`w-60`,children:[(0,L.jsx)(d,{className:W===null&&G===`unstaged`?`bg-foreground/[0.08]`:void 0,onClick:()=>zt(`unstaged`),children:(0,L.jsx)(`span`,{children:`Working tree`})}),(0,L.jsx)(d,{className:W===null&&G===`branch`?`bg-foreground/[0.08]`:void 0,onClick:()=>zt(`branch`),children:(0,L.jsx)(`span`,{children:`Branch changes`})}),(0,L.jsx)(d,{className:W!==null&&q?.turnId===st?.turnId?`bg-foreground/[0.08]`:void 0,onClick:()=>{st&&Rt(st.turnId)},children:(0,L.jsx)(`span`,{children:`Latest turn`})}),(0,L.jsxs)(p,{children:[(0,L.jsx)(m,{children:`Turn`}),(0,L.jsx)(f,{className:`w-64`,children:U.map(e=>{let t=e.checkpointTurnCount??V[e.turnId]??`?`;return(0,L.jsxs)(d,{className:e.turnId===q?.turnId?`bg-foreground/[0.08]`:void 0,onClick:()=>Rt(e.turnId),children:[(0,L.jsxs)(`span`,{children:[`Turn `,t]}),(0,L.jsx)(`span`,{className:`ml-auto text-xs tabular-nums text-muted-foreground`,children:ge(e.completedAt,o.timestampFormat)})]},e.turnId)})})]})]})]}),W===null&&G===`branch`&&Z?.baseRef&&(0,L.jsxs)(`div`,{className:`flex min-w-0 max-w-full items-center gap-2 overflow-hidden text-xs text-muted-foreground`,title:`${Z.headRef??`HEAD`} → ${Z.baseRef}`,"aria-label":`Comparing ${Z.headRef??`HEAD`} against ${Z.baseRef}`,children:[(0,L.jsx)(`span`,{className:`min-w-0 max-w-48 truncate`,children:Z.headRef??`HEAD`}),(0,L.jsx)(Fe,{className:`size-3.5 shrink-0 opacity-70`}),(0,L.jsxs)(xe,{items:St,filteredItems:Ct,value:K??H,onOpenChange:e=>{e||Se(``)},onValueChange:e=>{e&&Bt(e===H?null:e)},children:[(0,L.jsxs)(we,{className:`inline-flex min-w-0 max-w-48 items-center gap-1 overflow-hidden rounded-md px-1.5 py-1 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring`,"aria-label":`Change comparison target. Currently ${Z.baseRef}`,children:[(0,L.jsx)(`span`,{className:`min-w-0 truncate`,children:Z.baseRef}),(0,L.jsx)(_,{className:`size-3.5 shrink-0 opacity-70`})]}),(0,L.jsxs)(Re,{align:`start`,className:`w-72 min-w-0 max-w-[calc(100vw-1rem)] overflow-hidden [&>[data-slot=combobox-popup]]:min-w-0 [&>[data-slot=combobox-popup]]:overflow-hidden`,children:[(0,L.jsx)(`div`,{className:`min-w-0 shrink-0 px-3 pt-2.5`,children:(0,L.jsxs)(`div`,{className:`relative -translate-y-px border-b border-border/70 pb-1.5 transition-colors focus-within:border-ring`,children:[(0,L.jsx)(ye,{"aria-hidden":`true`,className:`pointer-events-none absolute top-1.5 left-0 size-4 shrink-0 text-muted-foreground/55`}),(0,L.jsx)(Le,{className:`[&_input]:h-6.5 [&_input]:ps-5 [&_input]:font-sans [&_input]:leading-6.5`,inputClassName:`rounded-none bg-transparent text-sm`,placeholder:`Search refs...`,showTrigger:!1,size:`sm`,unstyled:!0,value:D,onChange:e=>Se(e.target.value)})]})}),(0,L.jsxs)(`div`,{className:`grid shrink-0 grid-cols-[1rem_minmax(0,1fr)] items-center gap-2 border-b border-border/70 ps-3 pe-6.5 pt-2 pb-1.5 font-medium text-[10px] text-muted-foreground uppercase tracking-wide`,children:[(0,L.jsx)(`span`,{"aria-hidden":`true`}),(0,L.jsxs)(`div`,{className:`grid min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center`,children:[(0,L.jsx)(`span`,{children:`Branch`}),(0,L.jsx)(`span`,{className:`text-right`,children:`Remote`})]})]}),(0,L.jsx)(Pe,{children:`No matching refs.`}),(0,L.jsxs)(Ae,{className:`max-h-64 min-w-0 overflow-x-hidden`,children:[(0,L.jsx)(Ce,{className:`h-8 w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)] py-0`,contentClassName:`w-full min-w-0 overflow-hidden`,value:H,children:(0,L.jsx)(`span`,{className:`block min-w-0 truncate`,children:`Automatic`})}),yt.map(e=>{let t=xt(e),n=e.local!==null&&e.remote!==null,r=e.remote?.name===t;return(0,L.jsx)(Ce,{className:`h-8 w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)] py-0`,contentClassName:`w-full min-w-0 overflow-hidden`,value:t,children:(0,L.jsxs)(`div`,{className:`grid w-full min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center overflow-hidden`,children:[(0,L.jsx)(`span`,{className:`block min-w-0 truncate pe-2`,children:e.label}),n?(0,L.jsx)(`div`,{className:`flex justify-end`,onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,L.jsx)(De,{"aria-label":`Use remote version of ${e.label}`,checked:r,className:`[--thumb-size:--spacing(3)]`,onCheckedChange:t=>{let n=t?e.remote?.name:e.local?.name;n&&Bt(n)}})}):e.remote?(0,L.jsx)(`span`,{className:`flex justify-end text-muted-foreground`,title:`Remote only`,children:(0,L.jsx)(oe,{"aria-hidden":`true`,className:`size-3`})}):null]})},e.id)})]})]})]})]})]}),(0,L.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[$.length>0&&(0,L.jsx)(Be,{additions:Nt.additions,deletions:Nt.deletions,className:`mr-1 text-[11px]`,layout:`inline`}),$.length>0&&(0,L.jsxs)(g,{children:[(0,L.jsx)(v,{render:(0,L.jsx)(s,{type:`button`,size:`icon-xs`,variant:`outline`,"aria-label":Mt?`Expand all files`:`Collapse all files`,onClick:Lt}),children:Mt?(0,L.jsx)(Ee,{className:`size-3`}):(0,L.jsx)(ce,{className:`size-3`})}),(0,L.jsx)(C,{side:`top`,children:Mt?`Expand all files`:`Collapse all files`})]}),(0,L.jsxs)(k,{className:`shrink-0`,variant:`outline`,size:`xs`,value:[h],onValueChange:e=>{let t=e[0];(t===`stacked`||t===`split`)&&y(t)},children:[(0,L.jsx)(M,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,L.jsx)(A,{className:`size-3`})}),(0,L.jsx)(M,{"aria-label":`Split diff view`,value:`split`,children:(0,L.jsx)(le,{className:`size-3`})})]}),(0,L.jsxs)(g,{children:[(0,L.jsx)(v,{render:(0,L.jsx)(M,{"aria-label":b?`Disable diff line wrapping`:`Enable diff line wrapping`,variant:`outline`,size:`xs`,pressed:b,onPressedChange:e=>{re(!!e)}}),children:(0,L.jsx)(_e,{className:`size-3`})}),(0,L.jsx)(C,{side:`top`,children:b?`Disable line wrapping`:`Enable line wrapping`})]}),(0,L.jsxs)(g,{children:[(0,L.jsx)(v,{render:(0,L.jsx)(M,{"aria-label":S?`Show whitespace changes`:`Hide whitespace changes`,variant:`outline`,size:`xs`,pressed:S,onPressedChange:e=>{w(!!e)}}),children:(0,L.jsx)(We,{className:`size-3`})}),(0,L.jsx)(C,{side:`top`,children:S?`Show whitespace changes`:`Hide whitespace changes`})]})]})]}),children:I?Qe?W!==null&&U.length===0?(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`No completed turns yet.`}):(0,L.jsx)(L.Fragment,{children:(0,L.jsxs)(`div`,{className:`diff-panel-viewport flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden`,children:[Et&&(0,L.jsx)(`p`,{className:`shrink-0 border-b border-border/70 bg-muted/40 px-3 py-1.5 text-[11px] text-muted-foreground`,children:`This diff was truncated because it exceeded the preview limit. The changes shown are incomplete.`}),Ot&&!Q&&(0,L.jsx)(`div`,{className:`px-3`,children:(0,L.jsx)(`p`,{className:`mb-2 text-[11px] text-red-500/80`,children:Ot})}),Q?Q.kind===`files`?(0,L.jsx)(`div`,{className:`min-h-0 flex-1`,onClickCapture:e=>{let t=(e.nativeEvent.composedPath?.()??[]).find(e=>e instanceof HTMLElement&&e.hasAttribute(`data-title`))?.textContent?.trim();t&&Ft(t)},children:(0,L.jsx)(Ye,{viewerRef:He,className:`diff-render-surface h-full min-h-0 overflow-auto`,files:$,sectionId:lt,sectionTitle:dt,composerDraftTarget:t,renderHeaderPrefix:(e,t,n)=>{let r=P(e);return(0,L.jsxs)(g,{children:[(0,L.jsx)(v,{render:(0,L.jsx)(`button`,{type:`button`,className:i(`inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 transition-colors hover:bg-foreground/10 focus-visible:outline-hidden`,Te(e)),"aria-label":n?`Expand ${r}`:`Collapse ${r}`,"aria-expanded":!n,onClick:e=>{e.stopPropagation(),It(t)}}),children:n?(0,L.jsx)(T,{className:`size-4`}):(0,L.jsx)(_,{className:`size-4`})}),(0,L.jsx)(C,{side:`top`,children:n?`Expand diff`:`Collapse diff`})]})},options:{diffStyle:h===`split`?`split`:`unified`,lineDiffType:`none`,overflow:b?`wrap`:`scroll`,theme:Ne(a),themeType:a,unsafeCSS:it,stickyHeaders:!0,itemMetrics:{diffHeaderHeight:33},layout:{paddingTop:0,paddingBottom:8,gap:8}}},Y??lt)}):(0,L.jsx)(`div`,{className:`min-h-0 flex-1 overflow-auto p-2`,children:(0,L.jsxs)(`div`,{className:`space-y-2`,children:[(0,L.jsx)(`p`,{className:`text-[11px] text-muted-foreground/75`,children:Q.reason}),(0,L.jsx)(`pre`,{className:i(`max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90`,b?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:Q.text})]})}):Dt?(0,L.jsx)(be,{label:q?`Loading checkpoint diff...`:G===`unstaged`?`Loading working tree diff...`:`Loading branch diff...`}):(0,L.jsx)(`div`,{className:`flex h-full items-center justify-center px-3 py-2 text-xs text-muted-foreground/70`,children:(0,L.jsx)(`p`,{children:kt?`No net changes in this selection.`:`No patch available for this selection.`})})]})}):(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`Turn diffs are unavailable because this project is not a git repository.`}):(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`Select a thread to inspect turn diffs.`})})}export{Se as DiffWorkerPoolProvider,U as default};
98
- //# sourceMappingURL=DiffPanel-BcgYZQjD.js.map
98
+ //# sourceMappingURL=DiffPanel-BHvSBQra.js.map