@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
@@ -2,28 +2,35 @@
2
2
 
3
3
  import {
4
4
  PLAN_MODE_INSTRUCTION,
5
+ applyAgentEvent,
5
6
  applyTurnUsage,
6
7
  contextTokens,
7
8
  fallbackTurnFailDetail,
9
+ finalizeParts,
8
10
  formatTurnExitError,
9
11
  getAdapter,
12
+ isBrightsyNdjsonLine,
10
13
  isSessionQuotaLimit,
11
14
  looksLikeAgentFailureMessage,
12
15
  looksLikeInvalidAgentSession,
16
+ normalizeParseResult,
13
17
  parseBrightsyCliLine,
14
18
  parseSessionQuotaResetAt,
19
+ partsToAssistantText,
15
20
  pushTurnStderr,
16
21
  resolveQuotaFallbackAgent,
17
22
  shouldRetryFailedAgentTurn,
23
+ stripBrightsyNdjsonNoise,
18
24
  summarizeTurnStderr,
25
+ toolDescription,
19
26
  turnFailChatText
20
- } from "./chunk-AY2EQI2P.js";
27
+ } from "./chunk-VOJSO3RM.js";
21
28
  import {
22
29
  addWorkspace,
23
30
  ensureWorkspace,
24
31
  removeWorkspace,
25
32
  syncWorkspacesFromThreads
26
- } from "./chunk-OQDIYVDD.js";
33
+ } from "./chunk-YFAXVUY2.js";
27
34
  import {
28
35
  extractPresentedPlan,
29
36
  readPlanFile,
@@ -44,14 +51,14 @@ import {
44
51
  isOrchestratorThread,
45
52
  isSlackCoordinatorThread,
46
53
  orchestratorSessionPoisonedByBuiltins
47
- } from "./chunk-TROJ3PVH.js";
54
+ } from "./chunk-VOD3HFLP.js";
48
55
  import {
49
56
  SLACK_REPLY_FORMATTING,
50
57
  coordinatorSystemPrompt,
51
58
  coordinatorTurnReminder,
52
59
  enrichWorkspacesWithGithub,
53
60
  ensureGlobalCoordinatorCwd
54
- } from "./chunk-VRTKGKUW.js";
61
+ } from "./chunk-AROMOP3C.js";
55
62
  import {
56
63
  addPrStackLayer,
57
64
  allocateTeamName,
@@ -94,7 +101,7 @@ import {
94
101
  threadDisplayLabel,
95
102
  withRepoGitLock,
96
103
  worktreeNameFromPath
97
- } from "./chunk-JVIW55KT.js";
104
+ } from "./chunk-YXDR43ZC.js";
98
105
  import {
99
106
  ATTACHMENTS_DIR,
100
107
  LEGACY_ATTACHMENTS_DIR,
@@ -111,7 +118,7 @@ import {
111
118
  updateThread,
112
119
  withThreadLock,
113
120
  writeThread
114
- } from "./chunk-P3BQ5DOL.js";
121
+ } from "./chunk-KYOTBZ6S.js";
115
122
  import {
116
123
  childEnvWithAppSettings,
117
124
  isSecureFileEncrypted,
@@ -125,7 +132,7 @@ import {
125
132
  stripNestedElectronEnv,
126
133
  updateAdvancedSettings,
127
134
  writeSecureJson
128
- } from "./chunk-NE4TOOKS.js";
135
+ } from "./chunk-SGEVS5SY.js";
129
136
  import {
130
137
  writePrivateFile
131
138
  } from "./chunk-NSTQ6QKD.js";
@@ -654,238 +661,13 @@ import { existsSync as existsSync16 } from "fs";
654
661
  import { createInterface } from "readline";
655
662
  import { execa } from "execa";
656
663
 
