glimmervoid 0.38.2 → 0.40.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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/glimmervoid.js +33 -42
  3. package/dist/chunks/{adapters-CAHxZYT3.js → adapters-B6tbX3Aj.js} +27 -14
  4. package/dist/chunks/{adapters-DDjC7_vG.js → adapters-CXQfLoyj.js} +1 -1
  5. package/dist/chunks/agent-api-cli-BBech5lF.js +1 -0
  6. package/dist/chunks/{agent-api-cli-B5Tm0wXO.js → agent-api-cli-BNHJTmNW.js} +44 -77
  7. package/dist/chunks/agent-api-core-DDrJQEdE.js +304 -0
  8. package/dist/chunks/{agent-setup-cli-DmMfCw5O.js → agent-setup-cli-CeBBwKuL.js} +2 -2
  9. package/dist/chunks/config-store-BZpN2djp.js +1 -0
  10. package/dist/chunks/{config-store-BUNZs4j7.js → config-store-DqMScSdg.js} +82 -268
  11. package/dist/chunks/contracts-CloExMlS.js +680 -0
  12. package/dist/chunks/{contracts-HVCEJfxs.js → control-messages-DpBaniJi.js} +1275 -1021
  13. package/dist/chunks/{git-version-rWZjF2Px.js → git-version-CJQMfxtZ.js} +2 -2
  14. package/dist/chunks/{grok-B6bsCgdd.js → grok-BLzhApwT.js} +7 -8
  15. package/dist/chunks/{guardrails-deps-Cb-ki4EU.js → guardrails-deps-CLxK4J-g.js} +1 -1
  16. package/dist/chunks/{json-file-CIJf0Cel.js → json-file-DFCTvPjj.js} +3 -7
  17. package/dist/chunks/{main-BNSbP-Yk.js → main-DDU8IvFD.js} +28791 -31978
  18. package/dist/chunks/{pair-cli-DNp8i5L4.js → pair-cli-CsOVTQGJ.js} +2 -2
  19. package/dist/chunks/{remote-config-C_s2pnLC.js → remote-config-HlABuLTp.js} +2 -2
  20. package/dist/chunks/{session-BlT68ppa.js → session-BwB43SCa.js} +119 -71
  21. package/dist/chunks/{session-routes-CT1JrjoT.js → session-routes-DNJzsckH.js} +25 -10
  22. package/dist/chunks/{settings-cli-BbzxCyG5.js → settings-cli-DkkbK-dj.js} +30 -156
  23. package/dist/chunks/settings-readout-core-DrXT4aWm.js +201 -0
  24. package/dist/chunks/{ssh-sign-cli-C74BGTQS.js → ssh-sign-cli-CYeKRevK.js} +2 -2
  25. package/dist/client/assets/index-BK9jLR47.js +148 -0
  26. package/dist/client/assets/index-CU_uqJmi.css +2 -0
  27. package/dist/client/assets/xterm-kR64YvZ-.js +79 -0
  28. package/dist/client/assets/zod-BRLv4KqJ.js +55 -0
  29. package/dist/client/index.html +7 -3
  30. package/dist/scripts/postinstall-path-check.js +21 -3
  31. package/dist/server/index.js +1 -1
  32. package/package.json +3 -4
  33. package/dist/chunks/agent-api-cli-BDu1CxZf.js +0 -1
  34. package/dist/chunks/agent-api-core-B_mUSenR.js +0 -341
  35. package/dist/chunks/browser-config-BrBT8269.js +0 -762
  36. package/dist/chunks/config-CjawSOBk.js +0 -219
  37. package/dist/chunks/config-store-MAVQhGMh.js +0 -1
  38. package/dist/chunks/factory-D7ryES9n.js +0 -240
  39. package/dist/chunks/knowledge-graph-cli-ByUJoKw_.js +0 -1354
  40. package/dist/client/assets/index-B5uVtedd.css +0 -1
  41. package/dist/client/assets/index-b13-NGGS.js +0 -275
@@ -1,6 +1,6 @@
1
1
  import { r as errorMessage } from "./text-DoirglWV.js";
2
- import { c as resolveConfigPath } from "./config-store-BUNZs4j7.js";
3
- import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-C_s2pnLC.js";
2
+ import { c as resolveConfigPath } from "./config-store-DqMScSdg.js";
3
+ import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-HlABuLTp.js";
4
4
  import fs from "node:fs";
5
5
  //#region server/text-format.ts
