@sideboard-ai/core 0.1.109 → 0.1.110

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.
Files changed (43) hide show
  1. package/dist/agents/cursor-runner.cjs +87 -12
  2. package/dist/agents/cursor-runner.js +37 -11
  3. package/dist/{agents-XB332VUJ.js → agents-MQDW3YXL.js} +6 -6
  4. package/dist/{agents-YIMHDI46.js → agents-WK54VP7J.js} +7 -7
  5. package/dist/{app-settings-EBCVMFF6.js → app-settings-5XAGNDX7.js} +3 -1
  6. package/dist/{app-settings-IYSSVZHH.js → app-settings-J4LUWIRN.js} +3 -1
  7. package/dist/{chunk-WD2TARQS.js → chunk-3UOKB6VQ.js} +40 -0
  8. package/dist/{chunk-756EO4GK.js → chunk-4EWPKYOU.js} +4 -4
  9. package/dist/{chunk-4LKD3PGO.js → chunk-4NR5FL46.js} +10 -0
  10. package/dist/{chunk-FBV6NK62.js → chunk-7KWYXGIU.js} +2 -2
  11. package/dist/{chunk-KGSVLZV6.js → chunk-A4VZXJEJ.js} +2 -0
  12. package/dist/{chunk-VRTKGKUW.js → chunk-AROMOP3C.js} +2 -2
  13. package/dist/{chunk-EW7COXYE.js → chunk-C4KHDW3U.js} +2 -2
  14. package/dist/{chunk-Q6B3NRCT.js → chunk-EAAB4EK5.js} +154 -287
  15. package/dist/{chunk-I2OJ2YSP.js → chunk-KQBI5HNT.js} +2 -2
  16. package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
  17. package/dist/{chunk-KKHDPV45.js → chunk-RSIWPLRG.js} +473 -37
  18. package/dist/{chunk-NE4TOOKS.js → chunk-SGEVS5SY.js} +10 -0
  19. package/dist/{chunk-TROJ3PVH.js → chunk-VOD3HFLP.js} +4 -4
  20. package/dist/{chunk-AY2EQI2P.js → chunk-VOJSO3RM.js} +472 -46
  21. package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
  22. package/dist/{chunk-LTPX5N6K.js → chunk-XOZDAVOP.js} +162 -276
  23. package/dist/{chunk-OQDIYVDD.js → chunk-YFAXVUY2.js} +2 -2
  24. package/dist/{chunk-JVIW55KT.js → chunk-YXDR43ZC.js} +2 -2
  25. package/dist/{coordinator-prompt-JKOU6BWV.js → coordinator-prompt-AR66L3N4.js} +4 -4
  26. package/dist/{coordinator-prompt-V66BYTUV.js → coordinator-prompt-BHMLWL64.js} +4 -4
  27. package/dist/{global-workspace-WBQWQQQY.js → global-workspace-SKFODUQQ.js} +5 -5
  28. package/dist/{global-workspace-NCTBE7G7.js → global-workspace-XSUFEIAQ.js} +5 -5
  29. package/dist/index.cjs +835 -489
  30. package/dist/index.d.cts +51 -3
  31. package/dist/index.d.ts +51 -3
  32. package/dist/index.js +44 -23
  33. package/dist/mcp/run-stdio.cjs +812 -487
  34. package/dist/mcp/run-stdio.js +17 -12
  35. package/dist/{orchestrator-6W7EKSPO.js → orchestrator-FCZVCKBK.js} +10 -10
  36. package/dist/{orchestrator-JVGVPKLI.js → orchestrator-SCATSB3O.js} +8 -8
  37. package/dist/{thread-store-DQJGDKIJ.js → thread-store-LPTBVW5C.js} +1 -1
  38. package/dist/{thread-store-4OUEQ2DB.js → thread-store-OEALWU7Y.js} +1 -1
  39. package/dist/{workspaces-SUBEDSGB.js → workspaces-HV3J4TTW.js} +6 -6
  40. package/dist/{workspaces-I3554R3F.js → workspaces-XAQVKTLO.js} +6 -6
  41. package/dist/{worktree-7H6HB6GW.js → worktree-N2EV24EE.js} +3 -3
  42. package/dist/{worktree-2UWO7VEK.js → worktree-XFJED3VU.js} +3 -3
  43. package/package.json +1 -1
