@p4code/cli 0.4.10 → 0.4.12

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
@@ -240,7 +240,7 @@ const make$93 = () => {
240
240
  const layer$82 = Layer.sync(NetService, make$93);
241
241
  //#endregion
242
242
  //#region package.json
243
- var version = "0.4.10";
243
+ var version = "0.4.12";
244
244
  //#endregion
245
245
  //#region src/config.ts
246
246
  /**
@@ -6680,6 +6680,7 @@ Schema$1.Struct({
6680
6680
  /** Which half of a Fusion pair a session or turn belongs to. */
6681
6681
  const FusionRole = Schema$1.Literals(["implementer", "watcher"]);
6682
6682
  const ProviderSessionStartInput = Schema$1.Struct({
6683
+ systemPrompt: Schema$1.optional(TrimmedNonEmptyString),
6683
6684
  threadId: ThreadId,
6684
6685
  provider: Schema$1.optional(ProviderDriverKind),
6685
6686
  providerInstanceId: Schema$1.optional(ProviderInstanceId),
@@ -23552,8 +23553,8 @@ const removeMemoryFile = Effect.fn("memoryFile.removeMemoryFile")(function* (inp
23552
23553
  * config directory — the one holding `.credentials.json` — instead of a managed
23553
23554
  * home the user would have to log in to again. See `docs/architecture/hub.md`.
23554
23555
  *
23555
- * Keyed by skills directory so a second provider home is additive rather than a
23556
- * migration.
23556
+ * Keyed by skills directory so ownership can move safely when the configured
23557
+ * provider path migrates to the provider-neutral shared root.
23557
23558
  *
23558
23559
  * @module sync/skillManifest
23559
23560
  */
@@ -23595,6 +23596,20 @@ const withEntriesFor = (manifest, skillsRoot, entries) => ({
23595
23596
  [skillsRoot]: [...entries].sort((left, right) => left.name.localeCompare(right.name))
23596
23597
  }
23597
23598
  });
23599
+ const moveEntriesFor = (manifest, sourceRoot, targetRoot) => {
23600
+ if (sourceRoot === targetRoot || manifest.directories[sourceRoot] === void 0) return manifest;
23601
+ const { [sourceRoot]: sourceEntries, ...directories } = manifest.directories;
23602
+ const targetEntries = directories[targetRoot] ?? [];
23603
+ const merged = new Map(targetEntries.map((entry) => [entry.name, entry]));
23604
+ for (const entry of sourceEntries ?? []) merged.set(entry.name, entry);
23605
+ return {
23606
+ version: 1,
23607
+ directories: {
23608
+ ...directories,
23609
+ [targetRoot]: [...merged.values()].sort((left, right) => left.name.localeCompare(right.name))
23610
+ }
23611
+ };
23612
+ };
23598
23613
  const writeSkillManifest = Effect.fn("skillManifest.write")(function* (manifestPath, manifest) {
23599
23614
  yield* writeFileStringAtomically({
23600
23615
  filePath: manifestPath,
@@ -23803,6 +23818,170 @@ function planSkillSync(input) {
23803
23818
  };
23804
23819
  }
23805
23820
  //#endregion
23821
+ //#region src/sync/sharedSkillRoot.ts
23822
+ const SHARED_SKILL_ROOT_REFUSAL = "shared-root-migration-blocked";
23823
+ const inspectLayout = Effect.fn("sharedSkillRoot.inspectLayout")(function* (input) {
23824
+ const fileSystem = yield* FileSystem.FileSystem;
23825
+ const path = yield* Path.Path;
23826
+ const targetRoot = path.resolve(input.sharedSkillsRoot ?? path.join(NodeOS.homedir(), ".agents", "skills"));
23827
+ const claudeRoot = path.resolve(input.claudeSkillsRoot);
23828
+ const manifest = yield* readSkillManifest(input.manifestPath);
23829
+ if (claudeRoot === targetRoot) return {
23830
+ claudeRoot,
23831
+ targetRoot,
23832
+ manifest,
23833
+ entries: [],
23834
+ candidateSkillNames: [],
23835
+ ignoredEntries: [],
23836
+ refused: [],
23837
+ linked: true,
23838
+ exists: yield* fileSystem.exists(targetRoot)
23839
+ };
23840
+ const linkedTarget = yield* fileSystem.readLink(claudeRoot).pipe(Effect.map((target) => path.resolve(path.dirname(claudeRoot), target)), Effect.option);
23841
+ if (linkedTarget._tag === "Some") return {
23842
+ claudeRoot,
23843
+ targetRoot,
23844
+ manifest,
23845
+ entries: [],
23846
+ candidateSkillNames: [],
23847
+ ignoredEntries: [],
23848
+ refused: linkedTarget.value === targetRoot ? [] : [{
23849
+ name: claudeRoot,
23850
+ reason: SHARED_SKILL_ROOT_REFUSAL
23851
+ }],
23852
+ linked: linkedTarget.value === targetRoot,
23853
+ exists: true
23854
+ };
23855
+ const exists = yield* fileSystem.exists(claudeRoot);
23856
+ if (exists) {
23857
+ const sourceDevice = (yield* fileSystem.stat(claudeRoot)).dev;
23858
+ let targetProbe = targetRoot;
23859
+ while (!(yield* fileSystem.exists(targetProbe))) {
23860
+ const parent = path.dirname(targetProbe);
23861
+ if (parent === targetProbe) break;
23862
+ targetProbe = parent;
23863
+ }
23864
+ if (sourceDevice !== (yield* fileSystem.stat(targetProbe)).dev) return {
23865
+ claudeRoot,
23866
+ targetRoot,
23867
+ manifest,
23868
+ entries: [],
23869
+ candidateSkillNames: [],
23870
+ ignoredEntries: [],
23871
+ refused: [{
23872
+ name: claudeRoot,
23873
+ reason: SHARED_SKILL_ROOT_REFUSAL
23874
+ }],
23875
+ linked: false,
23876
+ exists
23877
+ };
23878
+ }
23879
+ const entries = exists ? yield* fileSystem.readDirectory(claudeRoot) : [];
23880
+ const managedNames = new Set(entriesFor(manifest, claudeRoot).map((entry) => entry.name));
23881
+ const candidateSkillNames = [];
23882
+ const ignoredEntries = [];
23883
+ const strayEntries = [];
23884
+ for (const entry of entries) {
23885
+ if (isIgnoredEntry(entry)) {
23886
+ ignoredEntries.push(entry);
23887
+ continue;
23888
+ }
23889
+ const entryPath = path.join(claudeRoot, entry);
23890
+ if ((yield* fileSystem.stat(entryPath)).type === "Directory" && (yield* fileSystem.exists(path.join(entryPath, "SKILL.md")))) candidateSkillNames.push(entry);
23891
+ else strayEntries.push(entry);
23892
+ }
23893
+ return {
23894
+ claudeRoot,
23895
+ targetRoot,
23896
+ manifest,
23897
+ entries,
23898
+ candidateSkillNames,
23899
+ ignoredEntries,
23900
+ refused: [...candidateSkillNames.filter((entry) => !managedNames.has(entry)), ...strayEntries].map((name) => ({
23901
+ name,
23902
+ reason: SHARED_SKILL_ROOT_REFUSAL
23903
+ })),
23904
+ linked: false,
23905
+ exists
23906
+ };
23907
+ });
23908
+ /** Read-only root resolution used by status and previews. */
23909
+ const inspectSharedSkillRoot = Effect.fn("sharedSkillRoot.inspect")(function* (input) {
23910
+ const layout = yield* inspectLayout(input);
23911
+ if (layout.refused.length > 0) return {
23912
+ root: null,
23913
+ refused: layout.refused
23914
+ };
23915
+ return {
23916
+ root: layout.linked || !layout.exists ? layout.targetRoot : layout.claudeRoot,
23917
+ refused: []
23918
+ };
23919
+ });
23920
+ /**
23921
+ * Make Claude's configured skill path an alias of the provider-neutral user
23922
+ * skill root. Existing unmanaged content is never moved or replaced.
23923
+ */
23924
+ const prepareSharedSkillRoot = Effect.fn("sharedSkillRoot.prepare")(function* (input) {
23925
+ const fileSystem = yield* FileSystem.FileSystem;
23926
+ const path = yield* Path.Path;
23927
+ const layout = yield* inspectLayout(input);
23928
+ const { candidateSkillNames, claudeRoot, ignoredEntries, manifest, targetRoot } = layout;
23929
+ if (layout.refused.length > 0) return {
23930
+ root: null,
23931
+ refused: layout.refused
23932
+ };
23933
+ if (layout.linked) {
23934
+ yield* fileSystem.makeDirectory(targetRoot, { recursive: true });
23935
+ const migrated = moveEntriesFor(manifest, claudeRoot, targetRoot);
23936
+ if (migrated !== manifest) yield* writeSkillManifest(input.manifestPath, migrated);
23937
+ return {
23938
+ root: targetRoot,
23939
+ refused: []
23940
+ };
23941
+ }
23942
+ if (layout.exists) if (!(yield* fileSystem.exists(targetRoot))) {
23943
+ yield* fileSystem.makeDirectory(path.dirname(targetRoot), { recursive: true });
23944
+ yield* fileSystem.rename(claudeRoot, targetRoot);
23945
+ } else {
23946
+ const backupRoot = `${claudeRoot}.p4code-migrated`;
23947
+ if (ignoredEntries.length > 0 && (yield* fileSystem.exists(backupRoot))) return {
23948
+ root: null,
23949
+ refused: [{
23950
+ name: backupRoot,
23951
+ reason: SHARED_SKILL_ROOT_REFUSAL
23952
+ }]
23953
+ };
23954
+ const targetEntries = new Set(yield* fileSystem.readDirectory(targetRoot));
23955
+ const collisions = candidateSkillNames.filter((entry) => targetEntries.has(entry));
23956
+ if (collisions.length > 0) return {
23957
+ root: null,
23958
+ refused: collisions.map((name) => ({
23959
+ name,
23960
+ reason: SHARED_SKILL_ROOT_REFUSAL
23961
+ }))
23962
+ };
23963
+ for (const entry of candidateSkillNames) yield* fileSystem.rename(path.join(claudeRoot, entry), path.join(targetRoot, entry));
23964
+ }
23965
+ else {
23966
+ yield* fileSystem.makeDirectory(targetRoot, { recursive: true });
23967
+ yield* fileSystem.makeDirectory(path.dirname(claudeRoot), { recursive: true });
23968
+ }
23969
+ const stagedLink = `${claudeRoot}.p4code-link`;
23970
+ yield* fileSystem.remove(stagedLink, { force: true });
23971
+ yield* fileSystem.symlink(targetRoot, stagedLink);
23972
+ if (layout.exists && (yield* fileSystem.exists(claudeRoot))) if (ignoredEntries.length > 0) {
23973
+ const backupRoot = `${claudeRoot}.p4code-migrated`;
23974
+ yield* fileSystem.rename(claudeRoot, backupRoot);
23975
+ } else yield* fileSystem.remove(claudeRoot, { recursive: true });
23976
+ yield* fileSystem.rename(stagedLink, claudeRoot);
23977
+ const migrated = moveEntriesFor(manifest, claudeRoot, targetRoot);
23978
+ if (migrated !== manifest) yield* writeSkillManifest(input.manifestPath, migrated);
23979
+ return {
23980
+ root: targetRoot,
23981
+ refused: []
23982
+ };
23983
+ });
23984
+ //#endregion
23806
23985
  //#region src/sync/AssetSync.ts
23807
23986
  /**
23808
23987
  * Syncing user-scope agent assets between this machine and the hub.
@@ -23863,10 +24042,30 @@ const make$77 = Effect.gen(function* () {
23863
24042
  const claudeHome = Effect.fn("AssetSync.claudeHome")(function* () {
23864
24043
  return { homePath: (yield* settingsStore.getSettings.pipe(Effect.orElseSucceed(() => void 0)))?.providers.claudeAgent.homePath ?? "" };
23865
24044
  });
24045
+ const inspectSkillRoot = Effect.fn("AssetSync.inspectSkillRoot")(function* () {
24046
+ const claudeSkillsRoot = yield* claudeHome().pipe(Effect.flatMap(resolveClaudeUserSkillsDir));
24047
+ return yield* inspectSharedSkillRoot({
24048
+ claudeSkillsRoot,
24049
+ manifestPath
24050
+ }).pipe(Effect.catchCause((cause) => Effect.logWarning("shared skill root inspection failed", { cause }).pipe(Effect.as({
24051
+ root: null,
24052
+ refused: [{
24053
+ name: claudeSkillsRoot,
24054
+ reason: SHARED_SKILL_ROOT_REFUSAL
24055
+ }]
24056
+ }))));
24057
+ });
23866
24058
  const drivers = [
23867
24059
  {
23868
24060
  kind: "skill",
23869
- resolveRoot: claudeHome().pipe(Effect.flatMap(resolveClaudeUserSkillsDir)),
24061
+ prepareRoot: Effect.gen(function* () {
24062
+ yield* prepareSharedSkillRoot({
24063
+ claudeSkillsRoot: yield* claudeHome().pipe(Effect.flatMap(resolveClaudeUserSkillsDir)),
24064
+ manifestPath
24065
+ });
24066
+ }).pipe(Effect.catchCause((cause) => Effect.logWarning("shared skill root migration failed", { cause }))),
24067
+ resolveState: inspectSkillRoot(),
24068
+ resolveRoot: inspectSkillRoot().pipe(Effect.map((result) => result.root)),
23870
24069
  read: (root) => readSkillDirectory(root),
23871
24070
  write: ({ root, name, files }) => writeSkillDirectory({
23872
24071
  skillsRoot: root,
@@ -23924,6 +24123,19 @@ const make$77 = Effect.gen(function* () {
23924
24123
  }
23925
24124
  ];
23926
24125
  const driverFor = (kind) => drivers.find((driver) => driver.kind === kind);
24126
+ const resolveDriverState = Effect.fn("AssetSync.resolveDriverState")(function* (driver) {
24127
+ if (driver.resolveState) return yield* driver.resolveState;
24128
+ return {
24129
+ root: yield* driver.resolveRoot,
24130
+ refused: []
24131
+ };
24132
+ });
24133
+ const resolveAllDriverStates = Effect.fn("AssetSync.resolveAllDriverStates")(function* () {
24134
+ return yield* Effect.forEach(drivers, (driver) => resolveDriverState(driver).pipe(Effect.map((state) => ({
24135
+ driver,
24136
+ ...state
24137
+ }))), { concurrency: "unbounded" });
24138
+ });
23927
24139
  const isConfigured = link.current.pipe(Effect.map((state) => Option.isSome(state.settings)));
23928
24140
  /**
23929
24141
  * The three views for one kind, gathered once.
@@ -23931,14 +24143,15 @@ const make$77 = Effect.gen(function* () {
23931
24143
  * `status` and `run` both need exactly this and disagreeing about it is how a
23932
24144
  * panel comes to show something the next sync does not do.
23933
24145
  */
23934
- const viewsFor = Effect.fn("AssetSync.viewsFor")(function* (driver, hubAssets) {
23935
- const root = yield* driver.resolveRoot;
24146
+ const viewsFor = Effect.fn("AssetSync.viewsFor")(function* (driver, hubAssets, resolved) {
24147
+ const state = resolved ?? (yield* resolveDriverState(driver));
24148
+ const root = state.root;
23936
24149
  const hub = hubAssets.filter((asset) => asset.kind === driver.kind);
23937
24150
  if (root === null) return {
23938
24151
  root,
23939
24152
  hub,
23940
24153
  local: [],
23941
- refused: [],
24154
+ refused: state.refused,
23942
24155
  managed: []
23943
24156
  };
23944
24157
  const local = yield* driver.read(root);
@@ -23951,7 +24164,11 @@ const make$77 = Effect.gen(function* () {
23951
24164
  managed: entriesFor(manifest, root)
23952
24165
  };
23953
24166
  });
23954
- const rootsOf = Effect.fn("AssetSync.rootsOf")(function* () {
24167
+ const rootsOf = Effect.fn("AssetSync.rootsOf")(function* (states) {
24168
+ if (states) return states.map(({ driver, root }) => ({
24169
+ kind: driver.kind,
24170
+ path: root
24171
+ }));
23955
24172
  const roots = [];
23956
24173
  for (const driver of drivers) roots.push({
23957
24174
  kind: driver.kind,
@@ -23961,7 +24178,9 @@ const make$77 = Effect.gen(function* () {
23961
24178
  });
23962
24179
  const run = Effect.gen(function* () {
23963
24180
  if (!(yield* isConfigured)) return EMPTY_REPORT;
23964
- const roots = yield* rootsOf();
24181
+ for (const driver of drivers) if (driver.prepareRoot) yield* driver.prepareRoot;
24182
+ const resolvedDrivers = yield* resolveAllDriverStates();
24183
+ const roots = yield* rootsOf(resolvedDrivers);
23965
24184
  const hubAssets = yield* client.list().pipe(Effect.option);
23966
24185
  if (Option.isNone(hubAssets)) return {
23967
24186
  ...EMPTY_REPORT,
@@ -23976,8 +24195,9 @@ const make$77 = Effect.gen(function* () {
23976
24195
  const conflicts = [];
23977
24196
  const refused = [];
23978
24197
  const shareMode = (yield* link.current).shareMode;
23979
- for (const driver of drivers) {
23980
- const views = yield* viewsFor(driver, hubAssets.value);
24198
+ for (const resolved of resolvedDrivers) {
24199
+ const driver = resolved.driver;
24200
+ const views = yield* viewsFor(driver, hubAssets.value, resolved);
23981
24201
  const kind = driver.kind;
23982
24202
  for (const entry of views.refused) refused.push({
23983
24203
  kind,
@@ -24127,7 +24347,8 @@ const make$77 = Effect.gen(function* () {
24127
24347
  */
24128
24348
  const assetStatus = Effect.gen(function* () {
24129
24349
  const state = yield* link.current;
24130
- const roots = yield* rootsOf();
24350
+ const resolvedDrivers = yield* resolveAllDriverStates();
24351
+ const roots = yield* rootsOf(resolvedDrivers);
24131
24352
  const base = {
24132
24353
  syncMode: state.syncMode,
24133
24354
  shareMode: state.shareMode,
@@ -24137,9 +24358,10 @@ const make$77 = Effect.gen(function* () {
24137
24358
  const hubAssets = Option.isNone(state.settings) ? Option.none() : yield* client.list().pipe(Effect.option);
24138
24359
  const entries = [];
24139
24360
  const refused = [];
24140
- for (const driver of drivers) {
24361
+ for (const resolved of resolvedDrivers) {
24362
+ const driver = resolved.driver;
24141
24363
  const kind = driver.kind;
24142
- const views = yield* viewsFor(driver, Option.getOrElse(hubAssets, () => []));
24364
+ const views = yield* viewsFor(driver, Option.getOrElse(hubAssets, () => []), resolved);
24143
24365
  for (const entry of views.refused) refused.push({
24144
24366
  kind,
24145
24367
  name: entry.name,
@@ -24467,6 +24689,7 @@ const make$77 = Effect.gen(function* () {
24467
24689
  path: null,
24468
24690
  detail: `Unknown asset kind '${input.kind}'.`
24469
24691
  };
24692
+ if (driver.prepareRoot) yield* driver.prepareRoot;
24470
24693
  const root = yield* driver.resolveRoot;
24471
24694
  if (root === null) return {
24472
24695
  outcome: "no-root",
@@ -28643,7 +28866,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
28643
28866
  updatedAt: engagement.occurredAt
28644
28867
  }
28645
28868
  });
28646
- return events.map((event) => {
28869
+ const enrichedEvents = events.map((event) => {
28647
28870
  if (event.type === "thread.created") return {
28648
28871
  ...event,
28649
28872
  payload: {
@@ -28686,6 +28909,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
28686
28909
  default: return event;
28687
28910
  }
28688
28911
  });
28912
+ return enrichedEvents.length === 1 ? enrichedEvents[0] : enrichedEvents;
28689
28913
  });
28690
28914
  //#endregion
28691
28915
  //#region src/orchestration/Services/ProjectionPipeline.ts
@@ -32545,8 +32769,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
32545
32769
  settled_at AS "settledAt",
32546
32770
  lifecycle AS "lifecycle",
32547
32771
  lifecycle_reason AS "lifecycleReason",
32548
- lifecycle_changed_at AS "lifecycleChangedAt",
32549
- last_engaged_at AS "lastEngagedAt",
32772
+ COALESCE(lifecycle_changed_at, archived_at, settled_at, created_at) AS "lifecycleChangedAt",
32773
+ COALESCE(last_engaged_at, MAX(created_at, COALESCE(latest_user_message_at, created_at),
32774
+ COALESCE((SELECT MAX(message.updated_at) FROM projection_thread_messages message
32775
+ WHERE message.thread_id = projection_threads.thread_id
32776
+ AND message.role IN ('user', 'assistant')), created_at))) AS "lastEngagedAt",
32550
32777
  snoozed_until AS "snoozedUntil",
32551
32778
  snoozed_at AS "snoozedAt",
32552
32779
  pinned_at AS "pinnedAt",
@@ -32586,8 +32813,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
32586
32813
  settled_at AS "settledAt",
32587
32814
  lifecycle AS "lifecycle",
32588
32815
  lifecycle_reason AS "lifecycleReason",
32589
- lifecycle_changed_at AS "lifecycleChangedAt",
32590
- last_engaged_at AS "lastEngagedAt",
32816
+ COALESCE(lifecycle_changed_at, archived_at, settled_at, created_at) AS "lifecycleChangedAt",
32817
+ COALESCE(last_engaged_at, MAX(created_at, COALESCE(latest_user_message_at, created_at),
32818
+ COALESCE((SELECT MAX(message.updated_at) FROM projection_thread_messages message
32819
+ WHERE message.thread_id = projection_threads.thread_id
32820
+ AND message.role IN ('user', 'assistant')), created_at))) AS "lastEngagedAt",
32591
32821
  snoozed_until AS "snoozedUntil",
32592
32822
  snoozed_at AS "snoozedAt",
32593
32823
  pinned_at AS "pinnedAt",
@@ -32629,8 +32859,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
32629
32859
  settled_at AS "settledAt",
32630
32860
  lifecycle AS "lifecycle",
32631
32861
  lifecycle_reason AS "lifecycleReason",
32632
- lifecycle_changed_at AS "lifecycleChangedAt",
32633
- last_engaged_at AS "lastEngagedAt",
32862
+ COALESCE(lifecycle_changed_at, archived_at, settled_at, created_at) AS "lifecycleChangedAt",
32863
+ COALESCE(last_engaged_at, MAX(created_at, COALESCE(latest_user_message_at, created_at),
32864
+ COALESCE((SELECT MAX(message.updated_at) FROM projection_thread_messages message
32865
+ WHERE message.thread_id = projection_threads.thread_id
32866
+ AND message.role IN ('user', 'assistant')), created_at))) AS "lastEngagedAt",
32634
32867
  snoozed_until AS "snoozedUntil",
32635
32868
  snoozed_at AS "snoozedAt",
32636
32869
  pinned_at AS "pinnedAt",
@@ -33097,8 +33330,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
33097
33330
  settled_at AS "settledAt",
33098
33331
  lifecycle AS "lifecycle",
33099
33332
  lifecycle_reason AS "lifecycleReason",
33100
- lifecycle_changed_at AS "lifecycleChangedAt",
33101
- last_engaged_at AS "lastEngagedAt",
33333
+ COALESCE(lifecycle_changed_at, archived_at, settled_at, created_at) AS "lifecycleChangedAt",
33334
+ COALESCE(last_engaged_at, MAX(created_at, COALESCE(latest_user_message_at, created_at),
33335
+ COALESCE((SELECT MAX(message.updated_at) FROM projection_thread_messages message
33336
+ WHERE message.thread_id = projection_threads.thread_id
33337
+ AND message.role IN ('user', 'assistant')), created_at))) AS "lastEngagedAt",
33102
33338
  snoozed_until AS "snoozedUntil",
33103
33339
  snoozed_at AS "snoozedAt",
33104
33340
  pinned_at AS "pinnedAt",
@@ -73407,6 +73643,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
73407
73643
  const unpromptedSubagents = input.unpromptedSubagents !== void 0 ? input.unpromptedSubagents : options?.resolveUnpromptedSubagents === void 0 ? DEFAULT_SERVER_SETTINGS.enableUnpromptedSubagents : yield* options.resolveUnpromptedSubagents;
73408
73644
  const compressRuleset = compressRulesetFor(input.compressMode ?? "off");
73409
73645
  const systemPromptAppend = [
73646
+ ...input.systemPrompt ? [input.systemPrompt] : [],
73410
73647
  CLAUDE_STRUCTURED_USER_QUESTIONS_PROMPT,
73411
73648
  ...narrateBeforeTools ? [NARRATE_BEFORE_TOOLS_PROMPT] : [],
73412
73649
  ...guardrailPromptsFor(guardrailSettings),
@@ -111015,6 +111252,7 @@ const make$4 = Effect.gen(function* () {
111015
111252
  threadId,
111016
111253
  ...preferredProvider ? { provider: preferredProvider } : {},
111017
111254
  providerInstanceId: desiredInstanceId,
111255
+ ...isChatProject(thread.projectId) && preferredProvider === "claudeAgent" ? { systemPrompt: P4_CHAT_SYSTEM_PROMPT } : {},
111018
111256
  ...effectiveCwd ? { cwd: effectiveCwd } : {},
111019
111257
  modelSelection: desiredModelSelection,
111020
111258
  ...input?.resumeCursor !== void 0 ? { resumeCursor: input.resumeCursor } : {},
@@ -111182,7 +111420,8 @@ const make$4 = Effect.gen(function* () {
111182
111420
  staleRulesetMode: sessionRulesetMode
111183
111421
  });
111184
111422
  if (levelChangedMidSession) threadSessionRulesetModes.set(input.threadId, compressMode);
111185
- const inputWithCompressPrefix = inputWithStructuredQuestionPolicy !== void 0 && compressPrefix !== void 0 ? `${compressPrefix}\n\n${inputWithStructuredQuestionPolicy}` : inputWithStructuredQuestionPolicy;
111423
+ const chatInput = isChatProject(thread.projectId) && activeSession?.provider !== "opencode" && activeSession?.provider !== "claudeAgent" && thread.messages.filter((message) => message.role === "user").length === 1 ? [P4_CHAT_SYSTEM_PROMPT, inputWithStructuredQuestionPolicy].filter(Boolean).join("\n\n") : inputWithStructuredQuestionPolicy;
111424
+ const inputWithCompressPrefix = chatInput !== void 0 && compressPrefix !== void 0 ? `${compressPrefix}\n\n${chatInput}` : chatInput;
111186
111425
  return {
111187
111426
  threadId: input.threadId,
111188
111427
  ...isChatProject(thread.projectId) && activeSession?.provider === "opencode" ? { systemPrompt: P4_CHAT_SYSTEM_PROMPT } : {},
@@ -0,0 +1,98 @@
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{Dl as i,Et as a,Fa as o,Ga as s,Gr as c,Ha as l,Ia as ee,Oa as te,Ou as u,Pr as ne,Ua as d,Ul as f,Va as p,Wa as m,Yl as h,_n as g,au as _,b as v,cl as y,eu as re,gt as b,h as x,ht as S,ja as ie,ll as C,sl as ae,st as w,ul as T,vt as E,xn as D,zr as oe}from"./previewAssetResource-CVDZ-YAw.js";import{a as O,c as se,i as k,n as A,o as j,r as M,s as ce,t as le}from"./toggle-group-RD3apHNe.js";import{F as ue,Fr as de,I as fe,J as pe,L as me,Lr as he,Mr as ge,Nr as _e,R as N,Y as ve,_ as ye,_r as be,at as xe,cr as Se,ct as Ce,dr as we,fr as Te,h as Ee,hr as De,it as Oe,jr as ke,lr as Ae,lt as P,oi as je,or as Me,ot as Ne,pr as Pe,rt as Fe,si as Ie,sr as Le,st as Re,ur as ze,yr as Be,zr as Ve}from"./index-BvhnZNuc.js";import{a as He,n as Ue}from"./fileCommentAnnotations-C0bQJBDi.js";var We=T(`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}w.getState().openFile(e,t);return}r(n?x(t,n):t)}var I=r();function Ke(e,t){let n=(0,I.c)(4),r=De(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:a,options:o,viewerRef:s,className:l,renderHeaderPrefix:ee}=e,te=ne(Qe),u=ne(B),d;t[0]===a?d=t[1]:(d=e=>e.getComposerDraft(a)?.reviewComments??qe,t[0]=a,t[1]=d);let f=ne(d),[p,m]=(0,F.useState)(null),[h,g]=(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]!==h||t[5]!==n||t[6]!==f||t[7]!==r){let e;t[9]!==h||t[10]!==f||t[11]!==r?(e=e=>{let{fileDiff:t,filePath:n,fileKey:i,collapsed:a}=e,o=f.filter(e=>e.sectionId===r&&e.filePath===n&&(e.fenceLanguage??`diff`)===`diff`).reduce((e,n)=>{let r=c(t,n);return r?R(e,r,{id:n.id,kind:`comment`,range:r,rangeLabel:n.rangeLabel,text:n.text}):e},[]),s=h?.fileKey===i?[...o,h.annotation]:o;return{id:i,type:`diff`,fileDiff:t,annotations:s,collapsed:a,version:Oe(`${a?`1`:`0`}:${s.flatMap(z).join(`:`)}`)}},t[9]=h,t[10]=f,t[11]=r,t[12]=e):e=t[12],y=n.map(e),t[4]=h,t[5]=n,t[6]=f,t[7]=r,t[8]=y}else y=t[8];let re=y,b;t[13]!==a||t[14]!==h?.annotation||t[15]!==u?(b=e=>{m(null),h?.annotation.metadata.entries.some(t=>t.id===e)?g(null):u(a,e)},t[13]=a,t[14]=h?.annotation,t[15]=u,t[16]=b):b=t[16];let x=b,S;t[17]!==te||t[18]!==a||t[19]!==h||t[20]!==v||t[21]!==r||t[22]!==i?(S=(e,t)=>{let n=h?.annotation.metadata.entries.find(t=>t.id===e),o=h?v.get(h.fileKey):void 0;if(!n||!o)return;let s=oe({id:n.id,sectionId:r,sectionTitle:i,filePath:o.filePath,fileDiff:o.fileDiff,range:n.range,text:t});s&&te(a,s),m(null),g(null)},t[17]=te,t[18]=a,t[19]=h,t[20]=v,t[21]=r,t[22]=i,t[23]=S):S=t[23];let ie=S,C;t[24]!==v||t[25]!==r||t[26]!==i?(C=(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=oe({id:o,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:e,text:``});s&&g({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]=C):C=t[27];let ae=C,w=h!==null,T;t[28]===s?T=t[29]:(T=s?{ref:s}:{},t[28]=s,t[29]=T);let E;t[30]===l?E=t[31]:(E=l?{className:l}:{},t[30]=l,t[31]=E);let D=!w,se=!w,k;t[32]!==ae||t[33]!==o||t[34]!==se||t[35]!==D?(k={...o,enableGutterUtility:D,enableLineSelection:se,onLineSelectionEnd:ae},t[32]=ae,t[33]=o,t[34]=se,t[35]=D,t[36]=k):k=t[36];let A;t[37]===ee?A=t[38]:(A=e=>e.type===`diff`?ee(e.fileDiff,e.id,e.collapsed===!0):null,t[37]=ee,t[38]=A);let j;t[39]!==x||t[40]!==ie?(j=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:()=>x(e.id),onComment:t=>ie(e.id,t),onDelete:()=>x(e.id)},e.id))}),t[39]=x,t[40]=ie,t[41]=j):j=t[41];let M;return t[42]!==re||t[43]!==p||t[44]!==k||t[45]!==A||t[46]!==j||t[47]!==T||t[48]!==E?(M=(0,L.jsx)(O,{...T,...E,items:re,selectedLines:p,onSelectedLinesChange:m,options:k,renderHeaderPrefix:A,renderAnnotation:j}),t[42]=re,t[43]=p,t[44]=k,t[45]=A,t[46]=j,t[47]=T,t[48]=E,t[49]=M):M=t[49],M}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:f(e,{label:`environment-data:review:diff-preview`,tag:u.reviewGetDiffPreview,staleTimeMs:5e3})}}var et=$e(D);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
+ [data-diffs-header],
3
+ [data-diff],
4
+ [data-file],
5
+ [data-error-wrapper],
6
+ [data-virtualizer-buffer] {
7
+ --diffs-header-font-family: var(--font-sans) !important;
8
+ --diffs-font-family: var(--font-mono) !important;
9
+ --diffs-bg: color-mix(in srgb, var(--card) 90%, var(--background)) !important;
10
+ --diffs-light-bg: color-mix(in srgb, var(--card) 90%, var(--background)) !important;
11
+ --diffs-dark-bg: color-mix(in srgb, var(--card) 90%, var(--background)) !important;
12
+ --diffs-token-light-bg: transparent;
13
+ --diffs-token-dark-bg: transparent;
14
+
15
+ --diffs-bg-context-override: color-mix(in srgb, var(--background) 97%, var(--foreground));
16
+ --diffs-bg-hover-override: color-mix(in srgb, var(--background) 94%, var(--foreground));
17
+ --diffs-bg-separator-override: color-mix(in srgb, var(--background) 95%, var(--foreground));
18
+ --diffs-bg-buffer-override: color-mix(in srgb, var(--background) 90%, var(--foreground));
19
+
20
+ --diffs-bg-addition-override: color-mix(in srgb, var(--background) 92%, var(--success));
21
+ --diffs-bg-addition-number-override: color-mix(in srgb, var(--background) 88%, var(--success));
22
+ --diffs-bg-addition-hover-override: color-mix(in srgb, var(--background) 85%, var(--success));
23
+ --diffs-bg-addition-emphasis-override: color-mix(in srgb, var(--background) 80%, var(--success));
24
+
25
+ --diffs-bg-deletion-override: color-mix(in srgb, var(--background) 92%, var(--destructive));
26
+ --diffs-bg-deletion-number-override: color-mix(in srgb, var(--background) 88%, var(--destructive));
27
+ --diffs-bg-deletion-hover-override: color-mix(in srgb, var(--background) 85%, var(--destructive));
28
+ --diffs-bg-deletion-emphasis-override: color-mix(
29
+ in srgb,
30
+ var(--background) 80%,
31
+ var(--destructive)
32
+ );
33
+
34
+ background-color: var(--diffs-bg) !important;
35
+ }
36
+
37
+ [data-file-info] {
38
+ background-color: color-mix(in srgb, var(--card) 94%, var(--foreground)) !important;
39
+ border-block-color: var(--border) !important;
40
+ color: var(--foreground) !important;
41
+ }
42
+
43
+ [data-diffs-header] {
44
+ position: sticky !important;
45
+ top: 0;
46
+ z-index: 4;
47
+ background-color: color-mix(in srgb, var(--card) 94%, var(--foreground)) !important;
48
+ border-bottom: 1px solid var(--border) !important;
49
+ align-items: center !important;
50
+ font-family: var(--font-sans) !important;
51
+ font-size: 12px !important;
52
+ line-height: 1 !important;
53
+ min-height: 32px !important;
54
+ padding-block: 6px !important;
55
+ }
56
+
57
+ [data-diffs-header] [data-header-content] {
58
+ align-items: center !important;
59
+ line-height: 1 !important;
60
+ }
61
+
62
+ [data-diffs-header] [data-metadata] {
63
+ align-items: center !important;
64
+ line-height: 1 !important;
65
+ font-variant-numeric: tabular-nums;
66
+ }
67
+
68
+ [data-diffs-header] [data-additions-count],
69
+ [data-diffs-header] [data-deletions-count] {
70
+ font-family: var(--font-mono) !important;
71
+ font-size: 11px !important;
72
+ font-variant-numeric: tabular-nums;
73
+ line-height: 1 !important;
74
+ }
75
+
76
+ [data-diffs-header] [data-change-icon],
77
+ [data-diffs-header] [data-rename-icon] {
78
+ display: block;
79
+ flex-shrink: 0;
80
+ }
81
+
82
+ [data-title] {
83
+ cursor: pointer;
84
+ transition:
85
+ color 120ms ease,
86
+ text-decoration-color 120ms ease;
87
+ text-decoration: underline;
88
+ text-decoration-color: transparent;
89
+ text-underline-offset: 2px;
90
+ font-family: var(--font-sans) !important;
91
+ }
92
+
93
+ [data-title]:hover {
94
+ color: color-mix(in srgb, var(--foreground) 84%, var(--primary)) !important;
95
+ text-decoration-color: currentColor;
96
+ }
97
+ `;function U({mode:e=`inline`,composerDraftTarget:t,initialGitScope:n,threadRef:r}){let{resolvedTheme:c}=v(),u=de(),[ne]=(0,F.useState)(n),[f,x]=(0,F.useState)(`stacked`),[w,T]=(0,F.useState)(u.wordWrap),[D,oe]=(0,F.useState)(u.diffIgnoreWhitespace),[O,ye]=(0,F.useState)(``),[De,Oe]=(0,F.useState)(()=>({scopeKey:null,fileKeys:rt})),He=(0,F.useRef)(null),Ue=r.threadId,I=_e(r),qe=I?.projectId??null,Je=ge(I&&qe?{environmentId:I.environmentId,projectId:qe}:null),R=I?.worktreePath??Je?.workspaceRoot,z=i(g.configValueAtom(I?.environmentId??null)),Xe=be(I?.environmentId??null,z?.availableEditors??[]),Ze=a(I!=null&&R!=null?ke.status({environmentId:I.environmentId,input:{cwd:R}}):null),B=N(e=>me(e.byThreadKey,r,ne===`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=De.scopeKey===Y?De.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:D,cacheScope:q?`turn:${q.turnId}`:null},{enabled:Qe&&q!==void 0}),mt=a(W===null&&I&&R?et.diffPreview({environmentId:I.environmentId,input:{cwd:R,...K?{baseRef:K}:{},ignoreWhitespace:D}}):null),ht=W===null&&mt.error?.includes(`configured workspace root`)===!0&&z?.cwd!==void 0&&z.cwd!==R,gt=a(ht&&I&&z?et.diffPreview({environmentId:I.environmentId,input:{cwd:z.cwd,...K?{baseRef:K}:{},ignoreWhitespace:D}}):null),X=ht?gt:mt,Z=X.data?.sources.find(e=>e.kind===(G===`unstaged`?`working-tree`:`branch-range`)),_t=a(W===null&&G===`branch`&&I&&X.data?.cwd?ke.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`local`,...O.trim().length>0?{query:O.trim()}:{},limit:100}}):null),vt=a(W===null&&G===`branch`&&I&&X.data?.cwd?ke.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`remote`,...O.trim().length>0?{query:O.trim()}:{},limit:100}}):null),yt=tt(_t.data?.refs.filter(e=>e.name!==Z?.headRef)??[],vt.data?.refs??[]),bt=nt(yt,O),xt=e=>K&&K===e.remote?.name?K:e.local?.name??e.remote?.name??e.id,St=[H,...yt.map(xt)],Ct=[...O.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)(()=>Re(Tt,`diff-panel:${c}`,{compactPartialHunkOffsets:W===null}),[c,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=Fe(e);return{fileDiff:e,filePath:P(e),fileKey:t,collapsed:ut.has(t)}}),[ut,At]),jt=(0,F.useMemo)(()=>$.map(e=>e.fileKey),[$]),Mt=M(jt,ut),Nt=(0,F.useMemo)(()=>Ne(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=ue({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`&&!h(t)&&console.warn(`Failed to open diff file in editor.`,{operation:`open-diff-file`,environmentId:r.environmentId,threadId:r.threadId,..._(re(t))})})()}})},[R,Pt,Xe,r]),It=(0,F.useCallback)(e=>{Oe(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)(()=>{Oe(e=>{let t=e.scopeKey===Y?e.fileKeys:rt;return{scopeKey:Y,fileKeys:k(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)(ve,{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)(ie,{children:[(0,L.jsxs)(m,{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)(y,{className:`size-3.5 shrink-0 text-muted-foreground`})]}),(0,L.jsxs)(ee,{align:`start`,className:`w-60`,children:[(0,L.jsx)(o,{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)(o,{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)(o,{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)(d,{children:`Turn`}),(0,L.jsx)(l,{className:`w-64`,children:U.map(e=>{let t=e.checkpointTurnCount??V[e.turnId]??`?`;return(0,L.jsxs)(o,{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:Be(e.completedAt,u.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)(Ie,{className:`size-3.5 shrink-0 opacity-70`}),(0,L.jsxs)(Le,{items:St,filteredItems:Ct,value:K??H,onOpenChange:e=>{e||ye(``)},onValueChange:e=>{e&&Bt(e===H?null:e)},children:[(0,L.jsxs)(Pe,{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)(y,{className:`size-3.5 shrink-0 opacity-70`})]}),(0,L.jsxs)(Te,{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)(Ve,{"aria-hidden":`true`,className:`pointer-events-none absolute top-1.5 left-0 size-4 shrink-0 text-muted-foreground/55`}),(0,L.jsx)(Ae,{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:O,onChange:e=>ye(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)(Se,{children:`No matching refs.`}),(0,L.jsxs)(we,{className:`max-h-64 min-w-0 overflow-x-hidden`,children:[(0,L.jsx)(ze,{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)(ze,{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)(Me,{"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)(C,{"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)(Ee,{additions:Nt.additions,deletions:Nt.deletions,className:`mr-1 text-[11px]`,layout:`inline`}),$.length>0&&(0,L.jsxs)(S,{children:[(0,L.jsx)(E,{render:(0,L.jsx)(te,{type:`button`,size:`icon-xs`,variant:`outline`,"aria-label":Mt?`Expand all files`:`Collapse all files`,onClick:Lt}),children:Mt?(0,L.jsx)(je,{className:`size-3`}):(0,L.jsx)(se,{className:`size-3`})}),(0,L.jsx)(b,{side:`top`,children:Mt?`Expand all files`:`Collapse all files`})]}),(0,L.jsxs)(A,{className:`shrink-0`,variant:`outline`,size:`xs`,value:[f],onValueChange:e=>{let t=e[0];(t===`stacked`||t===`split`)&&x(t)},children:[(0,L.jsx)(le,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,L.jsx)(j,{className:`size-3`})}),(0,L.jsx)(le,{"aria-label":`Split diff view`,value:`split`,children:(0,L.jsx)(ce,{className:`size-3`})})]}),(0,L.jsxs)(S,{children:[(0,L.jsx)(E,{render:(0,L.jsx)(le,{"aria-label":w?`Disable diff line wrapping`:`Enable diff line wrapping`,variant:`outline`,size:`xs`,pressed:w,onPressedChange:e=>{T(!!e)}}),children:(0,L.jsx)(he,{className:`size-3`})}),(0,L.jsx)(b,{side:`top`,children:w?`Disable line wrapping`:`Enable line wrapping`})]}),(0,L.jsxs)(S,{children:[(0,L.jsx)(E,{render:(0,L.jsx)(le,{"aria-label":D?`Show whitespace changes`:`Hide whitespace changes`,variant:`outline`,size:`xs`,pressed:D,onPressedChange:e=>{oe(!!e)}}),children:(0,L.jsx)(We,{className:`size-3`})}),(0,L.jsx)(b,{side:`top`,children:D?`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)(S,{children:[(0,L.jsx)(E,{render:(0,L.jsx)(`button`,{type:`button`,className:s(`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`,xe(e)),"aria-label":n?`Expand ${r}`:`Collapse ${r}`,"aria-expanded":!n,onClick:e=>{e.stopPropagation(),It(t)}}),children:n?(0,L.jsx)(ae,{className:`size-4`}):(0,L.jsx)(y,{className:`size-4`})}),(0,L.jsx)(b,{side:`top`,children:n?`Expand diff`:`Collapse diff`})]})},options:{diffStyle:f===`split`?`split`:`unified`,lineDiffType:`none`,overflow:w?`wrap`:`scroll`,theme:Ce(c),themeType:c,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:s(`max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90`,w?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:Q.text})]})}):Dt?(0,L.jsx)(pe,{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{ye as DiffWorkerPoolProvider,U as default};
98
+ //# sourceMappingURL=DiffPanel-Bm0q47ri.js.map