6
6
  function trimIso(iso) {
@@ -2,8 +2,8 @@ import { n as errorLabel, r as errorMessage } from "./text-DoirglWV.js";
2
2
  import { n as equalsIgnoringCaseOnWindows } from "./paths-Bu4eH1Yd.js";
3
3
  import { n as isRecord } from "./coerce-NSst8oRP.js";
4
4
  import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
5
- import { a as jsonStateLoadError, d as writeJsonAtomicSync, l as sleepSync, s as loadJsonStateFileSync, u as writeJsonAtomic } from "./json-file-CIJf0Cel.js";
6
- import { o as glimmervoidHomeDir, st as canonicalizePath } from "./config-store-BUNZs4j7.js";
5
+ import { a as jsonStateLoadError, d as writeJsonAtomicSync, l as sleepSync, s as loadJsonStateFileSync, u as writeJsonAtomic } from "./json-file-DFCTvPjj.js";
6
+ import { o as glimmervoidHomeDir, ot as canonicalizePath } from "./config-store-DqMScSdg.js";
7
7
  import fs from "node:fs";
8
8
  import path from "node:path";
9
9
  import crypto from "node:crypto";
@@ -13,26 +13,15 @@ var STATES = Object.freeze({
13
13
  });
14
14
  Object.freeze({
15
15
  [STATES.DORMANT]: "Dormant",
16
- [STATES.INITIALIZING]: "Preparing",
16
+ [STATES.INITIALIZING]: "Starting",
17
17
  [STATES.STARTING]: "Starting",
18
18
  [STATES.RUNNING]: "Working",
19
19
  [STATES.WAITING]: "Needs Input",
20
20
  [STATES.IDLE]: "Idle",
21
- [STATES.COMPLETE]: "Complete",
21
+ [STATES.COMPLETE]: "Idle",
22
22
  [STATES.DONE]: "Exited",
23
23
  [STATES.FAILED]: "Failed"
24
24
  });
25
- Object.freeze({
26
- [STATES.DORMANT]: "○",
27
- [STATES.INITIALIZING]: "◌",
28
- [STATES.STARTING]: "◐",
29
- [STATES.RUNNING]: "●",
30
- [STATES.WAITING]: "◆",
31
- [STATES.IDLE]: "◍",
32
- [STATES.FAILED]: "▲",
33
- [STATES.DONE]: "■",
34
- [STATES.COMPLETE]: "◇"
35
- });
36
25
  var KILLABLE_STATES = Object.freeze([
37
26
  STATES.INITIALIZING,
38
27
  STATES.STARTING,
@@ -60,6 +49,10 @@ var githubPollingShape = {
60
49
  isRefreshing: z.boolean().optional(),
61
50
  refreshNotice: z.string().nullable().optional()
62
51
  };
52
+ var GithubPrsFreshness = z.strictObject({
53
+ lastRefreshedAt: z.number().finite().nonnegative().nullable(),
54
+ error: z.string().nullable()
55
+ });
63
56
  var GithubPollingRefreshRequest = z.object({ lane: z.enum([
64
57
  "my-prs",
65
58
  "team-review",
@@ -67,7 +60,8 @@ var GithubPollingRefreshRequest = z.object({ lane: z.enum([
67
60
  ]) });
68
61
  var GithubPollingRefreshResult = z.object({
69
62
  ok: z.boolean(),
70
- error: z.string().optional()
63
+ error: z.string().optional(),
64
+ freshness: GithubPrsFreshness.optional()
71
65
  });
72
66
  //#endregion
73
67
  //#region shared/contracts/github-ids.ts
@@ -92,20 +86,6 @@ function shortSha(sha, { chars = 7, validate = false } = {}) {
92
86
  //#region shared/contracts/team-review.ts
93
87
  var CommitSha = z.string().regex(FULL_SHA_RE);
94
88
  var repoSlug = z.string().regex(/^[^/]+\/[^/]+$/);
95
- var SearchedPr = z.object({
96
- number: z.number().int().positive(),
97
- title: z.string(),
98
- html_url: z.string(),
99
- draft: z.boolean().optional(),
100
- created_at: z.string().optional(),
101
- updated_at: z.string().optional(),
102
- repository_url: z.string(),
103
- user: z.object({
104
- login: z.string(),
105
- type: z.enum(["User", "Bot"])
106
- }).passthrough(),
107
- pull_request: z.object({}).passthrough()
108
- }).passthrough();
109
89
  var PrDetail = z.object({
110
90
  number: z.number().int().positive(),
111
91
  title: z.string(),
@@ -115,6 +95,11 @@ var PrDetail = z.object({
115
95
  login: z.string(),
116
96
  is_bot: z.boolean().optional()
117
97
  }).passthrough(),
98
+ state: z.enum([
99
+ "OPEN",
100
+ "CLOSED",
101
+ "MERGED"
102
+ ]).optional(),
118
103
  isDraft: z.boolean(),
119
104
  isCrossRepository: z.boolean(),
120
105
  baseRefName: z.string(),
@@ -241,6 +226,12 @@ var PriorReview = z.object({
241
226
  comments: z.array(ReviewComment),
242
227
  wasPosted: z.boolean()
243
228
  });
229
+ var EarlierReview = PriorReview.pick({
230
+ head: true,
231
+ verdict: true,
232
+ summary: true,
233
+ wasPosted: true
234
+ }).extend({ comments: z.array(DraftComment) });
244
235
  var ReviewThreadId = z.string().min(1).max(256).regex(NODE_ID_RE);
245
236
  var TeamReviewThreadResult = z.object({
246
237
  addressed: z.boolean(),
@@ -361,7 +352,8 @@ var ReviewDraft = z.object({
361
352
  postedAt: z.number().finite().optional(),
362
353
  postedEvent: PostedReviewEvent.optional(),
363
354
  priorReviewedHead: CommitSha.optional(),
364
- requeuedHead: CommitSha.optional()
355
+ requeuedHead: CommitSha.optional(),
356
+ earlierReview: EarlierReview.optional()
365
357
  });
366
358
  function canApproveAfterComment(draft) {
367
359
  return draft.status === "posted" && draft.postedEvent === "COMMENT";
@@ -435,6 +427,7 @@ var TeamReviewStateEntry = z.object({
435
427
  requeuedHead: CommitSha.optional(),
436
428
  priorReview: PriorReview.optional(),
437
429
  discardedReviewHead: CommitSha.optional(),
430
+ requestedAt: z.number().finite().optional(),
438
431
  updatedAt: z.number().finite()
439
432
  });
440
433
  z.record(z.string(), TeamReviewStateEntry);
@@ -673,6 +666,16 @@ var MyPr = z.object({
673
666
  isMergeQueueHeldForRepairPush: z.boolean().optional(),
674
667
  mergeQueueFailure: MyPrMergeQueueFailure.optional()
675
668
  }).refine((pr) => pr.key === `${pr.repo}#${pr.number}`);
669
+ var MyPrLaneEntry = z.strictObject({
670
+ key: pullRequestKey,
671
+ autoRebase: MyPr.shape.autoRebase,
672
+ keepMergeable: MyPr.shape.keepMergeable,
673
+ keepMergeableAttempt: MyPr.shape.keepMergeableAttempt,
674
+ isKeepMergeableFixInFlight: MyPr.shape.isKeepMergeableFixInFlight,
675
+ mergeQueuePosition: MyPr.shape.mergeQueuePosition,
676
+ isMergeQueueHeldForRepairPush: MyPr.shape.isMergeQueueHeldForRepairPush,
677
+ mergeQueueFailure: MyPr.shape.mergeQueueFailure
678
+ });
676
679
  var MyPrsStatus = z.object({
677
680
  ...githubPollingShape,
678
681
  type: z.literal("my-prs-status"),
@@ -680,11 +683,12 @@ var MyPrsStatus = z.object({
680
683
  configured: z.boolean(),
681
684
  reason: z.string().nullable().optional(),
682
685
  viewer: z.string().nullable(),
683
- prs: z.array(MyPr),
686
+ prs: z.array(MyPrLaneEntry),
684
687
  truncatedNote: z.string().nullable().optional(),
685
688
  isKeepMergeableEnabled: z.boolean().optional(),
686
689
  isMergeQueueEnabled: z.boolean().optional()
687
690
  }).passthrough();
691
+ var MyPrsSnapshot = MyPrsStatus.extend({ prs: z.array(MyPr) });
688
692
  var MyPrMergeRequest = z.object({
689
693
  repo: repositoryName,
690
694
  number: z.number().int().positive(),
@@ -842,7 +846,7 @@ var MyPrMergeStateResponse = z.object({
842
846
  }).nullable() }).nullable() }),
843
847
  errors: z.array(z.unknown()).optional()
844
848
  });
845
- var MyPrSearchResponse = z.object({
849
+ z.object({
846
850
  data: z.object({
847
851
  open: z.object({
848
852
  issueCount: nonnegativeInteger,
@@ -855,9 +859,14 @@ var MyPrSearchResponse = z.object({
855
859
  }),
856
860
  errors: z.array(z.unknown()).optional()
857
861
  });
862
+ var SESSION_NAME_PATTERN = /^[a-zA-Z0-9_\-. ()]{1,64}$/;
863
+ var SESSION_NAME_RULE_TEXT = "Session name may only contain letters, numbers, spaces, dashes, dots, underscores, and parentheses (max 64 chars)";
858
864
  var TASK_TITLE_CONTROL_CHARACTERS = /[\x00-\x1f\x7f-\x9f]/;
859
865
  var TaskTitle = z.string().refine((title) => !TASK_TITLE_CONTROL_CHARACTERS.test(title)).trim().max(120);
860
- var RefinedTaskTitle = z.object({ title: z.string().nullable() }).strict();
866
+ var RefinedTaskTitle = z.object({
867
+ title: z.string().nullable(),
868
+ name: z.string().nullable().optional()
869
+ }).strict();
861
870
  var SessionState = z.enum(STATES);
862
871
  var PendingWakeup = z.object({
863
872
  at: z.number().finite().nullable(),
@@ -900,6 +909,17 @@ var ConversationApprovalDecision = z.enum([
900
909
  "acceptForSession",
901
910
  "decline"
902
911
  ]);
912
+ var COHERENCE_HOOKS_REASON_MAX_CHARS = 80;
913
+ var COHERENCE_HOOKS_INACTIVE = Object.freeze({
914
+ notInstalled: "not installed",
915
+ unsupportedVersion: "unsupported version",
916
+ codexHooksUntrusted: "Codex hooks need trust in /hooks"
917
+ });
918
+ var CoherenceHooksState = z.discriminatedUnion("active", [z.object({ active: z.literal(true) }).strict(), z.object({
919
+ active: z.literal(false),
920
+ reason: z.string().min(1).max(COHERENCE_HOOKS_REASON_MAX_CHARS),
921
+ version: z.string().optional()
922
+ }).strict()]);
903
923
  var SessionSnapshot = z.object({
904
924
  id: z.string(),
905
925
  name: z.string(),
@@ -915,6 +935,7 @@ var SessionSnapshot = z.object({
915
935
  isWorktree: z.boolean(),
916
936
  isWorkspace: z.boolean().default(false),
917
937
  isGuarded: z.boolean().default(false),
938
+ isGuardrailsReleased: z.boolean().default(false),
918
939
  resumeSessionId: z.string().nullable(),
919
940
  activeAgents: z.number().int().nonnegative(),
920
941
  awaitingBackgroundTasks: z.boolean(),
@@ -929,8 +950,10 @@ var SessionSnapshot = z.object({
929
950
  mergeStatus: z.string().nullable(),
930
951
  mergeReason: z.string().nullable(),
931
952
  worktreeNotice: z.string().nullable(),
953
+ failureReason: z.string().nullable().optional(),
932
954
  effectiveBase: z.string().nullable(),
933
955
  linkedPrs: z.array(LinkedPr).default([]),
956
+ coherenceHooks: CoherenceHooksState.nullable().default(null),
934
957
  auditLog: z.array(z.unknown())
935
958
  }).passthrough();
936
959
  var AGENT_URL_ENV = "GLIMMERVOID_AGENT_URL";
@@ -948,29 +971,19 @@ var SshSignReply = z.union([z.object({
948
971
  ok: z.literal(false),
949
972
  error: z.string()
950
973
  }).strict()]);
951
- var AGENT_API_VERBS = [
974
+ var SESSION_COMMANDS = [
975
+ "push",
952
976
  "spawn",
953
977
  "attention",
954
978
  "board",
955
- "dispatch",
956
- "reopen",
957
- "cancel",
958
- "push",
959
979
  "edit",
960
- "limits",
961
- "factory-status",
962
- "factory-retry",
963
- "factory-setup",
964
- "factory-queue"
980
+ "review",
981
+ "reviews",
982
+ "prs",
983
+ "link-pr",
984
+ "settings"
965
985
  ];
966
- var ORCHESTRATOR_AGENT_VERBS = [
967
- "dispatch",
968
- "reopen",
969
- "cancel"
970
- ];
971
- var AgentFactoryStatusRequest = z.object({ projectId: z.string().trim().min(1).max(128).optional() }).strict();
972
- var AgentFactoryRetryRequest = z.object({ intentId: z.string().trim().min(1).max(128) }).strict();
973
- var AgentFactorySetupRequest = z.object({}).strict();
986
+ var AGENT_API_VERBS = [...SESSION_COMMANDS, "limits"];
974
987
  var AgentSpawnRequest = z.object({
975
988
  prompt: z.string({ error: "prompt must be a string" }).min(1, { error: "prompt must not be empty" }).max(2e4, { error: "prompt must be at most 20000 characters" }).refine((prompt) => !prompt.trimStart().startsWith("-"), { message: "prompt must not start with a dash, which the agent CLI would read as an option" }),
976
989
  name: z.string({ error: "name must be a string" }).min(1, { error: "name must not be empty" }).max(200, { error: "name must be at most 200 characters" }).optional(),
@@ -991,6 +1004,61 @@ z.object({
991
1004
  state: SessionSnapshot.shape.state,
992
1005
  ephemeral: SessionSnapshot.shape.ephemeral
993
1006
  }).strict();
1007
+ var AgentPullRequestRequest = z.object({ pr: z.string({ error: "pr must be a string" }).min(1, { error: "pr must not be empty" }).max(300, { error: "pr must be at most 300 characters" }) }).strict();
1008
+ var AgentSettingsRequest = z.object({
1009
+ command: z.enum(["list", "get"], { error: "command must be list or get" }),
1010
+ path: z.string({ error: "path must be a string" }).min(1, { error: "path must not be empty" }).max(200, { error: "path must be at most 200 characters" }).optional()
1011
+ }).strict();
1012
+ var AgentSettingsReply = z.union([z.object({
1013
+ ok: z.literal(true),
1014
+ text: z.string(),
1015
+ readout: z.unknown()
1016
+ }).strict(), z.object({
1017
+ ok: z.literal(false),
1018
+ error: z.string()
1019
+ }).strict()]);
1020
+ var PullRequestIdentity = QueuedReview.pick({
1021
+ key: true,
1022
+ title: true,
1023
+ url: true,
1024
+ author: true
1025
+ });
1026
+ z.object({
1027
+ ok: z.literal(true),
1028
+ configured: z.boolean(),
1029
+ reason: z.string().nullable(),
1030
+ reviewing: z.array(PullRequestIdentity.extend({ phase: InFlightReview.shape.phase })),
1031
+ queued: z.array(PullRequestIdentity),
1032
+ drafts: z.array(PullRequestIdentity.extend({
1033
+ status: ReviewDraft.shape.status,
1034
+ verdict: z.string(),
1035
+ summary: ReviewDraft.shape.summary,
1036
+ comments: z.number().int().nonnegative(),
1037
+ isOutOfDate: z.boolean()
1038
+ }))
1039
+ }).strict();
1040
+ z.object({
1041
+ ok: z.literal(true),
1042
+ configured: z.boolean(),
1043
+ prs: z.array(z.object({
1044
+ key: MyPr.shape.key,
1045
+ title: MyPr.shape.title,
1046
+ url: MyPr.shape.url,
1047
+ state: MyPr.shape.state,
1048
+ isDraft: MyPr.shape.isDraft,
1049
+ stage: MyPr.shape.stage,
1050
+ reviewDecision: MyPr.shape.reviewDecision,
1051
+ approvals: MyPr.shape.approvals,
1052
+ unresolvedThreads: MyPr.shape.unresolvedThreads,
1053
+ behindBy: MyPr.shape.behindBy,
1054
+ mergeable: MyPr.shape.mergeable,
1055
+ isInMergeQueue: MyPr.shape.isInMergeQueue,
1056
+ checks: MyPr.shape.checks.pick({
1057
+ state: true,
1058
+ failing: true
1059
+ })
1060
+ }).strict())
1061
+ }).strict();
994
1062
  var SESSION_DOC_BODY_CAP_BYTES = 262144;
995
1063
  var SESSION_DOC_PATH_MAX_CHARS = 4096;
996
1064
  var AgentEditRequest = z.object({ path: z.string({ error: "path must be a string" }).min(1, { error: "path must not be empty" }).max(SESSION_DOC_PATH_MAX_CHARS, { error: `path must be at most ${SESSION_DOC_PATH_MAX_CHARS} characters` }) }).strict();
@@ -999,13 +1067,6 @@ var SessionDoc = z.object({
999
1067
  name: z.string(),
1000
1068
  surfacedAt: z.number().finite()
1001
1069
  }).strict();
1002
- var SESSION_COMMANDS = [
1003
- "push",
1004
- "spawn",
1005
- "attention",
1006
- "board",
1007
- "edit"
1008
- ];
1009
1070
  var AgentLimitsReply = z.object({
1010
1071
  commands: z.array(z.object({
1011
1072
  name: z.enum(SESSION_COMMANDS),
@@ -1018,18 +1079,5 @@ var AgentLimitsReply = z.object({
1018
1079
  route: z.string()
1019
1080
  }).strict())
1020
1081
  }).strict().extend({ ok: z.literal(true) }).strict();
1021
- var AgentDispatchRequest = z.object({
1022
- workId: z.string().regex(/^wrk-[0-9a-f]{16}$/).optional(),
1023
- readyIntent: z.string().regex(/^wrk-[0-9a-f]{16}$/).optional()
1024
- }).strict().refine((request) => Boolean(request.workId) !== Boolean(request.readyIntent), "Expected exactly one work id or ready intent");
1025
- var AgentTicketRequest = z.object({ workId: z.string({ error: "workId must be a string" }).regex(/^wrk-[0-9a-f]{16}$/, { error: "workId must match wrk-[0-9a-f]{16}" }) }).strict();
1026
- z.discriminatedUnion("ok", [z.object({
1027
- ok: z.literal(true),
1028
- workId: z.string(),
1029
- state: z.enum(["open", "cancelled"])
1030
- }), z.object({
1031
- ok: z.literal(false),
1032
- reason: z.string()
1033
- })]);
1034
1082
  //#endregion
1035
- export { SessionPrLinks as $, SessionState as A, FULL_SHA_RE as At, MyPrKeepMergeableResult as B, KILLABLE_STATES as Bt, SESSION_COMMANDS as C, TeamReviewThreadCommentsResponse as Ct, SSH_SIGN_BODY_CAP_BYTES as D, decisionAsIfApprovalRequired as Dt, SIGN_URL_ENV as E, canApproveAfterComment as Et, LinkedPr as F, REPO_SLUG_RE as Ft, MyPrMergeWhenReadyRequest as G, MyPrMergeRequest as H, RESTARTABLE_STATES as Ht, MyPrAutoRebase as I, repoParts as It, MyPrSearchResponse as J, MyPrMergeWhenReadyResult as K, MyPrCheckContext as L, GithubPollingRefreshRequest as Lt, SshSignRequest as M, shortSha as Mt, TASK_TITLE_CONTROL_CHARACTERS as N, GH_SEGMENT as Nt, SessionDoc as O, hasRequiredActionHead as Ot, TaskTitle as P, NODE_ID_RE as Pt, MyPrsStatus as Q, MyPrCheckContextsResponse as R, GithubPollingRefreshResult as Rt, RefinedTaskTitle as S, TeamReviewStatus as St, SESSION_DOC_PATH_MAX_CHARS as T, TeamReviewThreadsRepository as Tt, MyPrMergeResult as U, STATES as Ut, MyPrMergeMethod as V, MERGEABLE_LIVE_STATES as Vt, MyPrMergeStateResponse as W, MyPrThreadsResponse as X, MyPrThreadNode as Y, MyPrsState as Z, ConversationApproval as _, TeamReviewActionRequest as _t, AgentDispatchRequest as a, GithubReviewState as at, ORCHESTRATOR_AGENT_VERBS as b, TeamReviewResolveResponse as bt, AgentFactorySetupRequest as c, QueuedReview as ct, AgentSpawnRequest as d, ReviewDraft as dt, repositoryName as et, AgentTicketRequest as f, ReviewFinding as ft, ConversationAnswers as g, SearchedPr as gt, CONVERSATION_TOOL_RESULT_HOOK_EVENT as h, ReviewVerdict as ht, AgentAttentionRequest as i, GithubReviewDecision as it, SshSignReply as j, HEX_SHA_RE as jt, SessionSnapshot as k, hasStandingViewerApproval as kt, AgentFactoryStatusRequest as l, ReviewChecksState as lt, CONVERSATION_PERMISSION_HOOK_EVENT as m, ReviewThreadId as mt, AGENT_URL_ENV as n, DECIDING_REVIEW_STATES as nt, AgentEditRequest as o, PostingPlan as ot, CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS as p, ReviewResult as pt, MyPrSearchNode as q, ASK_USER_QUESTION_TOOL_NAME as r, FindingSeverity as rt, AgentFactoryRetryRequest as s, PrDetail as st, AGENT_API_VERBS as t, CommitSha as tt, AgentLimitsReply as u, ReviewComment as ut, ConversationApprovalDecision as v, TeamReviewActionResult as vt, SESSION_DOC_BODY_CAP_BYTES as w, TeamReviewThreadResult as wt, PendingWakeup as x, TeamReviewStateEntry as xt, ConversationQuestion as y, TeamReviewCompareFiles as yt, MyPrKeepMergeableRequest as z, githubPollingShape as zt };
1083
+ export { MyPrsSnapshot as $, SessionSnapshot as A, canApproveAfterComment as At, MyPrCheckContextsResponse as B, repoParts as Bt, SESSION_DOC_BODY_CAP_BYTES as C, TeamReviewCompareFiles as Ct, SIGN_URL_ENV as D, TeamReviewThreadCommentsResponse as Dt, SESSION_NAME_RULE_TEXT as E, TeamReviewStatus as Et, TaskTitle as F, HEX_SHA_RE as Ft, MyPrMergeRequest as G, KILLABLE_STATES as Gt, MyPrKeepMergeableResult as H, GithubPollingRefreshResult as Ht, LinkedPr as I, shortSha as It, MyPrMergeWhenReadyRequest as J, STATES as Jt, MyPrMergeResult as K, MERGEABLE_LIVE_STATES as Kt, MyPr as L, GH_SEGMENT as Lt, SshSignReply as M, hasRequiredActionHead as Mt, SshSignRequest as N, hasStandingViewerApproval as Nt, SSH_SIGN_BODY_CAP_BYTES as O, TeamReviewThreadResult as Ot, TASK_TITLE_CONTROL_CHARACTERS as P, FULL_SHA_RE as Pt, MyPrThreadsResponse as Q, MyPrAutoRebase as R, NODE_ID_RE as Rt, SESSION_COMMANDS as S, TeamReviewActionResult as St, SESSION_NAME_PATTERN as T, TeamReviewStateEntry as Tt, MyPrLaneEntry as U, GithubPrsFreshness as Ut, MyPrKeepMergeableRequest as V, GithubPollingRefreshRequest as Vt, MyPrMergeMethod as W, githubPollingShape as Wt, MyPrSearchNode as X, MyPrMergeWhenReadyResult as Y, MyPrThreadNode as Z, ConversationApproval as _, ReviewFinding as _t, AgentEditRequest as a, CommitSha as at, PendingWakeup as b, ReviewVerdict as bt, AgentSettingsReply as c, FindingSeverity as ct, COHERENCE_HOOKS_INACTIVE as d, PostingPlan as dt, MyPrsState as et, CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS as f, PrDetail as ft, ConversationAnswers as g, ReviewDraft as gt, CoherenceHooksState as h, ReviewComment as ht, AgentAttentionRequest as i, repositoryName as it, SessionState as j, decisionAsIfApprovalRequired as jt, SessionDoc as k, TeamReviewThreadsRepository as kt, AgentSettingsRequest as l, GithubReviewDecision as lt, CONVERSATION_TOOL_RESULT_HOOK_EVENT as m, ReviewChecksState as mt, AGENT_URL_ENV as n, SessionPrLinks as nt, AgentLimitsReply as o, DECIDING_REVIEW_STATES as ot, CONVERSATION_PERMISSION_HOOK_EVENT as p, QueuedReview as pt, MyPrMergeStateResponse as q, RESTARTABLE_STATES as qt, ASK_USER_QUESTION_TOOL_NAME as r, pullRequestKeyFormat as rt, AgentPullRequestRequest as s, EarlierReview as st, AGENT_API_VERBS as t, MyPrsStatus as tt, AgentSpawnRequest as u, GithubReviewState as ut, ConversationApprovalDecision as v, ReviewResult as vt, SESSION_DOC_PATH_MAX_CHARS as w, TeamReviewResolveResponse as wt, RefinedTaskTitle as x, TeamReviewActionRequest as xt, ConversationQuestion as y, ReviewThreadId as yt, MyPrCheckContext as z, REPO_SLUG_RE as zt };
@@ -1,4 +1,4 @@
1
- import { C as SESSION_COMMANDS } from "./session-BlT68ppa.js";
1
+ import { S as SESSION_COMMANDS } from "./session-BwB43SCa.js";
2
2
  //#region session/core/session-routes.ts
3
3
  var SUPERVISION_LINE = "Glimmervoid supervises this session. Run glimmervoid --help for the commands it gives you and this session's limits.";
4
4
  var GUARDRAILS_LINE = "Its guardrails are OS-enforced, so a read, write or connection they refuse will not succeed on retry.";
@@ -41,11 +41,7 @@ function pushRoute({ isEphemeral, isSpawnedChild, hasOwnWorktree }) {
41
41
  };
42
42
  return ANSWERS;
43
43
  }
44
- function spawnRoute({ isEphemeral, isSpawnedChild, factoryRole }) {
45
- if (factoryRole === "worker") return {
46
- answers: false,
47
- reason: "the factory starts and counts its workers, so a worker may not spawn a session"
48
- };
44
+ function spawnRoute({ isEphemeral, isSpawnedChild }) {
49
45
  if (isSpawnedChild) return {
50
46
  answers: false,
51
47
  reason: "a spawned session may not spawn another"
@@ -56,9 +52,8 @@ function spawnRoute({ isEphemeral, isSpawnedChild, factoryRole }) {
56
52
  };
57
53
  return ANSWERS;
58
54
  }
59
- function hasOperatorCard({ isEphemeral, isSpawnedChild, factoryRole }) {
55
+ function hasOperatorCard({ isEphemeral, isSpawnedChild }) {
60
56
  if (!isEphemeral) return true;
61
- if (factoryRole !== null) return true;
62
57
  return isSpawnedChild;
63
58
  }
64
59
  function attentionRoute(caller) {
@@ -75,12 +70,32 @@ function editRoute(caller) {
75
70
  reason: "a lane session cannot surface a file, because it has no card for the operator to open the file from"
76
71
  };
77
72
  }
73
+ function operatorStateRoute(caller) {
74
+ if (hasOperatorCard(caller)) return ANSWERS;
75
+ return {
76
+ answers: false,
77
+ reason: "a lane session cannot read or queue the operator's reviews, pull requests or settings, because a lane runs on input the operator has not vetted"
78
+ };
79
+ }
80
+ function linkPrRoute(caller) {
81
+ if (hasOperatorCard(caller)) return ANSWERS;
82
+ return {
83
+ answers: false,
84
+ reason: "a lane session cannot link a pull request, because it has no card to show the link on"
85
+ };
86
+ }
78
87
  var COMMAND_ROUTES = Object.freeze({
79
88
  push: pushRoute,
80
89
  spawn: spawnRoute,
81
90
  attention: attentionRoute,
82
91
  board: () => ANSWERS,
83
- edit: editRoute
92
+ edit: editRoute,
93
+ review: operatorStateRoute,
94
+ reviews: operatorStateRoute,
95
+ prs: operatorStateRoute,
96
+ "link-pr": linkPrRoute,
97
+ settings: operatorStateRoute,
98
+ limits: () => ANSWERS
84
99
  });
85
100
  function commandLimit(name, facts) {
86
101
  const verdict = COMMAND_ROUTES[name](facts);
@@ -124,4 +139,4 @@ function formatSessionLimits({ commands, guarded, deadEnds }) {
124
139
  ];
125
140
  }
126
141
  //#endregion
127
- export { formatSessionLimits as a, spawnRoute as c, editRoute as i, supervisionLine as l, attentionRoute as n, permitsHelpCommand as o, describeSessionLimits as r, pushRoute as s, NO_OWN_WORKTREE_REASON as t };
142
+ export { permitsHelpCommand as a, formatSessionLimits as i, NO_OWN_WORKTREE_REASON as n, supervisionLine as o, describeSessionLimits as r, COMMAND_ROUTES as t };
@@ -1,10 +1,11 @@
1
1
  import { r as errorMessage, t as errorCode } from "./text-DoirglWV.js";
2
- import "./session-BlT68ppa.js";
2
+ import { c as AgentSettingsReply } from "./session-BwB43SCa.js";
3
3
  import { t as renderTable } from "./ascii-figure-core-pDAwtlKO.js";
4
4
  import { n as glimmervoidHomeDir, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
5
5
  import { n as isRecord } from "./coerce-NSst8oRP.js";
6
- import { $ as withEnvSecrets, A as settingsOf, C as deleteValueAtPath, D as scoreSettingsSearch, E as parsePosthogProjectSelection, M as FILE_ONLY_GROUPS, N as SETTINGS_REGISTRY, O as setValueAtPath, S as cloneValue, T as hasScaledUnit, X as ENV_SECRET_BINDINGS, Z as readEnvSecrets, j as valueAtPath, k as settingsGroupOf, l as saveConfigFileOnce, s as loadConfigFile, u as validateConfig, w as displayText, x as SETTINGS_INDEX } from "./config-store-BUNZs4j7.js";
7
- import { r as BrowserConfig } from "./config-CjawSOBk.js";
6
+ import { C as deleteValueAtPath, D as scoreSettingsSearch, E as parsePosthogProjectSelection, N as SETTINGS_REGISTRY, O as setValueAtPath, Q as withEnvSecrets, S as cloneValue, X as readEnvSecrets, Y as ENV_SECRET_BINDINGS, j as valueAtPath, l as saveConfigFileOnce, s as loadConfigFile, u as validateConfig } from "./config-store-DqMScSdg.js";
7
+ import { p as BrowserConfig } from "./contracts-CloExMlS.js";
8
+ import { a as fail, c as listSettings, d as renderSectionTables, f as requireConfigFileSetting, g as valueText, h as succeed, i as describeSetting, l as readSetting, m as settingsRequestForServer, n as configFileViewOf, o as fitColumn, p as sectionOf, r as defaultText, s as getSetting, t as ALL_SETTINGS } from "./settings-readout-core-DrXT4aWm.js";
8
9
  import fs from "node:fs";
9
10
  import os from "node:os";
10
11
  import { parseArgs } from "node:util";
@@ -25,132 +26,12 @@ var usage = `glimmervoid settings: read and change config.json from the command
25
26
  A secret (a bot token or API key) is never set or unset here, since a value on the command line lands in shell history;
26
27
  change it in the dashboard settings or through its environment variable.
27
28
  --json machine-readable output`;
28
- var VALUE_COLUMN_WIDTH = 40;
29
29
  var EFFECT_NOTES = Object.freeze({
30
30
  now: "A running Glimmervoid applies it without a restart.",
31
31
  "new-sessions": "Sessions started after this change use it.",
32
32
  restart: "Restart Glimmervoid to apply it."
33
33
  });
34
34
  var HAND_EDITED_SETTING_REASONS = /* @__PURE__ */ new Map([["port", "a listener port that clashes with remote.port stops Glimmervoid from starting"]]);
35
- var SECTION_BY_SETTING_ID = new Map([...SETTINGS_REGISTRY.sections.flatMap((section) => section.settings.map((setting) => [setting.id, {
36
- id: section.id,
37
- title: section.title
38
- }])), ...SETTINGS_REGISTRY.fileOnly.map((setting) => {
39
- const groupId = setting.group ?? "";
40
- return [setting.id, {
41
- id: groupId,
42
- title: settingsGroupOf(groupId)?.title ?? groupId
43
- }];
44
- })]);
45
- var ALL_SETTINGS = [...settingsOf(SETTINGS_REGISTRY.sections), ...SETTINGS_REGISTRY.fileOnly];
46
- var SECTION_ORDER = [...SETTINGS_REGISTRY.sections.map((section) => ({
47
- id: section.id,
48
- title: section.title
49
- })), ...Object.entries(FILE_ONLY_GROUPS).map(([id, group]) => ({
50
- id,
51
- title: group.title
52
- }))];
53
- function fail(message) {
54
- return {
55
- ok: false,
56
- message
57
- };
58
- }
59
- function succeed(value) {
60
- return {
61
- ok: true,
62
- value
63
- };
64
- }
65
- function isConfigFileSetting(setting) {
66
- return setting.scope === "machine" && setting.control !== "readonly";
67
- }
68
- function sectionOf(setting) {
69
- return SECTION_BY_SETTING_ID.get(setting.id) ?? {
70
- id: "",
71
- title: ""
72
- };
73
- }
74
- function describeSetting(setting) {
75
- const descriptor = {
76
- id: setting.id,
77
- path: setting.path,
78
- title: setting.title,
79
- description: setting.description,
80
- type: setting.control,
81
- scope: setting.scope,
82
- access: setting.access,
83
- effect: setting.takesEffect,
84
- default: cloneValue(setting.defaultValue) ?? null,
85
- unit: setting.unit?.storedLabel ?? setting.unit?.label ?? null,
86
- displayUnit: setting.unit?.label ?? null,
87
- storedPerDisplay: setting.unit?.storedPerDisplay ?? 1,
88
- section: sectionOf(setting)
89
- };
90
- if (setting.options) descriptor.options = setting.options.map((option) => option.value);
91
- if (setting.range) descriptor.range = setting.range;
92
- if (setting.fileOnlyReason) descriptor.fileOnlyReason = setting.fileOnlyReason;
93
- return descriptor;
94
- }
95
- function isStoredSecret(value) {
96
- return typeof value === "string" && value.length > 0;
97
- }
98
- function readSetting(setting, view) {
99
- const stored = valueAtPath(view.config, setting.path);
100
- const source = view.secretSources[setting.path] ?? (stored !== void 0 ? "config.json" : "default");
101
- const readout = {
102
- ...describeSetting(setting),
103
- secret: setting.control === "password",
104
- source
105
- };
106
- if (readout.secret) {
107
- readout.configured = isStoredSecret(stored);
108
- return readout;
109
- }
110
- readout.value = stored !== void 0 ? cloneValue(stored) : readout.default;
111
- return readout;
112
- }
113
- function fitColumn(text) {
114
- if (text.length <= VALUE_COLUMN_WIDTH) return text;
115
- return `${text.slice(0, 37)}...`;
116
- }
117
- function storedValueText(setting, value) {
118
- if (setting.valueKind) return displayText(setting, value);
119
- const stored = JSON.stringify(value ?? null);
120
- if (typeof value !== "number" || !hasScaledUnit(setting)) return stored;
121
- return `${stored} (${displayText(setting, value)})`;
122
- }
123
- function valueText(readout, setting) {
124
- if (readout.secret) return readout.configured ? "configured" : "not configured";
125
- return storedValueText(setting, readout.value);
126
- }
127
- function defaultText(setting) {
128
- return storedValueText(setting, setting.defaultValue);
129
- }
130
- function settingsBySection(settings) {
131
- return SECTION_ORDER.map((section) => ({
132
- section,
133
- settings: settings.filter((setting) => sectionOf(setting).id === section.id)
134
- })).filter((group) => group.settings.length > 0);
135
- }
136
- function renderSectionTables(settings, headers, rowOf) {
137
- return settingsBySection(settings).map(({ section, settings: grouped }) => renderTable({
138
- title: section.title,
139
- headers,
140
- rows: grouped.map(rowOf),
141
- align: headers.map(() => "left")
142
- })).join("\n\n");
143
- }
144
- function resolveSetting(argument) {
145
- return SETTINGS_INDEX.byPath.get(argument) ?? SETTINGS_INDEX.byId.get(argument) ?? null;
146
- }
147
- function requireConfigFileSetting(argument, configPath) {
148
- const setting = resolveSetting(argument);
149
- if (!setting) return fail(`${argument} is not a setting in the registry, so this command cannot read or change it; edit config.json at ${configPath} by hand`);
150
- if (setting.scope === "browser") return fail(`${setting.id} is a browser preference saved in each browser, not in config.json; change it in the dashboard under Settings > ${sectionOf(setting).title}`);
151
- if (setting.control === "readonly") return fail(`${setting.id} is a read-only status row under Settings > ${sectionOf(setting).title}; it has no config.json key`);
152
- return succeed(setting);
153
- }
154
35
  function requirePositional(positionals, index, name) {
155
36
  const value = positionals[index];
156
37
  if (value === void 0) throw new Error(`missing <${name}>\n\n${usage}`);
@@ -284,12 +165,7 @@ function openConfigFile() {
284
165
  if (!decided.path) return fail(`no config.json at ${decided.homePath}. Start Glimmervoid once to create it; glimmervoid settings schema needs no config file`);
285
166
  const loaded = readConfigFile(decided.path, homeDir);
286
167
  if (!loaded.ok) return fail(loaded.message);
287
- const secretSources = Object.fromEntries(readEnvSecrets(env).map((secret) => [`${secret.blockName}.${secret.secretKey}`, secret.environmentVariable]));
288
- return succeed({
289
- configPath: decided.path,
290
- config: loaded.value,
291
- secretSources
292
- });
168
+ return succeed(configFileViewOf(decided.path, loaded.value, env));
293
169
  }
294
170
  function print(context, jsonValue, text) {
295
171
  context.writeOutput(`${context.isJson ? JSON.stringify(jsonValue, null, 2) : text}\n`);
@@ -324,35 +200,13 @@ function requireWritableSetting(context, view) {
324
200
  }
325
201
  var commands = {
326
202
  list: (context) => {
327
- const view = requireView();
328
- const settings = ALL_SETTINGS.filter(isConfigFileSetting);
329
- const readouts = settings.map((setting) => readSetting(setting, view));
330
- const readoutById = new Map(readouts.map((readout) => [readout.id, readout]));
331
- const rowOf = (setting) => {
332
- const readout = readoutById.get(setting.id);
333
- if (!readout) return [
334
- setting.path,
335
- "",
336
- ""
337
- ];
338
- return [
339
- setting.path,
340
- fitColumn(valueText(readout, setting)),
341
- readout.source
342
- ];
343
- };
344
- return print(context, readouts, renderSectionTables(settings, [
345
- "Setting",
346
- "Value",
347
- "Source"
348
- ], rowOf));
203
+ const report = listSettings(requireView());
204
+ return print(context, report.readout, report.text);
349
205
  },
350
206
  get: (context) => {
351
207
  const view = requireView();
352
- const setting = requireSetting(context, view);
353
- const readout = readSetting(setting, view);
354
- const sourceNote = readout.secret && !readout.configured ? "" : ` (${readout.source})`;
355
- return print(context, readout, `${setting.path} = ${valueText(readout, setting)}${sourceNote}`);
208
+ const report = getSetting(view, requireSetting(context, view));
209
+ return print(context, report.readout, report.text);
356
210
  },
357
211
  set: (context) => {
358
212
  const view = requireView();
@@ -472,6 +326,26 @@ function processIo() {
472
326
  writeError: (text) => process.stderr.write(text)
473
327
  };
474
328
  }
329
+ async function runSettingsCli(commandArguments, io = processIo()) {
330
+ const serverRequest = settingsRequestForServer(commandArguments, process.env);
331
+ if (!serverRequest) return runSettingsCommand(commandArguments, io);
332
+ const { askAgentApi } = await import("./agent-api-cli-BBech5lF.js");
333
+ const reply = AgentSettingsReply.safeParse(await askAgentApi("settings", serverRequest).catch((error) => ({
334
+ ok: false,
335
+ error: errorMessage(error)
336
+ })));
337
+ if (!reply.success) {
338
+ io.writeError("settings: Glimmervoid sent a reply this command cannot read\n");
339
+ return 1;
340
+ }
341
+ if (!reply.data.ok) {
342
+ io.writeError(`settings: ${reply.data.error}\n`);
343
+ return 1;
344
+ }
345
+ const isJson = commandArguments.includes("--json");
346
+ io.writeOutput(`${isJson ? JSON.stringify(reply.data.readout, null, 2) : reply.data.text}\n`);
347
+ return 0;
348
+ }
475
349
  function runSettingsCommand(commandArguments, io = processIo()) {
476
350
  try {
477
351
  return runCommandLine(commandArguments, io);
@@ -481,4 +355,4 @@ function runSettingsCommand(commandArguments, io = processIo()) {
481
355
  }
482
356
  }
483
357
  //#endregion
484
- export { runSettingsCommand };
358
+ export { runSettingsCli };