@@ -1,20 +1,27 @@
1
1
  import {
2
2
  PLAN_MODE_INSTRUCTION,
3
3
  allAdapters,
4
+ applyAgentEvent,
4
5
  applyTurnUsage,
5
6
  contextTokens,
7
+ finalizeParts,
6
8
  getAdapter,
9
+ isBrightsyNdjsonLine,
7
10
  isSessionQuotaLimit,
11
+ normalizeParseResult,
8
12
  parseBrightsyCliLine,
9
13
  parseSessionQuotaResetAt,
10
- resolveQuotaFallbackAgent
11
- } from "./chunk-KKHDPV45.js";
14
+ partsToAssistantText,
15
+ resolveQuotaFallbackAgent,
16
+ stripBrightsyNdjsonNoise,
17
+ toolDescription
18
+ } from "./chunk-RSIWPLRG.js";
12
19
  import {
13
20
  addWorkspace,
14
21
  ensureWorkspace,
15
22
  removeWorkspace,
16
23
  syncWorkspacesFromThreads
17
- } from "./chunk-FBV6NK62.js";
24
+ } from "./chunk-7KWYXGIU.js";
18
25
  import {
19
26
  assertOrchestratorCapableAgent,
20
27
  coerceOrchestratorAgent,
@@ -27,14 +34,14 @@ import {
27
34
  isOrchestratorThread,
28
35
  isSlackCoordinatorThread,
29
36
  orchestratorSessionPoisonedByBuiltins
30
- } from "./chunk-756EO4GK.js";
37
+ } from "./chunk-4EWPKYOU.js";
31
38
  import {
32
39
  SLACK_REPLY_FORMATTING,
33
40
  coordinatorSystemPrompt,
34
41
  coordinatorTurnReminder,
35
42
  enrichWorkspacesWithGithub,
36
43
  ensureGlobalCoordinatorCwd
37
- } from "./chunk-I2OJ2YSP.js";
44
+ } from "./chunk-KQBI5HNT.js";
38
45
  import {
39
46
  extractPresentedPlan,
40
47
  readPlanFile,
@@ -42,7 +49,7 @@ import {
42
49
  } from "./chunk-QTUESPAW.js";
43
50
  import {
44
51
  createAgentStreamCoalescer
45
- } from "./chunk-MMI4RJ5I.js";
52
+ } from "./chunk-WIHKHR5R.js";
46
53
  import {
47
54
  fallbackTurnFailDetail,
48
55
  formatTurnExitError,
@@ -52,7 +59,7 @@ import {
52
59
  shouldRetryFailedAgentTurn,
53
60
  summarizeTurnStderr,
54
61
  turnFailChatText
55
- } from "./chunk-WD2TARQS.js";
62
+ } from "./chunk-3UOKB6VQ.js";
56
63
  import {
57
64
  releaseCaffeinateHoldForThread
58
65
  } from "./chunk-DCOZABNT.js";
@@ -98,7 +105,7 @@ import {
98
105
  threadDisplayLabel,
99
106
  withRepoGitLock,
100
107
  worktreeNameFromPath
101
- } from "./chunk-EW7COXYE.js";
108
+ } from "./chunk-C4KHDW3U.js";
102
109
  import {
103
110
  ATTACHMENTS_DIR,
104
111
  LEGACY_ATTACHMENTS_DIR,
@@ -116,7 +123,7 @@ import {
116
123
  resolveVaultKey,
117
124
  updateAdvancedSettings,
118
125
  writeSecureJson
119
- } from "./chunk-4LKD3PGO.js";
126
+ } from "./chunk-4NR5FL46.js";
120
127
  import {
121
128
  stripNestedElectronEnv
122
129
  } from "./chunk-4TR3HZFT.js";
