glimmervoid 0.38.0 → 0.38.2

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 (37) hide show
  1. package/dist/bin/glimmervoid.js +17 -15
  2. package/dist/chunks/{adapters-B-IkWl-r.js → adapters-CAHxZYT3.js} +4 -4
  3. package/dist/chunks/{adapters-Dt3vwxwY.js → adapters-DDjC7_vG.js} +1 -1
  4. package/dist/chunks/{agent-api-cli-BcZ9DLCF.js → agent-api-cli-B5Tm0wXO.js} +27 -8
  5. package/dist/chunks/{agent-api-cli-3hryuewm.js → agent-api-cli-BDu1CxZf.js} +1 -1
  6. package/dist/chunks/{agent-api-core--8WtU1xU.js → agent-api-core-B_mUSenR.js} +36 -4
  7. package/dist/chunks/{agent-setup-cli-BixDoCkF.js → agent-setup-cli-DmMfCw5O.js} +1 -1
  8. package/dist/chunks/{config-BHBZsCBc.js → browser-config-BrBT8269.js} +2 -217
  9. package/dist/chunks/config-CjawSOBk.js +219 -0
  10. package/dist/chunks/{config-store-DbfMbz4j.js → config-store-BUNZs4j7.js} +4 -3
  11. package/dist/chunks/config-store-MAVQhGMh.js +1 -0
  12. package/dist/chunks/{contracts-u40eJhaf.js → contracts-HVCEJfxs.js} +6 -239
  13. package/dist/chunks/factory-D7ryES9n.js +240 -0
  14. package/dist/chunks/{git-version-BpnTd8sU.js → git-version-rWZjF2Px.js} +1 -1
  15. package/dist/chunks/{grok-xFs6zIu4.js → grok-B6bsCgdd.js} +2 -2
  16. package/dist/chunks/{hook-tools-BkxllUHE.js → hook-tools-Dl7-r2Eb.js} +1 -1
  17. package/dist/chunks/{knowledge-graph-cli-DcspNqhz.js → knowledge-graph-cli-ByUJoKw_.js} +1 -1
  18. package/dist/chunks/{main-w01-P1oZ.js → main-BNSbP-Yk.js} +689 -523
  19. package/dist/chunks/{pair-cli-BdoyrDCr.js → pair-cli-DNp8i5L4.js} +2 -2
  20. package/dist/chunks/{remote-config-61zJ0hME.js → remote-config-C_s2pnLC.js} +1 -1
  21. package/dist/chunks/{rtk-hook-core-VrUafGAp.js → rtk-hook-core-B-MpzPin.js} +89 -83
  22. package/dist/chunks/rtk-resolver-BGE6Hd_L.js +1 -0
  23. package/dist/chunks/{rtk-resolver-C_micGrL.js → rtk-resolver-BgoPsEhT.js} +1 -1
  24. package/dist/chunks/{session-8Pv0y1vz.js → session-BlT68ppa.js} +5 -2
  25. package/dist/chunks/{session-routes-D-GZC-Sy.js → session-routes-CT1JrjoT.js} +1 -1
  26. package/dist/chunks/{settings-cli-DKJsm3AP.js → settings-cli-BbzxCyG5.js} +3 -3
  27. package/dist/chunks/{ssh-sign-cli-Dc2gOCwE.js → ssh-sign-cli-C74BGTQS.js} +2 -2
  28. package/dist/client/assets/index-B5uVtedd.css +1 -0
  29. package/dist/client/assets/index-b13-NGGS.js +275 -0
  30. package/dist/client/index.html +3 -2
  31. package/dist/server/index.js +1 -1
  32. package/dist/session/hook-tool-relay.js +1 -1
  33. package/package.json +3 -2
  34. package/dist/chunks/config-store-DYj3wYgw.js +0 -1
  35. package/dist/chunks/rtk-resolver-B8BPgN9L.js +0 -1
  36. package/dist/client/assets/index-BfqmOGgc.js +0 -275
  37. package/dist/client/assets/index-DxABp5yJ.css +0 -1