657
- // src/agents/message-parts.ts
658
- function asRecord(input) {
659
- if (input && typeof input === "object" && !Array.isArray(input)) {
660
- return input;
661
- }
662
- return void 0;
663
- }
664
- function str(v) {
665
- return typeof v === "string" && v.trim() ? v : void 0;
666
- }
667
- function toolDetail(name, input) {
668
- if (!input) return void 0;
669
- const command = str(input.command) ?? str(input.cmd);
670
- if (command) return command;
671
- const path = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
672
- if (path) return path;
673
- const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
674
- if (pattern) return pattern;
675
- const query = str(input.query) ?? str(input.prompt);
676
- if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
677
- try {
678
- const raw = JSON.stringify(input);
679
- return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
680
- } catch {
681
- return name;
682
- }
683
- }
684
- function toolDescription(name, input) {
685
- const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
686
- if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
687
- if (/connectedAgentRequest/i.test(name)) {
688
- return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
689
- }
690
- if (/present_artifact$/i.test(name)) {
691
- return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
692
- }
693
- if (/present_plan$/i.test(name)) {
694
- return str(input?.title) ? `Plan ${str(input?.title)}` : "Present plan";
695
- }
696
- if (/present_schema$/i.test(name)) {
697
- return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
698
- }
699
- if (/present_files$/i.test(name)) {
700
- return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
701
- }
702
- if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
703
- return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
704
- }
705
- if (!input) return n;
706
- if (/bash|shell|terminal/i.test(name) && str(input.command)) {
707
- const cmd = str(input.command);
708
- if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
709
- if (/git\s+status/i.test(cmd)) return "Check git status";
710
- if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
711
- if (/git\s+branch/i.test(cmd)) return "List branches";
712
- if (/grep|rg\b/i.test(cmd)) return "Search repository";
713
- return "Run shell command";
714
- }
715
- if (/edit|write|apply/i.test(name)) {
716
- const path = str(input.file_path) ?? str(input.path);
717
- return path ? `Edit ${path.split("/").pop()}` : "Edit file";
718
- }
719
- if (/read/i.test(name)) {
720
- const path = str(input.file_path) ?? str(input.path);
721
- return path ? `Read ${path.split("/").pop()}` : "Read file";
722
- }
723
- if (/grep/i.test(name)) return "Search files";
724
- if (/glob/i.test(name)) return "Find files";
725
- return n;
726
- }
727
- function toolFilePath(input) {
728
- if (!input) return void 0;
729
- return str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
730
- }
731
- function countLines(text) {
732
- if (!text) return 0;
733
- return text.split("\n").length;
734
- }
735
- function diffFromInput(input) {
736
- if (!input) return {};
737
- const oldS = str(input.old_string) ?? str(input.oldString);
738
- const newS = str(input.new_string) ?? str(input.newString) ?? str(input.content);
739
- if (oldS != null || newS != null) {
740
- return {
741
- additions: countLines(newS),
742
- deletions: countLines(oldS)
743
- };
744
- }
745
- return {};
746
- }
747
- function parseDiffStat(result) {
748
- if (!result) return {};
749
- const paired = result.match(/\+(\d+)\s+-(\d+)/);
750
- if (paired) {
751
- return {
752
- additions: Number(paired[1]),
753
- deletions: Number(paired[2])
754
- };
755
- }
756
- const verbose = result.match(
757
- /(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
758
- );
759
- if (verbose) {
760
- return {
761
- additions: Number(verbose[1]),
762
- deletions: verbose[2] != null ? Number(verbose[2]) : void 0
763
- };
764
- }
765
- return {};
766
- }
767
- function applyAgentEvent(parts, event) {
768
- if (event.type === "stdout") {
769
- const data = event.data;
770
- if (!data) return parts;
771
- const next = [...parts];
772
- const last = next[next.length - 1];
773
- if (last?.type === "text") {
774
- next[next.length - 1] = { type: "text", text: last.text + data };
775
- } else {
776
- next.push({ type: "text", text: data });
777
- }
778
- return next;
779
- }
780
- if (event.type === "thinking") {
781
- const data = event.data;
782
- if (!data) return parts;
783
- const next = [...parts];
784
- const last = next[next.length - 1];
785
- if (last?.type === "thinking") {
786
- next[next.length - 1] = { type: "thinking", text: last.text + data };
787
- } else {
788
- next.push({ type: "thinking", text: data });
789
- }
790
- return next;
791
- }
792
- if (event.type === "tool_use") {
793
- const input = asRecord(event.input);
794
- const diff = diffFromInput(input);
795
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
796
- if (existing >= 0) {
797
- const prev = parts[existing];
798
- const next = [...parts];
799
- next[existing] = {
800
- ...prev,
801
- name: event.name || prev.name,
802
- input: input ?? prev.input,
803
- description: toolDescription(event.name || prev.name, input ?? prev.input),
804
- detail: toolDetail(event.name || prev.name, input ?? prev.input) ?? prev.detail,
805
- filePath: toolFilePath(input) ?? prev.filePath,
806
- additions: diff.additions ?? prev.additions,
807
- deletions: diff.deletions ?? prev.deletions
808
- };
809
- return next;
810
- }
811
- return [
812
- ...parts,
813
- {
814
- type: "tool",
815
- id: event.id,
816
- name: event.name,
817
- input,
818
- description: toolDescription(event.name, input),
819
- detail: toolDetail(event.name, input),
820
- status: "running",
821
- filePath: toolFilePath(input),
822
- ...diff
823
- }
824
- ];
825
- }
826
- if (event.type === "tool_result") {
827
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
828
- const fromResult = parseDiffStat(event.content);
829
- if (existing < 0) {
830
- return [
831
- ...parts,
832
- {
833
- type: "tool",
834
- id: event.id,
835
- name: "tool",
836
- description: "tool",
837
- status: event.isError ? "error" : "done",
838
- result: event.content,
839
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
840
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
841
- }
842
- ];
843
- }
844
- return parts.map((p, i) => {
845
- if (i !== existing || p.type !== "tool") return p;
846
- return {
847
- ...p,
848
- status: event.isError ? "error" : "done",
849
- result: event.content,
850
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
851
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
852
- };
853
- });
854
- }
855
- return parts;
856
- }
857
- function partsToAssistantText(parts) {
858
- return parts.filter((p) => p.type === "text").map((p) => p.text).join("").trim();
859
- }
860
- function stripBrightsyNdjsonNoise(text) {
861
- if (!text || !text.includes('"type"')) return text;
862
- let out = text;
863
- out = out.replace(
864
- /\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
865
- ""
866
- );
867
- out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
868
- return out.trim();
869
- }
870
- function isBrightsyNdjsonLine(line) {
871
- const t = line.trim();
872
- if (!t.startsWith("{")) return false;
873
- return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
874
- }
875
- function finalizeParts(parts) {
876
- return parts.map(
877
- (p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
878
- );
879
- }
880
- function normalizeParseResult(parsed) {
881
- if (!parsed) return [];
882
- return Array.isArray(parsed) ? parsed : [parsed];
883
- }
884
-
885
664
  // src/agents/cursor-stream-coalesce.ts
886
665
  function isTextEvent(event) {
887
666
  return event.type === "stdout" || event.type === "thinking";
888
667
  }
668
+ function parentKey(event) {
669
+ return event.parentId ?? "";
670
+ }
889
671
  function createAgentStreamCoalescer(emit, opts) {
890
672
  const intervalMs = opts?.intervalMs ?? 32;
891
673
  let pending = null;
@@ -898,7 +680,11 @@ function createAgentStreamCoalescer(emit, opts) {
898
680
  if (!pending) return;
899
681
  const event = pending;
900
682
  pending = null;
901
- emit({ type: event.type, data: event.data });
683
+ emit({
684
+ type: event.type,
685
+ data: event.data,
686
+ ...event.parentId ? { parentId: event.parentId } : {}
687
+ });
902
688
  };
903
689
  const schedule = () => {
904
690
  if (timer) return;
@@ -913,11 +699,15 @@ function createAgentStreamCoalescer(emit, opts) {
913
699
  return;
914
700
  }
915
701
  if (!event.data) return;
916
- if (pending && pending.type === event.type) {
702
+ if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
917
703
  pending.data += event.data;
918
704
  } else {
919
705
  flush2();
920
- pending = { type: event.type, data: event.data };
706
+ pending = {
707
+ type: event.type,
708
+ data: event.data,
709
+ ...event.parentId ? { parentId: event.parentId } : {}
710
+ };
921
711
  }
922
712
  schedule();
923
713
  },
@@ -941,9 +731,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
941
731
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
942
732
  );
943
733
  }
944
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-WBQWQQQY.js");
734
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SKFODUQQ.js");
945
735
  if (isGlobalThread2(thread)) {
946
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-V66BYTUV.js");
736
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-BHMLWL64.js");
947
737
  ensureGlobalCoordinatorCwd2(
948
738
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
949
739
  );
@@ -1510,7 +1300,8 @@ function worktreeBindingFrom(from) {
1510
1300
  prState: from.prState,
1511
1301
  skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
1512
1302
  stackId: from.stackId,
1513
- stackLayer: from.stackLayer
1303
+ stackLayer: from.stackLayer,
1304
+ cowboy: from.cowboy
1514
1305
  };
1515
1306
  }
1516
1307
  function threadsSharingWorktree(worktreePath) {
@@ -2495,6 +2286,55 @@ async function createThread(input, _onSetupLine) {
2495
2286
  if (!existsSync7(repoPath)) {
2496
2287
  throw new Error(`Repo not found: ${repoPath}`);
2497
2288
  }
2289
+ if (input.cowboy) {
2290
+ const { cowboyModeEnabled } = await import("./app-settings-5XAGNDX7.js");
2291
+ if (!cowboyModeEnabled()) {
2292
+ throw new Error(
2293
+ "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
2294
+ );
2295
+ }
2296
+ if (input.sourceType === "pr" || input.sourceType === "ticket" || input.sourceType === "adopt") {
2297
+ throw new Error(
2298
+ "Cowboy mode works on the project folder (default branch), not a PR, ticket, or adopt."
2299
+ );
2300
+ }
2301
+ const defaultBranch = await resolveDefaultBranch(repoPath, { network: false });
2302
+ const head = await currentBranch(repoPath);
2303
+ if (head === "HEAD") {
2304
+ throw new Error(
2305
+ "Cowboy mode needs a named branch in the project folder (not a detached HEAD)."
2306
+ );
2307
+ }
2308
+ if (head !== defaultBranch) {
2309
+ throw new Error(
2310
+ `Cowboy mode uses ${defaultBranch} in the project folder. Switch that checkout to ${defaultBranch} first (currently ${head}).`
2311
+ );
2312
+ }
2313
+ const explicitTitle2 = input.title?.trim();
2314
+ const thread2 = createEmptyThread({
2315
+ title: explicitTitle2 || `Cowboy \xB7 ${head}`,
2316
+ userSetTitle: Boolean(explicitTitle2),
2317
+ sourceType: "branch",
2318
+ sourceRef: head,
2319
+ branchName: head,
2320
+ worktreePath: repoPath,
2321
+ repoPath,
2322
+ agent: resolved.agent,
2323
+ autonomy: input.autonomy ?? "default",
2324
+ model: resolved.model,
2325
+ effort: resolved.effort,
2326
+ fast: resolved.fast,
2327
+ planMode: Boolean(input.planMode),
2328
+ attachments: input.attachments ?? [],
2329
+ sourceIsFork: false,
2330
+ parentThreadId: input.parentThreadId ?? null,
2331
+ status: "idle",
2332
+ cowboy: true
2333
+ });
2334
+ writeThread(thread2);
2335
+ await ensureWorkspace(repoPath);
2336
+ return readThread(thread2.id) ?? thread2;
2337
+ }
2498
2338
  let sourceRef = input.sourceRef;
2499
2339
  let sourceIsFork = false;
2500
2340
  let prUrl = null;
@@ -2558,7 +2398,7 @@ async function createThread(input, _onSetupLine) {
2558
2398
  return readThread(thread.id) ?? thread;
2559
2399
  }
2560
2400
  async function listLinearIssues(agent, repoPath) {
2561
- const { getAdapter: getAdapter2 } = await import("./agents-XB332VUJ.js");
2401
+ const { getAdapter: getAdapter2 } = await import("./agents-MQDW3YXL.js");
2562
2402
  await requireAgent(agent, { requireLinear: true });
2563
2403
  const adapter = getAdapter2(agent);
2564
2404
  if (!adapter.listLinearIssues) {
@@ -2567,6 +2407,18 @@ async function listLinearIssues(agent, repoPath) {
2567
2407
  return adapter.listLinearIssues(repoPath);
2568
2408
  }
2569
2409
 
2410
+ // src/threads/cowboy.ts
2411
+ function isCowboyThread(thread) {
2412
+ return Boolean(thread?.cowboy);
2413
+ }
2414
+ function isPrimaryCheckoutThread(thread) {
2415
+ if (!thread?.worktreePath || !thread.repoPath) return false;
2416
+ return normalizeWorktreePath(thread.worktreePath) === normalizeWorktreePath(thread.repoPath);
2417
+ }
2418
+ function shouldRemoveWorktreeOnTeardown(thread) {
2419
+ return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
2420
+ }
2421
+
2570
2422
  // src/store/turn-live.ts
2571
2423
  import {
2572
2424
  existsSync as existsSync8,
@@ -2931,7 +2783,7 @@ async function adoptThread(input) {
2931
2783
  messages: input.messages ?? []
2932
2784
  });
2933
2785
  writeThread(thread);
2934
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-I3554R3F.js");
2786
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-XAQVKTLO.js");
2935
2787
  await ensureWorkspace2(repoPath);
2936
2788
  return thread;
2937
2789
  }
@@ -4164,13 +4016,22 @@ async function previewLand(thread) {
4164
4016
  isFork: true
4165
4017
  };
4166
4018
  }
4167
- const target = await resolveDefaultBranch(thread.repoPath);
4168
- if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
4019
+ if (isCowboyThread(thread)) {
4020
+ const current2 = await currentBranch(thread.worktreePath);
4021
+ const dirty = await isDirty(thread.worktreePath);
4022
+ const diff2 = await getDiff(thread.worktreePath, thread.repoPath, { base: current2 });
4023
+ return {
4024
+ branch: current2,
4025
+ target: current2,
4026
+ diffStat: diff2.stat,
4027
+ dirty,
4028
+ blocked: false,
4029
+ isFork: false,
4030
+ cowboy: true
4031
+ };
4169
4032
  }
4170
- const { stdout: head } = await import("./run-XKTAJRWF.js").then(
4171
- ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
4172
- );
4173
- const current = head.trim();
4033
+ const target = await resolveDefaultBranch(thread.repoPath);
4034
+ const current = await currentBranch(thread.worktreePath);
4174
4035
  if (current === target) {
4175
4036
  return {
4176
4037
  branch: current,
@@ -4197,6 +4058,19 @@ async function confirmLand(thread, opts) {
4197
4058
  if (preview.blocked) {
4198
4059
  throw new Error(preview.blockReason ?? "Land blocked");
4199
4060
  }
4061
+ if (preview.cowboy) {
4062
+ const meta2 = await suggestPrMetadata(thread.worktreePath, {
4063
+ base: preview.branch,
4064
+ fallbackTitle: thread.title,
4065
+ sourceLabel: `${thread.sourceType}:${thread.sourceRef}`
4066
+ });
4067
+ let committed2 = false;
4068
+ if (preview.dirty) {
4069
+ committed2 = await commitAll(thread.worktreePath, meta2.commitMessage);
4070
+ }
4071
+ await pushBranch(thread.worktreePath, preview.branch);
4072
+ return { prUrl: null, pushed: true, committed: committed2 };
4073
+ }
4200
4074
  const meta = await suggestPrMetadata(thread.worktreePath, {
4201
4075
  base: preview.target,
4202
4076
  fallbackTitle: thread.title,
@@ -5055,7 +4929,7 @@ function formatScheduledPrompt(name, prompt) {
5055
4929
  ${prompt}`;
5056
4930
  }
5057
4931
  async function defaultDeps() {
5058
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-JVGVPKLI.js");
4932
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-SCATSB3O.js");
5059
4933
  const orch = getOrchestrator2();
5060
4934
  return {
5061
4935
  findThread: (id) => findThreadByRef(id),
@@ -5273,7 +5147,7 @@ var Orchestrator = class {
5273
5147
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
5274
5148
  });
5275
5149
  }
5276
- const { autoCleanupOrphansEnabled } = await import("./app-settings-EBCVMFF6.js");
5150
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-5XAGNDX7.js");
5277
5151
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
5278
5152
  await cleanupOrphanWorktrees({ repoPaths });
5279
5153
  }
@@ -5430,7 +5304,9 @@ var Orchestrator = class {
5430
5304
  return thread;
5431
5305
  }
5432
5306
  async finishCreateThread(threadId, prompt) {
5433
- const setup = this.runSetupAfterCreate(threadId);
5307
+ const created = this.getThread(threadId);
5308
+ const skipSetup = isCowboyThread(created);
5309
+ const setup = skipSetup ? Promise.resolve() : this.runSetupAfterCreate(threadId);
5434
5310
  if (prompt) {
5435
5311
  try {
5436
5312
  await this.send(threadId, prompt);
@@ -5442,7 +5318,8 @@ var Orchestrator = class {
5442
5318
  }
5443
5319
  }
5444
5320
  await setup;
5445
- const { autoRunAfterSetupEnabled } = await import("./app-settings-EBCVMFF6.js");
5321
+ if (skipSetup) return;
5322
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-5XAGNDX7.js");
5446
5323
  if (autoRunAfterSetupEnabled()) {
5447
5324
  try {
5448
5325
  await this.startDev(threadId);
@@ -5727,7 +5604,7 @@ var Orchestrator = class {
5727
5604
  }
5728
5605
  const isBrightsy = fresh.agent === "brightsy";
5729
5606
  const isOrchestration = isOrchestratorThread(fresh);
5730
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-EBCVMFF6.js");
5607
+ const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-5XAGNDX7.js");
5731
5608
  const gitAuthMode = getGithubGitAuthMode();
5732
5609
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
5733
5610
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -6486,7 +6363,7 @@ var Orchestrator = class {
6486
6363
  updateThread(thread.id, { title: meta.title });
6487
6364
  }
6488
6365
  }
6489
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-EBCVMFF6.js");
6366
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-5XAGNDX7.js");
6490
6367
  const latest = this.requireThread(thread.id);
6491
6368
  if (!shouldAutoArchiveOnPrMerge({
6492
6369
  previousPrState: prevState || null,
@@ -6773,23 +6650,25 @@ var Orchestrator = class {
6773
6650
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
6774
6651
  if (siblings.length === 0) {
6775
6652
  this.stopDev(thread.id);
6776
- try {
6777
- await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
6778
- this.emit({
6779
- type: "turn_output",
6780
- threadId: thread.id,
6781
- event: { type: "stdout", data: `[archive] ${line}` }
6653
+ if (shouldRemoveWorktreeOnTeardown(thread)) {
6654
+ try {
6655
+ await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
6656
+ this.emit({
6657
+ type: "turn_output",
6658
+ threadId: thread.id,
6659
+ event: { type: "stdout", data: `[archive] ${line}` }
6660
+ });
6782
6661
  });
6783
- });
6784
- } catch {
6662
+ } catch {
6663
+ }
6664
+ await removeWorktree(thread.repoPath, thread.worktreePath);
6785
6665
  }
6786
- await removeWorktree(thread.repoPath, thread.worktreePath);
6787
6666
  }
6788
6667
  const archived = setStatus(thread.id, "archived");
6789
6668
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
6790
6669
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
6791
6670
  try {
6792
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-I3554R3F.js");
6671
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-XAQVKTLO.js");
6793
6672
  await ensureWorkspace2(thread.repoPath);
6794
6673
  } catch {
6795
6674
  }
@@ -6811,15 +6690,17 @@ var Orchestrator = class {
6811
6690
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
6812
6691
  if (siblings.length === 0) {
6813
6692
  this.stopDev(thread.id);
6814
- try {
6815
- await runArchiveScript(thread.repoPath, thread.worktreePath);
6816
- } catch {
6693
+ if (shouldRemoveWorktreeOnTeardown(thread)) {
6694
+ try {
6695
+ await runArchiveScript(thread.repoPath, thread.worktreePath);
6696
+ } catch {
6697
+ }
6698
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-5XAGNDX7.js");
6699
+ const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
6700
+ await removeWorktree(thread.repoPath, thread.worktreePath, {
6701
+ deleteBranch: deleteBranch ? thread.branchName : void 0
6702
+ });
6817
6703
  }
6818
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-EBCVMFF6.js");
6819
- const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
6820
- await removeWorktree(thread.repoPath, thread.worktreePath, {
6821
- deleteBranch: deleteBranch ? thread.branchName : void 0
6822
- });
6823
6704
  }
6824
6705
  deleteThreadRecord(thread.id);
6825
6706
  }
@@ -6836,7 +6717,12 @@ var Orchestrator = class {
6836
6717
  return restored2;
6837
6718
  }
6838
6719
  if (!existsSync16(thread.worktreePath)) {
6839
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7H6HB6GW.js");
6720
+ if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
6721
+ throw new Error(
6722
+ `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
6723
+ );
6724
+ }
6725
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-N2EV24EE.js");
6840
6726
  const slug = thread.worktreePath.split("/").pop();
6841
6727
  const dest = thread.worktreePath;
6842
6728
  await withRepoGitLock(thread.repoPath, async () => {
@@ -6944,7 +6830,7 @@ async function startOrchestration(opts) {
6944
6830
  sourceRef: "default",
6945
6831
  ...createOpts
6946
6832
  }).catch(async () => {
6947
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7H6HB6GW.js");
6833
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-N2EV24EE.js");
6948
6834
  const repo = await resolveRepoRoot2(repoPath);
6949
6835
  const def = await resolveDefaultBranch2(repo);
6950
6836
  return orch.createThread({
@@ -6954,7 +6840,7 @@ async function startOrchestration(opts) {
6954
6840
  repoPath: repo
6955
6841
  });
6956
6842
  });
6957
- const { updateThread: upd } = await import("./thread-store-DQJGDKIJ.js");
6843
+ const { updateThread: upd } = await import("./thread-store-LPTBVW5C.js");
6958
6844
  const updated = upd(thread.id, {
6959
6845
  sourceType: "orchestration",
6960
6846
  sourceRef: goal
@@ -2,11 +2,11 @@
2
2
 
3
3
  import {
4
4
  isGlobalRepoPath
5
- } from "./chunk-TROJ3PVH.js";
5
+ } from "./chunk-VOD3HFLP.js";
6
6
  import {
7
7
  ensureGhPreferOrigin,
8
8
  resolveRepoRoot
9
- } from "./chunk-JVIW55KT.js";
9
+ } from "./chunk-YXDR43ZC.js";
10
10
  import {
11
11
  appDataDir
12
12
  } from "./chunk-BD2ICC4D.js";
@@ -5,11 +5,11 @@ import {
5
5
  } from "./chunk-B3SJXYIJ.js";
6
6
  import {
7
7
  listThreads
8
- } from "./chunk-P3BQ5DOL.js";
8
+ } from "./chunk-KYOTBZ6S.js";
9
9
  import {
10
10
  getGithubGitAuthMode,
11
11
  getGithubPat
12
- } from "./chunk-NE4TOOKS.js";
12
+ } from "./chunk-SGEVS5SY.js";
13
13
  import {
14
14
  worktreesRoot
15
15
  } from "./chunk-BD2ICC4D.js";