@@ -134,7 +141,7 @@ import {
134
141
  updateThread,
135
142
  withThreadLock,
136
143
  writeThread
137
- } from "./chunk-KGSVLZV6.js";
144
+ } from "./chunk-A4VZXJEJ.js";
138
145
  import {
139
146
  appDataDir,
140
147
  findConventionSetup,
@@ -727,236 +734,6 @@ import { existsSync as existsSync16 } from "fs";
727
734
  // src/agents/spawn.ts
728
735
  import { createInterface } from "readline";
729
736
  import { execa } from "execa";
730
-
731
- // src/agents/message-parts.ts
732
- function asRecord(input) {
733
- if (input && typeof input === "object" && !Array.isArray(input)) {
734
- return input;
735
- }
736
- return void 0;
737
- }
738
- function str(v) {
739
- return typeof v === "string" && v.trim() ? v : void 0;
740
- }
741
- function toolDetail(name, input) {
742
- if (!input) return void 0;
743
- const command = str(input.command) ?? str(input.cmd);
744
- if (command) return command;
745
- const path = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
746
- if (path) return path;
747
- const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
748
- if (pattern) return pattern;
749
- const query = str(input.query) ?? str(input.prompt);
750
- if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
751
- try {
752
- const raw = JSON.stringify(input);
753
- return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
754
- } catch {
755
- return name;
756
- }
757
- }
758
- function toolDescription(name, input) {
759
- const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
760
- if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
761
- if (/connectedAgentRequest/i.test(name)) {
762
- return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
763
- }
764
- if (/present_artifact$/i.test(name)) {
765
- return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
766
- }
767
- if (/present_plan$/i.test(name)) {
768
- return str(input?.title) ? `Plan ${str(input?.title)}` : "Present plan";
769
- }
770
- if (/present_schema$/i.test(name)) {
771
- return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
772
- }
773
- if (/present_files$/i.test(name)) {
774
- return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
775
- }
776
- if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
777
- return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
778
- }
779
- if (!input) return n;
780
- if (/bash|shell|terminal/i.test(name) && str(input.command)) {
781
- const cmd = str(input.command);
782
- if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
783
- if (/git\s+status/i.test(cmd)) return "Check git status";
784
- if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
785
- if (/git\s+branch/i.test(cmd)) return "List branches";
786
- if (/grep|rg\b/i.test(cmd)) return "Search repository";
787
- return "Run shell command";
788
- }
789
- if (/edit|write|apply/i.test(name)) {
790
- const path = str(input.file_path) ?? str(input.path);
791
- return path ? `Edit ${path.split("/").pop()}` : "Edit file";
792
- }
793
- if (/read/i.test(name)) {
794
- const path = str(input.file_path) ?? str(input.path);
795
- return path ? `Read ${path.split("/").pop()}` : "Read file";
796
- }
797
- if (/grep/i.test(name)) return "Search files";
798
- if (/glob/i.test(name)) return "Find files";
799
- return n;
800
- }
801
- function toolFilePath(input) {
802
- if (!input) return void 0;
803
- return str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
804
- }
805
- function countLines(text) {
806
- if (!text) return 0;
807
- return text.split("\n").length;
808
- }
809
- function diffFromInput(input) {
810
- if (!input) return {};
811
- const oldS = str(input.old_string) ?? str(input.oldString);
812
- const newS = str(input.new_string) ?? str(input.newString) ?? str(input.content);
813
- if (oldS != null || newS != null) {
814
- return {
815
- additions: countLines(newS),
816
- deletions: countLines(oldS)
817
- };
818
- }
819
- return {};
820
- }
821
- function parseDiffStat(result) {
822
- if (!result) return {};
823
- const paired = result.match(/\+(\d+)\s+-(\d+)/);
824
- if (paired) {
825
- return {
826
- additions: Number(paired[1]),
827
- deletions: Number(paired[2])
828
- };
829
- }
830
- const verbose = result.match(
831
- /(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
832
- );
833
- if (verbose) {
834
- return {
835
- additions: Number(verbose[1]),
836
- deletions: verbose[2] != null ? Number(verbose[2]) : void 0
837
- };
838
- }
839
- return {};
840
- }
841
- function applyAgentEvent(parts, event) {
842
- if (event.type === "stdout") {
843
- const data = event.data;
844
- if (!data) return parts;
845
- const next = [...parts];
846
- const last = next[next.length - 1];
847
- if (last?.type === "text") {
848
- next[next.length - 1] = { type: "text", text: last.text + data };
849
- } else {
850
- next.push({ type: "text", text: data });
851
- }
852
- return next;
853
- }
854
- if (event.type === "thinking") {
855
- const data = event.data;
856
- if (!data) return parts;
857
- const next = [...parts];
858
- const last = next[next.length - 1];
859
- if (last?.type === "thinking") {
860
- next[next.length - 1] = { type: "thinking", text: last.text + data };
861
- } else {
862
- next.push({ type: "thinking", text: data });
863
- }
864
- return next;
865
- }
866
- if (event.type === "tool_use") {
867
- const input = asRecord(event.input);
868
- const diff = diffFromInput(input);
869
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
870
- if (existing >= 0) {
871
- const prev = parts[existing];
872
- const next = [...parts];
873
- next[existing] = {
874
- ...prev,
875
- name: event.name || prev.name,
876
- input: input ?? prev.input,
877
- description: toolDescription(event.name || prev.name, input ?? prev.input),
878
- detail: toolDetail(event.name || prev.name, input ?? prev.input) ?? prev.detail,
879
- filePath: toolFilePath(input) ?? prev.filePath,
880
- additions: diff.additions ?? prev.additions,
881
- deletions: diff.deletions ?? prev.deletions
882
- };
883
- return next;
884
- }
885
- return [
886
- ...parts,
887
- {
888
- type: "tool",
889
- id: event.id,
890
- name: event.name,
891
- input,
892
- description: toolDescription(event.name, input),
893
- detail: toolDetail(event.name, input),
894
- status: "running",
895
- filePath: toolFilePath(input),
896
- ...diff
897
- }
898
- ];
899
- }
900
- if (event.type === "tool_result") {
901
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
902
- const fromResult = parseDiffStat(event.content);
903
- if (existing < 0) {
904
- return [
905
- ...parts,
906
- {
907
- type: "tool",
908
- id: event.id,
909
- name: "tool",
910
- description: "tool",
911
- status: event.isError ? "error" : "done",
912
- result: event.content,
913
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
914
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
915
- }
916
- ];
917
- }
918
- return parts.map((p, i) => {
919
- if (i !== existing || p.type !== "tool") return p;
920
- return {
921
- ...p,
922
- status: event.isError ? "error" : "done",
923
- result: event.content,
924
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
925
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
926
- };
927
- });
928
- }
929
- return parts;
930
- }
931
- function partsToAssistantText(parts) {
932
- return parts.filter((p) => p.type === "text").map((p) => p.text).join("").trim();
933
- }
934
- function stripBrightsyNdjsonNoise(text) {
935
- if (!text || !text.includes('"type"')) return text;
936
- let out = text;
937
- out = out.replace(
938
- /\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
939
- ""
940
- );
941
- out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
942
- return out.trim();
943
- }
944
- function isBrightsyNdjsonLine(line) {
945
- const t = line.trim();
946
- if (!t.startsWith("{")) return false;
947
- return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
948
- }
949
- function finalizeParts(parts) {
950
- return parts.map(
951
- (p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
952
- );
953
- }
954
- function normalizeParseResult(parsed) {
955
- if (!parsed) return [];
956
- return Array.isArray(parsed) ? parsed : [parsed];
957
- }
958
-
959
- // src/agents/spawn.ts
960
737
  function applyPromptCacheTtlEnv(agent, env) {
961
738
  if (agent === "claude" && env.FORCE_PROMPT_CACHING_5M !== "1") {
962
739
  env.ENABLE_PROMPT_CACHING_1H ??= "1";
@@ -972,9 +749,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
972
749
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
973
750
  );
974
751
  }
975
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-NCTBE7G7.js");
752
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-XSUFEIAQ.js");
976
753
  if (isGlobalThread2(thread)) {
977
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-JKOU6BWV.js");
754
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-AR66L3N4.js");
978
755
  ensureGlobalCoordinatorCwd2(
979
756
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
980
757
  );
@@ -1541,7 +1318,8 @@ function worktreeBindingFrom(from) {
1541
1318
  prState: from.prState,
1542
1319
  skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
1543
1320
  stackId: from.stackId,
1544
- stackLayer: from.stackLayer
1321
+ stackLayer: from.stackLayer,
1322
+ cowboy: from.cowboy
1545
1323
  };
1546
1324
  }
1547
1325
  function threadsSharingWorktree(worktreePath) {
@@ -2558,6 +2336,55 @@ async function createThread(input, _onSetupLine) {
2558
2336
  if (!existsSync7(repoPath)) {
2559
2337
  throw new Error(`Repo not found: ${repoPath}`);
2560
2338
  }
2339
+ if (input.cowboy) {
2340
+ const { cowboyModeEnabled } = await import("./app-settings-J4LUWIRN.js");
2341
+ if (!cowboyModeEnabled()) {
2342
+ throw new Error(
2343
+ "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
2344
+ );
2345
+ }
2346
+ if (input.sourceType === "pr" || input.sourceType === "ticket" || input.sourceType === "adopt") {
2347
+ throw new Error(
2348
+ "Cowboy mode works on the project folder (default branch), not a PR, ticket, or adopt."
2349
+ );
2350
+ }
2351
+ const defaultBranch = await resolveDefaultBranch(repoPath, { network: false });
2352
+ const head = await currentBranch(repoPath);
2353
+ if (head === "HEAD") {
2354
+ throw new Error(
2355
+ "Cowboy mode needs a named branch in the project folder (not a detached HEAD)."
2356
+ );
2357
+ }
2358
+ if (head !== defaultBranch) {
2359
+ throw new Error(
2360
+ `Cowboy mode uses ${defaultBranch} in the project folder. Switch that checkout to ${defaultBranch} first (currently ${head}).`
2361
+ );
2362
+ }
2363
+ const explicitTitle2 = input.title?.trim();
2364
+ const thread2 = createEmptyThread({
2365
+ title: explicitTitle2 || `Cowboy \xB7 ${head}`,
2366
+ userSetTitle: Boolean(explicitTitle2),
2367
+ sourceType: "branch",
2368
+ sourceRef: head,
2369
+ branchName: head,
2370
+ worktreePath: repoPath,
2371
+ repoPath,
2372
+ agent: resolved.agent,
2373
+ autonomy: input.autonomy ?? "default",
2374
+ model: resolved.model,
2375
+ effort: resolved.effort,
2376
+ fast: resolved.fast,
2377
+ planMode: Boolean(input.planMode),
2378
+ attachments: input.attachments ?? [],
2379
+ sourceIsFork: false,
2380
+ parentThreadId: input.parentThreadId ?? null,
2381
+ status: "idle",
2382
+ cowboy: true
2383
+ });
2384
+ writeThread(thread2);
2385
+ await ensureWorkspace(repoPath);
2386
+ return readThread(thread2.id) ?? thread2;
2387
+ }
2561
2388
  let sourceRef = input.sourceRef;
2562
2389
  let sourceIsFork = false;
2563
2390
  let prUrl = null;
@@ -2621,7 +2448,7 @@ async function createThread(input, _onSetupLine) {
2621
2448
  return readThread(thread.id) ?? thread;
2622
2449
  }
2623
2450
  async function listLinearIssues(agent, repoPath) {
2624
- const { getAdapter: getAdapter2 } = await import("./agents-YIMHDI46.js");
2451
+ const { getAdapter: getAdapter2 } = await import("./agents-WK54VP7J.js");
2625
2452
  await requireAgent(agent, { requireLinear: true });
2626
2453
  const adapter = getAdapter2(agent);
2627
2454
  if (!adapter.listLinearIssues) {
@@ -2630,6 +2457,18 @@ async function listLinearIssues(agent, repoPath) {
2630
2457
  return adapter.listLinearIssues(repoPath);
2631
2458
  }
2632
2459
 
2460
+ // src/threads/cowboy.ts
2461
+ function isCowboyThread(thread) {
2462
+ return Boolean(thread?.cowboy);
2463
+ }
2464
+ function isPrimaryCheckoutThread(thread) {
2465
+ if (!thread?.worktreePath || !thread.repoPath) return false;
2466
+ return normalizeWorktreePath(thread.worktreePath) === normalizeWorktreePath(thread.repoPath);
2467
+ }
2468
+ function shouldRemoveWorktreeOnTeardown(thread) {
2469
+ return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
2470
+ }
2471
+
2633
2472
  // src/store/turn-live.ts
2634
2473
  import {
2635
2474
  existsSync as existsSync8,
@@ -2994,7 +2833,7 @@ async function adoptThread(input) {
2994
2833
  messages: input.messages ?? []
2995
2834
  });
2996
2835
  writeThread(thread);
2997
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-SUBEDSGB.js");
2836
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-HV3J4TTW.js");
2998
2837
  await ensureWorkspace2(repoPath);
2999
2838
  return thread;
3000
2839
  }
@@ -4240,13 +4079,22 @@ async function previewLand(thread) {
4240
4079
  isFork: true
4241
4080
  };
4242
4081
  }
4243
- const target = await resolveDefaultBranch(thread.repoPath);
4244
- if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
4082
+ if (isCowboyThread(thread)) {
4083
+ const current2 = await currentBranch(thread.worktreePath);
4084
+ const dirty = await isDirty(thread.worktreePath);
4085
+ const diff2 = await getDiff(thread.worktreePath, thread.repoPath, { base: current2 });
4086
+ return {
4087
+ branch: current2,
4088
+ target: current2,
4089
+ diffStat: diff2.stat,
4090
+ dirty,
4091
+ blocked: false,
4092
+ isFork: false,
4093
+ cowboy: true
4094
+ };
4245
4095
  }
4246
- const { stdout: head } = await import("./run-CFKZPY7F.js").then(
4247
- ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
4248
- );
4249
- const current = head.trim();
4096
+ const target = await resolveDefaultBranch(thread.repoPath);
4097
+ const current = await currentBranch(thread.worktreePath);
4250
4098
  if (current === target) {
4251
4099
  return {
4252
4100
  branch: current,
@@ -4273,6 +4121,19 @@ async function confirmLand(thread, opts) {
4273
4121
  if (preview.blocked) {
4274
4122
  throw new Error(preview.blockReason ?? "Land blocked");
4275
4123
  }
4124
+ if (preview.cowboy) {
4125
+ const meta2 = await suggestPrMetadata(thread.worktreePath, {
4126
+ base: preview.branch,
4127
+ fallbackTitle: thread.title,
4128
+ sourceLabel: `${thread.sourceType}:${thread.sourceRef}`
4129
+ });
4130
+ let committed2 = false;
4131
+ if (preview.dirty) {
4132
+ committed2 = await commitAll(thread.worktreePath, meta2.commitMessage);
4133
+ }
4134
+ await pushBranch(thread.worktreePath, preview.branch);
4135
+ return { prUrl: null, pushed: true, committed: committed2 };
4136
+ }
4276
4137
  const meta = await suggestPrMetadata(thread.worktreePath, {
4277
4138
  base: preview.target,
4278
4139
  fallbackTitle: thread.title,
@@ -5244,7 +5105,7 @@ function formatScheduledPrompt(name, prompt) {
5244
5105
  ${prompt}`;
5245
5106
  }
5246
5107
  async function defaultDeps() {
5247
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-6W7EKSPO.js");
5108
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-FCZVCKBK.js");
5248
5109
  const orch = getOrchestrator2();
5249
5110
  return {
5250
5111
  findThread: (id) => findThreadByRef(id),
@@ -5462,7 +5323,7 @@ var Orchestrator = class {
5462
5323
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
5463
5324
  });
5464
5325
  }
5465
- const { autoCleanupOrphansEnabled } = await import("./app-settings-IYSSVZHH.js");
5326
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-J4LUWIRN.js");
5466
5327
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
5467
5328
  await cleanupOrphanWorktrees({ repoPaths });
5468
5329
  }
@@ -5619,7 +5480,9 @@ var Orchestrator = class {
5619
5480
  return thread;
5620
5481
  }
5621
5482
  async finishCreateThread(threadId, prompt) {
5622
- const setup = this.runSetupAfterCreate(threadId);
5483
+ const created = this.getThread(threadId);
5484
+ const skipSetup = isCowboyThread(created);
5485
+ const setup = skipSetup ? Promise.resolve() : this.runSetupAfterCreate(threadId);
5623
5486
  if (prompt) {
5624
5487
  try {
5625
5488
  await this.send(threadId, prompt);
@@ -5631,7 +5494,8 @@ var Orchestrator = class {
5631
5494
  }
5632
5495
  }
5633
5496
  await setup;
5634
- const { autoRunAfterSetupEnabled } = await import("./app-settings-IYSSVZHH.js");
5497
+ if (skipSetup) return;
5498
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-J4LUWIRN.js");
5635
5499
  if (autoRunAfterSetupEnabled()) {
5636
5500
  try {
5637
5501
  await this.startDev(threadId);
@@ -5916,7 +5780,7 @@ var Orchestrator = class {
5916
5780
  }
5917
5781
  const isBrightsy = fresh.agent === "brightsy";
5918
5782
  const isOrchestration = isOrchestratorThread(fresh);
5919
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-IYSSVZHH.js");
5783
+ const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-J4LUWIRN.js");
5920
5784
  const gitAuthMode = getGithubGitAuthMode();
5921
5785
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
5922
5786
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -6675,7 +6539,7 @@ var Orchestrator = class {
6675
6539
  updateThread(thread.id, { title: meta.title });
6676
6540
  }
6677
6541
  }
6678
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-IYSSVZHH.js");
6542
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-J4LUWIRN.js");
6679
6543
  const latest = this.requireThread(thread.id);
6680
6544
  if (!shouldAutoArchiveOnPrMerge({
6681
6545
  previousPrState: prevState || null,
@@ -6962,23 +6826,25 @@ var Orchestrator = class {
6962
6826
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
6963
6827
  if (siblings.length === 0) {
6964
6828
  this.stopDev(thread.id);
6965
- try {
6966
- await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
6967
- this.emit({
6968
- type: "turn_output",
6969
- threadId: thread.id,
6970
- event: { type: "stdout", data: `[archive] ${line}` }
6829
+ if (shouldRemoveWorktreeOnTeardown(thread)) {
6830
+ try {
6831
+ await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
6832
+ this.emit({
6833
+ type: "turn_output",
6834
+ threadId: thread.id,
6835
+ event: { type: "stdout", data: `[archive] ${line}` }
6836
+ });
6971
6837
  });
6972
- });
6973
- } catch {
6838
+ } catch {
6839
+ }
6840
+ await removeWorktree(thread.repoPath, thread.worktreePath);
6974
6841
  }
6975
- await removeWorktree(thread.repoPath, thread.worktreePath);
6976
6842
  }
6977
6843
  const archived = setStatus(thread.id, "archived");
6978
6844
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
6979
6845
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
6980
6846
  try {
6981
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-SUBEDSGB.js");
6847
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-HV3J4TTW.js");
6982
6848
  await ensureWorkspace2(thread.repoPath);
6983
6849
  } catch {
6984
6850
  }
@@ -7000,15 +6866,17 @@ var Orchestrator = class {
7000
6866
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
7001
6867
  if (siblings.length === 0) {
7002
6868
  this.stopDev(thread.id);
7003
- try {
7004
- await runArchiveScript(thread.repoPath, thread.worktreePath);
7005
- } catch {
6869
+ if (shouldRemoveWorktreeOnTeardown(thread)) {
6870
+ try {
6871
+ await runArchiveScript(thread.repoPath, thread.worktreePath);
6872
+ } catch {
6873
+ }
6874
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-J4LUWIRN.js");
6875
+ const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
6876
+ await removeWorktree(thread.repoPath, thread.worktreePath, {
6877
+ deleteBranch: deleteBranch ? thread.branchName : void 0
6878
+ });
7006
6879
  }
7007
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-IYSSVZHH.js");
7008
- const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
7009
- await removeWorktree(thread.repoPath, thread.worktreePath, {
7010
- deleteBranch: deleteBranch ? thread.branchName : void 0
7011
- });
7012
6880
  }
7013
6881
  deleteThreadRecord(thread.id);
7014
6882
  }
@@ -7025,7 +6893,12 @@ var Orchestrator = class {
7025
6893
  return restored2;
7026
6894
  }
7027
6895
  if (!existsSync16(thread.worktreePath)) {
7028
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-2UWO7VEK.js");
6896
+ if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
6897
+ throw new Error(
6898
+ `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
6899
+ );
6900
+ }
6901
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-XFJED3VU.js");
7029
6902
  const slug = thread.worktreePath.split("/").pop();
7030
6903
  const dest = thread.worktreePath;
7031
6904
  await withRepoGitLock(thread.repoPath, async () => {
@@ -7133,7 +7006,7 @@ async function startOrchestration(opts) {
7133
7006
  sourceRef: "default",
7134
7007
  ...createOpts
7135
7008
  }).catch(async () => {
7136
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-2UWO7VEK.js");
7009
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-XFJED3VU.js");
7137
7010
  const repo = await resolveRepoRoot2(repoPath);
7138
7011
  const def = await resolveDefaultBranch2(repo);
7139
7012
  return orch.createThread({
@@ -7143,7 +7016,7 @@ async function startOrchestration(opts) {
7143
7016
  repoPath: repo
7144
7017
  });
7145
7018
  });
7146
- const { updateThread: upd } = await import("./thread-store-4OUEQ2DB.js");
7019
+ const { updateThread: upd } = await import("./thread-store-OEALWU7Y.js");
7147
7020
  const updated = upd(thread.id, {
7148
7021
  sourceType: "orchestration",
7149
7022
  sourceRef: goal
@@ -7197,15 +7070,6 @@ export {
7197
7070
  dismissSlackReplyBadge,
7198
7071
  permalinkForSlackReplyBadge,
7199
7072
  refreshSlackReplyBadges,
7200
- toolDetail,
7201
- toolDescription,
7202
- toolFilePath,
7203
- applyAgentEvent,
7204
- partsToAssistantText,
7205
- stripBrightsyNdjsonNoise,
7206
- isBrightsyNdjsonLine,
7207
- finalizeParts,
7208
- normalizeParseResult,
7209
7073
  applyPromptCacheTtlEnv,
7210
7074
  spawnAgentTurn,
7211
7075
  AGENT_GIT_ACTIONS,
@@ -7278,6 +7142,9 @@ export {
7278
7142
  requireAgent,
7279
7143
  createThread,
7280
7144
  listLinearIssues,
7145
+ isCowboyThread,
7146
+ isPrimaryCheckoutThread,
7147
+ shouldRemoveWorktreeOnTeardown,
7281
7148
  readTurnLive,
7282
7149
  forkThreadWorktree,
7283
7150
  resolveConductorCursorAgentId,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  resolveGithubRepoSlug
3
- } from "./chunk-EW7COXYE.js";
3
+ } from "./chunk-C4KHDW3U.js";
4
4
  import {
5
5
  resolveThreadDefaults
6
- } from "./chunk-4LKD3PGO.js";
6
+ } from "./chunk-4NR5FL46.js";
7
7
  import {
8
8
  globalAgentCwd,
9
9
  sideboardReposDir
@@ -43,6 +43,7 @@ function normalizeThread(raw) {
43
43
  prTitle: raw.prTitle ?? null,
44
44
  prState: raw.prState ?? null,
45
45
  skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
46
+ cowboy: Boolean(raw.cowboy),
46
47
  stackId: raw.stackId ?? null,
47
48
  stackLayer: raw.stackLayer ?? null,
48
49
  userSetTitle: Boolean(raw.userSetTitle),
@@ -71,6 +72,7 @@ function createEmptyThread(partial) {
71
72
  prTitle: partial.prTitle ?? null,
72
73
  prState: partial.prState ?? null,
73
74
  skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
75
+ cowboy: Boolean(partial.cowboy),
74
76
  stackId: partial.stackId ?? null,
75
77
  stackLayer: partial.stackLayer ?? null,
76
78
  userSetTitle: partial.userSetTitle ?? false,