@halcyonlabs/app 0.47.0-halcyon.325 → 0.47.0-halcyon.327
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 +72 -72
- package/package.json +1 -1
- package/server/dist/builtin-plugins/orbit/dist/assets/orbit/revision +1 -1
- package/server/dist/builtin-plugins/orbit/dist/assets/plugins/orbit/front/CLAUDE.md +8 -4
- package/server/dist/builtin-plugins/orbit/skills/github-change/pre-push.d.mts +13 -0
- package/server/dist/builtin-plugins/orbit/skills/github-change/pre-push.mjs +357 -28
package/dist/index.d.ts
CHANGED
|
@@ -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 +1 @@
|
|
|
1
|
-
|
|
1
|
+
816da1404c5f550e8c8876501fb540d2c02669cf
|
|
@@ -30,8 +30,8 @@ guess one.
|
|
|
30
30
|
|
|
31
31
|
### Plain words before sending
|
|
32
32
|
|
|
33
|
-
Compose each reply privately before sending it, using the review command described
|
|
34
|
-
below. Revise from its reader's critique and send exactly the final text it returns.
|
|
33
|
+
Compose each final reply privately before sending it, using the review command described
|
|
34
|
+
below. Send the first plain line required by rule 5 before compose rounds. Revise from its reader's critique and send exactly the final text it returns.
|
|
35
35
|
Record corrections and later reactions in the memory store; retrieve examples for
|
|
36
36
|
each draft. Do not turn corrections into a maintained file or a new wording rule.
|
|
37
37
|
Use judgment about meaning; do not make word lists or add glossary entries.
|
|
@@ -61,8 +61,10 @@ These hold whatever the preferences say; the tone and standing instructions add
|
|
|
61
61
|
Ask rare real questions here in chat, in the existing Waiting for you list; push notifications reach {{owner}}.
|
|
62
62
|
Link an existing live question instead of asking it again. Never use the operator inbox.
|
|
63
63
|
Never ask for routine status.
|
|
64
|
-
5. **Answer
|
|
65
|
-
|
|
64
|
+
5. **Answer first.** In any turn {{owner}} starts, write one short plain line within seconds:
|
|
65
|
+
the answer if you have it, or what you are doing. Write it before tool calls and before
|
|
66
|
+
compose rounds; at most one or two quick lookups may come first. Then do the work and
|
|
67
|
+
send the final message with the result.
|
|
66
68
|
6. **Introduce yourself once** to a person, the first time you deal with them, then never again.
|
|
67
69
|
7. **Never claim to be human**, to anyone, even when it would be easier.
|
|
68
70
|
8. **Verify before claiming.** Say something is done or ready only after seeing it (a child's
|
|
@@ -264,6 +266,8 @@ and push notifications. `bb orbit threads list` shows each thread's root message
|
|
|
264
266
|
|
|
265
267
|
## Every turn
|
|
266
268
|
|
|
269
|
+
In a turn {{owner}} starts, send the first plain line from rule 5 before these steps.
|
|
270
|
+
|
|
267
271
|
1. Read `{{data}}/open-loops.md` (your open loops' index), and today's journal
|
|
268
272
|
(`{{data}}/journal/YYYY-MM-DD.md`) if it exists. When the event service runs, read
|
|
269
273
|
`/var/db/orbit/events/views/now.md` first: what waits on {{owner}}, what's in flight, what's
|
|
@@ -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 {
|
|
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 {
|
|
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 =
|
|
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) =>
|
|
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) => ({
|
|
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)
|
|
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"])
|
|
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")
|
|
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
|
|
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 = [
|
|
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
|
-
|
|
238
|
-
|
|
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,
|
|
250
|
-
folders.add(join(checkout, dir, "target"));
|
|
296
|
+
for (const output of PACKAGE_OUTPUTS) folders.add(join(checkout, dir, output));
|
|
251
297
|
}
|
|
252
|
-
|
|
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(
|
|
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)
|
|
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)
|
|
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
|
|
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(
|
|
293
|
-
|
|
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(
|
|
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(
|
|
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;
|