@halcyonlabs/app 0.47.0-halcyon.325 → 0.47.0-halcyon.326

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/index.d.ts CHANGED
@@ -316,8 +316,8 @@ declare const appKeybindingOverridesSchema: z$1.ZodArray<z$1.ZodObject<{
316
316
  shift: z$1.ZodBoolean;
317
317
  }, z$1.core.$strict>>;
318
318
  platform: z$1.ZodOptional<z$1.ZodEnum<{
319
- windows: "windows";
320
319
  mac: "mac";
320
+ windows: "windows";
321
321
  linux: "linux";
322
322
  }>>;
323
323
  }, z$1.core.$strict>>;
@@ -524,8 +524,8 @@ declare const environmentSchema: z$1.ZodObject<{
524
524
  retireAt: z$1.ZodNullable<z$1.ZodNumber>;
525
525
  teardown: z$1.ZodNullable<z$1.ZodObject<{
526
526
  status: z$1.ZodEnum<{
527
- failed: "failed";
528
527
  running: "running";
528
+ failed: "failed";
529
529
  removed: "removed";
530
530
  }>;
531
531
  attempt: z$1.ZodNumber;
@@ -620,8 +620,8 @@ declare const hostSchema: z$1.ZodObject<{
620
620
  pendingLog: z$1.ZodString;
621
621
  teardown: z$1.ZodNullable<z$1.ZodObject<{
622
622
  status: z$1.ZodEnum<{
623
- failed: "failed";
624
623
  running: "running";
624
+ failed: "failed";
625
625
  removed: "removed";
626
626
  }>;
627
627
  attempt: z$1.ZodNumber;
@@ -732,8 +732,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
732
732
  providerThreadId: z$1.ZodString;
733
733
  objective: z$1.ZodString;
734
734
  status: z$1.ZodEnum<{
735
- active: "active";
736
735
  paused: "paused";
736
+ active: "active";
737
737
  budgetLimited: "budgetLimited";
738
738
  complete: "complete";
739
739
  }>;
@@ -1304,9 +1304,9 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
1304
1304
  step: z$1.ZodString;
1305
1305
  status: z$1.ZodOptional<z$1.ZodEnum<{
1306
1306
  pending: "pending";
1307
- active: "active";
1308
1307
  completed: "completed";
1309
1308
  failed: "failed";
1309
+ active: "active";
1310
1310
  }>>;
1311
1311
  }, z$1.core.$strip>>;
1312
1312
  explanation: z$1.ZodOptional<z$1.ZodString>;
@@ -1385,10 +1385,10 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
1385
1385
  }>;
1386
1386
  taskStatus: z$1.ZodEnum<{
1387
1387
  pending: "pending";
1388
+ running: "running";
1389
+ paused: "paused";
1388
1390
  completed: "completed";
1389
1391
  failed: "failed";
1390
- paused: "paused";
1391
- running: "running";
1392
1392
  killed: "killed";
1393
1393
  stopped: "stopped";
1394
1394
  }>;
@@ -1405,8 +1405,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
1405
1405
  index: z$1.ZodNumber;
1406
1406
  label: z$1.ZodString;
1407
1407
  state: z$1.ZodEnum<{
1408
- failed: "failed";
1409
1408
  running: "running";
1409
+ failed: "failed";
1410
1410
  queued: "queued";
1411
1411
  done: "done";
1412
1412
  skipped: "skipped";
@@ -2076,9 +2076,9 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2076
2076
  step: z$1.ZodString;
2077
2077
  status: z$1.ZodOptional<z$1.ZodEnum<{
2078
2078
  pending: "pending";
2079
- active: "active";
2080
2079
  completed: "completed";
2081
2080
  failed: "failed";
2081
+ active: "active";
2082
2082
  }>>;
2083
2083
  }, z$1.core.$strip>>;
2084
2084
  explanation: z$1.ZodOptional<z$1.ZodString>;
@@ -2157,10 +2157,10 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2157
2157
  }>;
2158
2158
  taskStatus: z$1.ZodEnum<{
2159
2159
  pending: "pending";
2160
+ running: "running";
2161
+ paused: "paused";
2160
2162
  completed: "completed";
2161
2163
  failed: "failed";
2162
- paused: "paused";
2163
- running: "running";
2164
2164
  killed: "killed";
2165
2165
  stopped: "stopped";
2166
2166
  }>;
@@ -2177,8 +2177,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2177
2177
  index: z$1.ZodNumber;
2178
2178
  label: z$1.ZodString;
2179
2179
  state: z$1.ZodEnum<{
2180
- failed: "failed";
2181
2180
  running: "running";
2181
+ failed: "failed";
2182
2182
  queued: "queued";
2183
2183
  done: "done";
2184
2184
  skipped: "skipped";
@@ -2389,10 +2389,10 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2389
2389
  }>;
2390
2390
  taskStatus: z$1.ZodEnum<{
2391
2391
  pending: "pending";
2392
+ running: "running";
2393
+ paused: "paused";
2392
2394
  completed: "completed";
2393
2395
  failed: "failed";
2394
- paused: "paused";
2395
- running: "running";
2396
2396
  killed: "killed";
2397
2397
  stopped: "stopped";
2398
2398
  }>;
@@ -2409,8 +2409,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2409
2409
  index: z$1.ZodNumber;
2410
2410
  label: z$1.ZodString;
2411
2411
  state: z$1.ZodEnum<{
2412
- failed: "failed";
2413
2412
  running: "running";
2413
+ failed: "failed";
2414
2414
  queued: "queued";
2415
2415
  done: "done";
2416
2416
  skipped: "skipped";
@@ -2488,10 +2488,10 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2488
2488
  }>;
2489
2489
  taskStatus: z$1.ZodEnum<{
2490
2490
  pending: "pending";
2491
+ running: "running";
2492
+ paused: "paused";
2491
2493
  completed: "completed";
2492
2494
  failed: "failed";
2493
- paused: "paused";
2494
- running: "running";
2495
2495
  killed: "killed";
2496
2496
  stopped: "stopped";
2497
2497
  }>;
@@ -2508,8 +2508,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2508
2508
  index: z$1.ZodNumber;
2509
2509
  label: z$1.ZodString;
2510
2510
  state: z$1.ZodEnum<{
2511
- failed: "failed";
2512
2511
  running: "running";
2512
+ failed: "failed";
2513
2513
  queued: "queued";
2514
2514
  done: "done";
2515
2515
  skipped: "skipped";
@@ -2704,9 +2704,9 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2704
2704
  step: z$1.ZodString;
2705
2705
  status: z$1.ZodOptional<z$1.ZodEnum<{
2706
2706
  pending: "pending";
2707
- active: "active";
2708
2707
  completed: "completed";
2709
2708
  failed: "failed";
2709
+ active: "active";
2710
2710
  }>>;
2711
2711
  }, z$1.core.$strip>>;
2712
2712
  explanation: z$1.ZodOptional<z$1.ZodString>;
@@ -2715,8 +2715,8 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
2715
2715
  threadId: z$1.ZodString;
2716
2716
  providerThreadId: z$1.ZodString;
2717
2717
  state: z$1.ZodEnum<{
2718
- idle: "idle";
2719
2718
  running: "running";
2719
+ idle: "idle";
2720
2720
  }>;
2721
2721
  }, z$1.core.$strip>, z$1.ZodObject<{
2722
2722
  type: z$1.ZodLiteral<"turn/diff/updated">;
@@ -3578,9 +3578,9 @@ declare const threadEventSchema: z$1.ZodUnion<readonly [z$1.ZodIntersection<z$1.
3578
3578
  threadId: z$1.ZodString;
3579
3579
  provisioningId: z$1.ZodString;
3580
3580
  status: z$1.ZodEnum<{
3581
- active: "active";
3582
3581
  completed: "completed";
3583
3582
  failed: "failed";
3583
+ active: "active";
3584
3584
  cancelled: "cancelled";
3585
3585
  }>;
3586
3586
  environmentId: z$1.ZodNullable<z$1.ZodString>;
@@ -5766,9 +5766,9 @@ declare const hostDaemonCommandRegistry: {
5766
5766
  }, z$1.core.$strict>, z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
5767
5767
  kind: z$1.ZodLiteral<"wording">;
5768
5768
  status: z$1.ZodEnum<{
5769
+ unavailable: "unavailable";
5769
5770
  pass: "pass";
5770
5771
  revise: "revise";
5771
- unavailable: "unavailable";
5772
5772
  }>;
5773
5773
  }, z$1.core.$strict>, z$1.ZodObject<{
5774
5774
  kind: z$1.ZodLiteral<"review">;
@@ -6009,8 +6009,8 @@ declare const hostDaemonCommandRegistry: {
6009
6009
  providerInstallation: z$1.ZodBoolean;
6010
6010
  supportsServiceTier: z$1.ZodBoolean;
6011
6011
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6012
- "accept-edits": "accept-edits";
6013
6012
  auto: "auto";
6013
+ "accept-edits": "accept-edits";
6014
6014
  full: "full";
6015
6015
  }>>;
6016
6016
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6036,16 +6036,16 @@ declare const hostDaemonCommandRegistry: {
6036
6036
  permissionScope: z$1.ZodLiteral<"workspace">;
6037
6037
  approvalReviewer: z$1.ZodLiteral<"user">;
6038
6038
  permissionEscalation: z$1.ZodEnum<{
6039
- ask: "ask";
6040
6039
  deny: "deny";
6040
+ ask: "ask";
6041
6041
  }>;
6042
6042
  }, z$1.core.$strip>, z$1.ZodObject<{
6043
6043
  permissionMode: z$1.ZodLiteral<"auto">;
6044
6044
  permissionScope: z$1.ZodLiteral<"workspace">;
6045
6045
  approvalReviewer: z$1.ZodLiteral<"automatic">;
6046
6046
  permissionEscalation: z$1.ZodEnum<{
6047
- ask: "ask";
6048
6047
  deny: "deny";
6048
+ ask: "ask";
6049
6049
  }>;
6050
6050
  }, z$1.core.$strip>, z$1.ZodObject<{
6051
6051
  permissionMode: z$1.ZodLiteral<"full">;
@@ -6158,8 +6158,8 @@ declare const hostDaemonCommandRegistry: {
6158
6158
  providerInstallation: z$1.ZodBoolean;
6159
6159
  supportsServiceTier: z$1.ZodBoolean;
6160
6160
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6161
- "accept-edits": "accept-edits";
6162
6161
  auto: "auto";
6162
+ "accept-edits": "accept-edits";
6163
6163
  full: "full";
6164
6164
  }>>;
6165
6165
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6185,16 +6185,16 @@ declare const hostDaemonCommandRegistry: {
6185
6185
  permissionScope: z$1.ZodLiteral<"workspace">;
6186
6186
  approvalReviewer: z$1.ZodLiteral<"user">;
6187
6187
  permissionEscalation: z$1.ZodEnum<{
6188
- ask: "ask";
6189
6188
  deny: "deny";
6189
+ ask: "ask";
6190
6190
  }>;
6191
6191
  }, z$1.core.$strip>, z$1.ZodObject<{
6192
6192
  permissionMode: z$1.ZodLiteral<"auto">;
6193
6193
  permissionScope: z$1.ZodLiteral<"workspace">;
6194
6194
  approvalReviewer: z$1.ZodLiteral<"automatic">;
6195
6195
  permissionEscalation: z$1.ZodEnum<{
6196
- ask: "ask";
6197
6196
  deny: "deny";
6197
+ ask: "ask";
6198
6198
  }>;
6199
6199
  }, z$1.core.$strip>, z$1.ZodObject<{
6200
6200
  permissionMode: z$1.ZodLiteral<"full">;
@@ -6330,8 +6330,8 @@ declare const hostDaemonCommandRegistry: {
6330
6330
  }>;
6331
6331
  origin: z$1.ZodEnum<{
6332
6332
  builtin: "builtin";
6333
- project: "project";
6334
6333
  user: "user";
6334
+ project: "project";
6335
6335
  }>;
6336
6336
  label: z$1.ZodString;
6337
6337
  argumentHint: z$1.ZodNullable<z$1.ZodString>;
@@ -6420,8 +6420,8 @@ declare const hostDaemonCommandRegistry: {
6420
6420
  }>;
6421
6421
  origin: z$1.ZodEnum<{
6422
6422
  builtin: "builtin";
6423
- project: "project";
6424
6423
  user: "user";
6424
+ project: "project";
6425
6425
  }>;
6426
6426
  label: z$1.ZodString;
6427
6427
  argumentHint: z$1.ZodNullable<z$1.ZodString>;
@@ -6523,8 +6523,8 @@ declare const hostDaemonCommandRegistry: {
6523
6523
  }>;
6524
6524
  origin: z$1.ZodEnum<{
6525
6525
  builtin: "builtin";
6526
- project: "project";
6527
6526
  user: "user";
6527
+ project: "project";
6528
6528
  }>;
6529
6529
  label: z$1.ZodString;
6530
6530
  argumentHint: z$1.ZodNullable<z$1.ZodString>;
@@ -6613,8 +6613,8 @@ declare const hostDaemonCommandRegistry: {
6613
6613
  }>;
6614
6614
  origin: z$1.ZodEnum<{
6615
6615
  builtin: "builtin";
6616
- project: "project";
6617
6616
  user: "user";
6617
+ project: "project";
6618
6618
  }>;
6619
6619
  label: z$1.ZodString;
6620
6620
  argumentHint: z$1.ZodNullable<z$1.ZodString>;
@@ -6668,16 +6668,16 @@ declare const hostDaemonCommandRegistry: {
6668
6668
  permissionScope: z$1.ZodLiteral<"workspace">;
6669
6669
  approvalReviewer: z$1.ZodLiteral<"user">;
6670
6670
  permissionEscalation: z$1.ZodEnum<{
6671
- ask: "ask";
6672
6671
  deny: "deny";
6672
+ ask: "ask";
6673
6673
  }>;
6674
6674
  }, z$1.core.$strip>, z$1.ZodObject<{
6675
6675
  permissionMode: z$1.ZodLiteral<"auto">;
6676
6676
  permissionScope: z$1.ZodLiteral<"workspace">;
6677
6677
  approvalReviewer: z$1.ZodLiteral<"automatic">;
6678
6678
  permissionEscalation: z$1.ZodEnum<{
6679
- ask: "ask";
6680
6679
  deny: "deny";
6680
+ ask: "ask";
6681
6681
  }>;
6682
6682
  }, z$1.core.$strip>, z$1.ZodObject<{
6683
6683
  permissionMode: z$1.ZodLiteral<"full">;
@@ -6696,8 +6696,8 @@ declare const hostDaemonCommandRegistry: {
6696
6696
  providerInstallation: z$1.ZodBoolean;
6697
6697
  supportsServiceTier: z$1.ZodBoolean;
6698
6698
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6699
- "accept-edits": "accept-edits";
6700
6699
  auto: "auto";
6700
+ "accept-edits": "accept-edits";
6701
6701
  full: "full";
6702
6702
  }>>;
6703
6703
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6715,6 +6715,9 @@ declare const hostDaemonCommandRegistry: {
6715
6715
  workspaceContext: z$1.ZodObject<{
6716
6716
  workspacePath: z$1.ZodString;
6717
6717
  }, z$1.core.$strip>;
6718
+ projectId: z$1.ZodString;
6719
+ providerThreadId: z$1.ZodString;
6720
+ providerId: z$1.ZodString;
6718
6721
  bridgeLaunch: z$1.ZodObject<{
6719
6722
  pluginId: z$1.ZodString;
6720
6723
  source: z$1.ZodObject<{
@@ -6726,8 +6729,8 @@ declare const hostDaemonCommandRegistry: {
6726
6729
  providerInstallation: z$1.ZodBoolean;
6727
6730
  supportsServiceTier: z$1.ZodBoolean;
6728
6731
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6729
- "accept-edits": "accept-edits";
6730
6732
  auto: "auto";
6733
+ "accept-edits": "accept-edits";
6731
6734
  full: "full";
6732
6735
  }>>;
6733
6736
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6745,8 +6748,6 @@ declare const hostDaemonCommandRegistry: {
6745
6748
  replace: "replace";
6746
6749
  append: "append";
6747
6750
  }>;
6748
- projectId: z$1.ZodString;
6749
- providerId: z$1.ZodString;
6750
6751
  instructions: z$1.ZodString;
6751
6752
  dynamicTools: z$1.ZodArray<z$1.ZodObject<{
6752
6753
  name: z$1.ZodString;
@@ -6822,7 +6823,6 @@ declare const hostDaemonCommandRegistry: {
6822
6823
  sourceRootPath: z$1.ZodString;
6823
6824
  skillFilePath: z$1.ZodString;
6824
6825
  }, z$1.core.$strict>], "kind">>;
6825
- providerThreadId: z$1.ZodString;
6826
6826
  }, z$1.core.$strict>;
6827
6827
  target: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
6828
6828
  mode: z$1.ZodLiteral<"start">;
@@ -6884,16 +6884,16 @@ declare const hostDaemonCommandRegistry: {
6884
6884
  permissionScope: z$1.ZodLiteral<"workspace">;
6885
6885
  approvalReviewer: z$1.ZodLiteral<"user">;
6886
6886
  permissionEscalation: z$1.ZodEnum<{
6887
- ask: "ask";
6888
6887
  deny: "deny";
6888
+ ask: "ask";
6889
6889
  }>;
6890
6890
  }, z$1.core.$strip>, z$1.ZodObject<{
6891
6891
  permissionMode: z$1.ZodLiteral<"auto">;
6892
6892
  permissionScope: z$1.ZodLiteral<"workspace">;
6893
6893
  approvalReviewer: z$1.ZodLiteral<"automatic">;
6894
6894
  permissionEscalation: z$1.ZodEnum<{
6895
- ask: "ask";
6896
6895
  deny: "deny";
6896
+ ask: "ask";
6897
6897
  }>;
6898
6898
  }, z$1.core.$strip>, z$1.ZodObject<{
6899
6899
  permissionMode: z$1.ZodLiteral<"full">;
@@ -6912,8 +6912,8 @@ declare const hostDaemonCommandRegistry: {
6912
6912
  providerInstallation: z$1.ZodBoolean;
6913
6913
  supportsServiceTier: z$1.ZodBoolean;
6914
6914
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6915
- "accept-edits": "accept-edits";
6916
6915
  auto: "auto";
6916
+ "accept-edits": "accept-edits";
6917
6917
  full: "full";
6918
6918
  }>>;
6919
6919
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6931,6 +6931,9 @@ declare const hostDaemonCommandRegistry: {
6931
6931
  workspaceContext: z$1.ZodObject<{
6932
6932
  workspacePath: z$1.ZodString;
6933
6933
  }, z$1.core.$strip>;
6934
+ projectId: z$1.ZodString;
6935
+ providerThreadId: z$1.ZodString;
6936
+ providerId: z$1.ZodString;
6934
6937
  bridgeLaunch: z$1.ZodObject<{
6935
6938
  pluginId: z$1.ZodString;
6936
6939
  source: z$1.ZodObject<{
@@ -6942,8 +6945,8 @@ declare const hostDaemonCommandRegistry: {
6942
6945
  providerInstallation: z$1.ZodBoolean;
6943
6946
  supportsServiceTier: z$1.ZodBoolean;
6944
6947
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
6945
- "accept-edits": "accept-edits";
6946
6948
  auto: "auto";
6949
+ "accept-edits": "accept-edits";
6947
6950
  full: "full";
6948
6951
  }>>;
6949
6952
  supportsThreadArchive: z$1.ZodBoolean;
@@ -6961,8 +6964,6 @@ declare const hostDaemonCommandRegistry: {
6961
6964
  replace: "replace";
6962
6965
  append: "append";
6963
6966
  }>;
6964
- projectId: z$1.ZodString;
6965
- providerId: z$1.ZodString;
6966
6967
  instructions: z$1.ZodString;
6967
6968
  dynamicTools: z$1.ZodArray<z$1.ZodObject<{
6968
6969
  name: z$1.ZodString;
@@ -7038,7 +7039,6 @@ declare const hostDaemonCommandRegistry: {
7038
7039
  sourceRootPath: z$1.ZodString;
7039
7040
  skillFilePath: z$1.ZodString;
7040
7041
  }, z$1.core.$strict>], "kind">>;
7041
- providerThreadId: z$1.ZodString;
7042
7042
  }, z$1.core.$strict>;
7043
7043
  }, z$1.core.$strict>, z$1.ZodObject<{
7044
7044
  cleared: z$1.ZodBoolean;
@@ -7077,8 +7077,8 @@ declare const hostDaemonCommandRegistry: {
7077
7077
  providerInstallation: z$1.ZodBoolean;
7078
7078
  supportsServiceTier: z$1.ZodBoolean;
7079
7079
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
7080
- "accept-edits": "accept-edits";
7081
7080
  auto: "auto";
7081
+ "accept-edits": "accept-edits";
7082
7082
  full: "full";
7083
7083
  }>>;
7084
7084
  supportsThreadArchive: z$1.ZodBoolean;
@@ -7110,8 +7110,8 @@ declare const hostDaemonCommandRegistry: {
7110
7110
  providerInstallation: z$1.ZodBoolean;
7111
7111
  supportsServiceTier: z$1.ZodBoolean;
7112
7112
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
7113
- "accept-edits": "accept-edits";
7114
7113
  auto: "auto";
7114
+ "accept-edits": "accept-edits";
7115
7115
  full: "full";
7116
7116
  }>>;
7117
7117
  supportsThreadArchive: z$1.ZodBoolean;
@@ -7493,8 +7493,8 @@ declare const hostDaemonCommandRegistry: {
7493
7493
  skills: z$1.ZodArray<z$1.ZodObject<{
7494
7494
  path: z$1.ZodString;
7495
7495
  origin: z$1.ZodEnum<{
7496
- project: "project";
7497
7496
  user: "user";
7497
+ project: "project";
7498
7498
  }>;
7499
7499
  recursive: z$1.ZodBoolean;
7500
7500
  ancestors: z$1.ZodBoolean;
@@ -7512,8 +7512,8 @@ declare const hostDaemonCommandRegistry: {
7512
7512
  commands: z$1.ZodArray<z$1.ZodObject<{
7513
7513
  path: z$1.ZodString;
7514
7514
  origin: z$1.ZodEnum<{
7515
- project: "project";
7516
7515
  user: "user";
7516
+ project: "project";
7517
7517
  }>;
7518
7518
  recursive: z$1.ZodBoolean;
7519
7519
  ancestors: z$1.ZodBoolean;
@@ -7538,8 +7538,8 @@ declare const hostDaemonCommandRegistry: {
7538
7538
  skill: "skill";
7539
7539
  }>;
7540
7540
  origin: z$1.ZodEnum<{
7541
- project: "project";
7542
7541
  user: "user";
7542
+ project: "project";
7543
7543
  }>;
7544
7544
  description: z$1.ZodNullable<z$1.ZodString>;
7545
7545
  argumentHint: z$1.ZodNullable<z$1.ZodString>;
@@ -7586,8 +7586,8 @@ declare const hostDaemonCommandRegistry: {
7586
7586
  skills: z$1.ZodArray<z$1.ZodObject<{
7587
7587
  path: z$1.ZodString;
7588
7588
  origin: z$1.ZodEnum<{
7589
- project: "project";
7590
7589
  user: "user";
7590
+ project: "project";
7591
7591
  }>;
7592
7592
  recursive: z$1.ZodBoolean;
7593
7593
  ancestors: z$1.ZodBoolean;
@@ -7605,8 +7605,8 @@ declare const hostDaemonCommandRegistry: {
7605
7605
  commands: z$1.ZodArray<z$1.ZodObject<{
7606
7606
  path: z$1.ZodString;
7607
7607
  origin: z$1.ZodEnum<{
7608
- project: "project";
7609
7608
  user: "user";
7609
+ project: "project";
7610
7610
  }>;
7611
7611
  recursive: z$1.ZodBoolean;
7612
7612
  ancestors: z$1.ZodBoolean;
@@ -7632,14 +7632,14 @@ declare const hostDaemonCommandRegistry: {
7632
7632
  realPath: z$1.ZodString;
7633
7633
  contentSha256: z$1.ZodString;
7634
7634
  rootKind: z$1.ZodEnum<{
7635
+ plugin: "plugin";
7635
7636
  "shared-user": "shared-user";
7636
7637
  "shared-project": "shared-project";
7637
- plugin: "plugin";
7638
7638
  "bb-project": "bb-project";
7639
- "provider-user": "provider-user";
7640
- "provider-project": "provider-project";
7641
7639
  "bb-data-dir": "bb-data-dir";
7642
7640
  "bb-builtin": "bb-builtin";
7641
+ "provider-project": "provider-project";
7642
+ "provider-user": "provider-user";
7643
7643
  }>;
7644
7644
  linked: z$1.ZodBoolean;
7645
7645
  }, z$1.core.$strip>>;
@@ -7693,14 +7693,14 @@ declare const hostDaemonCommandRegistry: {
7693
7693
  realPath: z$1.ZodString;
7694
7694
  contentSha256: z$1.ZodString;
7695
7695
  rootKind: z$1.ZodEnum<{
7696
+ plugin: "plugin";
7696
7697
  "shared-user": "shared-user";
7697
7698
  "shared-project": "shared-project";
7698
- plugin: "plugin";
7699
7699
  "bb-project": "bb-project";
7700
- "provider-user": "provider-user";
7701
- "provider-project": "provider-project";
7702
7700
  "bb-data-dir": "bb-data-dir";
7703
7701
  "bb-builtin": "bb-builtin";
7702
+ "provider-project": "provider-project";
7703
+ "provider-user": "provider-user";
7704
7704
  }>;
7705
7705
  linked: z$1.ZodBoolean;
7706
7706
  }, z$1.core.$strip>>;
@@ -7708,10 +7708,10 @@ declare const hostDaemonCommandRegistry: {
7708
7708
  "host.delete_skill": HostDaemonCommandDescriptor<"host.delete_skill", z$1.ZodObject<{
7709
7709
  type: z$1.ZodLiteral<"host.delete_skill">;
7710
7710
  scope: z$1.ZodEnum<{
7711
- "bb-user": "bb-user";
7712
7711
  "bb-project": "bb-project";
7713
- "provider-user": "provider-user";
7714
7712
  "provider-project": "provider-project";
7713
+ "provider-user": "provider-user";
7714
+ "bb-user": "bb-user";
7715
7715
  }>;
7716
7716
  name: z$1.ZodString;
7717
7717
  cwd: z$1.ZodNullable<z$1.ZodString>;
@@ -7722,8 +7722,8 @@ declare const hostDaemonCommandRegistry: {
7722
7722
  "host.write_skill": HostDaemonCommandDescriptor<"host.write_skill", z$1.ZodObject<{
7723
7723
  type: z$1.ZodLiteral<"host.write_skill">;
7724
7724
  scope: z$1.ZodEnum<{
7725
- "bb-user": "bb-user";
7726
7725
  "bb-project": "bb-project";
7726
+ "bb-user": "bb-user";
7727
7727
  }>;
7728
7728
  name: z$1.ZodString;
7729
7729
  cwd: z$1.ZodNullable<z$1.ZodString>;
@@ -7820,8 +7820,8 @@ declare const hostDaemonCommandRegistry: {
7820
7820
  selectedBranch: z$1.ZodOptional<z$1.ZodString>;
7821
7821
  limit: z$1.ZodNumber;
7822
7822
  remoteRefresh: z$1.ZodEnum<{
7823
- none: "none";
7824
7823
  background: "background";
7824
+ none: "none";
7825
7825
  }>;
7826
7826
  }, z$1.core.$strict>, z$1.ZodObject<{
7827
7827
  branches: z$1.ZodArray<z$1.ZodString>;
@@ -7865,9 +7865,9 @@ declare const hostDaemonCommandRegistry: {
7865
7865
  base64: "base64";
7866
7866
  utf8: "utf8";
7867
7867
  }>;
7868
- mimeType: z$1.ZodOptional<z$1.ZodString>;
7869
- sizeBytes: z$1.ZodNumber;
7870
7868
  sha256: z$1.ZodString;
7869
+ sizeBytes: z$1.ZodNumber;
7870
+ mimeType: z$1.ZodOptional<z$1.ZodString>;
7871
7871
  modifiedAtMs: z$1.ZodOptional<z$1.ZodNumber>;
7872
7872
  notModified: z$1.ZodLiteral<true>;
7873
7873
  }, z$1.core.$strip>]>, "onlineRpc", true>;
@@ -7942,8 +7942,8 @@ declare const hostDaemonCommandRegistry: {
7942
7942
  providerInstallation: z$1.ZodBoolean;
7943
7943
  supportsServiceTier: z$1.ZodBoolean;
7944
7944
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
7945
- "accept-edits": "accept-edits";
7946
7945
  auto: "auto";
7946
+ "accept-edits": "accept-edits";
7947
7947
  full: "full";
7948
7948
  }>>;
7949
7949
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8072,8 +8072,8 @@ declare const hostDaemonCommandRegistry: {
8072
8072
  providerInstallation: z$1.ZodBoolean;
8073
8073
  supportsServiceTier: z$1.ZodBoolean;
8074
8074
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
8075
- "accept-edits": "accept-edits";
8076
8075
  auto: "auto";
8076
+ "accept-edits": "accept-edits";
8077
8077
  full: "full";
8078
8078
  }>>;
8079
8079
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8109,8 +8109,8 @@ declare const hostDaemonCommandRegistry: {
8109
8109
  providerInstallation: z$1.ZodBoolean;
8110
8110
  supportsServiceTier: z$1.ZodBoolean;
8111
8111
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
8112
- "accept-edits": "accept-edits";
8113
8112
  auto: "auto";
8113
+ "accept-edits": "accept-edits";
8114
8114
  full: "full";
8115
8115
  }>>;
8116
8116
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8132,10 +8132,10 @@ declare const hostDaemonCommandRegistry: {
8132
8132
  health: z$1.ZodObject<{
8133
8133
  status: z$1.ZodEnum<{
8134
8134
  unknown: "unknown";
8135
+ ready: "ready";
8135
8136
  not_installed: "not_installed";
8136
8137
  unauthenticated: "unauthenticated";
8137
8138
  expired: "expired";
8138
- ready: "ready";
8139
8139
  unsupported_version: "unsupported_version";
8140
8140
  }>;
8141
8141
  statusMessage: z$1.ZodNullable<z$1.ZodString>;
@@ -8163,8 +8163,8 @@ declare const hostDaemonCommandRegistry: {
8163
8163
  providerInstallation: z$1.ZodBoolean;
8164
8164
  supportsServiceTier: z$1.ZodBoolean;
8165
8165
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
8166
- "accept-edits": "accept-edits";
8167
8166
  auto: "auto";
8167
+ "accept-edits": "accept-edits";
8168
8168
  full: "full";
8169
8169
  }>>;
8170
8170
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8224,8 +8224,8 @@ declare const hostDaemonCommandRegistry: {
8224
8224
  providerInstallation: z$1.ZodBoolean;
8225
8225
  supportsServiceTier: z$1.ZodBoolean;
8226
8226
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
8227
- "accept-edits": "accept-edits";
8228
8227
  auto: "auto";
8228
+ "accept-edits": "accept-edits";
8229
8229
  full: "full";
8230
8230
  }>>;
8231
8231
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8278,8 +8278,8 @@ declare const hostDaemonCommandRegistry: {
8278
8278
  providerInstallation: z$1.ZodBoolean;
8279
8279
  supportsServiceTier: z$1.ZodBoolean;
8280
8280
  permissionModes: z$1.ZodArray<z$1.ZodEnum<{
8281
- "accept-edits": "accept-edits";
8282
8281
  auto: "auto";
8282
+ "accept-edits": "accept-edits";
8283
8283
  full: "full";
8284
8284
  }>>;
8285
8285
  supportsThreadArchive: z$1.ZodBoolean;
@@ -8631,8 +8631,8 @@ declare const hostDaemonCommandRegistry: {
8631
8631
  message: z$1.ZodNullable<z$1.ZodString>;
8632
8632
  state: z$1.ZodNullable<z$1.ZodEnum<{
8633
8633
  pending: "pending";
8634
- ready: "ready";
8635
8634
  activating: "activating";
8635
+ ready: "ready";
8636
8636
  }>>;
8637
8637
  }, z$1.core.$strict>, "onlineRpc", true>;
8638
8638
  "server_move.prepare": HostDaemonCommandDescriptor<"server_move.prepare", z$1.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@halcyonlabs/app",
3
- "version": "0.47.0-halcyon.325",
3
+ "version": "0.47.0-halcyon.326",
4
4
  "description": "bb app launcher for npx",
5
5
  "keywords": [
6
6
  "bb",
@@ -1 +1 @@
1
- 8ff74541b7680e1d97a352a75ea8603420001081
1
+ 10f5c81216e5bf74f0946d078047db4b55c47f59
@@ -10,3 +10,16 @@ export declare function workflowSteps(text: string): Step[];
10
10
  export declare function derivedChecks(top: string): { setup: Step[]; checks: Step[]; skipped: string[] };
11
11
  export declare function rebuildableFolders(top: string): { job: string; folders: string[] } | null;
12
12
  export declare function declareRebuildable(top: string): string[];
13
+
14
+ export declare function releaseSourceSnapshot(top: string): boolean;
15
+ export declare function requireSingleCheckout(top: string, checkOutput?: string[]): void;
16
+ export declare function buildEnvironment(top: string, env?: Record<string, string | undefined>, exchange?: string): Record<string, string | undefined>;
17
+ export declare function cleanupBuildOutputs(top: string, keep?: string[]): string[];
18
+
19
+ export type CheckOutput = { current: string; folders: string[] };
20
+ export declare function prepareCheckOutput(top: string): CheckOutput | null;
21
+ export declare function cleanupCheckOutput(top: string, context: CheckOutput | null, keep?: string[]): string[];
22
+
23
+ export declare function runAll(top: string, steps: (Step & { setup?: boolean })[], log: string, context?: CheckOutput | null, environment?: Record<string, string | undefined>): { ok: boolean; skipped: boolean; status: number | string | null; command: string }[];
24
+
25
+ export declare function activeBuildLease(env: Record<string, string | undefined>, queue?: string): boolean;
@@ -1,9 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawnSync } from "node:child_process";
4
- import { appendFileSync, existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ import {
5
+ appendFileSync,
6
+ closeSync,
7
+ constants,
8
+ existsSync,
9
+ fstatSync,
10
+ lstatSync,
11
+ mkdirSync,
12
+ mkdtempSync,
13
+ openSync,
14
+ readdirSync,
15
+ readFileSync,
16
+ readSync,
17
+ realpathSync,
18
+ rmSync,
19
+ writeFileSync,
20
+ } from "node:fs";
5
21
  import { tmpdir } from "node:os";
6
- import { dirname, join, relative, resolve } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+ import { basename, dirname, join, relative, resolve } from "node:path";
7
24
 
8
25
  const USAGE = `usage: pre-push.mjs [--repo <dir>] [--base <ref>] [--list] [--log <file>]
9
26
 
@@ -16,7 +33,8 @@ Exit status: 0 every check passed, 1 a check failed, 2 the checks could not be
16
33
  worked out (the reason is printed), 3 the repository declares and runs no checks.
17
34
  A check that exits 78 does not apply on this machine: it is listed as not run.`;
18
35
 
19
- const CHECK = /\b(?:test|tests|lint|typecheck|type-check|check|clippy|fmt|format|vet|pytest|unittest|tox|ruff|mypy|eslint|biome|prettier|tsc|golangci-lint|rspec|phpunit|ctest)\b/;
36
+ const CHECK =
37
+ /\b(?:test|tests|lint|typecheck|type-check|check|clippy|fmt|format|vet|pytest|unittest|tox|ruff|mypy|eslint|biome|prettier|tsc|golangci-lint|rspec|phpunit|ctest)\b/;
20
38
  const UNSUITED =
21
39
  /\$\{\{|\bsudo\b|\bapt(?:-get)?\b|\bbrew\b|\bdocker\b|\bdeploy|\bpublish|\brelease\b|\bupload|\bgh\s|\bcurl\b|\bwget\b|\bsecrets?\b|\bGITHUB_|\bgit\s+push\b|\b(?:npm|pnpm|yarn|pip|cargo|go)\s+(?:ci|install|fetch|get)\b/i;
22
40
  const SCRIPTS = ["lint", "typecheck", "type-check", "check", "test"];
@@ -62,7 +80,9 @@ export function glob(pattern) {
62
80
  const full = pattern.endsWith("/") ? `${pattern}**` : pattern;
63
81
  const body = full
64
82
  .split(/(\*\*\/|\*\*|\*|\?)/)
65
- .map((part) => (part === "**/" ? "(?:.*/)?" : part === "**" ? ".*" : part === "*" ? "[^/]*" : part === "?" ? "[^/]" : part.replace(/[.+^${}()|[\]\\]/g, "\\$&")))
83
+ .map((part) =>
84
+ part === "**/" ? "(?:.*/)?" : part === "**" ? ".*" : part === "*" ? "[^/]*" : part === "?" ? "[^/]" : part.replace(/[.+^${}()|[\]\\]/g, "\\$&"),
85
+ )
66
86
  .join("");
67
87
  return new RegExp(`^${body}$`);
68
88
  }
@@ -88,7 +108,11 @@ export function selectDeclared(declared, changed) {
88
108
  const checks = declared.checks
89
109
  .map((check, i) => ({ ...check, files: check.always ? [] : changed.filter((file) => matchers[i].some((re) => re.test(file))) }))
90
110
  .filter((check) => check.always || check.files.length > 0)
91
- .map((check) => ({ command: check.command, cwd: ".", why: check.always ? `always (${check.source})` : `${check.files.length} changed under ${check.patterns.join(" ")} (${check.source})` }));
111
+ .map((check) => ({
112
+ command: check.command,
113
+ cwd: ".",
114
+ why: check.always ? `always (${check.source})` : `${check.files.length} changed under ${check.patterns.join(" ")} (${check.source})`,
115
+ }));
92
116
  const uncovered = changed.filter((file) => !matchers.some((list) => list.some((re) => re.test(file))));
93
117
  const setup = checks.length > 0 ? declared.setup.map((s) => ({ command: s.command, cwd: ".", why: `setup (${s.source})` })) : [];
94
118
  return { setup, checks, uncovered };
@@ -159,7 +183,11 @@ export function derivedChecks(top) {
159
183
  const ciSteps = [];
160
184
  const skipped = [];
161
185
  const folder = join(top, ".github", "workflows");
162
- const files = existsSync(folder) ? readdirSync(folder).filter((f) => /\.ya?ml$/.test(f)).sort() : [];
186
+ const files = existsSync(folder)
187
+ ? readdirSync(folder)
188
+ .filter((f) => /\.ya?ml$/.test(f))
189
+ .sort()
190
+ : [];
163
191
  for (const file of files) {
164
192
  const text = readFileSync(join(folder, file), "utf8");
165
193
  if (!triggersOnChanges(text)) continue;
@@ -182,7 +210,8 @@ export function derivedChecks(top) {
182
210
  if (existsSync(join(top, "go.mod"))) checks.push({ command: "go test ./...", cwd: ".", why: "go.mod" });
183
211
  if (existsSync(join(top, "Makefile"))) {
184
212
  const make = readFileSync(join(top, "Makefile"), "utf8");
185
- for (const target of ["check", "test"]) if (new RegExp(`^${target}:`, "m").test(make)) checks.push({ command: `make ${target}`, cwd: ".", why: "Makefile" });
213
+ for (const target of ["check", "test"])
214
+ if (new RegExp(`^${target}:`, "m").test(make)) checks.push({ command: `make ${target}`, cwd: ".", why: "Makefile" });
186
215
  }
187
216
  return { setup: checks.length > 0 ? setup : [], checks, skipped };
188
217
  }
@@ -198,7 +227,9 @@ function packageManager(top) {
198
227
  function plan(top, base) {
199
228
  const changes = must(top, "status", "--porcelain=v1", "--untracked-files=no");
200
229
  if (changes.trim()) throw new Refusal(`commit first: the checks must run on what you push, and these tracked files have changes:\n${changes.trimEnd()}`);
201
- const untracked = must(top, "ls-files", "--others", "--exclude-standard", "-z").split("\0").filter((f) => f && !f.startsWith(".orbit-build/"));
230
+ const untracked = must(top, "ls-files", "--others", "--exclude-standard", "-z")
231
+ .split("\0")
232
+ .filter((f) => f && !f.startsWith(".orbit-build/"));
202
233
  if (!git(top, "rev-parse", "-q", "--verify", `${base}^{commit}`).ok) throw new Refusal(`${base} is not a commit here: fetch it, or pass --base <ref>`);
203
234
  const mergeBase = git(top, "merge-base", base, "HEAD");
204
235
  if (!mergeBase.ok) throw new Refusal(`the branch and ${base} share no history here (a depth-limited clone?): fetch more history, or pass --base <ref>`);
@@ -215,12 +246,20 @@ function plan(top, base) {
215
246
  return { kind: "derived", changed, untracked, uncovered: [], ...derivedChecks(top) };
216
247
  }
217
248
 
218
- function runAll(top, steps, log) {
249
+ export function runAll(top, steps, log, context, environment = process.env.BB_THREAD_ID ? buildEnvironment(top) : { ...process.env }) {
219
250
  const results = [];
251
+ if (context) environment.TMPDIR = context.current;
252
+ const covered = process.platform === "linux" && activeBuildLease(environment);
253
+ const inherited = covered ? Number(environment.ORBIT_BUILD_LEASE.split(":")[0]) : null;
254
+ const stdio =
255
+ inherited === null ? "pipe" : Array.from({ length: inherited + 1 }, (_, index) => (index < 3 ? "pipe" : index === inherited ? index : "ignore"));
220
256
  for (const step of steps) {
221
257
  const started = Date.now();
222
258
  appendFileSync(log, `\n$ (cd ${step.cwd}) ${step.command}\n`);
223
- const result = spawnSync("bash", ["-c", step.command], { cwd: resolve(top, step.cwd), encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
259
+ const queued = process.platform === "linux" && environment.BB_THREAD_ID && !covered && existsSync("/usr/local/orbit/bin/orbit-build");
260
+ const program = queued ? "/usr/local/orbit/bin/orbit-build" : "bash";
261
+ const args = queued ? ["--", "/bin/bash", "-c", step.command] : ["-c", step.command];
262
+ const result = spawnSync(program, args, { cwd: resolve(top, step.cwd), env: environment, stdio, encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
224
263
  const output = `${result.stdout ?? ""}${result.stderr ?? ""}${result.error ? `${result.error.message}\n` : ""}`;
225
264
  appendFileSync(log, output);
226
265
  const seconds = Math.round((Date.now() - started) / 1000);
@@ -231,14 +270,22 @@ function runAll(top, steps, log) {
231
270
  return results;
232
271
  }
233
272
 
234
- const BUILD_CACHES = ["cargo-target", "cargo-home/registry", "cargo-home/git", "pnpm-store", "npm-cache", "tmp", "cache"];
273
+ const BUILD_CACHES = [
274
+ "cargo-target",
275
+ "cargo-home/registry",
276
+ "cargo-home/git",
277
+ "pnpm-store",
278
+ "npm-cache",
279
+ "tmp",
280
+ "cache",
281
+ "rustup",
282
+ "rustup-home",
283
+ "home/.rustup",
284
+ ];
235
285
 
236
286
  export function rebuildableFolders(top) {
237
- let job = dirname(top);
238
- while (!existsSync(join(job, ".orbit-outputs.json")) && !existsSync(join(job, ".bb-env-setup.sh"))) {
239
- if (dirname(job) === job) return null;
240
- job = dirname(job);
241
- }
287
+ const job = jobRoot(top);
288
+ if (!job) return null;
242
289
  const checkout = relative(job, top);
243
290
  if (checkout === "" || checkout.startsWith("..")) return null;
244
291
  const tracked = spawnSync("git", ["ls-files", "-z", "--", "*package.json", "*Cargo.toml"], { cwd: top, encoding: "utf8" });
@@ -246,22 +293,274 @@ export function rebuildableFolders(top) {
246
293
  for (const file of (tracked.stdout ?? "").split("\0").filter(Boolean)) dirs.add(dirname(file) === "." ? "" : dirname(file));
247
294
  const folders = new Set(BUILD_CACHES.map((name) => join(checkout, ".orbit-build", name)));
248
295
  for (const dir of dirs) {
249
- folders.add(join(checkout, dir, "node_modules"));
250
- folders.add(join(checkout, dir, "target"));
296
+ for (const output of PACKAGE_OUTPUTS) folders.add(join(checkout, dir, output));
251
297
  }
252
- return { job, folders: [...folders].filter((folder) => existsSync(join(job, folder))).sort() };
298
+ for (const output of ["packages/templates/src/generated", "packages/plugin-build/src/generated"]) folders.add(join(checkout, output));
299
+ const sourceFiles = must(top, "ls-files", "-z")
300
+ .split("\0")
301
+ .filter(Boolean)
302
+ .map((file) => join(checkout, file));
303
+ return {
304
+ job,
305
+ folders: [...folders]
306
+ .filter((folder) => existsSync(join(job, folder)) && !sourceFiles.some((file) => file === folder || file.startsWith(`${folder}/`)))
307
+ .sort(),
308
+ };
253
309
  }
254
310
 
255
311
  export function declareRebuildable(top) {
256
312
  const found = rebuildableFolders(top);
257
313
  if (!found) return [];
258
314
  const list = join(found.job, ".orbit-rebuildable");
259
- const known = new Set(existsSync(list) ? readFileSync(list, "utf8").split("\n").filter(Boolean) : []);
315
+ const known = new Set((metadataText(list) ?? "").split("\n").filter(Boolean));
260
316
  const added = found.folders.filter((folder) => !known.has(folder));
261
- if (added.length > 0) appendFileSync(list, `${added.join("\n")}\n`);
317
+ if (added.length > 0) {
318
+ const fd = openSync(list, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW | constants.O_NONBLOCK, 0o600);
319
+ try {
320
+ const info = fstatSync(fd);
321
+ if (!info.isFile() || info.nlink !== 1 || info.uid !== process.getuid()) throw new Refusal("rebuildable output metadata must stay inside this job");
322
+ appendFileSync(fd, `${added.join("\n")}\n`);
323
+ } finally {
324
+ closeSync(fd);
325
+ }
326
+ }
262
327
  return added;
263
328
  }
264
329
 
330
+ function jobRoot(top) {
331
+ let job = dirname(top);
332
+ while (!existsSync(join(job, ".orbit-outputs.json")) && !existsSync(join(job, ".bb-env-setup.sh"))) {
333
+ if (dirname(job) === job) return null;
334
+ job = dirname(job);
335
+ }
336
+ return job;
337
+ }
338
+
339
+ function safeLocalPath(root, path) {
340
+ const parts = relative(root, path).split(/[\\/]/);
341
+ if (parts.some((part) => part === ".." || part === "")) return false;
342
+ let current = root;
343
+ for (const part of parts) {
344
+ current = join(current, part);
345
+ if (existsSync(current) && lstatSync(current).isSymbolicLink()) return false;
346
+ }
347
+ return true;
348
+ }
349
+
350
+ export function releaseSourceSnapshot(top) {
351
+ const job = jobRoot(top);
352
+ if (!job) return false;
353
+ const origin = git(top, "remote", "get-url", "origin");
354
+ if (!origin.ok || !origin.out.trim().startsWith("file://")) return false;
355
+ const source = fileURLToPath(origin.out.trim());
356
+ const name = relative(top, source).replaceAll("\\", "/");
357
+ if (!/^\.orbit-build\/tmp\/upstream(?:-[0-9]+)?\/repo\.git$/.test(name) || !safeLocalPath(job, source)) return false;
358
+ const sourceHead = git(source, "rev-parse", "HEAD");
359
+ const base = git(top, "rev-parse", defaultBase(top));
360
+ const refs = git(source, "for-each-ref", "--format=%(objectname) %(refname)");
361
+ if (!sourceHead.ok || !base.ok || sourceHead.out !== base.out || !refs.ok) return false;
362
+ const records = refs.out.trim().split("\n").filter(Boolean);
363
+ if (records.length !== 1 || !records[0].startsWith(`${base.out.trim()} refs/heads/`)) return false;
364
+ if (git(source, "rev-parse", "--is-bare-repository").out.trim() !== "true") return false;
365
+ const unreachable = git(source, "fsck", "--no-reflogs", "--unreachable");
366
+ if (!unreachable.ok || unreachable.out.trim()) return false;
367
+ rmSync(dirname(source), { recursive: true });
368
+ return true;
369
+ }
370
+
371
+ const PACKAGE_OUTPUTS = ["node_modules", "target", "dist", "build", "bundled-types", ".turbo"];
372
+ const SCAN_CACHES = new Set([...PACKAGE_OUTPUTS, ".git", "cargo-home", "cargo-target", "pnpm-store", "npm-cache", "cache", "home", "rustup", "rustup-home"]);
373
+
374
+ export function requireSingleCheckout(top, checkOutput = []) {
375
+ const job = jobRoot(top);
376
+ if (!job) return;
377
+ const pending = [job];
378
+ while (pending.length) {
379
+ const directory = pending.pop();
380
+ if (checkOutput.includes(directory)) continue;
381
+ if (directory !== top) {
382
+ const metadata = join(directory, ".git");
383
+ const worktree = existsSync(metadata) && (lstatSync(metadata).isFile() || existsSync(join(metadata, "HEAD")));
384
+ const bare = existsSync(join(directory, "HEAD")) && existsSync(join(directory, "objects")) && existsSync(join(directory, "config"));
385
+ if (worktree || bare)
386
+ throw new Refusal(
387
+ `another checkout is kept at ${relative(job, directory)}; save its unpublished work and remove that extra copy before installing or building`,
388
+ );
389
+ }
390
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
391
+ if (entry.isDirectory() && !SCAN_CACHES.has(entry.name)) pending.push(join(directory, entry.name));
392
+ }
393
+ }
394
+ }
395
+
396
+ export function buildEnvironment(
397
+ top,
398
+ env = process.env,
399
+ exchange = process.platform === "darwin" ? "/private/var/db/orbit/exchange/github/in" : "/var/db/orbit/exchange/github/in",
400
+ ) {
401
+ if (!jobRoot(top) || !existsSync(exchange)) return { ...env };
402
+ const store = join(realpathSync(exchange), ".pnpm-store");
403
+ try {
404
+ mkdirSync(store, { mode: 0o700 });
405
+ } catch (error) {
406
+ if (error.code !== "EEXIST") throw error;
407
+ }
408
+ const info = lstatSync(store);
409
+ if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== process.getuid() || (info.mode & 0o077) !== 0)
410
+ throw new Refusal("the station package store must be a private directory owned by this account");
411
+ return {
412
+ ...env,
413
+ npm_config_store_dir: store,
414
+ npm_config_package_import_method: "hardlink",
415
+ npm_config_verify_store_integrity: "true",
416
+ npm_config_side_effects_cache: "false",
417
+ };
418
+ }
419
+
420
+ function metadataText(path) {
421
+ let descriptor;
422
+ try {
423
+ descriptor = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
424
+ } catch (error) {
425
+ if (error.code === "ENOENT") return null;
426
+ throw new Refusal("work output metadata must be a private regular file inside this job");
427
+ }
428
+ try {
429
+ const info = fstatSync(descriptor);
430
+ if (!info.isFile() || info.nlink !== 1 || info.uid !== process.getuid())
431
+ throw new Refusal("work output metadata must be a private regular file inside this job");
432
+ return readFileSync(descriptor, "utf8");
433
+ } finally {
434
+ closeSync(descriptor);
435
+ }
436
+ }
437
+
438
+ export function cleanupBuildOutputs(top, keep = []) {
439
+ const found = rebuildableFolders(top);
440
+ if (!found) return [];
441
+ const declaration = join(found.job, ".orbit-outputs.json");
442
+ const text = metadataText(declaration);
443
+ let declared;
444
+ try {
445
+ declared = text === null ? [] : JSON.parse(text);
446
+ } catch {
447
+ throw new Refusal("declare result files as a JSON list before cleaning build output");
448
+ }
449
+ if (!Array.isArray(declared) || declared.some((name) => typeof name !== "string"))
450
+ throw new Refusal("declare result files as a JSON list before cleaning build output");
451
+ const protectedFiles = [...declared.map((name) => resolve(found.job, name)), ...keep.map((name) => resolve(name))];
452
+ const tracked = must(top, "ls-files", "-z")
453
+ .split("\0")
454
+ .filter(Boolean)
455
+ .map((name) => join(top, name));
456
+ const removed = [];
457
+ for (const folder of found.folders) {
458
+ const path = join(found.job, folder);
459
+ if (!existsSync(path) || !safeLocalPath(found.job, path)) continue;
460
+ const includes = (name) => name === path || name.startsWith(`${path}/`);
461
+ if (protectedFiles.some(includes) || tracked.some(includes)) continue;
462
+ rmSync(path, { recursive: true, force: true });
463
+ removed.push(folder);
464
+ }
465
+ return removed;
466
+ }
467
+
468
+ export function activeBuildLease(env, queue = "/var/db/orbit/exchange/github/in/.build-gate") {
469
+ if (env.ORBIT_BUILD_LEASE === undefined) return false;
470
+ const match = /^([0-9]+):([0-9]{20}\.lease)$/.exec(env.ORBIT_BUILD_LEASE);
471
+ if (!match || Number(match[1]) < 3 || !Number.isSafeInteger(Number(match[1])))
472
+ throw new Refusal("the inherited build lease is unreadable; run this check inside its original build");
473
+ let directory;
474
+ try {
475
+ directory = openSync(queue, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
476
+ const owner = fstatSync(directory);
477
+ if (owner.uid !== process.getuid() || (owner.mode & 0o077) !== 0) throw new Error("unsafe queue");
478
+ const held = fstatSync(Number(match[1]));
479
+ const reference = lstatSync(`/proc/self/fd/${directory}/${match[2]}`);
480
+ const state = Buffer.alloc(7);
481
+ if (
482
+ !held.isFile() ||
483
+ held.size !== 7 ||
484
+ held.nlink !== 1 ||
485
+ held.dev !== reference.dev ||
486
+ held.ino !== reference.ino ||
487
+ readSync(Number(match[1]), state, 0, 7, 0) !== 7 ||
488
+ state.toString() !== "running"
489
+ )
490
+ throw new Error("inactive lease");
491
+ return true;
492
+ } catch {
493
+ throw new Refusal("the inherited build lease was closed; run this check inside its original build");
494
+ } finally {
495
+ if (directory !== undefined) closeSync(directory);
496
+ }
497
+ }
498
+ function ownedCheckOutput(top, path) {
499
+ const job = jobRoot(top);
500
+ if (!job || dirname(path) !== join(job, "tmp") || !/^c[a-zA-Z0-9]{6}$/.test(basename(path))) return false;
501
+ const text = metadataText(join(path, ".orbit-check-output"));
502
+ if (text === null) return false;
503
+ let marker;
504
+ try {
505
+ marker = JSON.parse(text);
506
+ } catch {
507
+ throw new Refusal("temporary check output has unreadable ownership metadata");
508
+ }
509
+ if (
510
+ marker?.checkout !== top ||
511
+ typeof marker.head !== "string" ||
512
+ !/^[a-f0-9]{40}$/.test(marker.head) ||
513
+ !git(top, "cat-file", "-e", `${marker.head}^{commit}`).ok
514
+ )
515
+ throw new Refusal("temporary check output no longer matches this checkout; keep it until its work is saved");
516
+ return true;
517
+ }
518
+
519
+ export function prepareCheckOutput(top) {
520
+ const job = jobRoot(top);
521
+ if (!job) return null;
522
+ const temporary = join(job, "tmp");
523
+ if (!safeLocalPath(job, temporary)) throw new Refusal("the job's temporary output directory cannot be a link");
524
+ mkdirSync(temporary, { recursive: true, mode: 0o700 });
525
+ const folders = [];
526
+ for (const entry of readdirSync(temporary, { withFileTypes: true })) {
527
+ if (!entry.isDirectory() || !(entry.name.startsWith("c") && entry.name.length === 7)) continue;
528
+ const path = join(temporary, entry.name);
529
+ if (!ownedCheckOutput(top, path)) continue;
530
+ folders.push(path);
531
+ }
532
+ const current = mkdtempSync(join(temporary, "c"));
533
+ writeFileSync(join(current, ".orbit-check-output"), JSON.stringify({ checkout: top, head: must(top, "rev-parse", "HEAD").trim() }), {
534
+ mode: 0o600,
535
+ flag: "wx",
536
+ });
537
+ return { current, folders: [...folders, current] };
538
+ }
539
+
540
+ export function cleanupCheckOutput(top, context, keep = []) {
541
+ const job = jobRoot(top);
542
+ if (!job || context === null) return [];
543
+ const text = metadataText(join(job, ".orbit-outputs.json"));
544
+ let outputs;
545
+ try {
546
+ outputs = text === null ? [] : JSON.parse(text);
547
+ } catch {
548
+ throw new Refusal("declare result files as a JSON list before cleaning check output");
549
+ }
550
+ if (!Array.isArray(outputs) || outputs.some((name) => typeof name !== "string"))
551
+ throw new Refusal("declare result files as a JSON list before cleaning check output");
552
+ const protectedFiles = [...outputs.map((name) => resolve(job, name)), ...keep.map((name) => resolve(name))];
553
+ const removed = [];
554
+ for (const path of context.folders) {
555
+ if (!existsSync(path)) continue;
556
+ if (!safeLocalPath(job, path) || !ownedCheckOutput(top, path)) throw new Refusal("temporary check output changed; keep it until its work is saved");
557
+ if (protectedFiles.some((name) => name === path || name.startsWith(`${path}/`))) continue;
558
+ rmSync(path, { recursive: true });
559
+ removed.push(path);
560
+ }
561
+ return removed;
562
+ }
563
+
265
564
  function main() {
266
565
  let options;
267
566
  try {
@@ -278,28 +577,58 @@ function main() {
278
577
  for (const step of steps) console.log(` ${step.setup ? "setup" : "check"} ${step.command}${step.cwd === "." ? "" : ` (in ${step.cwd})`} [${step.why}]`);
279
578
  if (found.uncovered.length > 0) console.log(`not covered by a declared check: ${found.uncovered.join(", ")}`);
280
579
  if (found.skipped.length > 0) console.log(`CI steps not run here (they need CI's own setup); run what applies by hand:\n ${found.skipped.join("\n ")}`);
281
- if (found.untracked.length > 0) console.log(`untracked files, not part of the push: ${found.untracked.slice(0, 10).join(", ")}${found.untracked.length > 10 ? ", …" : ""}`);
580
+ if (found.untracked.length > 0)
581
+ console.log(`untracked files, not part of the push: ${found.untracked.slice(0, 10).join(", ")}${found.untracked.length > 10 ? ", …" : ""}`);
282
582
  if (found.checks.length === 0) {
283
583
  console.log("pre-push: NONE: the repository declares no pre-push check and its CI and package scripts run none. Say so in the pull request.");
284
584
  return 3;
285
585
  }
286
586
  if (options.list) return 0;
287
- const log = options.log ?? join(process.env.TMPDIR || tmpdir(), `pre-push-${new Date().toISOString().replace(/[:.]/g, "-")}.log`);
587
+ const context = process.env.BB_THREAD_ID ? prepareCheckOutput(top) : null;
588
+ if (process.env.BB_THREAD_ID) {
589
+ releaseSourceSnapshot(top);
590
+ requireSingleCheckout(top, context?.folders);
591
+ }
592
+ const logRoot = context ? join(jobRoot(top), "logs") : process.env.TMPDIR || tmpdir();
593
+ if (context && !safeLocalPath(jobRoot(top), logRoot)) throw new Refusal("the job check log directory cannot be a link");
594
+ mkdirSync(logRoot, { recursive: true, mode: 0o700 });
595
+ const log = options.log ?? join(logRoot, `pre-push-${new Date().toISOString().replace(/[:.]/g, "-")}.log`);
288
596
  writeFileSync(log, `pre-push against ${base} at ${must(top, "rev-parse", "HEAD").trim()}\n`);
289
- const results = runAll(top, steps, log);
597
+ const results = runAll(top, steps, log, context);
290
598
  for (const r of results) {
291
599
  const reason = r.skipped ? r.output.trim().split("\n").at(-1) || "does not apply here" : null;
292
- console.log(`${r.skipped ? "skip" : r.ok ? "pass" : "FAIL"} ${r.command} (${reason ?? (r.ok ? "" : `exit ${r.status}, `)}${reason ? "" : `${r.seconds}s`})`);
293
- if (!r.ok) console.log(r.output.trimEnd().split("\n").slice(-TAIL).map((l) => ` ${l}`).join("\n"));
600
+ console.log(
601
+ `${r.skipped ? "skip" : r.ok ? "pass" : "FAIL"} ${r.command} (${reason ?? (r.ok ? "" : `exit ${r.status}, `)}${reason ? "" : `${r.seconds}s`})`,
602
+ );
603
+ if (!r.ok)
604
+ console.log(
605
+ r.output
606
+ .trimEnd()
607
+ .split("\n")
608
+ .slice(-TAIL)
609
+ .map((l) => ` ${l}`)
610
+ .join("\n"),
611
+ );
294
612
  }
295
613
  const failed = results.filter((r) => !r.ok);
296
614
  const setupFailed = failed.some((r) => r.setup);
297
615
  if (failed.length > 0) {
298
- console.log(`pre-push: FAIL (${setupFailed ? "setup failed, so no check ran" : `${failed.length} of ${found.checks.length} checks failed`}). Full output: ${log}`);
616
+ console.log(
617
+ `pre-push: FAIL (${setupFailed ? "setup failed, so no check ran" : `${failed.length} of ${found.checks.length} checks failed`}). Full output: ${log}`,
618
+ );
299
619
  return 1;
300
620
  }
621
+ if (process.env.BB_THREAD_ID) {
622
+ cleanupCheckOutput(top, context, [log]);
623
+ requireSingleCheckout(top, context?.folders);
624
+ declareRebuildable(top);
625
+ const removed = cleanupBuildOutputs(top, [log]);
626
+ console.log(`pre-push: removed ${removed.length} install and build output folders after passing checks.`);
627
+ }
301
628
  const notRun = results.filter((r) => r.skipped).length;
302
- console.log(`pre-push: PASS (${found.checks.length} checks${notRun ? `, ${notRun} not run on this machine: name them in the pull request` : ""}). Full output: ${log}`);
629
+ console.log(
630
+ `pre-push: PASS (${found.checks.length} checks${notRun ? `, ${notRun} not run on this machine: name them in the pull request` : ""}). Full output: ${log}`,
631
+ );
303
632
  return 0;
304
633
  } catch (error) {
305
634
  if (!(error instanceof Refusal)) throw error;