@@ -2,34 +2,36 @@ import { i as sanitizeOneLine, n as requireExecutableSpawnHelper, r as firstLine
2
2
  import { a as isMissingFileError, i as errorText$1, r as errorMessage, t as errorCode } from "./text-DoirglWV.js";
3
3
  import { a as sanitizeWorktreeName, i as safePathSegment, n as equalsIgnoringCaseOnWindows, r as isPathInside, t as caseFoldedPathKey } from "./paths-Bu4eH1Yd.js";
4
4
  import { a as packageRoot, n as cliPath, o as relayPath, r as clientDir, s as resolvePackageBin, t as bundled } from "./runtime-paths-BkeftE60.js";
5
- import { At as HEX_SHA_RE, B as MyPrMergeMethod, Bt as MERGEABLE_LIVE_STATES, C as SESSION_DOC_BODY_CAP_BYTES, Ct as TeamReviewThreadResult, E as SSH_SIGN_BODY_CAP_BYTES, Et as decisionAsIfApprovalRequired, F as MyPrAutoRebase, Ft as repoParts, Ht as STATES, I as MyPrCheckContext, J as MyPrThreadNode, K as MyPrSearchNode, L as MyPrCheckContextsResponse, M as TASK_TITLE_CONTROL_CHARACTERS, Mt as GH_SEGMENT, N as TaskTitle, Nt as NODE_ID_RE, Ot as hasStandingViewerApproval, P as LinkedPr, Pt as REPO_SLUG_RE, R as MyPrKeepMergeableRequest, St as TeamReviewThreadCommentsResponse, T as SIGN_URL_ENV, Tt as canApproveAfterComment, U as MyPrMergeStateResponse, V as MyPrMergeRequest, Vt as RESTARTABLE_STATES, W as MyPrMergeWhenReadyRequest, X as MyPrsState, Y as MyPrThreadsResponse, Z as MyPrsStatus, a as AgentDispatchRequest, at as PostingPlan, bt as TeamReviewStateEntry, ct as ReviewChecksState, d as AgentTicketRequest, dt as ReviewFinding, et as CommitSha, f as CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS, ft as ReviewResult, gt as TeamReviewActionRequest, ht as SearchedPr, it as GithubReviewState, j as SshSignRequest, jt as shortSha$1, kt as FULL_SHA_RE, lt as ReviewComment, m as CONVERSATION_TOOL_RESULT_HOOK_EVENT, mt as ReviewVerdict, n as AGENT_URL_ENV, nt as FindingSeverity, ot as PrDetail, p as CONVERSATION_PERMISSION_HOOK_EVENT, pt as ReviewThreadId, q as MyPrSearchResponse, r as ASK_USER_QUESTION_TOOL_NAME, rt as GithubReviewDecision, st as QueuedReview, tt as DECIDING_REVIEW_STATES, ut as ReviewDraft, v as ConversationQuestion, vt as TeamReviewCompareFiles, wt as TeamReviewThreadsRepository, x as RefinedTaskTitle, xt as TeamReviewStatus, y as ORCHESTRATOR_AGENT_VERBS, yt as TeamReviewResolveResponse, zt as KILLABLE_STATES } from "./session-8Pv0y1vz.js";
5
+ import { At as FULL_SHA_RE, Bt as KILLABLE_STATES, Ct as TeamReviewThreadCommentsResponse, D as SSH_SIGN_BODY_CAP_BYTES, Dt as decisionAsIfApprovalRequired, E as SIGN_URL_ENV, Et as canApproveAfterComment, F as LinkedPr, Ft as REPO_SLUG_RE, G as MyPrMergeWhenReadyRequest, H as MyPrMergeRequest, Ht as RESTARTABLE_STATES, I as MyPrAutoRebase, It as repoParts, J as MyPrSearchResponse, L as MyPrCheckContext, M as SshSignRequest, Mt as shortSha$1, N as TASK_TITLE_CONTROL_CHARACTERS, Nt as GH_SEGMENT, P as TaskTitle, Pt as NODE_ID_RE, Q as MyPrsStatus, R as MyPrCheckContextsResponse, S as RefinedTaskTitle, St as TeamReviewStatus, Tt as TeamReviewThreadsRepository, Ut as STATES, V as MyPrMergeMethod, Vt as MERGEABLE_LIVE_STATES, W as MyPrMergeStateResponse, X as MyPrThreadsResponse, Y as MyPrThreadNode, Z as MyPrsState, _t as TeamReviewActionRequest, a as AgentDispatchRequest, at as GithubReviewState, b as ORCHESTRATOR_AGENT_VERBS, bt as TeamReviewResolveResponse, ct as QueuedReview, dt as ReviewDraft, f as AgentTicketRequest, ft as ReviewFinding, gt as SearchedPr, h as CONVERSATION_TOOL_RESULT_HOOK_EVENT, ht as ReviewVerdict, it as GithubReviewDecision, jt as HEX_SHA_RE, kt as hasStandingViewerApproval, lt as ReviewChecksState, m as CONVERSATION_PERMISSION_HOOK_EVENT, mt as ReviewThreadId, n as AGENT_URL_ENV, nt as DECIDING_REVIEW_STATES, ot as PostingPlan, p as CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS, pt as ReviewResult, q as MyPrSearchNode, r as ASK_USER_QUESTION_TOOL_NAME, rt as FindingSeverity, st as PrDetail, tt as CommitSha, ut as ReviewComment, w as SESSION_DOC_BODY_CAP_BYTES, wt as TeamReviewThreadResult, xt as TeamReviewStateEntry, y as ConversationQuestion, yt as TeamReviewCompareFiles, z as MyPrKeepMergeableRequest } from "./session-BlT68ppa.js";
6
6
  import { n as execFileAsync, o as spawn, r as execFileSync, t as execFile } from "./child-process-safe-CbQnyh7D.js";
7
7
  import { n as glimmervoidHomeDir, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
8
- import { i as parseCommandLine, n as warnWhenGitIsTooOld } from "./git-version-BpnTd8sU.js";
8
+ import { i as parseCommandLine, n as warnWhenGitIsTooOld } from "./git-version-rWZjF2Px.js";
9
9
  import { n as checkGuardrailsDependencies, t as allowGuardedSpawn } from "./guardrails-deps-Cb-ki4EU.js";
10
10
  import { t as HOOK_URL_ENV } from "./hook-relay-core-DA_bz2KA.js";
11
11
  import { t as HOOK_VIA_GUARDRAILS_PROXY_ENV } from "./guardrails-proxy-core-BI3rdY-m.js";
12
12
  import { t as refocusReplyFor } from "./refocus-core-BKQKllq7.js";
13
13
  import { a as positiveIntOr, c as textOr, i as numberOr, n as isRecord, o as positiveNumberOr, r as nonNegativeIntOr, s as rawTextOr, t as coercedNumberOr } from "./coerce-NSst8oRP.js";
14
14
  import { n as parseJsonRecord, t as parseJsonOrNull } from "./json-core-dfa_7Fak.js";
15
- import { a as SANE_YOLO_FILES } from "./rtk-hook-core-VrUafGAp.js";
15
+ import { s as saneYoloFiles } from "./rtk-hook-core-B-MpzPin.js";
16
16
  import { _ as lineStartOffsets, a as projectForUri, b as replacedSpanOfWholeTextChange, c as visionsLaneReloadSignature, d as applyDidOpen, f as createDocStore, g as lineOfOffset, h as getDoc, i as isUriInProjects, l as applyDidChange, m as formatRange, n as applyEditorNotification, o as resolveVisionsScopeProjects, p as detectBlankLineBoundary, r as createEditorState, s as scopePathsOf, t as ACTIVITY_METHOD, u as applyDidClose, v as listDocs, x as uriOfParams, y as offsetOfPosition } from "./ingest-editor-core-B2tycW_m.js";
17
17
  import { n as DEFAULT_MAX_MS, r as nextBackoffMs, t as DEFAULT_BASE_MS } from "./backoff-DjVpfHk7.js";
18
18
  import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
19
- import { o as permitsHelpCommand, r as describeSessionLimits } from "./session-routes-D-GZC-Sy.js";
20
- import { a as decideFactoryControlAllowance, c as deriveChildSessionName, d as describeUnavailableFactoryState, f as formatFactoryStatus, h as parseAgentVerb, i as decideEditAllowance, l as describePushLanding, m as isOrchestratorAgentVerb, n as decideAgentRequest, o as decideSpawnAllowance, r as decideAttentionAllowance, s as decideTicketAction, t as REFUSAL_REASON, u as describePushRouteRefusal } from "./agent-api-core--8WtU1xU.js";
21
- import { s as GLIMMERVOID_SECRET_KEYS } from "./grok-xFs6zIu4.js";
19
+ import { o as permitsHelpCommand, r as describeSessionLimits } from "./session-routes-CT1JrjoT.js";
20
+ import { $ as CoherenceTicketCreated, C as WorkflowsState, G as USAGE_INTEGER_RANGES, N as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, T as USAGE_VENDOR_KEYS, X as CoherenceOrient, a as DEFAULT_FACTORY_CHECKS, b as WorkflowSearchNode, et as CoherenceWorkCreated, o as DEFAULT_FACTORY_PROTECTED_PATHS, tt as CoherenceWorkInspect, v as WorkflowCommentBody, w as USAGE_COST_MODES, x as WorkflowsSettings, y as WorkflowLabelName } from "./browser-config-BrBT8269.js";
21
+ import { _ as isSingleFactoryPathSegment, a as FactoryControlRequest, c as FactoryHarnessVerdict, d as FactoryQueueIntentRequest, g as FactoryWorkerEvent, i as FactoryConsequences, l as FactoryLaneState, m as FactoryReviewerOutput, n as FACTORY_ERROR_MAX_CHARS, p as FactoryReviewVerdict, r as FACTORY_PROTECTED_PATH_FLOOR, s as FactoryHarnessStateLine, u as FactoryProjectState } from "./factory-D7ryES9n.js";
22
+ import { _ as parseAgentVerb, a as decideFactoryControlAllowance, c as deriveChildSessionName, d as describePushRouteRefusal, f as describeUnavailableFactoryState, g as isOrchestratorAgentVerb, i as decideEditAllowance, l as describeFactorySetupProfile, m as formatFactoryStatus, n as decideAgentRequest, o as decideSpawnAllowance, p as findSessionProjectId, r as decideAttentionAllowance, s as decideTicketAction, t as REFUSAL_REASON, u as describePushLanding } from "./agent-api-core-B_mUSenR.js";
23
+ import { s as GLIMMERVOID_SECRET_KEYS } from "./grok-B6bsCgdd.js";
22
24
  import { n as shellQuote } from "./hook-command-core-qTNK-xMF.js";
23
25
  import { C as headroomFromReadings, D as parseMemAvailableBytes, E as parseCgroupV2Path, S as cgroupLimitBytes, T as parseCgroupBytes, _ as createSpawnGate, a as jsonStateLoadError, c as loadedJsonValue, d as writeJsonAtomicSync, f as writeTextAtomic, g as createSerialQueue, h as createMemoryAdmission, i as createJsonStateWriter, m as createKeyedSerialQueue, n as appendJsonLines, o as loadJsonStateFile, p as writeTextAtomicSync, r as createJsonStateStore, s as loadJsonStateFileSync, t as appendJsonLine, u as writeJsonAtomic, v as isQueueAdmissionAbandoned, w as memoryReserveBytes, x as cgroupAncestorPaths, y as isQueueAdmissionTimeout } from "./json-file-CIJf0Cel.js";
24
- import { $ as CoherenceWorkCreated, C as USAGE_COST_MODES, M as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, Q as CoherenceTicketCreated, S as WorkflowsState, W as USAGE_INTEGER_RANGES, Y as CoherenceOrient, a as ConfigUpdate, b as WorkflowSearchNode, c as RUNTIME_CONFIG_SCALAR_KEYS, et as CoherenceWorkInspect, l as TASK_TITLE_SOURCE_PRIORITY, m as DEFAULT_FACTORY_PROTECTED_PATHS, o as PersistedTaskTitle, p as DEFAULT_FACTORY_CHECKS, r as BrowserConfig, s as ProjectConfig, u as configIssueMessage, v as WorkflowCommentBody, w as USAGE_VENDOR_KEYS, x as WorkflowsSettings, y as WorkflowLabelName } from "./config-BHBZsCBc.js";
25
- import { B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as decideTelemetryConsent, H as classifySessionExit, I as TELEMETRY_FLAGS_URL, J as parsePosthogReleaseId, K as exceptionFingerprint, L as adapterBucket, P as FIRST_RUN_NOTICE, Q as stableConfigKey, R as buildAiGenerationEvents, U as decideIsDevInstall, V as buildFactoryDecisionEvent, W as decideRemoteTelemetryState, Y as resolveProjectToken, a as generateProjectId, at as usablePrefixes, b as validateSettingsBlock, ct as comparableDirectoryPath, d as assetForPlatform, et as DEFAULT_BRANCH_GC_PREFIXES, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as sessionIdFromBranch, lt as isSameDirectoryPath, m as installTargetPath, n as DEFAULT_CONFIG, nt as planBranchGc, o as glimmervoidHomeDir$1, ot as worktreeIntegrationTips, p as findEscapingArchiveMember, q as nodeMajorVersion, r as createConfigStore, rt as planWorktreeGc, st as canonicalizePath, t as ABORT_CONFIG_SAVE, tt as matchedPrefix, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-DbfMbz4j.js";
26
- import { $ as FactoryControlRequest, A as ChangeMap, B as MergedPrListing, C as GithubIssuePullRequestsRepository, D as IssuesSearchResponse, E as IssueUpdate, F as BenchmarkJudgement, G as TELEMETRY_EVENT_SCHEMAS, H as PrCheckoutCaseInput, I as BenchmarkRun, J as FACTORY_DECISION_OUTPUT_MAX_BYTES, L as BenchmarkStatus, M as BenchmarkActionRequest, N as BenchmarkCase, O as IssuesState, P as BenchmarkId, Q as FactoryConsequences, R as BenchmarkSuite, S as planTitle, T as IssueKey, V as MinedPrReviewData, W as PendingCrashReport, X as FACTORY_ERROR_MAX_CHARS, Y as FactoryDecisionLogLine, Z as FACTORY_PROTECTED_PATH_FLOOR, _ as PLAN_RESULT_HOOK_EVENT, a as parseDataClientMessage, at as FactoryReviewVerdict, b as PlanRevision, c as DIFF_ANNOTATION_NOTE_MAX_CHARS, ct as isSingleFactoryPathSegment, d as MAX_RAW_LINE_CHARS, et as FactoryHarnessStateLine, f as TraceCheckpoint, g as PLAN_HOOK_OUTPUT_MAX_CHARS, h as PLAN_HOOK_EVENT, i as parseDataAttachHistory, it as FactoryQueueIntentRequest, j as changeMapFactId, k as IssuesStatus, l as InstallFlavor, m as PLAN_BODY_CAP_BYTES, n as HookEnvelope, nt as FactoryLaneState, o as CONTROL_FRAME_MAX_BYTES, ot as FactoryReviewerOutput, p as TraceRecord, q as TelemetryState, r as DEEP_HISTORY_SCROLLBACK_LINES, rt as FactoryProjectState, s as ClientMessage, st as FactoryWorkerEvent, t as HTTP_URL_RE, tt as FactoryHarnessVerdict, u as UpdateJournal, v as PLAN_TOOL_NAME, w as GithubIssueResponse, x as parseExitPlanModeHookPayload, y as PlanDecision, z as CommitComparison } from "./contracts-u40eJhaf.js";
27
- import { A as shouldPersistWarehouse, C as isUsageFile, D as resolveProjectsDirs, E as projectDirCandidates, M as claudeCode, O as scopedClaudeRoots, S as grokRootCandidates, T as passOutcome, _ as continuationDelayMs, a as describeAgentResolvability, b as expandTilde, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as codexSessionIdFromPath, h as codexRootCandidates, i as customAgentFingerprint, j as splitLines$1, k as shouldEvaluateDespiteIoFailures, l as listAgentIds, m as codexHomes, n as cachedAgentResolvability, o as getAdapter, p as codexFallbackRoots, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as decideFileRead, w as laneSpendStatus, x as grokHomes, y as dedupeCodexFiles } from "./adapters-B-IkWl-r.js";
28
- import { t as HOOK_TOOLS } from "./hook-tools-BkxllUHE.js";
26
+ import { B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as decideTelemetryConsent, H as classifySessionExit, I as TELEMETRY_FLAGS_URL, J as parsePosthogReleaseId, K as exceptionFingerprint, L as adapterBucket, P as FIRST_RUN_NOTICE, Q as stableConfigKey, R as buildAiGenerationEvents, U as decideIsDevInstall, V as buildFactoryDecisionEvent, W as decideRemoteTelemetryState, Y as resolveProjectToken, a as generateProjectId, at as usablePrefixes, b as validateSettingsBlock, ct as comparableDirectoryPath, d as assetForPlatform, et as DEFAULT_BRANCH_GC_PREFIXES, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as sessionIdFromBranch, lt as isSameDirectoryPath, m as installTargetPath, n as DEFAULT_CONFIG, nt as planBranchGc, o as glimmervoidHomeDir$1, ot as worktreeIntegrationTips, p as findEscapingArchiveMember, q as nodeMajorVersion, r as createConfigStore, rt as planWorktreeGc, st as canonicalizePath, t as ABORT_CONFIG_SAVE, tt as matchedPrefix, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-BUNZs4j7.js";
27
+ import { a as ConfigUpdate, c as RUNTIME_CONFIG_SCALAR_KEYS, l as TASK_TITLE_SOURCE_PRIORITY, o as PersistedTaskTitle, r as BrowserConfig, s as ProjectConfig, u as configIssueMessage } from "./config-CjawSOBk.js";
28
+ import { A as ChangeMap, B as MergedPrListing, C as GithubIssuePullRequestsRepository, D as IssuesSearchResponse, E as IssueUpdate, F as BenchmarkJudgement, G as TELEMETRY_EVENT_SCHEMAS, H as PrCheckoutCaseInput, I as BenchmarkRun, J as FACTORY_DECISION_OUTPUT_MAX_BYTES, L as BenchmarkStatus, M as BenchmarkActionRequest, N as BenchmarkCase, O as IssuesState, P as BenchmarkId, R as BenchmarkSuite, S as planTitle, T as IssueKey, V as MinedPrReviewData, W as PendingCrashReport, Y as FactoryDecisionLogLine, _ as PLAN_RESULT_HOOK_EVENT, a as parseDataClientMessage, b as PlanRevision, c as DIFF_ANNOTATION_NOTE_MAX_CHARS, d as MAX_RAW_LINE_CHARS, f as TraceCheckpoint, g as PLAN_HOOK_OUTPUT_MAX_CHARS, h as PLAN_HOOK_EVENT, i as parseDataAttachHistory, j as changeMapFactId, k as IssuesStatus, l as InstallFlavor, m as PLAN_BODY_CAP_BYTES, n as HookEnvelope, o as CONTROL_FRAME_MAX_BYTES, p as TraceRecord, q as TelemetryState, r as DEEP_HISTORY_SCROLLBACK_LINES, s as ClientMessage, t as HTTP_URL_RE, u as UpdateJournal, v as PLAN_TOOL_NAME, w as GithubIssueResponse, x as parseExitPlanModeHookPayload, y as PlanDecision, z as CommitComparison } from "./contracts-HVCEJfxs.js";
29
+ import { A as shouldPersistWarehouse, C as isUsageFile, D as resolveProjectsDirs, E as projectDirCandidates, M as claudeCode, O as scopedClaudeRoots, S as grokRootCandidates, T as passOutcome, _ as continuationDelayMs, a as describeAgentResolvability, b as expandTilde, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as codexSessionIdFromPath, h as codexRootCandidates, i as customAgentFingerprint, j as splitLines$1, k as shouldEvaluateDespiteIoFailures, l as listAgentIds, m as codexHomes, n as cachedAgentResolvability, o as getAdapter, p as codexFallbackRoots, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as decideFileRead, w as laneSpendStatus, x as grokHomes, y as dedupeCodexFiles } from "./adapters-CAHxZYT3.js";
30
+ import { t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
29
31
  import { a as formatSshPublicKey, c as orderAgentSockets, i as commitSigningShimText, l as parseSshPublicKey, n as NO_AGENT_HOLDS_KEY, o as isForwardedAgentDirName, r as agentListsKey, s as isSignableGitObject, t as COMMIT_SIGNING_SHIM_NAME } from "./ssh-signing-core-CRhVVWNW.js";
30
- import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-61zJ0hME.js";
32
+ import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-C_s2pnLC.js";
31
33
  import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-B-ZeRdsi.js";
32
- import { t as getRtkPath } from "./rtk-resolver-C_micGrL.js";
34
+ import { t as getRtkPath } from "./rtk-resolver-BgoPsEhT.js";
33
35
  import { createRequire } from "node:module";
34
36
  import fs, { constants, readFileSync } from "node:fs";
35
37
  import path, { join, resolve } from "node:path";
@@ -198,6 +200,7 @@ function createLifecycle({ shutdown, httpServer, extraServers = [], onRestart =
198
200
  warn: log
199
201
  });
200
202
  closeExtraServers(extraServers);
203
+ await prepareHandOffOnce();
201
204
  let exited = false;
202
205
  const doExit = () => {
203
206
  if (exited) return;
@@ -5008,6 +5011,70 @@ function createAgentApiWiring({ config, agentSessions, listAllSessions, listBoar
5008
5011
  if (routeRefusal) return routeRefusal;
5009
5012
  return describePushLanding(await session.mergeAndContinue({ force: true }));
5010
5013
  }
5014
+ async function setUpFactoryProject(session, factoryPort, projects) {
5015
+ const projectId = findSessionProjectId(config.projects, session.path);
5016
+ if (!projectId) return {
5017
+ status: 404,
5018
+ body: {
5019
+ ok: false,
5020
+ error: `no configured project has the path ${session.path}, so the operator has to add this repository as a project first`
5021
+ }
5022
+ };
5023
+ const outcome = await factoryPort.rerunSetup(projectId);
5024
+ if (!outcome.ok) return {
5025
+ status: 409,
5026
+ body: {
5027
+ ok: false,
5028
+ error: outcome.reason
5029
+ }
5030
+ };
5031
+ return {
5032
+ status: 200,
5033
+ body: {
5034
+ ok: true,
5035
+ projectId,
5036
+ profile: outcome.profile,
5037
+ text: describeFactorySetupProfile(outcome.profile, projects.some((project) => project.projectId === projectId))
5038
+ }
5039
+ };
5040
+ }
5041
+ async function queueFactoryIntent(session, factoryPort, projects, request) {
5042
+ const projectId = findSessionProjectId(config.projects, session.path);
5043
+ if (!projectId) return {
5044
+ status: 404,
5045
+ body: {
5046
+ ok: false,
5047
+ error: `no configured project has the path ${session.path}, so the operator has to add this repository as a project first`
5048
+ }
5049
+ };
5050
+ if (!projects.some((project) => project.projectId === projectId)) return {
5051
+ status: 409,
5052
+ body: {
5053
+ ok: false,
5054
+ error: `${projectId} is not a factory project yet: commit a coherence.config.json holding {} at the repository root, land it on the integration branch with glimmervoid push, then queue again`
5055
+ }
5056
+ };
5057
+ const outcome = await factoryPort.queueIntent({
5058
+ ...request,
5059
+ projectId
5060
+ });
5061
+ if (!outcome.ok) return {
5062
+ status: 409,
5063
+ body: {
5064
+ ok: false,
5065
+ error: outcome.error ?? "the factory refused the intent"
5066
+ }
5067
+ };
5068
+ return {
5069
+ status: 200,
5070
+ body: {
5071
+ ok: true,
5072
+ projectId,
5073
+ workId: outcome.workId,
5074
+ text: `Queued ${outcome.workId ?? "the intent"} on ${projectId}. Follow it with glimmervoid factory status --project ${projectId}`
5075
+ }
5076
+ };
5077
+ }
5011
5078
  async function handle(session, verb, payload) {
5012
5079
  const parsed = parseAgentVerb(verb, payload);
5013
5080
  if (!parsed.ok) return {
@@ -5017,7 +5084,7 @@ function createAgentApiWiring({ config, agentSessions, listAllSessions, listBoar
5017
5084
  error: parsed.error
5018
5085
  }
5019
5086
  };
5020
- if (parsed.verb === "factory-status" || parsed.verb === "factory-retry") {
5087
+ if (parsed.verb === "factory-status" || parsed.verb === "factory-retry" || parsed.verb === "factory-setup" || parsed.verb === "factory-queue") {
5021
5088
  const allowance = decideFactoryControlAllowance(roleFactsOf(session));
5022
5089
  if (!allowance.ok) return {
5023
5090
  status: allowance.status,
@@ -5034,6 +5101,8 @@ function createAgentApiWiring({ config, agentSessions, listAllSessions, listBoar
5034
5101
  error: "Factory is not running"
5035
5102
  }
5036
5103
  };
5104
+ if (parsed.verb === "factory-setup") return setUpFactoryProject(session, factory, projects);
5105
+ if (parsed.verb === "factory-queue") return queueFactoryIntent(session, factory, projects, parsed.request);
5037
5106
  if (parsed.verb === "factory-status") {
5038
5107
  const selectedProjects = parsed.request.projectId === void 0 ? projects : projects.filter((project) => project.projectId === parsed.request.projectId);
5039
5108
  if (parsed.request.projectId !== void 0 && selectedProjects.length === 0) return {
@@ -7030,6 +7099,7 @@ function createSessionEventWiring(dependencies) {
7030
7099
  };
7031
7100
  let lastPersistedWasActive = null;
7032
7101
  let lastPersistedWasWorking = null;
7102
+ let isTurnWorking = null;
7033
7103
  let spawnedAtMs = null;
7034
7104
  const persistProjectField = (field, value) => {
7035
7105
  Promise.resolve(persistSessionField(dependencies.configStore, dependencies.config, session.id, field, value)).catch((error) => dependencies.logger.warn(`[config] Failed to persist ${field}: ${errorMessage(error)}`));
@@ -7044,6 +7114,14 @@ function createSessionEventWiring(dependencies) {
7044
7114
  duration_seconds: durationSeconds
7045
7115
  });
7046
7116
  };
7117
+ const persistWasWorking = () => {
7118
+ const hasBackgroundWork = session.hasBackgroundWork;
7119
+ if (isTurnWorking === null && !hasBackgroundWork) return;
7120
+ const wasWorking = isTurnWorking === true || hasBackgroundWork;
7121
+ if (wasWorking === lastPersistedWasWorking) return;
7122
+ lastPersistedWasWorking = wasWorking;
7123
+ persistProjectField("wasWorking", wasWorking);
7124
+ };
7047
7125
  let liveTranscriptPath = null;
7048
7126
  session.on("claude-session-id", ({ id, vendor, isResumeTarget, transcriptPath }) => {
7049
7127
  liveTranscriptPath = transcriptPath;
@@ -7131,11 +7209,9 @@ function createSessionEventWiring(dependencies) {
7131
7209
  lastPersistedWasActive = nextWasActive;
7132
7210
  persistProjectField("wasActive", nextWasActive);
7133
7211
  }
7134
- const nextWasWorking = decideWasWorkingFlip(to, event, detail?.isIdleCompactionActivity === true);
7135
- if (nextWasWorking !== null && nextWasWorking !== lastPersistedWasWorking) {
7136
- lastPersistedWasWorking = nextWasWorking;
7137
- persistProjectField("wasWorking", nextWasWorking);
7138
- }
7212
+ const nextIsTurnWorking = decideWasWorkingFlip(to, event, detail?.isIdleCompactionActivity === true);
7213
+ if (nextIsTurnWorking !== null) isTurnWorking = nextIsTurnWorking;
7214
+ persistWasWorking();
7139
7215
  const acknowledgeDecision = decideAcknowledge(isAcknowledgeDeferredForCompaction, from, event, detail?.isIdleCompactionActivity === true);
7140
7216
  isAcknowledgeDeferredForCompaction = acknowledgeDecision.isAcknowledgeDeferred;
7141
7217
  clearCompactionConfirm();
@@ -7192,6 +7268,7 @@ function createSessionEventWiring(dependencies) {
7192
7268
  timestamp: Date.now()
7193
7269
  }));
7194
7270
  session.on("agents-change", (payload) => {
7271
+ persistWasWorking();
7195
7272
  dependencies.telegramChannel.recheck(session.id);
7196
7273
  dependencies.broadcastControl({
7197
7274
  type: "session-agents",
@@ -7203,6 +7280,7 @@ function createSessionEventWiring(dependencies) {
7203
7280
  });
7204
7281
  });
7205
7282
  relay("wakeup-change", "session-wakeup");
7283
+ session.on("wakeup-change", persistWasWorking);
7206
7284
  relay("prompt-kind-change", "session-prompt");
7207
7285
  relay("conversation-change", "session-conversation");
7208
7286
  session.on("merge-status", ({ mergeStatus, reason, parked }) => {
@@ -7432,7 +7510,7 @@ async function listRepoConversations({ repoPath, projectsDir, git, fsMod, limit
7432
7510
  //#endregion
7433
7511
  //#region session/core/auto-resume.ts
7434
7512
  var RESUME_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
7435
- var AUTO_CONTINUE_PROMPT = "Glimmervoid restarted while you were mid-turn and resumed this conversation. This is not a new request from the user: carry on with the task you were working on. Any tool call, background command or subagent that was running was stopped and its outcome is unknown, so check the current state, such as files, git status and running processes, before relying on it or repeating it. Do not recap or ask for confirmation. If the task was already finished, say so in one line.";
7513
+ var AUTO_CONTINUE_PROMPT = "Glimmervoid restarted while you were working and resumed this conversation. This is not a new request from the user: carry on with the task you were working on. Any tool call, background command, monitor or subagent that was running was stopped and its outcome is unknown, so check the current state, such as files, git status and running processes, before relying on it or repeating it, and start again any background work the task still needs. Do not recap or ask for confirmation. If the task was already finished, say so in one line.";
7436
7514
  function pickAutoResume(projects, config) {
7437
7515
  if (!Array.isArray(projects)) return [];
7438
7516
  if (config && config.autoResume === false) return [];
@@ -14653,6 +14731,12 @@ function createTaskRegistry({ agentTtlMs = DEFAULT_AGENT_TTL_MS, shellTaskTtlMs
14653
14731
  reap(at);
14654
14732
  return isOnlyBackgroundTasks(declaredEntries, countedAgents, idleTaskIds, (entry) => entryAgeMs(entry, at), shellTaskTtlMs, idleTeammateNames.size, teammateTaskTtlMs, agentTtlMs);
14655
14733
  },
14734
+ hasLiveMonitor() {
14735
+ const at = now();
14736
+ reap(at);
14737
+ if (declaredEntries === null) return false;
14738
+ return declaredEntries.some((entry) => entry.type === "monitor" && !(entry.id && idleTaskIds.has(entry.id)) && entryAgeMs(entry, at) < shellTaskTtlMs);
14739
+ },
14656
14740
  getBreakdown() {
14657
14741
  return breakdown;
14658
14742
  },
@@ -15174,6 +15258,431 @@ function createSessionOutput(options) {
15174
15258
  };
15175
15259
  }
15176
15260
  //#endregion
15261
+ //#region server/guardrails/core/guardrails-policy-core.ts
15262
+ var VENDOR_PROFILES = Object.freeze({
15263
+ claude: {
15264
+ homeEntries: [".claude", ".claude.json"],
15265
+ launchWritableFolders: ({ cwd, agentSessionId }) => [path.join("projects", encodeProjectDir(cwd)), ...agentSessionId === null ? [] : [path.join("session-env", agentSessionId)]],
15266
+ launchPrivateFolders: ["shell-snapshots"],
15267
+ launchHomeEnvName: null,
15268
+ loginFiles: [".credentials.json"],
15269
+ configEntries: [
15270
+ "settings.json",
15271
+ "settings.local.json",
15272
+ "hooks",
15273
+ "skills",
15274
+ "plugins",
15275
+ "commands",
15276
+ "agents",
15277
+ "CLAUDE.md",
15278
+ "AGENTS.md"
15279
+ ],
15280
+ apiDomains: ["api.anthropic.com", "platform.claude.com"],
15281
+ launchEnv: { DISABLE_AUTOUPDATER: "1" }
15282
+ },
15283
+ codex: {
15284
+ homeEntries: [".codex"],
15285
+ launchWritableFolders: () => [],
15286
+ launchPrivateFolders: [],
15287
+ launchHomeEnvName: "CODEX_HOME",
15288
+ loginFiles: ["auth.json"],
15289
+ configEntries: [
15290
+ "config.toml",
15291
+ "AGENTS.md",
15292
+ "skills",
15293
+ "rules",
15294
+ "prompts",
15295
+ "hooks.json"
15296
+ ],
15297
+ apiDomains: [
15298
+ "chatgpt.com",
15299
+ "*.chatgpt.com",
15300
+ "auth.openai.com",
15301
+ "api.openai.com",
15302
+ "*.openai.com"
15303
+ ],
15304
+ launchEnv: {}
15305
+ }
15306
+ });
15307
+ var GUARDRAILS_VENDORS = Object.freeze(["claude", "codex"]);
15308
+ var UNWRAPPED_VENDOR_HOME_ENTRIES = Object.freeze([".grok"]);
15309
+ var CREDENTIAL_HOME_ENTRIES = Object.freeze([
15310
+ ".ssh",
15311
+ ".config/gh",
15312
+ "Library/Keychains",
15313
+ ".git-credentials"
15314
+ ]);
15315
+ var CLOUD_CREDENTIAL_HOME_ENTRIES = Object.freeze([
15316
+ ".aws",
15317
+ ".azure",
15318
+ ".config/gcloud",
15319
+ ".kube",
15320
+ ".docker",
15321
+ ".gnupg",
15322
+ ".netrc",
15323
+ ".npmrc"
15324
+ ]);
15325
+ var STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES = Object.freeze(["Library/Keychains"]);
15326
+ var XDG_CONFIG_DEFAULT_HOME_PREFIX = ".config/";
15327
+ var SHARED_TEMP_DIRS = Object.freeze(["/tmp/claude", "/private/tmp/claude"]);
15328
+ var SHARED_HOME_WRITE_ENTRIES = Object.freeze([".npm/_logs"]);
15329
+ var GUARDRAILS_PLACEHOLDER_NAMES = Object.freeze([
15330
+ ".bash_profile",
15331
+ ".bashrc",
15332
+ ".claude",
15333
+ ".gitconfig",
15334
+ ".gitmodules",
15335
+ ".idea",
15336
+ ".mcp.json",
15337
+ ".profile",
15338
+ ".ripgreprc",
15339
+ ".vscode",
15340
+ ".zprofile",
15341
+ ".zshrc"
15342
+ ]);
15343
+ var WHOLE_FILESYSTEM = "/";
15344
+ var GUARDRAILS_TEMP_FOLDER = "guardrails-temp";
15345
+ var GLIMMERVOID_CONFIG_SIBLING_ENTRIES = Object.freeze([
15346
+ "bin",
15347
+ "pairings.json",
15348
+ "pairings-seen.json",
15349
+ "plans",
15350
+ "telegram-outbox.json",
15351
+ "traces",
15352
+ "uploads",
15353
+ "usage-budget-state.json",
15354
+ "usage-lanes.json",
15355
+ "usage-warehouse.json",
15356
+ "visions-intent.json"
15357
+ ]);
15358
+ var GLIMMERVOID_HOME_STATE_ENTRIES = Object.freeze([
15359
+ "benchmark-runs",
15360
+ "benchmarks",
15361
+ "config.json",
15362
+ "factory",
15363
+ "issues-cache.json",
15364
+ "knowledge-graph",
15365
+ "litellm-pricing.json",
15366
+ "my-prs-state.json",
15367
+ "my-prs-work",
15368
+ "posthog-reports",
15369
+ "posthog-state.json",
15370
+ "posthog-work",
15371
+ "recordings",
15372
+ "guardrails-homes",
15373
+ "guardrails-policies",
15374
+ "sane-yolo",
15375
+ "scratch",
15376
+ "sounds",
15377
+ "team-review-repos",
15378
+ "team-review-state.json",
15379
+ "team-review-work",
15380
+ "team-review-worktrees",
15381
+ "telemetry-pending-crash.json",
15382
+ "telemetry.json",
15383
+ "tmp",
15384
+ "update-check.json",
15385
+ "update-journal.json",
15386
+ "workflows-state.json",
15387
+ "workflows-work"
15388
+ ]);
15389
+ var RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS = Object.freeze(["commands", "agents"]);
15390
+ var GUARDED_PROXY_BYPASS = "localhost,::1,169.254.0.0/16,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16";
15391
+ var HOOK_LOOPBACK_HOST = "127.0.0.1";
15392
+ var AGENT_SESSION_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
15393
+ var STANDARD_OPEN_NETWORK = Object.freeze({
15394
+ allowAllUnixSockets: true,
15395
+ allowMachLookup: ["*"]
15396
+ });
15397
+ var STRICT_OPEN_NETWORK = Object.freeze({ allowAllUnixSockets: false });
15398
+ function unique(entries) {
15399
+ return [...new Set(entries)];
15400
+ }
15401
+ function literalEntries(entryPaths) {
15402
+ return unique(entryPaths).map((entryPath) => ({
15403
+ path: entryPath,
15404
+ literal: true
15405
+ }));
15406
+ }
15407
+ function homePaths(host, homeEntries) {
15408
+ return homeEntries.map((entry) => path.join(host.homeDir, entry));
15409
+ }
15410
+ function isInsideAny(parents, child) {
15411
+ return parents.some((parent) => isPathInside(parent, child));
15412
+ }
15413
+ function vendorStatePaths(host, vendor, stateFolderEntries) {
15414
+ return stateFolderEntries.map((entry) => path.join(host.vendorLocations[vendor].stateFolder, entry));
15415
+ }
15416
+ function vendorHeldPaths(host, vendor) {
15417
+ const { stateFolder, configFiles, otherHomes } = host.vendorLocations[vendor];
15418
+ return [
15419
+ stateFolder,
15420
+ ...configFiles,
15421
+ ...otherHomes
15422
+ ];
15423
+ }
15424
+ function launchHomeOf(host, vendor) {
15425
+ return path.join(host.launchHomeDir, vendor);
15426
+ }
15427
+ function vendorsWithLaunchHome(role) {
15428
+ if (role.vendorHome.scope === "state") return [];
15429
+ return role.vendors.filter((vendor) => VENDOR_PROFILES[vendor].launchHomeEnvName !== null);
15430
+ }
15431
+ function vendorWritableFolders(role, host) {
15432
+ const { vendorHome } = role;
15433
+ if (vendorHome.scope === "state") return role.vendors.map((vendor) => host.vendorLocations[vendor].stateFolder);
15434
+ return role.vendors.flatMap((vendor) => {
15435
+ const profile = VENDOR_PROFILES[vendor];
15436
+ if (profile.launchHomeEnvName !== null) return [launchHomeOf(host, vendor)];
15437
+ return vendorStatePaths(host, vendor, profile.launchWritableFolders(vendorHome));
15438
+ });
15439
+ }
15440
+ function launchPrivateFolders(role, host) {
15441
+ if (role.vendorHome.scope === "state") return [];
15442
+ return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].launchPrivateFolders));
15443
+ }
15444
+ function launchHomeLinkCandidates(role, host) {
15445
+ return vendorsWithLaunchHome(role).flatMap((vendor) => {
15446
+ const { configEntries, loginFiles } = VENDOR_PROFILES[vendor];
15447
+ const linkFor = (entry, isLogin) => ({
15448
+ linkPath: path.join(launchHomeOf(host, vendor), entry),
15449
+ targetPath: path.join(host.vendorLocations[vendor].stateFolder, entry),
15450
+ isLogin
15451
+ });
15452
+ return [...configEntries.map((entry) => linkFor(entry, false)), ...loginFiles.map((entry) => linkFor(entry, true))];
15453
+ });
15454
+ }
15455
+ function launchHomeEnv(role, host) {
15456
+ return Object.fromEntries(vendorsWithLaunchHome(role).flatMap((vendor) => {
15457
+ const envName = VENDOR_PROFILES[vendor].launchHomeEnvName;
15458
+ return envName === null ? [] : [[envName, launchHomeOf(host, vendor)]];
15459
+ }));
15460
+ }
15461
+ function vendorLoginFiles(role, host) {
15462
+ return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].loginFiles));
15463
+ }
15464
+ function roleWritableRoots(role) {
15465
+ return [
15466
+ ...role.writableRoots,
15467
+ ...role.lockedCheckouts,
15468
+ ...role.commitCheckouts.flatMap(({ checkout, gitDir }) => [checkout, gitDir])
15469
+ ];
15470
+ }
15471
+ function alwaysWritablePaths(role, host) {
15472
+ return [
15473
+ host.tempDir,
15474
+ ...roleWritableRoots(role),
15475
+ ...vendorWritableFolders(role, host)
15476
+ ];
15477
+ }
15478
+ function commitCheckoutWriteDenies({ checkout, gitDir }) {
15479
+ const gitPointer = path.join(checkout, ".git");
15480
+ const gitDirDenies = [path.join(gitDir, "hooks"), path.join(gitDir, "config")];
15481
+ if (path.resolve(gitPointer) === path.resolve(gitDir)) return gitDirDenies;
15482
+ return [gitPointer, ...gitDirDenies];
15483
+ }
15484
+ function writeDeniesWhenPresent(role, host) {
15485
+ const writablePaths = alwaysWritablePaths(role, host);
15486
+ const sharedHomeWrites = homePaths(host, SHARED_HOME_WRITE_ENTRIES).filter((sharedPath) => !isInsideAny(roleWritableRoots(role), sharedPath));
15487
+ const vendorConfig = role.vendors.flatMap((vendor) => [...vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].configEntries), ...host.vendorLocations[vendor].configFiles]).filter((configPath) => isInsideAny(writablePaths, configPath));
15488
+ return [
15489
+ ...SHARED_TEMP_DIRS,
15490
+ ...sharedHomeWrites,
15491
+ ...vendorConfig,
15492
+ ...role.commitCheckouts.flatMap(commitCheckoutWriteDenies)
15493
+ ];
15494
+ }
15495
+ function lockedCheckoutWriteDenies(role) {
15496
+ return role.lockedCheckouts.flatMap((checkout) => [path.join(checkout, ".git"), path.join(checkout, ".claude")]);
15497
+ }
15498
+ function lockedClaudeMountPoints(role) {
15499
+ return role.lockedCheckouts.flatMap((checkout) => RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS.map((folder) => path.join(checkout, ".claude", folder)));
15500
+ }
15501
+ function guardrailsPlaceholderPaths(role) {
15502
+ return unique([...(role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : []).flatMap((workingFolder) => GUARDRAILS_PLACEHOLDER_NAMES.map((placeholderName) => path.join(workingFolder, placeholderName))), ...lockedCheckoutWriteDenies(role)]);
15503
+ }
15504
+ function homeEntriesNamedLike(host, homeEntries) {
15505
+ return host.homeEntryNames.filter((entryName) => homeEntries.some((homeEntry) => entryName.startsWith(homeEntry)));
15506
+ }
15507
+ function relocatedXdgConfigPaths(host, homeEntries) {
15508
+ const xdgConfigHome = host.relocatedXdgConfigHome;
15509
+ if (xdgConfigHome === null) return [];
15510
+ return homeEntries.filter((entry) => entry.startsWith(XDG_CONFIG_DEFAULT_HOME_PREFIX)).map((entry) => path.join(xdgConfigHome, entry.slice(8)));
15511
+ }
15512
+ function isStandardLevel(role) {
15513
+ return role.guardrailLevel === "standard";
15514
+ }
15515
+ function blockedCredentialHomeEntries(role) {
15516
+ const credentialHomeEntries = [...CREDENTIAL_HOME_ENTRIES, ...CLOUD_CREDENTIAL_HOME_ENTRIES];
15517
+ if (!isStandardLevel(role)) return credentialHomeEntries;
15518
+ return credentialHomeEntries.filter((entry) => !STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES.includes(entry));
15519
+ }
15520
+ function credentialWriteBlocks(role, host) {
15521
+ const credentialHomeEntries = blockedCredentialHomeEntries(role);
15522
+ return [...homePaths(host, credentialHomeEntries), ...relocatedXdgConfigPaths(host, credentialHomeEntries)];
15523
+ }
15524
+ function glimmervoidStateWriteBlocks(role, host) {
15525
+ const keptWritable = alwaysWritablePaths(role, host);
15526
+ const configFolder = path.dirname(host.glimmervoidConfigFile);
15527
+ const homeEntries = [
15528
+ ...GLIMMERVOID_HOME_STATE_ENTRIES,
15529
+ ...GLIMMERVOID_CONFIG_SIBLING_ENTRIES,
15530
+ ...host.glimmervoidHomeEntryNames
15531
+ ].map((entryName) => path.join(host.glimmervoidHome, entryName));
15532
+ const configSiblings = GLIMMERVOID_CONFIG_SIBLING_ENTRIES.map((entryName) => path.join(configFolder, entryName));
15533
+ return unique([
15534
+ host.glimmervoidConfigFile,
15535
+ ...homeEntries,
15536
+ ...configSiblings
15537
+ ]).filter((entryPath) => !keptWritable.some((writable) => isPathInside(entryPath, writable)));
15538
+ }
15539
+ function standardWriteBlockCandidates(role, host) {
15540
+ if (!isStandardLevel(role)) return [];
15541
+ return unique([
15542
+ ...credentialWriteBlocks(role, host),
15543
+ ...glimmervoidStateWriteBlocks(role, host),
15544
+ ...role.blockedPaths ?? []
15545
+ ]);
15546
+ }
15547
+ function readDeniedPaths(role, host) {
15548
+ const otherVendors = GUARDRAILS_VENDORS.filter((vendor) => !role.vendors.includes(vendor));
15549
+ const otherVendorHomeEntries = [...otherVendors.flatMap((vendor) => VENDOR_PROFILES[vendor].homeEntries), ...UNWRAPPED_VENDOR_HOME_ENTRIES];
15550
+ const credentialHomeEntries = blockedCredentialHomeEntries(role);
15551
+ return [
15552
+ ...homePaths(host, [
15553
+ ...credentialHomeEntries,
15554
+ ...otherVendorHomeEntries,
15555
+ ...homeEntriesNamedLike(host, otherVendorHomeEntries)
15556
+ ]),
15557
+ ...relocatedXdgConfigPaths(host, credentialHomeEntries),
15558
+ ...otherVendors.flatMap((vendor) => vendorHeldPaths(host, vendor)),
15559
+ ...host.unwrappedVendorHomes,
15560
+ host.glimmervoidHome,
15561
+ ...launchPrivateFolders(role, host),
15562
+ ...role.readDenied
15563
+ ];
15564
+ }
15565
+ function guardrailsPolicyProbePaths(role, host) {
15566
+ return unique([
15567
+ ...writeDeniesWhenPresent(role, host),
15568
+ ...vendorLoginFiles(role, host),
15569
+ ...launchHomeLinkCandidates(role, host).map((link) => link.targetPath)
15570
+ ]);
15571
+ }
15572
+ function isValidPort(port) {
15573
+ return Number.isInteger(port) && port >= 1 && port <= 65535;
15574
+ }
15575
+ function hostNamedPaths(host) {
15576
+ const relocatedXdgConfigHomes = host.relocatedXdgConfigHome === null ? [] : [host.relocatedXdgConfigHome];
15577
+ return [
15578
+ host.homeDir,
15579
+ host.glimmervoidHome,
15580
+ host.glimmervoidConfigFile,
15581
+ host.tempDir,
15582
+ host.launchHomeDir,
15583
+ ...relocatedXdgConfigHomes,
15584
+ ...host.unwrappedVendorHomes,
15585
+ ...GUARDRAILS_VENDORS.flatMap((vendor) => vendorHeldPaths(host, vendor))
15586
+ ];
15587
+ }
15588
+ function guardrailsRoleRefusal(role, host) {
15589
+ const launchCwds = role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : [];
15590
+ const relativePath = [
15591
+ ...hostNamedPaths(host),
15592
+ ...roleWritableRoots(role),
15593
+ ...role.readDenied,
15594
+ ...role.readableWithinDenied,
15595
+ ...launchCwds
15596
+ ].find((namedPath) => !path.isAbsolute(namedPath));
15597
+ if (relativePath !== void 0) return `guardrails policy path is not absolute: ${relativePath}`;
15598
+ const rootOverProtectedHome = [...roleWritableRoots(role), ...vendorWritableFolders(role, host)].find((root) => isPathInside(root, host.homeDir) || isPathInside(root, host.glimmervoidHome));
15599
+ if (rootOverProtectedHome !== void 0) return `writable root ${rootOverProtectedHome} contains the home folder or the Glimmervoid home`;
15600
+ const writablePaths = alwaysWritablePaths(role, host);
15601
+ const reallowedAncestor = role.readableWithinDenied.find((readable) => writablePaths.some((writable) => isPathInside(readable, writable, { allowEqual: false })));
15602
+ if (reallowedAncestor !== void 0) return `readable path ${reallowedAncestor} is an ancestor of a writable root`;
15603
+ if (role.network.access === "allowlist" && role.network.hookPort !== null && !isValidPort(role.network.hookPort)) return "hook listener port is invalid";
15604
+ const agentSessionId = role.vendorHome.scope === "launch" ? role.vendorHome.agentSessionId : null;
15605
+ if (agentSessionId !== null && !AGENT_SESSION_ID_SHAPE.test(agentSessionId)) return "agent session id is invalid";
15606
+ return null;
15607
+ }
15608
+ function networkPolicy(role) {
15609
+ if (role.network.access === "open") return isStandardLevel(role) ? { ...STANDARD_OPEN_NETWORK } : { ...STRICT_OPEN_NETWORK };
15610
+ if (role.network.access === "none") return {
15611
+ allowedDomains: [],
15612
+ deniedDomains: [],
15613
+ allowLocalBinding: false,
15614
+ allowAllUnixSockets: false
15615
+ };
15616
+ const hookEndpoint = role.network.hookPort === null ? [] : [`${HOOK_LOOPBACK_HOST}:${role.network.hookPort}`];
15617
+ const vendorDomains = role.vendors.flatMap((vendor) => VENDOR_PROFILES[vendor].apiDomains);
15618
+ return {
15619
+ allowedDomains: unique([
15620
+ ...hookEndpoint,
15621
+ ...vendorDomains,
15622
+ ...role.network.domains
15623
+ ]),
15624
+ deniedDomains: [],
15625
+ strictAllowlist: true,
15626
+ allowLocalBinding: false,
15627
+ allowAllUnixSockets: false
15628
+ };
15629
+ }
15630
+ function guardedEnvFor(role, host) {
15631
+ if (role.network.access === "allowlist") return {
15632
+ NO_PROXY: GUARDED_PROXY_BYPASS,
15633
+ no_proxy: GUARDED_PROXY_BYPASS,
15634
+ [HOOK_VIA_GUARDRAILS_PROXY_ENV]: "1"
15635
+ };
15636
+ if (role.network.access === "open") return { TMPDIR: host.tempDir };
15637
+ return {};
15638
+ }
15639
+ function filesystemWrites(role, host, writablePaths) {
15640
+ if (isStandardLevel(role)) return {
15641
+ allowWrite: literalEntries([WHOLE_FILESYSTEM, ...writablePaths]),
15642
+ denyWrite: literalEntries(host.writeBlockedPaths)
15643
+ };
15644
+ const isPresent = (candidate) => host.existingPaths.has(candidate);
15645
+ return {
15646
+ allowWrite: literalEntries(writablePaths),
15647
+ denyWrite: literalEntries([...writeDeniesWhenPresent(role, host).filter(isPresent), ...lockedCheckoutWriteDenies(role)])
15648
+ };
15649
+ }
15650
+ function buildGuardrailsLaunchPlan(role, host) {
15651
+ const refusal = guardrailsRoleRefusal(role, host);
15652
+ if (refusal !== null) return {
15653
+ ok: false,
15654
+ reason: refusal
15655
+ };
15656
+ const isPresent = (candidate) => host.existingPaths.has(candidate);
15657
+ const writablePaths = [...alwaysWritablePaths(role, host), ...vendorLoginFiles(role, host).filter(isPresent)];
15658
+ const readDenied = readDeniedPaths(role, host);
15659
+ const writableWithinDenied = writablePaths.filter((writable) => isInsideAny(readDenied, writable));
15660
+ return {
15661
+ ok: true,
15662
+ plan: {
15663
+ launcher: role.network.access === "open" ? "open-network" : "runtime-cli",
15664
+ policy: {
15665
+ network: networkPolicy(role),
15666
+ filesystem: {
15667
+ denyRead: literalEntries(readDenied),
15668
+ allowRead: literalEntries([...writableWithinDenied, ...role.readableWithinDenied]),
15669
+ ...filesystemWrites(role, host, writablePaths)
15670
+ },
15671
+ terminalScope: isStandardLevel(role) ? "any" : "own",
15672
+ allowAppleEvents: isStandardLevel(role)
15673
+ },
15674
+ launchEnv: Object.assign({ CLAUDE_CODE_TMPDIR: host.tempDir }, ...role.vendors.map((vendor) => VENDOR_PROFILES[vendor].launchEnv), launchHomeEnv(role, host)),
15675
+ guardedEnv: guardedEnvFor(role, host),
15676
+ requiredDirectories: unique([
15677
+ host.tempDir,
15678
+ ...vendorWritableFolders(role, host),
15679
+ ...launchPrivateFolders(role, host)
15680
+ ]),
15681
+ launchHomeLinks: launchHomeLinkCandidates(role, host).filter((link) => isPresent(link.targetPath))
15682
+ }
15683
+ };
15684
+ }
15685
+ //#endregion
15177
15686
  //#region server/ingest/core/ingest-shell-core.ts
15178
15687
  var SOURCE$4 = "shellHistory";
15179
15688
  var SHELLS = Object.freeze([
@@ -15526,12 +16035,15 @@ var writtenHomes = /* @__PURE__ */ new Set();
15526
16035
  var warnedTools = /* @__PURE__ */ new Set();
15527
16036
  var ensuredDataDirs = /* @__PURE__ */ new Set();
15528
16037
  var RTK_DATA_FOLDER = "rtk";
16038
+ function currentGlimmervoidHome() {
16039
+ return glimmervoidHomeDir(os.homedir(), process.env);
16040
+ }
15529
16041
  function saneYoloHomeDir() {
15530
- return path.join(glimmervoidHomeDir(os.homedir(), process.env), "sane-yolo");
16042
+ return path.join(currentGlimmervoidHome(), "sane-yolo");
15531
16043
  }
15532
- function writeSaneYoloPolicy(homeDir) {
16044
+ function writeSaneYoloPolicy(homeDir, glimmervoidHome = currentGlimmervoidHome()) {
15533
16045
  if (writtenHomes.has(homeDir)) return;
15534
- for (const [relativePath, contents] of Object.entries(SANE_YOLO_FILES)) {
16046
+ for (const [relativePath, contents] of Object.entries(saneYoloFiles(path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER)))) {
15535
16047
  const filePath = path.join(homeDir, relativePath);
15536
16048
  const serialized = `${JSON.stringify(contents, null, 2)}\n`;
15537
16049
  fs.mkdirSync(path.dirname(filePath), {
@@ -16245,430 +16757,6 @@ function proveMergedAcrossTips(probes) {
16245
16757
  return mostCautiousProof;
16246
16758
  }
16247
16759
  //#endregion
16248
- //#region server/guardrails/core/guardrails-policy-core.ts
16249
- var VENDOR_PROFILES = Object.freeze({
16250
- claude: {
16251
- homeEntries: [".claude", ".claude.json"],
16252
- launchWritableFolders: ({ cwd, agentSessionId }) => [path.join("projects", encodeProjectDir(cwd)), ...agentSessionId === null ? [] : [path.join("session-env", agentSessionId)]],
16253
- launchPrivateFolders: ["shell-snapshots"],
16254
- launchHomeEnvName: null,
16255
- loginFiles: [".credentials.json"],
16256
- configEntries: [
16257
- "settings.json",
16258
- "settings.local.json",
16259
- "hooks",
16260
- "skills",
16261
- "plugins",
16262
- "commands",
16263
- "agents",
16264
- "CLAUDE.md",
16265
- "AGENTS.md"
16266
- ],
16267
- apiDomains: ["api.anthropic.com", "platform.claude.com"],
16268
- launchEnv: { DISABLE_AUTOUPDATER: "1" }
16269
- },
16270
- codex: {
16271
- homeEntries: [".codex"],
16272
- launchWritableFolders: () => [],
16273
- launchPrivateFolders: [],
16274
- launchHomeEnvName: "CODEX_HOME",
16275
- loginFiles: ["auth.json"],
16276
- configEntries: [
16277
- "config.toml",
16278
- "AGENTS.md",
16279
- "skills",
16280
- "rules",
16281
- "prompts",
16282
- "hooks.json"
16283
- ],
16284
- apiDomains: [
16285
- "chatgpt.com",
16286
- "*.chatgpt.com",
16287
- "auth.openai.com",
16288
- "api.openai.com",
16289
- "*.openai.com"
16290
- ],
16291
- launchEnv: {}
16292
- }
16293
- });
16294
- var GUARDRAILS_VENDORS = Object.freeze(["claude", "codex"]);
16295
- var UNWRAPPED_VENDOR_HOME_ENTRIES = Object.freeze([".grok"]);
16296
- var CREDENTIAL_HOME_ENTRIES = Object.freeze([
16297
- ".ssh",
16298
- ".config/gh",
16299
- "Library/Keychains",
16300
- ".git-credentials"
16301
- ]);
16302
- var CLOUD_CREDENTIAL_HOME_ENTRIES = Object.freeze([
16303
- ".aws",
16304
- ".azure",
16305
- ".config/gcloud",
16306
- ".kube",
16307
- ".docker",
16308
- ".gnupg",
16309
- ".netrc",
16310
- ".npmrc"
16311
- ]);
16312
- var STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES = Object.freeze(["Library/Keychains"]);
16313
- var XDG_CONFIG_DEFAULT_HOME_PREFIX = ".config/";
16314
- var SHARED_TEMP_DIRS = Object.freeze(["/tmp/claude", "/private/tmp/claude"]);
16315
- var SHARED_HOME_WRITE_ENTRIES = Object.freeze([".npm/_logs"]);
16316
- var GUARDRAILS_PLACEHOLDER_NAMES = Object.freeze([
16317
- ".bash_profile",
16318
- ".bashrc",
16319
- ".claude",
16320
- ".gitconfig",
16321
- ".gitmodules",
16322
- ".idea",
16323
- ".mcp.json",
16324
- ".profile",
16325
- ".ripgreprc",
16326
- ".vscode",
16327
- ".zprofile",
16328
- ".zshrc"
16329
- ]);
16330
- var WHOLE_FILESYSTEM = "/";
16331
- var GLIMMERVOID_CONFIG_SIBLING_ENTRIES = Object.freeze([
16332
- "bin",
16333
- "pairings.json",
16334
- "pairings-seen.json",
16335
- "plans",
16336
- "telegram-outbox.json",
16337
- "traces",
16338
- "uploads",
16339
- "usage-budget-state.json",
16340
- "usage-lanes.json",
16341
- "usage-warehouse.json",
16342
- "visions-intent.json"
16343
- ]);
16344
- var GLIMMERVOID_HOME_STATE_ENTRIES = Object.freeze([
16345
- "benchmark-runs",
16346
- "benchmarks",
16347
- "config.json",
16348
- "factory",
16349
- "issues-cache.json",
16350
- "knowledge-graph",
16351
- "litellm-pricing.json",
16352
- "my-prs-state.json",
16353
- "my-prs-work",
16354
- "posthog-reports",
16355
- "posthog-state.json",
16356
- "posthog-work",
16357
- "recordings",
16358
- "guardrails-homes",
16359
- "guardrails-policies",
16360
- "sane-yolo",
16361
- "scratch",
16362
- "sounds",
16363
- "team-review-repos",
16364
- "team-review-state.json",
16365
- "team-review-work",
16366
- "team-review-worktrees",
16367
- "telemetry-pending-crash.json",
16368
- "telemetry.json",
16369
- "tmp",
16370
- "update-check.json",
16371
- "update-journal.json",
16372
- "workflows-state.json",
16373
- "workflows-work"
16374
- ]);
16375
- var RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS = Object.freeze(["commands", "agents"]);
16376
- var GUARDED_PROXY_BYPASS = "localhost,::1,169.254.0.0/16,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16";
16377
- var HOOK_LOOPBACK_HOST = "127.0.0.1";
16378
- var AGENT_SESSION_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
16379
- var STANDARD_OPEN_NETWORK = Object.freeze({
16380
- allowAllUnixSockets: true,
16381
- allowMachLookup: ["*"]
16382
- });
16383
- var STRICT_OPEN_NETWORK = Object.freeze({ allowAllUnixSockets: false });
16384
- function unique(entries) {
16385
- return [...new Set(entries)];
16386
- }
16387
- function literalEntries(entryPaths) {
16388
- return unique(entryPaths).map((entryPath) => ({
16389
- path: entryPath,
16390
- literal: true
16391
- }));
16392
- }
16393
- function homePaths(host, homeEntries) {
16394
- return homeEntries.map((entry) => path.join(host.homeDir, entry));
16395
- }
16396
- function isInsideAny(parents, child) {
16397
- return parents.some((parent) => isPathInside(parent, child));
16398
- }
16399
- function vendorStatePaths(host, vendor, stateFolderEntries) {
16400
- return stateFolderEntries.map((entry) => path.join(host.vendorLocations[vendor].stateFolder, entry));
16401
- }
16402
- function vendorHeldPaths(host, vendor) {
16403
- const { stateFolder, configFiles, otherHomes } = host.vendorLocations[vendor];
16404
- return [
16405
- stateFolder,
16406
- ...configFiles,
16407
- ...otherHomes
16408
- ];
16409
- }
16410
- function launchHomeOf(host, vendor) {
16411
- return path.join(host.launchHomeDir, vendor);
16412
- }
16413
- function vendorsWithLaunchHome(role) {
16414
- if (role.vendorHome.scope === "state") return [];
16415
- return role.vendors.filter((vendor) => VENDOR_PROFILES[vendor].launchHomeEnvName !== null);
16416
- }
16417
- function vendorWritableFolders(role, host) {
16418
- const { vendorHome } = role;
16419
- if (vendorHome.scope === "state") return role.vendors.map((vendor) => host.vendorLocations[vendor].stateFolder);
16420
- return role.vendors.flatMap((vendor) => {
16421
- const profile = VENDOR_PROFILES[vendor];
16422
- if (profile.launchHomeEnvName !== null) return [launchHomeOf(host, vendor)];
16423
- return vendorStatePaths(host, vendor, profile.launchWritableFolders(vendorHome));
16424
- });
16425
- }
16426
- function launchPrivateFolders(role, host) {
16427
- if (role.vendorHome.scope === "state") return [];
16428
- return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].launchPrivateFolders));
16429
- }
16430
- function launchHomeLinkCandidates(role, host) {
16431
- return vendorsWithLaunchHome(role).flatMap((vendor) => {
16432
- const { configEntries, loginFiles } = VENDOR_PROFILES[vendor];
16433
- const linkFor = (entry, isLogin) => ({
16434
- linkPath: path.join(launchHomeOf(host, vendor), entry),
16435
- targetPath: path.join(host.vendorLocations[vendor].stateFolder, entry),
16436
- isLogin
16437
- });
16438
- return [...configEntries.map((entry) => linkFor(entry, false)), ...loginFiles.map((entry) => linkFor(entry, true))];
16439
- });
16440
- }
16441
- function launchHomeEnv(role, host) {
16442
- return Object.fromEntries(vendorsWithLaunchHome(role).flatMap((vendor) => {
16443
- const envName = VENDOR_PROFILES[vendor].launchHomeEnvName;
16444
- return envName === null ? [] : [[envName, launchHomeOf(host, vendor)]];
16445
- }));
16446
- }
16447
- function vendorLoginFiles(role, host) {
16448
- return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].loginFiles));
16449
- }
16450
- function roleWritableRoots(role) {
16451
- return [
16452
- ...role.writableRoots,
16453
- ...role.lockedCheckouts,
16454
- ...role.commitCheckouts.flatMap(({ checkout, gitDir }) => [checkout, gitDir])
16455
- ];
16456
- }
16457
- function alwaysWritablePaths(role, host) {
16458
- return [
16459
- host.tempDir,
16460
- ...roleWritableRoots(role),
16461
- ...vendorWritableFolders(role, host)
16462
- ];
16463
- }
16464
- function commitCheckoutWriteDenies({ checkout, gitDir }) {
16465
- const gitPointer = path.join(checkout, ".git");
16466
- const gitDirDenies = [path.join(gitDir, "hooks"), path.join(gitDir, "config")];
16467
- if (path.resolve(gitPointer) === path.resolve(gitDir)) return gitDirDenies;
16468
- return [gitPointer, ...gitDirDenies];
16469
- }
16470
- function writeDeniesWhenPresent(role, host) {
16471
- const writablePaths = alwaysWritablePaths(role, host);
16472
- const sharedHomeWrites = homePaths(host, SHARED_HOME_WRITE_ENTRIES).filter((sharedPath) => !isInsideAny(roleWritableRoots(role), sharedPath));
16473
- const vendorConfig = role.vendors.flatMap((vendor) => [...vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].configEntries), ...host.vendorLocations[vendor].configFiles]).filter((configPath) => isInsideAny(writablePaths, configPath));
16474
- return [
16475
- ...SHARED_TEMP_DIRS,
16476
- ...sharedHomeWrites,
16477
- ...vendorConfig,
16478
- ...role.commitCheckouts.flatMap(commitCheckoutWriteDenies)
16479
- ];
16480
- }
16481
- function lockedCheckoutWriteDenies(role) {
16482
- return role.lockedCheckouts.flatMap((checkout) => [path.join(checkout, ".git"), path.join(checkout, ".claude")]);
16483
- }
16484
- function lockedClaudeMountPoints(role) {
16485
- return role.lockedCheckouts.flatMap((checkout) => RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS.map((folder) => path.join(checkout, ".claude", folder)));
16486
- }
16487
- function guardrailsPlaceholderPaths(role) {
16488
- return unique([...(role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : []).flatMap((workingFolder) => GUARDRAILS_PLACEHOLDER_NAMES.map((placeholderName) => path.join(workingFolder, placeholderName))), ...lockedCheckoutWriteDenies(role)]);
16489
- }
16490
- function homeEntriesNamedLike(host, homeEntries) {
16491
- return host.homeEntryNames.filter((entryName) => homeEntries.some((homeEntry) => entryName.startsWith(homeEntry)));
16492
- }
16493
- function relocatedXdgConfigPaths(host, homeEntries) {
16494
- const xdgConfigHome = host.relocatedXdgConfigHome;
16495
- if (xdgConfigHome === null) return [];
16496
- return homeEntries.filter((entry) => entry.startsWith(XDG_CONFIG_DEFAULT_HOME_PREFIX)).map((entry) => path.join(xdgConfigHome, entry.slice(8)));
16497
- }
16498
- function isStandardLevel(role) {
16499
- return role.guardrailLevel === "standard";
16500
- }
16501
- function blockedCredentialHomeEntries(role) {
16502
- const credentialHomeEntries = [...CREDENTIAL_HOME_ENTRIES, ...CLOUD_CREDENTIAL_HOME_ENTRIES];
16503
- if (!isStandardLevel(role)) return credentialHomeEntries;
16504
- return credentialHomeEntries.filter((entry) => !STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES.includes(entry));
16505
- }
16506
- function credentialWriteBlocks(role, host) {
16507
- const credentialHomeEntries = blockedCredentialHomeEntries(role);
16508
- return [...homePaths(host, credentialHomeEntries), ...relocatedXdgConfigPaths(host, credentialHomeEntries)];
16509
- }
16510
- function glimmervoidStateWriteBlocks(role, host) {
16511
- const keptWritable = alwaysWritablePaths(role, host);
16512
- const configFolder = path.dirname(host.glimmervoidConfigFile);
16513
- const homeEntries = [
16514
- ...GLIMMERVOID_HOME_STATE_ENTRIES,
16515
- ...GLIMMERVOID_CONFIG_SIBLING_ENTRIES,
16516
- ...host.glimmervoidHomeEntryNames
16517
- ].map((entryName) => path.join(host.glimmervoidHome, entryName));
16518
- const configSiblings = GLIMMERVOID_CONFIG_SIBLING_ENTRIES.map((entryName) => path.join(configFolder, entryName));
16519
- return unique([
16520
- host.glimmervoidConfigFile,
16521
- ...homeEntries,
16522
- ...configSiblings
16523
- ]).filter((entryPath) => !keptWritable.some((writable) => isPathInside(entryPath, writable)));
16524
- }
16525
- function standardWriteBlockCandidates(role, host) {
16526
- if (!isStandardLevel(role)) return [];
16527
- return unique([
16528
- ...credentialWriteBlocks(role, host),
16529
- ...glimmervoidStateWriteBlocks(role, host),
16530
- ...role.blockedPaths ?? []
16531
- ]);
16532
- }
16533
- function readDeniedPaths(role, host) {
16534
- const otherVendors = GUARDRAILS_VENDORS.filter((vendor) => !role.vendors.includes(vendor));
16535
- const otherVendorHomeEntries = [...otherVendors.flatMap((vendor) => VENDOR_PROFILES[vendor].homeEntries), ...UNWRAPPED_VENDOR_HOME_ENTRIES];
16536
- const credentialHomeEntries = blockedCredentialHomeEntries(role);
16537
- return [
16538
- ...homePaths(host, [
16539
- ...credentialHomeEntries,
16540
- ...otherVendorHomeEntries,
16541
- ...homeEntriesNamedLike(host, otherVendorHomeEntries)
16542
- ]),
16543
- ...relocatedXdgConfigPaths(host, credentialHomeEntries),
16544
- ...otherVendors.flatMap((vendor) => vendorHeldPaths(host, vendor)),
16545
- ...host.unwrappedVendorHomes,
16546
- host.glimmervoidHome,
16547
- ...launchPrivateFolders(role, host),
16548
- ...role.readDenied
16549
- ];
16550
- }
16551
- function guardrailsPolicyProbePaths(role, host) {
16552
- return unique([
16553
- ...writeDeniesWhenPresent(role, host),
16554
- ...vendorLoginFiles(role, host),
16555
- ...launchHomeLinkCandidates(role, host).map((link) => link.targetPath)
16556
- ]);
16557
- }
16558
- function isValidPort(port) {
16559
- return Number.isInteger(port) && port >= 1 && port <= 65535;
16560
- }
16561
- function hostNamedPaths(host) {
16562
- const relocatedXdgConfigHomes = host.relocatedXdgConfigHome === null ? [] : [host.relocatedXdgConfigHome];
16563
- return [
16564
- host.homeDir,
16565
- host.glimmervoidHome,
16566
- host.glimmervoidConfigFile,
16567
- host.tempDir,
16568
- host.launchHomeDir,
16569
- ...relocatedXdgConfigHomes,
16570
- ...host.unwrappedVendorHomes,
16571
- ...GUARDRAILS_VENDORS.flatMap((vendor) => vendorHeldPaths(host, vendor))
16572
- ];
16573
- }
16574
- function guardrailsRoleRefusal(role, host) {
16575
- const launchCwds = role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : [];
16576
- const relativePath = [
16577
- ...hostNamedPaths(host),
16578
- ...roleWritableRoots(role),
16579
- ...role.readDenied,
16580
- ...role.readableWithinDenied,
16581
- ...launchCwds
16582
- ].find((namedPath) => !path.isAbsolute(namedPath));
16583
- if (relativePath !== void 0) return `guardrails policy path is not absolute: ${relativePath}`;
16584
- const rootOverProtectedHome = [...roleWritableRoots(role), ...vendorWritableFolders(role, host)].find((root) => isPathInside(root, host.homeDir) || isPathInside(root, host.glimmervoidHome));
16585
- if (rootOverProtectedHome !== void 0) return `writable root ${rootOverProtectedHome} contains the home folder or the Glimmervoid home`;
16586
- const writablePaths = alwaysWritablePaths(role, host);
16587
- const reallowedAncestor = role.readableWithinDenied.find((readable) => writablePaths.some((writable) => isPathInside(readable, writable, { allowEqual: false })));
16588
- if (reallowedAncestor !== void 0) return `readable path ${reallowedAncestor} is an ancestor of a writable root`;
16589
- if (role.network.access === "allowlist" && role.network.hookPort !== null && !isValidPort(role.network.hookPort)) return "hook listener port is invalid";
16590
- const agentSessionId = role.vendorHome.scope === "launch" ? role.vendorHome.agentSessionId : null;
16591
- if (agentSessionId !== null && !AGENT_SESSION_ID_SHAPE.test(agentSessionId)) return "agent session id is invalid";
16592
- return null;
16593
- }
16594
- function networkPolicy(role) {
16595
- if (role.network.access === "open") return isStandardLevel(role) ? { ...STANDARD_OPEN_NETWORK } : { ...STRICT_OPEN_NETWORK };
16596
- if (role.network.access === "none") return {
16597
- allowedDomains: [],
16598
- deniedDomains: [],
16599
- allowLocalBinding: false,
16600
- allowAllUnixSockets: false
16601
- };
16602
- const hookEndpoint = role.network.hookPort === null ? [] : [`${HOOK_LOOPBACK_HOST}:${role.network.hookPort}`];
16603
- const vendorDomains = role.vendors.flatMap((vendor) => VENDOR_PROFILES[vendor].apiDomains);
16604
- return {
16605
- allowedDomains: unique([
16606
- ...hookEndpoint,
16607
- ...vendorDomains,
16608
- ...role.network.domains
16609
- ]),
16610
- deniedDomains: [],
16611
- strictAllowlist: true,
16612
- allowLocalBinding: false,
16613
- allowAllUnixSockets: false
16614
- };
16615
- }
16616
- function guardedEnvFor(role, host) {
16617
- if (role.network.access === "allowlist") return {
16618
- NO_PROXY: GUARDED_PROXY_BYPASS,
16619
- no_proxy: GUARDED_PROXY_BYPASS,
16620
- [HOOK_VIA_GUARDRAILS_PROXY_ENV]: "1"
16621
- };
16622
- if (role.network.access === "open") return { TMPDIR: host.tempDir };
16623
- return {};
16624
- }
16625
- function filesystemWrites(role, host, writablePaths) {
16626
- if (isStandardLevel(role)) return {
16627
- allowWrite: literalEntries([WHOLE_FILESYSTEM, ...writablePaths]),
16628
- denyWrite: literalEntries(host.writeBlockedPaths)
16629
- };
16630
- const isPresent = (candidate) => host.existingPaths.has(candidate);
16631
- return {
16632
- allowWrite: literalEntries(writablePaths),
16633
- denyWrite: literalEntries([...writeDeniesWhenPresent(role, host).filter(isPresent), ...lockedCheckoutWriteDenies(role)])
16634
- };
16635
- }
16636
- function buildGuardrailsLaunchPlan(role, host) {
16637
- const refusal = guardrailsRoleRefusal(role, host);
16638
- if (refusal !== null) return {
16639
- ok: false,
16640
- reason: refusal
16641
- };
16642
- const isPresent = (candidate) => host.existingPaths.has(candidate);
16643
- const writablePaths = [...alwaysWritablePaths(role, host), ...vendorLoginFiles(role, host).filter(isPresent)];
16644
- const readDenied = readDeniedPaths(role, host);
16645
- const writableWithinDenied = writablePaths.filter((writable) => isInsideAny(readDenied, writable));
16646
- return {
16647
- ok: true,
16648
- plan: {
16649
- launcher: role.network.access === "open" ? "open-network" : "runtime-cli",
16650
- policy: {
16651
- network: networkPolicy(role),
16652
- filesystem: {
16653
- denyRead: literalEntries(readDenied),
16654
- allowRead: literalEntries([...writableWithinDenied, ...role.readableWithinDenied]),
16655
- ...filesystemWrites(role, host, writablePaths)
16656
- },
16657
- terminalScope: isStandardLevel(role) ? "any" : "own",
16658
- allowAppleEvents: isStandardLevel(role)
16659
- },
16660
- launchEnv: Object.assign({ CLAUDE_CODE_TMPDIR: host.tempDir }, ...role.vendors.map((vendor) => VENDOR_PROFILES[vendor].launchEnv), launchHomeEnv(role, host)),
16661
- guardedEnv: guardedEnvFor(role, host),
16662
- requiredDirectories: unique([
16663
- host.tempDir,
16664
- ...vendorWritableFolders(role, host),
16665
- ...launchPrivateFolders(role, host)
16666
- ]),
16667
- launchHomeLinks: launchHomeLinkCandidates(role, host).filter((link) => isPresent(link.targetPath))
16668
- }
16669
- };
16670
- }
16671
- //#endregion
16672
16760
  //#region shared/repo.ts
16673
16761
  var REPO_SLUG = "johncwaters/glimmervoid";
16674
16762
  //#endregion
@@ -21131,6 +21219,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
21131
21219
  };
21132
21220
  let publishedActiveAgents = 0;
21133
21221
  let publishedAwaitingBackgroundTasks = false;
21222
+ let publishedHasBackgroundWork = false;
21134
21223
  const wakeups = /* @__PURE__ */ new Map();
21135
21224
  let wakeupSeq = 0;
21136
21225
  let wakeupExpiryTimer = null;
@@ -21162,12 +21251,20 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
21162
21251
  function awaitingBackgroundTasks() {
21163
21252
  return detectBackgroundAgents && gateHeldReady !== null && port.state() === "RUNNING" && tasks.isOnlyBackgroundTasks();
21164
21253
  }
21254
+ function hasBackgroundWork() {
21255
+ if (activeAgentCount() > 0) return true;
21256
+ if (detectBackgroundAgents && tasks.hasLiveMonitor()) return true;
21257
+ return pendingWakeup() !== null;
21258
+ }
21165
21259
  function publishAgentsChange() {
21260
+ if (port.isDestroyed()) return;
21166
21261
  const activeAgents = activeAgentCount();
21167
21262
  const awaiting = awaitingBackgroundTasks();
21168
- if (activeAgents === publishedActiveAgents && awaiting === publishedAwaitingBackgroundTasks) return;
21263
+ const backgroundWork = hasBackgroundWork();
21264
+ if (activeAgents === publishedActiveAgents && awaiting === publishedAwaitingBackgroundTasks && backgroundWork === publishedHasBackgroundWork) return;
21169
21265
  publishedActiveAgents = activeAgents;
21170
21266
  publishedAwaitingBackgroundTasks = awaiting;
21267
+ publishedHasBackgroundWork = backgroundWork;
21171
21268
  port.emit("agents-change", {
21172
21269
  activeAgents,
21173
21270
  awaitingBackgroundTasks: awaiting
@@ -21394,6 +21491,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
21394
21491
  wakeupExpiryTimer.unref();
21395
21492
  }
21396
21493
  function emitWakeupChange() {
21494
+ if (port.isDestroyed()) return;
21397
21495
  port.emit("wakeup-change", { pendingWakeup: pendingWakeup() });
21398
21496
  armWakeupExpiryTimer();
21399
21497
  }
@@ -21418,6 +21516,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
21418
21516
  trackSubagent,
21419
21517
  activeAgentCount,
21420
21518
  awaitingBackgroundTasks,
21519
+ hasBackgroundWork,
21421
21520
  emitAgentsChange,
21422
21521
  clearAgents,
21423
21522
  stashGateHeldReady,
@@ -21776,11 +21875,8 @@ var Session = class extends EventEmitter {
21776
21875
  this._taskTitleSources.customTitle = this.customTitle;
21777
21876
  this._updateTaskTitle();
21778
21877
  }
21779
- get settledTaskTitle() {
21780
- return resolveTaskTitle({
21781
- ...this._taskTitleSources,
21782
- pendingPromptTitle: null
21783
- }).taskTitle;
21878
+ get refinedTaskTitle() {
21879
+ return this._taskTitleSources.refinedTitle ?? null;
21784
21880
  }
21785
21881
  get persistedTaskTitle() {
21786
21882
  return buildPersistedTaskTitle(this._taskTitleSources);
@@ -22113,6 +22209,9 @@ var Session = class extends EventEmitter {
22113
22209
  get hookSeen() {
22114
22210
  return this._hookSeen;
22115
22211
  }
22212
+ get hasBackgroundWork() {
22213
+ return this.backgroundTracking.hasBackgroundWork();
22214
+ }
22116
22215
  get agentToken() {
22117
22216
  return this._agentToken;
22118
22217
  }
@@ -23276,6 +23375,7 @@ var GuardrailsLaunchOwner = z.object({
23276
23375
  ownerHost: z.string(),
23277
23376
  ownerPidNamespace: z.string().nullable(),
23278
23377
  ownsTempDir: z.boolean(),
23378
+ keptTempFolderName: z.string().min(1).optional(),
23279
23379
  logins: z.array(GuardrailsLaunchLogin),
23280
23380
  placeholderPaths: z.array(z.string().min(1))
23281
23381
  }).strict();
@@ -23387,11 +23487,45 @@ function bridgeSocketLauncherEnv(inheritedTempDirectory, platform) {
23387
23487
  return { TMPDIR: SHORT_BRIDGE_SOCKET_FOLDER };
23388
23488
  }
23389
23489
  //#endregion
23490
+ //#region server/prune-files.ts
23491
+ var MS_PER_DAY = 864e5;
23492
+ function idForEntry(entry, suffixes) {
23493
+ for (const suffix of suffixes) {
23494
+ if (suffix.length === 0) return entry;
23495
+ if (entry.endsWith(suffix)) return entry.slice(0, -suffix.length);
23496
+ }
23497
+ return null;
23498
+ }
23499
+ async function pruneAgedFiles({ directory, suffixes, retainDays, now = Date.now(), isRetainedId = () => false, entryMode = "file", fsPromises = fs.promises }) {
23500
+ let entries;
23501
+ try {
23502
+ entries = await fsPromises.readdir(directory);
23503
+ } catch {
23504
+ return [];
23505
+ }
23506
+ const cutoff = now - retainDays * MS_PER_DAY;
23507
+ const removedIds = [];
23508
+ for (const entry of entries) {
23509
+ const id = idForEntry(entry, suffixes);
23510
+ if (!id || isRetainedId(id)) continue;
23511
+ const filePath = path.join(directory, entry);
23512
+ try {
23513
+ if ((await fsPromises.stat(filePath)).mtimeMs >= cutoff) continue;
23514
+ if (entryMode === "directory") await fsPromises.rm(filePath, {
23515
+ recursive: true,
23516
+ force: true
23517
+ });
23518
+ if (entryMode === "file") await fsPromises.unlink(filePath);
23519
+ removedIds.push(id);
23520
+ } catch {}
23521
+ }
23522
+ return removedIds;
23523
+ }
23524
+ //#endregion
23390
23525
  //#region server/guardrails/guardrails-launch.ts
23391
23526
  var LAUNCH_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
23392
23527
  var GUARDED_ENV_COMMAND = "/usr/bin/env";
23393
23528
  var POLICY_FOLDER = "guardrails-policies";
23394
- var TEMP_FOLDER = "guardrails-temp";
23395
23529
  var LAUNCH_HOME_FOLDER = "guardrails-homes";
23396
23530
  var START_FOLDER = "start";
23397
23531
  var OWNER_FILE_SUFFIX = ".owner.json";
@@ -23399,6 +23533,7 @@ var ENTER_FOLDER_SCRIPT = "cd \"$1\" && shift && exec \"$@\"";
23399
23533
  var LOGIN_FILE_MODE = 384;
23400
23534
  var ABSENT_PATH_DENY_PLATFORM = "darwin";
23401
23535
  var OWN_PID_NAMESPACE_LINK = "/proc/self/ns/pid";
23536
+ var SESSION_TEMP_RETAIN_DAYS = 7;
23402
23537
  async function isPresent(candidate) {
23403
23538
  try {
23404
23539
  await access(candidate);
@@ -23597,7 +23732,7 @@ async function sweepOrphanedGuardrailsLaunches(log = console) {
23597
23732
  policyPath: path.join(policyDir, `${launchId}.json`),
23598
23733
  ownerPath,
23599
23734
  launchHomeDir: path.join(glimmervoidHome, LAUNCH_HOME_FOLDER, launchId),
23600
- ownedTempDir: owner.ownsTempDir ? path.join(glimmervoidHome, TEMP_FOLDER, launchId) : null
23735
+ ownedTempDir: owner.ownsTempDir ? path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER, launchId) : null
23601
23736
  }, owner, launchId, { onlyNewerLogins: true });
23602
23737
  removedLaunchCount += 1;
23603
23738
  } catch (error) {
@@ -23609,6 +23744,24 @@ async function sweepOrphanedGuardrailsLaunches(log = console) {
23609
23744
  log.warn(`[guardrails] could not sweep leftover launch folders: ${errorMessage(error)}`);
23610
23745
  }
23611
23746
  }
23747
+ async function pruneLeftoverSessionTempFolders(glimmervoidHome, liveSessionIds, log = console) {
23748
+ const policyEntryNames = await readdir(path.join(glimmervoidHome, POLICY_FOLDER)).catch((error) => {
23749
+ if (isMissingFileError(error)) return [];
23750
+ log.warn(`[guardrails] kept every session temp folder because the launch list could not be read: ${errorMessage(error)}`);
23751
+ return null;
23752
+ });
23753
+ if (policyEntryNames === null) return;
23754
+ const ownerEntryNames = policyEntryNames.filter((entryName) => entryName.endsWith(OWNER_FILE_SUFFIX));
23755
+ const owners = await Promise.all(ownerEntryNames.map((entryName) => readOwnerFile(path.join(glimmervoidHome, POLICY_FOLDER, entryName))));
23756
+ const tempFolderNamesWithOwners = /* @__PURE__ */ new Set([...ownerEntryNames.map((entryName) => entryName.slice(0, -11)), ...owners.flatMap((owner) => owner?.keptTempFolderName === void 0 ? [] : [owner.keptTempFolderName])]);
23757
+ await pruneAgedFiles({
23758
+ directory: path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER),
23759
+ suffixes: [""],
23760
+ retainDays: SESSION_TEMP_RETAIN_DAYS,
23761
+ entryMode: "directory",
23762
+ isRetainedId: (id) => liveSessionIds.has(id) || tempFolderNamesWithOwners.has(id)
23763
+ });
23764
+ }
23612
23765
  function launcherCommand(plan, policyPath) {
23613
23766
  if (plan.launcher === "open-network") return {
23614
23767
  file: process.execPath,
@@ -23642,11 +23795,19 @@ function enteringFolder(enterDir, file, args) {
23642
23795
  ...args
23643
23796
  ];
23644
23797
  }
23645
- async function prepareGuardrailsLaunch({ role, launchId, tempDir, enterDir }) {
23798
+ function launchTempDirFor(glimmervoidHome, launchId, tempDir, keptTempFolderName) {
23799
+ if (tempDir !== void 0) return path.resolve(tempDir);
23800
+ return path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER, keptTempFolderName ?? launchId);
23801
+ }
23802
+ async function prepareGuardrailsLaunch({ role, launchId, tempDir, keptTempFolderName, enterDir }) {
23646
23803
  if (!LAUNCH_ID_SHAPE.test(launchId)) return {
23647
23804
  ok: false,
23648
23805
  reason: "guardrails launch id is invalid"
23649
23806
  };
23807
+ if (keptTempFolderName !== void 0 && !LAUNCH_ID_SHAPE.test(keptTempFolderName)) return {
23808
+ ok: false,
23809
+ reason: "guardrails temp folder name is invalid"
23810
+ };
23650
23811
  try {
23651
23812
  const policyDir = path.join(glimmervoidHomeDir$1(), POLICY_FOLDER);
23652
23813
  await mkdir(policyDir, {
@@ -23659,8 +23820,8 @@ async function prepareGuardrailsLaunch({ role, launchId, tempDir, enterDir }) {
23659
23820
  withRealRoots(role),
23660
23821
  readOwnPidNamespace()
23661
23822
  ]);
23662
- const ownsTempDir = tempDir === void 0;
23663
- const launchTempDir = tempDir === void 0 ? path.join(glimmervoidHome, TEMP_FOLDER, launchId) : path.resolve(tempDir);
23823
+ const ownsTempDir = tempDir === void 0 && keptTempFolderName === void 0;
23824
+ const launchTempDir = launchTempDirFor(glimmervoidHome, launchId, tempDir, keptTempFolderName);
23664
23825
  const launchHomeDir = path.join(glimmervoidHome, LAUNCH_HOME_FOLDER, launchId);
23665
23826
  const vendorLocations = await resolveVendorLocations(process.env, homeDir);
23666
23827
  if (vendorLocations === null) return {
@@ -23717,6 +23878,7 @@ async function prepareGuardrailsLaunch({ role, launchId, tempDir, enterDir }) {
23717
23878
  ownerHost: os.hostname(),
23718
23879
  ownerPidNamespace,
23719
23880
  ownsTempDir,
23881
+ ...keptTempFolderName === void 0 ? {} : { keptTempFolderName },
23720
23882
  logins: plan.launchHomeLinks.filter((link) => link.isLogin).map(({ linkPath, targetPath }) => ({
23721
23883
  linkPath,
23722
23884
  targetPath
@@ -28743,41 +28905,6 @@ async function commitAndLandFactoryLedger({ projectPath, ledger, targetBranch, m
28743
28905
  }
28744
28906
  }
28745
28907
  //#endregion
28746
- //#region server/prune-files.ts
28747
- var MS_PER_DAY = 864e5;
28748
- function idForEntry(entry, suffixes) {
28749
- for (const suffix of suffixes) {
28750
- if (suffix.length === 0) return entry;
28751
- if (entry.endsWith(suffix)) return entry.slice(0, -suffix.length);
28752
- }
28753
- return null;
28754
- }
28755
- async function pruneAgedFiles({ directory, suffixes, retainDays, now = Date.now(), isRetainedId = () => false, entryMode = "file", fsPromises = fs.promises }) {
28756
- let entries;
28757
- try {
28758
- entries = await fsPromises.readdir(directory);
28759
- } catch {
28760
- return [];
28761
- }
28762
- const cutoff = now - retainDays * MS_PER_DAY;
28763
- const removedIds = [];
28764
- for (const entry of entries) {
28765
- const id = idForEntry(entry, suffixes);
28766
- if (!id || isRetainedId(id)) continue;
28767
- const filePath = path.join(directory, entry);
28768
- try {
28769
- if ((await fsPromises.stat(filePath)).mtimeMs >= cutoff) continue;
28770
- if (entryMode === "directory") await fsPromises.rm(filePath, {
28771
- recursive: true,
28772
- force: true
28773
- });
28774
- if (entryMode === "file") await fsPromises.unlink(filePath);
28775
- removedIds.push(id);
28776
- } catch {}
28777
- }
28778
- return removedIds;
28779
- }
28780
- //#endregion
28781
28908
  //#region server/factory/factory-decision-log.ts
28782
28909
  function createFactoryDecisionLog({ homeDir = glimmervoidHomeDir$1(), now = Date.now, log = console, redact = (text) => text, onDecision } = {}) {
28783
28910
  const prunedDayByProject = /* @__PURE__ */ new Map();
@@ -36925,7 +37052,7 @@ function createTaskTitleRefiner({ getConfig, spawnLane, nowFn = () => Date.now()
36925
37052
  const request = {
36926
37053
  session,
36927
37054
  revision: session.taskTitlePromptRevision,
36928
- currentTitle: session.settledTaskTitle,
37055
+ currentTitle: session.refinedTaskTitle,
36929
37056
  recentPrompts: session.recentTaskPrompts
36930
37057
  };
36931
37058
  queuedBySession.set(session, request);
@@ -47102,6 +47229,7 @@ function createUploadsWiring({ configPath, liveSessionIds, setIntervalFn = DEFAU
47102
47229
  isRetainedId: (id) => retainedSessionIds.has(id),
47103
47230
  fsPromises: fs.promises
47104
47231
  });
47232
+ await pruneLeftoverSessionTempFolders(path.dirname(uploadsRoot), retainedSessionIds);
47105
47233
  }
47106
47234
  async function start() {
47107
47235
  if (timer) return;
@@ -52032,7 +52160,7 @@ function parseSinceParam(url) {
52032
52160
  return Number.isFinite(n) ? n : null;
52033
52161
  }
52034
52162
  function registerControlHandlers(controlWss, deps) {
52035
- const { sessions, agentSessions = /* @__PURE__ */ new Map(), config, configStore, broadcastControl, generateProjectId, applyConfigReload, applySettingsReload, requestShutdown, requestRestart, handleClientFocus, buildHealthSnapshot, getUpdateStatus, getUpdateJournal = null, getPostTurnLeftoversNotice = null, recheckPostTurnLeftovers = null, checkNow = null, applyUpdate = null, isStaging = null, noteRestartRequested = null, getRadarStatus, posthogReportsDir = null, posthogSetIssueStatus = null, radarArchiveInvestigation = null, getTeamReviewStatus = null, getMyPrsStatus = null, getIssuesStatus = null, issues = null, teamReview = null, myPrs = null, getBenchmarkStatus = null, getFactoryState = null, benchmarks = null, factory = null, createGithubClient = createPrGh, issueProjectRepos = null, serverBuild = () => null, getUsageSessions = null, getUsageReport = null, requestUsageReport = null, getPlanLimits = null, controlReplayLog = null, getRtkInstallStatus = () => null, resolveRtkPath = () => getRtkPath(), conversationFs = fs, conversationGit = runGitForConversationHistory, conversationProjectsDir = claudeProjectsDir(process.env, os.homedir()), readTracePage = null, readPlanRevision = null, decidePlanReview = null, sessionDocs = null, changeMapNarrator = null } = deps;
52163
+ const { sessions, agentSessions = /* @__PURE__ */ new Map(), config, configStore, broadcastControl, generateProjectId, applyConfigReload, applySettingsReload, requestShutdown, requestRestart, handleClientFocus, buildHealthSnapshot, getUpdateStatus, getUpdateJournal = null, getPostTurnLeftoversNotice = null, recheckPostTurnLeftovers = null, checkNow = null, applyUpdate = null, noteRestartRequested = null, getRadarStatus, posthogReportsDir = null, posthogSetIssueStatus = null, radarArchiveInvestigation = null, getTeamReviewStatus = null, getMyPrsStatus = null, getIssuesStatus = null, issues = null, teamReview = null, myPrs = null, getBenchmarkStatus = null, getFactoryState = null, benchmarks = null, factory = null, createGithubClient = createPrGh, issueProjectRepos = null, serverBuild = () => null, getUsageSessions = null, getUsageReport = null, requestUsageReport = null, getPlanLimits = null, controlReplayLog = null, getRtkInstallStatus = () => null, resolveRtkPath = () => getRtkPath(), conversationFs = fs, conversationGit = runGitForConversationHistory, conversationProjectsDir = claudeProjectsDir(process.env, os.homedir()), readTracePage = null, readPlanRevision = null, decidePlanReview = null, sessionDocs = null, changeMapNarrator = null } = deps;
52036
52164
  const changeMaps = createChangeMapService({
52037
52165
  sessions,
52038
52166
  narrator: changeMapNarrator,
@@ -53256,29 +53384,16 @@ function registerControlHandlers(controlWss, deps) {
53256
53384
  }
53257
53385
  await checkNow();
53258
53386
  }
53259
- async function handleUpdateApply(msg, ws) {
53387
+ async function handleUpdateApply(_msg, ws) {
53260
53388
  if (!applyUpdate) {
53261
53389
  sendError(ws, "[update-apply-unavailable] Update application is unavailable.");
53262
53390
  return;
53263
53391
  }
53264
53392
  const outcome = await applyUpdate();
53265
- if (!outcome.ok) {
53266
- sendError(ws, `[${outcome.reason || "update-refused"}] ${outcome.message}`);
53267
- return;
53268
- }
53269
- if (msg.restartWhenStaged !== true) return;
53270
- const confirmedSessionIds = new Set(msg.confirmedSessionIds ?? []);
53271
- if ([...sessions.keys(), ...agentSessions.keys()].some((liveSessionId) => !confirmedSessionIds.has(liveSessionId))) {
53272
- sendError(ws, "[update-restart-skipped] The update is staged, but sessions started since you confirmed. Restart when ready.");
53273
- return;
53274
- }
53275
- handleRestart(msg, ws);
53393
+ if (outcome.ok) return;
53394
+ sendError(ws, `[${outcome.reason || "update-refused"}] ${outcome.message}`);
53276
53395
  }
53277
- function handleRestart(_msg, ws) {
53278
- if (isStaging?.()) {
53279
- sendError(ws, "[update-staging] Wait for the update staging run to finish before restarting.");
53280
- return;
53281
- }
53396
+ function handleRestart(_msg) {
53282
53397
  noteRestartRequested?.();
53283
53398
  console.log("[control] Restart requested via UI");
53284
53399
  broadcastControl({ type: "restarting" });
@@ -53739,7 +53854,6 @@ function createBackendControl(dependencies) {
53739
53854
  recheckPostTurnLeftovers: dependencies.recheckPostTurnLeftovers,
53740
53855
  checkNow: dependencies.checkNow,
53741
53856
  applyUpdate: dependencies.applyUpdate,
53742
- isStaging: dependencies.isStaging,
53743
53857
  noteRestartRequested: dependencies.noteRestartRequested,
53744
53858
  getRadarStatus: () => posthog.getStatus(),
53745
53859
  posthogSetIssueStatus: (args) => posthog.setIssueStatus(args),
@@ -53791,6 +53905,7 @@ var PREVIOUS_DEPENDENCIES_BACKUP_NAME = "prev-node_modules";
53791
53905
  var QUARANTINED_DIST_NAME = "broken-dist";
53792
53906
  var QUARANTINED_DEPENDENCIES_NAME = "broken-node_modules";
53793
53907
  var SUPPORTED_UPDATE_REMOTE = "origin";
53908
+ var LOWEST_SCHEDULING_PRIORITY = "19";
53794
53909
  var TRANSITIONS_ALLOWED_BY_STATE = Object.freeze({
53795
53910
  idle: Object.freeze(["begin-run"]),
53796
53911
  running: Object.freeze([
@@ -53952,6 +54067,21 @@ function planSteps({ lockfileChanged }) {
53952
54067
  "build"
53953
54068
  ];
53954
54069
  }
54070
+ function lowPriorityCommand({ file, args, platform }) {
54071
+ if (platform === "win32") return {
54072
+ file,
54073
+ args
54074
+ };
54075
+ return {
54076
+ file: "nice",
54077
+ args: [
54078
+ "-n",
54079
+ LOWEST_SCHEDULING_PRIORITY,
54080
+ file,
54081
+ ...args
54082
+ ]
54083
+ };
54084
+ }
53955
54085
  function planHandOffRenames({ root, stagingPath, lockfileChanged }) {
53956
54086
  const updatePath = `${root}/.glimmervoid/update`;
53957
54087
  const renames = [{
@@ -54478,6 +54608,7 @@ function createBackendUpdateCheck(dependencies) {
54478
54608
  let inFlight = null;
54479
54609
  let lastChannel = normalizeUpdateChannel(dependencies.config.updateChannel);
54480
54610
  let lastSurfacedIdentity = null;
54611
+ let lastDownloadedIdentity = null;
54481
54612
  let pendingChannelRefresh = false;
54482
54613
  let stopped = false;
54483
54614
  const now = dependencies.now || (() => Date.now());
@@ -54581,6 +54712,26 @@ function createBackendUpdateCheck(dependencies) {
54581
54712
  const latestRelease = status.latest || shortSha(status.latestSha) || "unknown";
54582
54713
  dependencies.logger.log(`[update] A newer glimmervoid is available: ${currentRelease} -> ${latestRelease}. Update: ${status.command}`);
54583
54714
  }
54715
+ function downloadInBackground(status) {
54716
+ const downloadUpdate = dependencies.downloadUpdate;
54717
+ if (!downloadUpdate || dependencies.config.checkForUpdates === false) return;
54718
+ if (!status.updateAvailable || status.applyRefusal) return;
54719
+ const identity = status.latestSha || status.latest;
54720
+ if (!identity || identity === lastDownloadedIdentity) return;
54721
+ lastDownloadedIdentity = identity;
54722
+ dependencies.logger.log(`[update] downloading ${status.latest || shortSha(status.latestSha)} in the background`);
54723
+ const allowRetryAtNextCheck = () => {
54724
+ if (lastDownloadedIdentity === identity) lastDownloadedIdentity = null;
54725
+ };
54726
+ downloadUpdate().then((outcome) => {
54727
+ if (outcome.ok) return;
54728
+ allowRetryAtNextCheck();
54729
+ dependencies.logger.log(`[update] background download stopped: ${outcome.message}`);
54730
+ }, (error) => {
54731
+ allowRetryAtNextCheck();
54732
+ dependencies.logger.log(`[update] background download failed: ${String(error)}`);
54733
+ });
54734
+ }
54584
54735
  function runCheck(ttlMs) {
54585
54736
  if (inFlight) return inFlight;
54586
54737
  const channel = normalizeUpdateChannel(dependencies.config.updateChannel);
@@ -54599,6 +54750,7 @@ function createBackendUpdateCheck(dependencies) {
54599
54750
  });
54600
54751
  const status = recordStatus(updateResult, checkedAt, channel);
54601
54752
  surfaceAvailableUpdate(status);
54753
+ downloadInBackground(status);
54602
54754
  return status;
54603
54755
  }).finally(() => {
54604
54756
  inFlight = null;
@@ -54621,6 +54773,7 @@ function createBackendUpdateCheck(dependencies) {
54621
54773
  recordedStatus = null;
54622
54774
  lastLaneSignature = null;
54623
54775
  lastSurfacedIdentity = null;
54776
+ lastDownloadedIdentity = null;
54624
54777
  updateAbort?.abort();
54625
54778
  return true;
54626
54779
  }
@@ -55054,6 +55207,7 @@ function createSessionGuardrails({ getSettings, uploadsRoot, guardrailsRefusal =
55054
55207
  const prepared = await prepareGuardrails({
55055
55208
  role,
55056
55209
  launchId: facts.launchId,
55210
+ keptTempFolderName: request.sessionId,
55057
55211
  enterDir: cwd
55058
55212
  });
55059
55213
  if (!prepared.ok) return {
@@ -55374,7 +55528,12 @@ function createUpdateApplyLane(dependencies) {
55374
55528
  stepId,
55375
55529
  now: clock()
55376
55530
  }));
55377
- const outcome = await command(file, args, cwd, timeout);
55531
+ const throttled = lowPriorityCommand({
55532
+ file,
55533
+ args,
55534
+ platform: dependencies.platform || process.platform
55535
+ });
55536
+ const outcome = await command(throttled.file, throttled.args, cwd, timeout);
55378
55537
  journal = appendStepOutput(journal, stepId, outcome.output);
55379
55538
  if (!outcome.ok) throw new Error(outcome.reason || `${stepId} failed`);
55380
55539
  await publish(finishStep(journal, {
@@ -55669,9 +55828,6 @@ function createUpdateApplyLane(dependencies) {
55669
55828
  activeRun = run;
55670
55829
  await run;
55671
55830
  }
55672
- function isStaging() {
55673
- return inFlight;
55674
- }
55675
55831
  function isRestartRequested() {
55676
55832
  return restartRequested;
55677
55833
  }
@@ -55778,7 +55934,6 @@ function createUpdateApplyLane(dependencies) {
55778
55934
  getJournal,
55779
55935
  handOffStagedUpdate,
55780
55936
  isRestartRequested,
55781
- isStaging,
55782
55937
  noteRestartRequested,
55783
55938
  startAfterListening,
55784
55939
  stop,
@@ -56780,6 +56935,12 @@ function createBackend(httpServer, options = {}) {
56780
56935
  visionsSetup.maybeApply();
56781
56936
  laneAssembly.restartDynamicLanes();
56782
56937
  }
56938
+ function downloadUpdateOnceListening() {
56939
+ if (httpServer.listening) return updateApply.applyUpdate();
56940
+ return new Promise((resolve) => {
56941
+ httpServer.once("listening", resolve);
56942
+ }).then(() => updateApply.applyUpdate());
56943
+ }
56783
56944
  const updateCheck = createBackendUpdateCheck({
56784
56945
  config,
56785
56946
  currentVersion: packageJson.version,
@@ -56790,7 +56951,8 @@ function createBackend(httpServer, options = {}) {
56790
56951
  isRestartRequested: () => updateApply.isRestartRequested(),
56791
56952
  getControlClientCount: () => controlWss.clients.size,
56792
56953
  broadcastControl,
56793
- logger: console
56954
+ logger: console,
56955
+ ...options.downloadUpdatesInBackground ? { downloadUpdate: downloadUpdateOnceListening } : {}
56794
56956
  });
56795
56957
  const updateApply = createUpdateApplyLane({
56796
56958
  gitWorkspace: assembledGitWorkspace,
@@ -56913,7 +57075,6 @@ function createBackend(httpServer, options = {}) {
56913
57075
  recheckPostTurnLeftovers,
56914
57076
  checkNow: updateCheck.checkNow,
56915
57077
  applyUpdate: updateApply.applyUpdate,
56916
- isStaging: updateApply.isStaging,
56917
57078
  noteRestartRequested: () => {
56918
57079
  updateApply.noteRestartRequested();
56919
57080
  updateCheck.refreshApplyAvailability();
@@ -56953,6 +57114,7 @@ function createBackend(httpServer, options = {}) {
56953
57114
  updateCheck.start();
56954
57115
  return {
56955
57116
  shutdown,
57117
+ handOffStagedUpdate: updateApply.handOffStagedUpdate,
56956
57118
  port,
56957
57119
  app,
56958
57120
  telemetry,
@@ -57002,7 +57164,10 @@ function isBootRefusal(error) {
57002
57164
  }
57003
57165
  function createBackendOrExit() {
57004
57166
  try {
57005
- return createBackend(server, { staticDir: "auto" });
57167
+ return createBackend(server, {
57168
+ staticDir: "auto",
57169
+ downloadUpdatesInBackground: true
57170
+ });
57006
57171
  } catch (err) {
57007
57172
  if (!isBootRefusal(err)) throw err;
57008
57173
  console.error(err.message);
@@ -57010,7 +57175,7 @@ function createBackendOrExit() {
57010
57175
  }
57011
57176
  }
57012
57177
  var backend = createBackendOrExit();
57013
- var { shutdown, port, app, telemetry, version } = backend;
57178
+ var { shutdown, handOffStagedUpdate, port, app, telemetry, version } = backend;
57014
57179
  server.on("request", app);
57015
57180
  function writeTerminalTitle(sequence) {
57016
57181
  if (!process.stdout.isTTY) return;
@@ -57091,7 +57256,8 @@ var { requestShutdown } = createLifecycle({
57091
57256
  httpServer: server,
57092
57257
  extraServers: remoteServers,
57093
57258
  spawn,
57094
- exit: exitWithClearedTerminalTitle
57259
+ exit: exitWithClearedTerminalTitle,
57260
+ beforeHandOff: handOffStagedUpdate
57095
57261
  });
57096
57262
  function handleShutdownSignal(signal) {
57097
57263
  console.log(`\n${signal} received - shutting down...`);