@bridge4dev/runner 0.31.0 → 0.33.0
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/adapters/claude.js +160 -45
- package/dist/adapters/codex.js +40 -14
- package/dist/adapters/types.d.ts +16 -1
- package/dist/index.js +13 -0
- package/dist/policy.d.ts +52 -1
- package/dist/policy.js +387 -53
- package/dist/protocol.d.ts +148 -18
- package/dist/protocol.js +38 -0
- package/dist/supervisor.js +102 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/protocol.d.ts
CHANGED
|
@@ -38,26 +38,52 @@ export declare const SessionDescriptorSchema: z.ZodObject<{
|
|
|
38
38
|
* scratch anyway; the bounds here only keep nonsense off the wire.
|
|
39
39
|
*/
|
|
40
40
|
agentPromptPath: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
41
|
+
/**
|
|
42
|
+
* Session 18: the project's git policy for agents.
|
|
43
|
+
*
|
|
44
|
+
* `.optional().catch(undefined)` for the QA-100 MAJOR-1 reason above — this
|
|
45
|
+
* rides inside `hello_ack` with every session on the server, so a malformed
|
|
46
|
+
* value must cost its own session's policy at most, never the frame.
|
|
47
|
+
*
|
|
48
|
+
* «Costs its own session's policy» is safe here BECAUSE of the polarity in
|
|
49
|
+
* `policy.ts`: `agentPushBan` resolves `undefined` to «refuse», so a value
|
|
50
|
+
* this schema drops leaves the session strictly more restricted, never less.
|
|
51
|
+
* That property is the whole reason `.catch(undefined)` is acceptable on a
|
|
52
|
+
* security field, and it is why the resolution lives in exactly one
|
|
53
|
+
* function rather than at each point of use.
|
|
54
|
+
*/
|
|
55
|
+
agentPushBan: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
56
|
+
agentProtectedBranches: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
57
|
+
agentAllowForcePush: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
58
|
+
agentAllowDestructiveGit: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
41
59
|
budgetUsd: z.ZodNullable<z.ZodNumber>;
|
|
42
60
|
budgetMinutes: z.ZodNullable<z.ZodNumber>;
|
|
43
61
|
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
44
63
|
id: string;
|
|
45
64
|
path: string;
|
|
46
65
|
projectId: string;
|
|
47
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
48
66
|
budgetUsd: number | null;
|
|
49
67
|
budgetMinutes: number | null;
|
|
50
68
|
agentAutoCommit?: boolean | undefined;
|
|
69
|
+
agentPushBan?: boolean | undefined;
|
|
51
70
|
agentPromptPath?: string | null | undefined;
|
|
71
|
+
agentProtectedBranches?: string[] | undefined;
|
|
72
|
+
agentAllowForcePush?: boolean | undefined;
|
|
73
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
52
74
|
}, {
|
|
75
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
53
76
|
id: string;
|
|
54
77
|
path: string;
|
|
55
78
|
projectId: string;
|
|
56
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
57
79
|
budgetUsd: number | null;
|
|
58
80
|
budgetMinutes: number | null;
|
|
59
81
|
agentAutoCommit?: boolean | undefined;
|
|
82
|
+
agentPushBan?: unknown;
|
|
60
83
|
agentPromptPath?: unknown;
|
|
84
|
+
agentProtectedBranches?: unknown;
|
|
85
|
+
agentAllowForcePush?: unknown;
|
|
86
|
+
agentAllowDestructiveGit?: unknown;
|
|
61
87
|
}>;
|
|
62
88
|
/**
|
|
63
89
|
* «Run this one without the project's agent prompt.» Absent means no — both
|
|
@@ -153,14 +179,18 @@ export declare const SessionDescriptorSchema: z.ZodObject<{
|
|
|
153
179
|
activeMsBase: number;
|
|
154
180
|
extraBudgetMinutes: number | null;
|
|
155
181
|
workspace: {
|
|
182
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
156
183
|
id: string;
|
|
157
184
|
path: string;
|
|
158
185
|
projectId: string;
|
|
159
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
160
186
|
budgetUsd: number | null;
|
|
161
187
|
budgetMinutes: number | null;
|
|
162
188
|
agentAutoCommit?: boolean | undefined;
|
|
189
|
+
agentPushBan?: boolean | undefined;
|
|
163
190
|
agentPromptPath?: string | null | undefined;
|
|
191
|
+
agentProtectedBranches?: string[] | undefined;
|
|
192
|
+
agentAllowForcePush?: boolean | undefined;
|
|
193
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
164
194
|
};
|
|
165
195
|
tickets: {
|
|
166
196
|
number: number;
|
|
@@ -188,14 +218,18 @@ export declare const SessionDescriptorSchema: z.ZodObject<{
|
|
|
188
218
|
prompt: string;
|
|
189
219
|
providerSessionId: string | null;
|
|
190
220
|
workspace: {
|
|
221
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
191
222
|
id: string;
|
|
192
223
|
path: string;
|
|
193
224
|
projectId: string;
|
|
194
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
195
225
|
budgetUsd: number | null;
|
|
196
226
|
budgetMinutes: number | null;
|
|
197
227
|
agentAutoCommit?: boolean | undefined;
|
|
228
|
+
agentPushBan?: unknown;
|
|
198
229
|
agentPromptPath?: unknown;
|
|
230
|
+
agentProtectedBranches?: unknown;
|
|
231
|
+
agentAllowForcePush?: unknown;
|
|
232
|
+
agentAllowDestructiveGit?: unknown;
|
|
199
233
|
};
|
|
200
234
|
tickets: {
|
|
201
235
|
number: number;
|
|
@@ -264,26 +298,52 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
264
298
|
* scratch anyway; the bounds here only keep nonsense off the wire.
|
|
265
299
|
*/
|
|
266
300
|
agentPromptPath: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
301
|
+
/**
|
|
302
|
+
* Session 18: the project's git policy for agents.
|
|
303
|
+
*
|
|
304
|
+
* `.optional().catch(undefined)` for the QA-100 MAJOR-1 reason above — this
|
|
305
|
+
* rides inside `hello_ack` with every session on the server, so a malformed
|
|
306
|
+
* value must cost its own session's policy at most, never the frame.
|
|
307
|
+
*
|
|
308
|
+
* «Costs its own session's policy» is safe here BECAUSE of the polarity in
|
|
309
|
+
* `policy.ts`: `agentPushBan` resolves `undefined` to «refuse», so a value
|
|
310
|
+
* this schema drops leaves the session strictly more restricted, never less.
|
|
311
|
+
* That property is the whole reason `.catch(undefined)` is acceptable on a
|
|
312
|
+
* security field, and it is why the resolution lives in exactly one
|
|
313
|
+
* function rather than at each point of use.
|
|
314
|
+
*/
|
|
315
|
+
agentPushBan: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
316
|
+
agentProtectedBranches: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
317
|
+
agentAllowForcePush: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
318
|
+
agentAllowDestructiveGit: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
267
319
|
budgetUsd: z.ZodNullable<z.ZodNumber>;
|
|
268
320
|
budgetMinutes: z.ZodNullable<z.ZodNumber>;
|
|
269
321
|
}, "strip", z.ZodTypeAny, {
|
|
322
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
270
323
|
id: string;
|
|
271
324
|
path: string;
|
|
272
325
|
projectId: string;
|
|
273
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
274
326
|
budgetUsd: number | null;
|
|
275
327
|
budgetMinutes: number | null;
|
|
276
328
|
agentAutoCommit?: boolean | undefined;
|
|
329
|
+
agentPushBan?: boolean | undefined;
|
|
277
330
|
agentPromptPath?: string | null | undefined;
|
|
331
|
+
agentProtectedBranches?: string[] | undefined;
|
|
332
|
+
agentAllowForcePush?: boolean | undefined;
|
|
333
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
278
334
|
}, {
|
|
335
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
279
336
|
id: string;
|
|
280
337
|
path: string;
|
|
281
338
|
projectId: string;
|
|
282
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
283
339
|
budgetUsd: number | null;
|
|
284
340
|
budgetMinutes: number | null;
|
|
285
341
|
agentAutoCommit?: boolean | undefined;
|
|
342
|
+
agentPushBan?: unknown;
|
|
286
343
|
agentPromptPath?: unknown;
|
|
344
|
+
agentProtectedBranches?: unknown;
|
|
345
|
+
agentAllowForcePush?: unknown;
|
|
346
|
+
agentAllowDestructiveGit?: unknown;
|
|
287
347
|
}>;
|
|
288
348
|
/**
|
|
289
349
|
* «Run this one without the project's agent prompt.» Absent means no — both
|
|
@@ -379,14 +439,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
379
439
|
activeMsBase: number;
|
|
380
440
|
extraBudgetMinutes: number | null;
|
|
381
441
|
workspace: {
|
|
442
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
382
443
|
id: string;
|
|
383
444
|
path: string;
|
|
384
445
|
projectId: string;
|
|
385
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
386
446
|
budgetUsd: number | null;
|
|
387
447
|
budgetMinutes: number | null;
|
|
388
448
|
agentAutoCommit?: boolean | undefined;
|
|
449
|
+
agentPushBan?: boolean | undefined;
|
|
389
450
|
agentPromptPath?: string | null | undefined;
|
|
451
|
+
agentProtectedBranches?: string[] | undefined;
|
|
452
|
+
agentAllowForcePush?: boolean | undefined;
|
|
453
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
390
454
|
};
|
|
391
455
|
tickets: {
|
|
392
456
|
number: number;
|
|
@@ -414,14 +478,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
414
478
|
prompt: string;
|
|
415
479
|
providerSessionId: string | null;
|
|
416
480
|
workspace: {
|
|
481
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
417
482
|
id: string;
|
|
418
483
|
path: string;
|
|
419
484
|
projectId: string;
|
|
420
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
421
485
|
budgetUsd: number | null;
|
|
422
486
|
budgetMinutes: number | null;
|
|
423
487
|
agentAutoCommit?: boolean | undefined;
|
|
488
|
+
agentPushBan?: unknown;
|
|
424
489
|
agentPromptPath?: unknown;
|
|
490
|
+
agentProtectedBranches?: unknown;
|
|
491
|
+
agentAllowForcePush?: unknown;
|
|
492
|
+
agentAllowDestructiveGit?: unknown;
|
|
425
493
|
};
|
|
426
494
|
tickets: {
|
|
427
495
|
number: number;
|
|
@@ -465,14 +533,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
465
533
|
activeMsBase: number;
|
|
466
534
|
extraBudgetMinutes: number | null;
|
|
467
535
|
workspace: {
|
|
536
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
468
537
|
id: string;
|
|
469
538
|
path: string;
|
|
470
539
|
projectId: string;
|
|
471
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
472
540
|
budgetUsd: number | null;
|
|
473
541
|
budgetMinutes: number | null;
|
|
474
542
|
agentAutoCommit?: boolean | undefined;
|
|
543
|
+
agentPushBan?: boolean | undefined;
|
|
475
544
|
agentPromptPath?: string | null | undefined;
|
|
545
|
+
agentProtectedBranches?: string[] | undefined;
|
|
546
|
+
agentAllowForcePush?: boolean | undefined;
|
|
547
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
476
548
|
};
|
|
477
549
|
tickets: {
|
|
478
550
|
number: number;
|
|
@@ -506,14 +578,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
506
578
|
prompt: string;
|
|
507
579
|
providerSessionId: string | null;
|
|
508
580
|
workspace: {
|
|
581
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
509
582
|
id: string;
|
|
510
583
|
path: string;
|
|
511
584
|
projectId: string;
|
|
512
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
513
585
|
budgetUsd: number | null;
|
|
514
586
|
budgetMinutes: number | null;
|
|
515
587
|
agentAutoCommit?: boolean | undefined;
|
|
588
|
+
agentPushBan?: unknown;
|
|
516
589
|
agentPromptPath?: unknown;
|
|
590
|
+
agentProtectedBranches?: unknown;
|
|
591
|
+
agentAllowForcePush?: unknown;
|
|
592
|
+
agentAllowDestructiveGit?: unknown;
|
|
517
593
|
};
|
|
518
594
|
tickets: {
|
|
519
595
|
number: number;
|
|
@@ -606,26 +682,52 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
606
682
|
* scratch anyway; the bounds here only keep nonsense off the wire.
|
|
607
683
|
*/
|
|
608
684
|
agentPromptPath: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
685
|
+
/**
|
|
686
|
+
* Session 18: the project's git policy for agents.
|
|
687
|
+
*
|
|
688
|
+
* `.optional().catch(undefined)` for the QA-100 MAJOR-1 reason above — this
|
|
689
|
+
* rides inside `hello_ack` with every session on the server, so a malformed
|
|
690
|
+
* value must cost its own session's policy at most, never the frame.
|
|
691
|
+
*
|
|
692
|
+
* «Costs its own session's policy» is safe here BECAUSE of the polarity in
|
|
693
|
+
* `policy.ts`: `agentPushBan` resolves `undefined` to «refuse», so a value
|
|
694
|
+
* this schema drops leaves the session strictly more restricted, never less.
|
|
695
|
+
* That property is the whole reason `.catch(undefined)` is acceptable on a
|
|
696
|
+
* security field, and it is why the resolution lives in exactly one
|
|
697
|
+
* function rather than at each point of use.
|
|
698
|
+
*/
|
|
699
|
+
agentPushBan: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
700
|
+
agentProtectedBranches: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
701
|
+
agentAllowForcePush: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
702
|
+
agentAllowDestructiveGit: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
609
703
|
budgetUsd: z.ZodNullable<z.ZodNumber>;
|
|
610
704
|
budgetMinutes: z.ZodNullable<z.ZodNumber>;
|
|
611
705
|
}, "strip", z.ZodTypeAny, {
|
|
706
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
612
707
|
id: string;
|
|
613
708
|
path: string;
|
|
614
709
|
projectId: string;
|
|
615
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
616
710
|
budgetUsd: number | null;
|
|
617
711
|
budgetMinutes: number | null;
|
|
618
712
|
agentAutoCommit?: boolean | undefined;
|
|
713
|
+
agentPushBan?: boolean | undefined;
|
|
619
714
|
agentPromptPath?: string | null | undefined;
|
|
715
|
+
agentProtectedBranches?: string[] | undefined;
|
|
716
|
+
agentAllowForcePush?: boolean | undefined;
|
|
717
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
620
718
|
}, {
|
|
719
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
621
720
|
id: string;
|
|
622
721
|
path: string;
|
|
623
722
|
projectId: string;
|
|
624
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
625
723
|
budgetUsd: number | null;
|
|
626
724
|
budgetMinutes: number | null;
|
|
627
725
|
agentAutoCommit?: boolean | undefined;
|
|
726
|
+
agentPushBan?: unknown;
|
|
628
727
|
agentPromptPath?: unknown;
|
|
728
|
+
agentProtectedBranches?: unknown;
|
|
729
|
+
agentAllowForcePush?: unknown;
|
|
730
|
+
agentAllowDestructiveGit?: unknown;
|
|
629
731
|
}>;
|
|
630
732
|
/**
|
|
631
733
|
* «Run this one without the project's agent prompt.» Absent means no — both
|
|
@@ -721,14 +823,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
721
823
|
activeMsBase: number;
|
|
722
824
|
extraBudgetMinutes: number | null;
|
|
723
825
|
workspace: {
|
|
826
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
724
827
|
id: string;
|
|
725
828
|
path: string;
|
|
726
829
|
projectId: string;
|
|
727
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
728
830
|
budgetUsd: number | null;
|
|
729
831
|
budgetMinutes: number | null;
|
|
730
832
|
agentAutoCommit?: boolean | undefined;
|
|
833
|
+
agentPushBan?: boolean | undefined;
|
|
731
834
|
agentPromptPath?: string | null | undefined;
|
|
835
|
+
agentProtectedBranches?: string[] | undefined;
|
|
836
|
+
agentAllowForcePush?: boolean | undefined;
|
|
837
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
732
838
|
};
|
|
733
839
|
tickets: {
|
|
734
840
|
number: number;
|
|
@@ -756,14 +862,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
756
862
|
prompt: string;
|
|
757
863
|
providerSessionId: string | null;
|
|
758
864
|
workspace: {
|
|
865
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
759
866
|
id: string;
|
|
760
867
|
path: string;
|
|
761
868
|
projectId: string;
|
|
762
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
763
869
|
budgetUsd: number | null;
|
|
764
870
|
budgetMinutes: number | null;
|
|
765
871
|
agentAutoCommit?: boolean | undefined;
|
|
872
|
+
agentPushBan?: unknown;
|
|
766
873
|
agentPromptPath?: unknown;
|
|
874
|
+
agentProtectedBranches?: unknown;
|
|
875
|
+
agentAllowForcePush?: unknown;
|
|
876
|
+
agentAllowDestructiveGit?: unknown;
|
|
767
877
|
};
|
|
768
878
|
tickets: {
|
|
769
879
|
number: number;
|
|
@@ -805,14 +915,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
805
915
|
activeMsBase: number;
|
|
806
916
|
extraBudgetMinutes: number | null;
|
|
807
917
|
workspace: {
|
|
918
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
808
919
|
id: string;
|
|
809
920
|
path: string;
|
|
810
921
|
projectId: string;
|
|
811
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
812
922
|
budgetUsd: number | null;
|
|
813
923
|
budgetMinutes: number | null;
|
|
814
924
|
agentAutoCommit?: boolean | undefined;
|
|
925
|
+
agentPushBan?: boolean | undefined;
|
|
815
926
|
agentPromptPath?: string | null | undefined;
|
|
927
|
+
agentProtectedBranches?: string[] | undefined;
|
|
928
|
+
agentAllowForcePush?: boolean | undefined;
|
|
929
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
816
930
|
};
|
|
817
931
|
tickets: {
|
|
818
932
|
number: number;
|
|
@@ -843,14 +957,18 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
843
957
|
prompt: string;
|
|
844
958
|
providerSessionId: string | null;
|
|
845
959
|
workspace: {
|
|
960
|
+
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
846
961
|
id: string;
|
|
847
962
|
path: string;
|
|
848
963
|
projectId: string;
|
|
849
|
-
trustMode: "STRICT" | "NORMAL" | "AUTO";
|
|
850
964
|
budgetUsd: number | null;
|
|
851
965
|
budgetMinutes: number | null;
|
|
852
966
|
agentAutoCommit?: boolean | undefined;
|
|
967
|
+
agentPushBan?: unknown;
|
|
853
968
|
agentPromptPath?: unknown;
|
|
969
|
+
agentProtectedBranches?: unknown;
|
|
970
|
+
agentAllowForcePush?: unknown;
|
|
971
|
+
agentAllowDestructiveGit?: unknown;
|
|
854
972
|
};
|
|
855
973
|
tickets: {
|
|
856
974
|
number: number;
|
|
@@ -1005,16 +1123,28 @@ export declare const GatewayFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
|
|
|
1005
1123
|
workspaceId: z.ZodString;
|
|
1006
1124
|
trustMode: z.ZodOptional<z.ZodEnum<["STRICT", "NORMAL", "AUTO"]>>;
|
|
1007
1125
|
agentAutoCommit: z.ZodOptional<z.ZodBoolean>;
|
|
1126
|
+
agentPushBan: z.ZodOptional<z.ZodBoolean>;
|
|
1127
|
+
agentProtectedBranches: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1128
|
+
agentAllowForcePush: z.ZodOptional<z.ZodBoolean>;
|
|
1129
|
+
agentAllowDestructiveGit: z.ZodOptional<z.ZodBoolean>;
|
|
1008
1130
|
}, "strip", z.ZodTypeAny, {
|
|
1009
1131
|
type: "workspace_settings";
|
|
1010
1132
|
workspaceId: string;
|
|
1011
|
-
agentAutoCommit?: boolean | undefined;
|
|
1012
1133
|
trustMode?: "STRICT" | "NORMAL" | "AUTO" | undefined;
|
|
1134
|
+
agentAutoCommit?: boolean | undefined;
|
|
1135
|
+
agentPushBan?: boolean | undefined;
|
|
1136
|
+
agentProtectedBranches?: string[] | undefined;
|
|
1137
|
+
agentAllowForcePush?: boolean | undefined;
|
|
1138
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
1013
1139
|
}, {
|
|
1014
1140
|
type: "workspace_settings";
|
|
1015
1141
|
workspaceId: string;
|
|
1016
|
-
agentAutoCommit?: boolean | undefined;
|
|
1017
1142
|
trustMode?: "STRICT" | "NORMAL" | "AUTO" | undefined;
|
|
1143
|
+
agentAutoCommit?: boolean | undefined;
|
|
1144
|
+
agentPushBan?: boolean | undefined;
|
|
1145
|
+
agentProtectedBranches?: string[] | undefined;
|
|
1146
|
+
agentAllowForcePush?: boolean | undefined;
|
|
1147
|
+
agentAllowDestructiveGit?: boolean | undefined;
|
|
1018
1148
|
}>, z.ZodObject<{
|
|
1019
1149
|
type: z.ZodLiteral<"session_settings">;
|
|
1020
1150
|
sessionId: z.ZodString;
|
package/dist/protocol.js
CHANGED
|
@@ -64,6 +64,31 @@ export const SessionDescriptorSchema = z.object({
|
|
|
64
64
|
* scratch anyway; the bounds here only keep nonsense off the wire.
|
|
65
65
|
*/
|
|
66
66
|
agentPromptPath: z.string().max(300).nullable().optional().catch(undefined),
|
|
67
|
+
/**
|
|
68
|
+
* Session 18: the project's git policy for agents.
|
|
69
|
+
*
|
|
70
|
+
* `.optional().catch(undefined)` for the QA-100 MAJOR-1 reason above — this
|
|
71
|
+
* rides inside `hello_ack` with every session on the server, so a malformed
|
|
72
|
+
* value must cost its own session's policy at most, never the frame.
|
|
73
|
+
*
|
|
74
|
+
* «Costs its own session's policy» is safe here BECAUSE of the polarity in
|
|
75
|
+
* `policy.ts`: `agentPushBan` resolves `undefined` to «refuse», so a value
|
|
76
|
+
* this schema drops leaves the session strictly more restricted, never less.
|
|
77
|
+
* That property is the whole reason `.catch(undefined)` is acceptable on a
|
|
78
|
+
* security field, and it is why the resolution lives in exactly one
|
|
79
|
+
* function rather than at each point of use.
|
|
80
|
+
*/
|
|
81
|
+
agentPushBan: z.boolean().optional().catch(undefined),
|
|
82
|
+
agentProtectedBranches: z
|
|
83
|
+
.array(z
|
|
84
|
+
.string()
|
|
85
|
+
.max(200)
|
|
86
|
+
.regex(/^[A-Za-z0-9][A-Za-z0-9._\-/]*$/))
|
|
87
|
+
.max(20)
|
|
88
|
+
.optional()
|
|
89
|
+
.catch(undefined),
|
|
90
|
+
agentAllowForcePush: z.boolean().optional().catch(undefined),
|
|
91
|
+
agentAllowDestructiveGit: z.boolean().optional().catch(undefined),
|
|
67
92
|
budgetUsd: z.number().nullable(),
|
|
68
93
|
budgetMinutes: z.number().nullable(),
|
|
69
94
|
}),
|
|
@@ -230,6 +255,19 @@ export const GatewayFrameSchema = z.discriminatedUnion('type', [
|
|
|
230
255
|
workspaceId: z.string().min(1).max(64),
|
|
231
256
|
trustMode: z.enum(['STRICT', 'NORMAL', 'AUTO']).optional(),
|
|
232
257
|
agentAutoCommit: z.boolean().optional(),
|
|
258
|
+
// Session 18 — the git policy, for the same reason: read on every tool
|
|
259
|
+
// call, so switching «Принудительно запретить push» back on must not
|
|
260
|
+
// require stopping the agent first.
|
|
261
|
+
agentPushBan: z.boolean().optional(),
|
|
262
|
+
agentProtectedBranches: z
|
|
263
|
+
.array(z
|
|
264
|
+
.string()
|
|
265
|
+
.max(200)
|
|
266
|
+
.regex(/^[A-Za-z0-9][A-Za-z0-9._\-/]*$/))
|
|
267
|
+
.max(20)
|
|
268
|
+
.optional(),
|
|
269
|
+
agentAllowForcePush: z.boolean().optional(),
|
|
270
|
+
agentAllowDestructiveGit: z.boolean().optional(),
|
|
233
271
|
}),
|
|
234
272
|
z.object({
|
|
235
273
|
type: z.literal('session_settings'),
|
package/dist/supervisor.js
CHANGED
|
@@ -22,6 +22,28 @@ import { availableModes, MODE_REFUSED_TEXT } from './adapters/types.js';
|
|
|
22
22
|
/** Refusals shared by every checkpoint command (ticket #126). */
|
|
23
23
|
const CHECKPOINTS_OFF = 'Restore points are switched off on this server ([checkpoints] enabled = false)';
|
|
24
24
|
const AGENT_BUSY = 'The agent is still working — stop the turn first';
|
|
25
|
+
/**
|
|
26
|
+
* The project's git policy, lifted out of a session descriptor (session 18).
|
|
27
|
+
*
|
|
28
|
+
* One function so that «which descriptor fields are the git policy» is answered
|
|
29
|
+
* once. Absent fields are passed through as absent — `resolveGitPolicy` in
|
|
30
|
+
* `policy.ts` is the single place that decides what absent MEANS, and inventing
|
|
31
|
+
* a default here would put a second such place in the codebase, facing the
|
|
32
|
+
* other way.
|
|
33
|
+
*/
|
|
34
|
+
function gitPolicyOf(descriptor) {
|
|
35
|
+
const w = descriptor.workspace;
|
|
36
|
+
return {
|
|
37
|
+
...(w.agentPushBan !== undefined ? { agentPushBan: w.agentPushBan } : {}),
|
|
38
|
+
...(w.agentProtectedBranches !== undefined
|
|
39
|
+
? { agentProtectedBranches: w.agentProtectedBranches }
|
|
40
|
+
: {}),
|
|
41
|
+
...(w.agentAllowForcePush !== undefined ? { agentAllowForcePush: w.agentAllowForcePush } : {}),
|
|
42
|
+
...(w.agentAllowDestructiveGit !== undefined
|
|
43
|
+
? { agentAllowDestructiveGit: w.agentAllowDestructiveGit }
|
|
44
|
+
: {}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
export class Supervisor {
|
|
26
48
|
ws;
|
|
27
49
|
opts;
|
|
@@ -131,11 +153,43 @@ export class Supervisor {
|
|
|
131
153
|
if (frame.agentAutoCommit !== undefined) {
|
|
132
154
|
running.descriptor.workspace.agentAutoCommit = frame.agentAutoCommit;
|
|
133
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Session 18: the git policy, applied live for the same reason as the
|
|
158
|
+
* two above — it is read on every tool call, so «switch push back
|
|
159
|
+
* off» must not mean «stop the agent first».
|
|
160
|
+
*
|
|
161
|
+
* The four fields move together, and the API sends all four in every
|
|
162
|
+
* frame that touches any of them, so a partial update cannot leave
|
|
163
|
+
* the runner with «push is allowed now» beside a protected list from
|
|
164
|
+
* before the change. `!== undefined` on the FRAME is what tells a
|
|
165
|
+
* policy change apart from a trust-only frame; inside the object,
|
|
166
|
+
* `undefined` keeps its restrictive meaning as everywhere else.
|
|
167
|
+
*/
|
|
168
|
+
const policyChanged = frame.agentPushBan !== undefined ||
|
|
169
|
+
frame.agentProtectedBranches !== undefined ||
|
|
170
|
+
frame.agentAllowForcePush !== undefined ||
|
|
171
|
+
frame.agentAllowDestructiveGit !== undefined;
|
|
172
|
+
if (policyChanged) {
|
|
173
|
+
const next = {
|
|
174
|
+
...(frame.agentPushBan !== undefined ? { agentPushBan: frame.agentPushBan } : {}),
|
|
175
|
+
...(frame.agentProtectedBranches !== undefined
|
|
176
|
+
? { agentProtectedBranches: frame.agentProtectedBranches }
|
|
177
|
+
: {}),
|
|
178
|
+
...(frame.agentAllowForcePush !== undefined
|
|
179
|
+
? { agentAllowForcePush: frame.agentAllowForcePush }
|
|
180
|
+
: {}),
|
|
181
|
+
...(frame.agentAllowDestructiveGit !== undefined
|
|
182
|
+
? { agentAllowDestructiveGit: frame.agentAllowDestructiveGit }
|
|
183
|
+
: {}),
|
|
184
|
+
};
|
|
185
|
+
Object.assign(running.descriptor.workspace, next);
|
|
186
|
+
}
|
|
134
187
|
running.session?.setWorkspacePolicy({
|
|
135
188
|
...(frame.trustMode !== undefined ? { trustMode: frame.trustMode } : {}),
|
|
136
189
|
...(frame.agentAutoCommit !== undefined
|
|
137
190
|
? { agentAutoCommit: frame.agentAutoCommit }
|
|
138
191
|
: {}),
|
|
192
|
+
...(policyChanged ? { gitPolicy: gitPolicyOf(running.descriptor) } : {}),
|
|
139
193
|
});
|
|
140
194
|
}
|
|
141
195
|
break;
|
|
@@ -406,6 +460,11 @@ export class Supervisor {
|
|
|
406
460
|
...(descriptor.workspace.agentAutoCommit === undefined
|
|
407
461
|
? {}
|
|
408
462
|
: { agentAutoCommit: descriptor.workspace.agentAutoCommit }),
|
|
463
|
+
// Session 18. Always present, even when every field inside it is absent:
|
|
464
|
+
// an absent OBJECT and an object of absent fields resolve identically
|
|
465
|
+
// (`resolveGitPolicy` gives both the restrictive reading), and passing it
|
|
466
|
+
// unconditionally keeps one code path instead of two.
|
|
467
|
+
gitPolicy: gitPolicyOf(descriptor),
|
|
409
468
|
mode: running.mode,
|
|
410
469
|
...(running.model ? { model: running.model } : {}),
|
|
411
470
|
...(running.effort ? { effort: running.effort } : {}),
|
|
@@ -3358,16 +3417,58 @@ export function composeInitialPrompt(descriptor) {
|
|
|
3358
3417
|
export function composeWorkspaceContext(descriptor, agentPrompt) {
|
|
3359
3418
|
const sections = [];
|
|
3360
3419
|
const plan = descriptor.branchPlan;
|
|
3420
|
+
/**
|
|
3421
|
+
* What this session may do about push, in one sentence (session 18).
|
|
3422
|
+
*
|
|
3423
|
+
* `!== false` — silence refuses, exactly as `resolveGitPolicy` reads it. This
|
|
3424
|
+
* text and the rule in `policy.ts` have to agree; an agent told it may push
|
|
3425
|
+
* and then refused has been lied to, and an agent told it may not while the
|
|
3426
|
+
* project allows it wastes the freedom the owner paid for.
|
|
3427
|
+
*/
|
|
3428
|
+
const pushLine = (() => {
|
|
3429
|
+
// `?.` and not `.`: this function is exported and called with descriptors
|
|
3430
|
+
// assembled by hand in tests and by older code paths. A missing `workspace`
|
|
3431
|
+
// must land on the refusing branch like every other unknown here, not throw
|
|
3432
|
+
// and take the whole session start with it.
|
|
3433
|
+
if (descriptor.workspace?.agentPushBan !== false) {
|
|
3434
|
+
return '- You cannot push: `git push` is refused for this project. A human presses «Push» in DevBridge when they want the branch on the remote.';
|
|
3435
|
+
}
|
|
3436
|
+
const guarded = descriptor.workspace?.agentProtectedBranches ?? ['main', 'master'];
|
|
3437
|
+
return guarded.length > 0
|
|
3438
|
+
? `- You may push, except to these protected branches: ${guarded.join(', ')}. Name the branch explicitly — \`git push <remote> <branch>\`.`
|
|
3439
|
+
: '- You may push.';
|
|
3440
|
+
})();
|
|
3361
3441
|
if (plan) {
|
|
3362
3442
|
const forked = plan.baseBranch ? ` It was branched from \`${plan.baseBranch}\`.` : '';
|
|
3363
3443
|
sections.push([
|
|
3364
3444
|
'Git in this session:',
|
|
3365
3445
|
`- You are in a dedicated worktree on branch \`${plan.branch}\`.${forked}`,
|
|
3366
3446
|
'- Commit to this branch. Do not switch branches and do not merge into the base branch yourself — a human presses «Apply» in DevBridge, which squash-merges your branch for them.',
|
|
3367
|
-
|
|
3447
|
+
pushLine,
|
|
3368
3448
|
`- Put a plan or working notes in \`docs/devbridge/${plan.branch.replace(/\//g, '-')}.md\`, unless this repository already has its own convention for where such documents live — if it does, follow that.`,
|
|
3369
3449
|
].join('\n'));
|
|
3370
3450
|
}
|
|
3451
|
+
else {
|
|
3452
|
+
/**
|
|
3453
|
+
* A DIRECT session got NO «Git in this session» block at all, and that is
|
|
3454
|
+
* the older half of this bug (session 16 shipped DIRECT as the default;
|
|
3455
|
+
* this block stayed gated on `branchPlan`, which only a BRANCH session
|
|
3456
|
+
* has). So the arrangement that writes into the person's OWN project
|
|
3457
|
+
* folder was the one told nothing about where it was — while the adapter's
|
|
3458
|
+
* static line went on claiming «a dedicated git worktree on a session
|
|
3459
|
+
* branch», which in DIRECT is simply false.
|
|
3460
|
+
*
|
|
3461
|
+
* Being in somebody's working copy is the case that needs saying MORE, not
|
|
3462
|
+
* less: there is no «Apply» to undo it, and uncommitted changes in that
|
|
3463
|
+
* folder may not be the agent's.
|
|
3464
|
+
*/
|
|
3465
|
+
sections.push([
|
|
3466
|
+
'Git in this session:',
|
|
3467
|
+
'- You are working in the PROJECT FOLDER ITSELF, on the branch it is already checked out on — not in a worktree of your own. There is no session branch and nothing to «apply» afterwards: your commits are immediately on the branch the person works on.',
|
|
3468
|
+
'- Uncommitted changes you find here may be a human’s, or another session’s. Never discard or reset what you did not write.',
|
|
3469
|
+
pushLine,
|
|
3470
|
+
].join('\n'));
|
|
3471
|
+
}
|
|
3371
3472
|
// The ticket convention lives HERE, not in the first chat message (session
|
|
3372
3473
|
// 16). It is a standing rule of the project — true on the twentieth turn as
|
|
3373
3474
|
// much as the first — and putting it in the visible prompt only trained the
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const RUNNER_VERSION = "0.
|
|
1
|
+
export declare const RUNNER_VERSION = "0.33.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED