glimmervoid 0.38.1 → 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.
- package/dist/bin/glimmervoid.js +8 -8
- package/dist/chunks/{adapters-B0EJp_oE.js → adapters-CAHxZYT3.js} +2 -2
- package/dist/chunks/{adapters-BIbF8RJB.js → adapters-DDjC7_vG.js} +1 -1
- package/dist/chunks/{agent-setup-cli-C9MMiask.js → agent-setup-cli-DmMfCw5O.js} +1 -1
- package/dist/chunks/{config-store-CKcDJebD.js → config-store-BUNZs4j7.js} +1 -1
- package/dist/chunks/config-store-MAVQhGMh.js +1 -0
- package/dist/chunks/{grok-y65HOvlU.js → grok-B6bsCgdd.js} +1 -1
- package/dist/chunks/{hook-tools-BkxllUHE.js → hook-tools-Dl7-r2Eb.js} +1 -1
- package/dist/chunks/{main-DeiiNNI7.js → main-BNSbP-Yk.js} +544 -481
- package/dist/chunks/{pair-cli-B9hHUHLl.js → pair-cli-DNp8i5L4.js} +2 -2
- package/dist/chunks/{remote-config-DlquYoVe.js → remote-config-C_s2pnLC.js} +1 -1
- package/dist/chunks/{rtk-hook-core-VrUafGAp.js → rtk-hook-core-B-MpzPin.js} +89 -83
- package/dist/chunks/rtk-resolver-BGE6Hd_L.js +1 -0
- package/dist/chunks/{rtk-resolver-C_micGrL.js → rtk-resolver-BgoPsEhT.js} +1 -1
- package/dist/chunks/{settings-cli-C5i9v59a.js → settings-cli-BbzxCyG5.js} +1 -1
- package/dist/client/assets/index-B5uVtedd.css +1 -0
- package/dist/client/assets/{index-ChXRDbjt.js → index-b13-NGGS.js} +42 -42
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +1 -1
- package/dist/session/hook-tool-relay.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/config-store-B6mX2phK.js +0 -1
- package/dist/chunks/rtk-resolver-B8BPgN9L.js +0 -1
- package/dist/client/assets/index-DA251uL1.css +0 -1
|
@@ -12,7 +12,7 @@ import { t as HOOK_VIA_GUARDRAILS_PROXY_ENV } from "./guardrails-proxy-core-BI3r
|
|
|
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 {
|
|
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";
|
|
@@ -20,18 +20,18 @@ import { o as permitsHelpCommand, r as describeSessionLimits } from "./session-r
|
|
|
20
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
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
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-
|
|
23
|
+
import { s as GLIMMERVOID_SECRET_KEYS } from "./grok-B6bsCgdd.js";
|
|
24
24
|
import { n as shellQuote } from "./hook-command-core-qTNK-xMF.js";
|
|
25
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";
|
|
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-
|
|
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
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
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-
|
|
30
|
-
import { t as HOOK_TOOLS } from "./hook-tools-
|
|
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";
|
|
31
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";
|
|
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-
|
|
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";
|
|
33
33
|
import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-B-ZeRdsi.js";
|
|
34
|
-
import { t as getRtkPath } from "./rtk-resolver-
|
|
34
|
+
import { t as getRtkPath } from "./rtk-resolver-BgoPsEhT.js";
|
|
35
35
|
import { createRequire } from "node:module";
|
|
36
36
|
import fs, { constants, readFileSync } from "node:fs";
|
|
37
37
|
import path, { join, resolve } from "node:path";
|
|
@@ -7099,6 +7099,7 @@ function createSessionEventWiring(dependencies) {
|
|
|
7099
7099
|
};
|
|
7100
7100
|
let lastPersistedWasActive = null;
|
|
7101
7101
|
let lastPersistedWasWorking = null;
|
|
7102
|
+
let isTurnWorking = null;
|
|
7102
7103
|
let spawnedAtMs = null;
|
|
7103
7104
|
const persistProjectField = (field, value) => {
|
|
7104
7105
|
Promise.resolve(persistSessionField(dependencies.configStore, dependencies.config, session.id, field, value)).catch((error) => dependencies.logger.warn(`[config] Failed to persist ${field}: ${errorMessage(error)}`));
|
|
@@ -7113,6 +7114,14 @@ function createSessionEventWiring(dependencies) {
|
|
|
7113
7114
|
duration_seconds: durationSeconds
|
|
7114
7115
|
});
|
|
7115
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
|
+
};
|
|
7116
7125
|
let liveTranscriptPath = null;
|
|
7117
7126
|
session.on("claude-session-id", ({ id, vendor, isResumeTarget, transcriptPath }) => {
|
|
7118
7127
|
liveTranscriptPath = transcriptPath;
|
|
@@ -7200,11 +7209,9 @@ function createSessionEventWiring(dependencies) {
|
|
|
7200
7209
|
lastPersistedWasActive = nextWasActive;
|
|
7201
7210
|
persistProjectField("wasActive", nextWasActive);
|
|
7202
7211
|
}
|
|
7203
|
-
const
|
|
7204
|
-
if (
|
|
7205
|
-
|
|
7206
|
-
persistProjectField("wasWorking", nextWasWorking);
|
|
7207
|
-
}
|
|
7212
|
+
const nextIsTurnWorking = decideWasWorkingFlip(to, event, detail?.isIdleCompactionActivity === true);
|
|
7213
|
+
if (nextIsTurnWorking !== null) isTurnWorking = nextIsTurnWorking;
|
|
7214
|
+
persistWasWorking();
|
|
7208
7215
|
const acknowledgeDecision = decideAcknowledge(isAcknowledgeDeferredForCompaction, from, event, detail?.isIdleCompactionActivity === true);
|
|
7209
7216
|
isAcknowledgeDeferredForCompaction = acknowledgeDecision.isAcknowledgeDeferred;
|
|
7210
7217
|
clearCompactionConfirm();
|
|
@@ -7261,6 +7268,7 @@ function createSessionEventWiring(dependencies) {
|
|
|
7261
7268
|
timestamp: Date.now()
|
|
7262
7269
|
}));
|
|
7263
7270
|
session.on("agents-change", (payload) => {
|
|
7271
|
+
persistWasWorking();
|
|
7264
7272
|
dependencies.telegramChannel.recheck(session.id);
|
|
7265
7273
|
dependencies.broadcastControl({
|
|
7266
7274
|
type: "session-agents",
|
|
@@ -7272,6 +7280,7 @@ function createSessionEventWiring(dependencies) {
|
|
|
7272
7280
|
});
|
|
7273
7281
|
});
|
|
7274
7282
|
relay("wakeup-change", "session-wakeup");
|
|
7283
|
+
session.on("wakeup-change", persistWasWorking);
|
|
7275
7284
|
relay("prompt-kind-change", "session-prompt");
|
|
7276
7285
|
relay("conversation-change", "session-conversation");
|
|
7277
7286
|
session.on("merge-status", ({ mergeStatus, reason, parked }) => {
|
|
@@ -7501,7 +7510,7 @@ async function listRepoConversations({ repoPath, projectsDir, git, fsMod, limit
|
|
|
7501
7510
|
//#endregion
|
|
7502
7511
|
//#region session/core/auto-resume.ts
|
|
7503
7512
|
var RESUME_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
7504
|
-
var AUTO_CONTINUE_PROMPT = "Glimmervoid restarted while you were
|
|
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.";
|
|
7505
7514
|
function pickAutoResume(projects, config) {
|
|
7506
7515
|
if (!Array.isArray(projects)) return [];
|
|
7507
7516
|
if (config && config.autoResume === false) return [];
|
|
@@ -14722,6 +14731,12 @@ function createTaskRegistry({ agentTtlMs = DEFAULT_AGENT_TTL_MS, shellTaskTtlMs
|
|
|
14722
14731
|
reap(at);
|
|
14723
14732
|
return isOnlyBackgroundTasks(declaredEntries, countedAgents, idleTaskIds, (entry) => entryAgeMs(entry, at), shellTaskTtlMs, idleTeammateNames.size, teammateTaskTtlMs, agentTtlMs);
|
|
14724
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
|
+
},
|
|
14725
14740
|
getBreakdown() {
|
|
14726
14741
|
return breakdown;
|
|
14727
14742
|
},
|
|
@@ -15243,6 +15258,431 @@ function createSessionOutput(options) {
|
|
|
15243
15258
|
};
|
|
15244
15259
|
}
|
|
15245
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
|
|
15246
15686
|
//#region server/ingest/core/ingest-shell-core.ts
|
|
15247
15687
|
var SOURCE$4 = "shellHistory";
|
|
15248
15688
|
var SHELLS = Object.freeze([
|
|
@@ -15595,12 +16035,15 @@ var writtenHomes = /* @__PURE__ */ new Set();
|
|
|
15595
16035
|
var warnedTools = /* @__PURE__ */ new Set();
|
|
15596
16036
|
var ensuredDataDirs = /* @__PURE__ */ new Set();
|
|
15597
16037
|
var RTK_DATA_FOLDER = "rtk";
|
|
16038
|
+
function currentGlimmervoidHome() {
|
|
16039
|
+
return glimmervoidHomeDir(os.homedir(), process.env);
|
|
16040
|
+
}
|
|
15598
16041
|
function saneYoloHomeDir() {
|
|
15599
|
-
return path.join(
|
|
16042
|
+
return path.join(currentGlimmervoidHome(), "sane-yolo");
|
|
15600
16043
|
}
|
|
15601
|
-
function writeSaneYoloPolicy(homeDir) {
|
|
16044
|
+
function writeSaneYoloPolicy(homeDir, glimmervoidHome = currentGlimmervoidHome()) {
|
|
15602
16045
|
if (writtenHomes.has(homeDir)) return;
|
|
15603
|
-
for (const [relativePath, contents] of Object.entries(
|
|
16046
|
+
for (const [relativePath, contents] of Object.entries(saneYoloFiles(path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER)))) {
|
|
15604
16047
|
const filePath = path.join(homeDir, relativePath);
|
|
15605
16048
|
const serialized = `${JSON.stringify(contents, null, 2)}\n`;
|
|
15606
16049
|
fs.mkdirSync(path.dirname(filePath), {
|
|
@@ -16314,430 +16757,6 @@ function proveMergedAcrossTips(probes) {
|
|
|
16314
16757
|
return mostCautiousProof;
|
|
16315
16758
|
}
|
|
16316
16759
|
//#endregion
|
|
16317
|
-
//#region server/guardrails/core/guardrails-policy-core.ts
|
|
16318
|
-
var VENDOR_PROFILES = Object.freeze({
|
|
16319
|
-
claude: {
|
|
16320
|
-
homeEntries: [".claude", ".claude.json"],
|
|
16321
|
-
launchWritableFolders: ({ cwd, agentSessionId }) => [path.join("projects", encodeProjectDir(cwd)), ...agentSessionId === null ? [] : [path.join("session-env", agentSessionId)]],
|
|
16322
|
-
launchPrivateFolders: ["shell-snapshots"],
|
|
16323
|
-
launchHomeEnvName: null,
|
|
16324
|
-
loginFiles: [".credentials.json"],
|
|
16325
|
-
configEntries: [
|
|
16326
|
-
"settings.json",
|
|
16327
|
-
"settings.local.json",
|
|
16328
|
-
"hooks",
|
|
16329
|
-
"skills",
|
|
16330
|
-
"plugins",
|
|
16331
|
-
"commands",
|
|
16332
|
-
"agents",
|
|
16333
|
-
"CLAUDE.md",
|
|
16334
|
-
"AGENTS.md"
|
|
16335
|
-
],
|
|
16336
|
-
apiDomains: ["api.anthropic.com", "platform.claude.com"],
|
|
16337
|
-
launchEnv: { DISABLE_AUTOUPDATER: "1" }
|
|
16338
|
-
},
|
|
16339
|
-
codex: {
|
|
16340
|
-
homeEntries: [".codex"],
|
|
16341
|
-
launchWritableFolders: () => [],
|
|
16342
|
-
launchPrivateFolders: [],
|
|
16343
|
-
launchHomeEnvName: "CODEX_HOME",
|
|
16344
|
-
loginFiles: ["auth.json"],
|
|
16345
|
-
configEntries: [
|
|
16346
|
-
"config.toml",
|
|
16347
|
-
"AGENTS.md",
|
|
16348
|
-
"skills",
|
|
16349
|
-
"rules",
|
|
16350
|
-
"prompts",
|
|
16351
|
-
"hooks.json"
|
|
16352
|
-
],
|
|
16353
|
-
apiDomains: [
|
|
16354
|
-
"chatgpt.com",
|
|
16355
|
-
"*.chatgpt.com",
|
|
16356
|
-
"auth.openai.com",
|
|
16357
|
-
"api.openai.com",
|
|
16358
|
-
"*.openai.com"
|
|
16359
|
-
],
|
|
16360
|
-
launchEnv: {}
|
|
16361
|
-
}
|
|
16362
|
-
});
|
|
16363
|
-
var GUARDRAILS_VENDORS = Object.freeze(["claude", "codex"]);
|
|
16364
|
-
var UNWRAPPED_VENDOR_HOME_ENTRIES = Object.freeze([".grok"]);
|
|
16365
|
-
var CREDENTIAL_HOME_ENTRIES = Object.freeze([
|
|
16366
|
-
".ssh",
|
|
16367
|
-
".config/gh",
|
|
16368
|
-
"Library/Keychains",
|
|
16369
|
-
".git-credentials"
|
|
16370
|
-
]);
|
|
16371
|
-
var CLOUD_CREDENTIAL_HOME_ENTRIES = Object.freeze([
|
|
16372
|
-
".aws",
|
|
16373
|
-
".azure",
|
|
16374
|
-
".config/gcloud",
|
|
16375
|
-
".kube",
|
|
16376
|
-
".docker",
|
|
16377
|
-
".gnupg",
|
|
16378
|
-
".netrc",
|
|
16379
|
-
".npmrc"
|
|
16380
|
-
]);
|
|
16381
|
-
var STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES = Object.freeze(["Library/Keychains"]);
|
|
16382
|
-
var XDG_CONFIG_DEFAULT_HOME_PREFIX = ".config/";
|
|
16383
|
-
var SHARED_TEMP_DIRS = Object.freeze(["/tmp/claude", "/private/tmp/claude"]);
|
|
16384
|
-
var SHARED_HOME_WRITE_ENTRIES = Object.freeze([".npm/_logs"]);
|
|
16385
|
-
var GUARDRAILS_PLACEHOLDER_NAMES = Object.freeze([
|
|
16386
|
-
".bash_profile",
|
|
16387
|
-
".bashrc",
|
|
16388
|
-
".claude",
|
|
16389
|
-
".gitconfig",
|
|
16390
|
-
".gitmodules",
|
|
16391
|
-
".idea",
|
|
16392
|
-
".mcp.json",
|
|
16393
|
-
".profile",
|
|
16394
|
-
".ripgreprc",
|
|
16395
|
-
".vscode",
|
|
16396
|
-
".zprofile",
|
|
16397
|
-
".zshrc"
|
|
16398
|
-
]);
|
|
16399
|
-
var WHOLE_FILESYSTEM = "/";
|
|
16400
|
-
var GLIMMERVOID_CONFIG_SIBLING_ENTRIES = Object.freeze([
|
|
16401
|
-
"bin",
|
|
16402
|
-
"pairings.json",
|
|
16403
|
-
"pairings-seen.json",
|
|
16404
|
-
"plans",
|
|
16405
|
-
"telegram-outbox.json",
|
|
16406
|
-
"traces",
|
|
16407
|
-
"uploads",
|
|
16408
|
-
"usage-budget-state.json",
|
|
16409
|
-
"usage-lanes.json",
|
|
16410
|
-
"usage-warehouse.json",
|
|
16411
|
-
"visions-intent.json"
|
|
16412
|
-
]);
|
|
16413
|
-
var GLIMMERVOID_HOME_STATE_ENTRIES = Object.freeze([
|
|
16414
|
-
"benchmark-runs",
|
|
16415
|
-
"benchmarks",
|
|
16416
|
-
"config.json",
|
|
16417
|
-
"factory",
|
|
16418
|
-
"issues-cache.json",
|
|
16419
|
-
"knowledge-graph",
|
|
16420
|
-
"litellm-pricing.json",
|
|
16421
|
-
"my-prs-state.json",
|
|
16422
|
-
"my-prs-work",
|
|
16423
|
-
"posthog-reports",
|
|
16424
|
-
"posthog-state.json",
|
|
16425
|
-
"posthog-work",
|
|
16426
|
-
"recordings",
|
|
16427
|
-
"guardrails-homes",
|
|
16428
|
-
"guardrails-policies",
|
|
16429
|
-
"sane-yolo",
|
|
16430
|
-
"scratch",
|
|
16431
|
-
"sounds",
|
|
16432
|
-
"team-review-repos",
|
|
16433
|
-
"team-review-state.json",
|
|
16434
|
-
"team-review-work",
|
|
16435
|
-
"team-review-worktrees",
|
|
16436
|
-
"telemetry-pending-crash.json",
|
|
16437
|
-
"telemetry.json",
|
|
16438
|
-
"tmp",
|
|
16439
|
-
"update-check.json",
|
|
16440
|
-
"update-journal.json",
|
|
16441
|
-
"workflows-state.json",
|
|
16442
|
-
"workflows-work"
|
|
16443
|
-
]);
|
|
16444
|
-
var RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS = Object.freeze(["commands", "agents"]);
|
|
16445
|
-
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";
|
|
16446
|
-
var HOOK_LOOPBACK_HOST = "127.0.0.1";
|
|
16447
|
-
var AGENT_SESSION_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
16448
|
-
var STANDARD_OPEN_NETWORK = Object.freeze({
|
|
16449
|
-
allowAllUnixSockets: true,
|
|
16450
|
-
allowMachLookup: ["*"]
|
|
16451
|
-
});
|
|
16452
|
-
var STRICT_OPEN_NETWORK = Object.freeze({ allowAllUnixSockets: false });
|
|
16453
|
-
function unique(entries) {
|
|
16454
|
-
return [...new Set(entries)];
|
|
16455
|
-
}
|
|
16456
|
-
function literalEntries(entryPaths) {
|
|
16457
|
-
return unique(entryPaths).map((entryPath) => ({
|
|
16458
|
-
path: entryPath,
|
|
16459
|
-
literal: true
|
|
16460
|
-
}));
|
|
16461
|
-
}
|
|
16462
|
-
function homePaths(host, homeEntries) {
|
|
16463
|
-
return homeEntries.map((entry) => path.join(host.homeDir, entry));
|
|
16464
|
-
}
|
|
16465
|
-
function isInsideAny(parents, child) {
|
|
16466
|
-
return parents.some((parent) => isPathInside(parent, child));
|
|
16467
|
-
}
|
|
16468
|
-
function vendorStatePaths(host, vendor, stateFolderEntries) {
|
|
16469
|
-
return stateFolderEntries.map((entry) => path.join(host.vendorLocations[vendor].stateFolder, entry));
|
|
16470
|
-
}
|
|
16471
|
-
function vendorHeldPaths(host, vendor) {
|
|
16472
|
-
const { stateFolder, configFiles, otherHomes } = host.vendorLocations[vendor];
|
|
16473
|
-
return [
|
|
16474
|
-
stateFolder,
|
|
16475
|
-
...configFiles,
|
|
16476
|
-
...otherHomes
|
|
16477
|
-
];
|
|
16478
|
-
}
|
|
16479
|
-
function launchHomeOf(host, vendor) {
|
|
16480
|
-
return path.join(host.launchHomeDir, vendor);
|
|
16481
|
-
}
|
|
16482
|
-
function vendorsWithLaunchHome(role) {
|
|
16483
|
-
if (role.vendorHome.scope === "state") return [];
|
|
16484
|
-
return role.vendors.filter((vendor) => VENDOR_PROFILES[vendor].launchHomeEnvName !== null);
|
|
16485
|
-
}
|
|
16486
|
-
function vendorWritableFolders(role, host) {
|
|
16487
|
-
const { vendorHome } = role;
|
|
16488
|
-
if (vendorHome.scope === "state") return role.vendors.map((vendor) => host.vendorLocations[vendor].stateFolder);
|
|
16489
|
-
return role.vendors.flatMap((vendor) => {
|
|
16490
|
-
const profile = VENDOR_PROFILES[vendor];
|
|
16491
|
-
if (profile.launchHomeEnvName !== null) return [launchHomeOf(host, vendor)];
|
|
16492
|
-
return vendorStatePaths(host, vendor, profile.launchWritableFolders(vendorHome));
|
|
16493
|
-
});
|
|
16494
|
-
}
|
|
16495
|
-
function launchPrivateFolders(role, host) {
|
|
16496
|
-
if (role.vendorHome.scope === "state") return [];
|
|
16497
|
-
return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].launchPrivateFolders));
|
|
16498
|
-
}
|
|
16499
|
-
function launchHomeLinkCandidates(role, host) {
|
|
16500
|
-
return vendorsWithLaunchHome(role).flatMap((vendor) => {
|
|
16501
|
-
const { configEntries, loginFiles } = VENDOR_PROFILES[vendor];
|
|
16502
|
-
const linkFor = (entry, isLogin) => ({
|
|
16503
|
-
linkPath: path.join(launchHomeOf(host, vendor), entry),
|
|
16504
|
-
targetPath: path.join(host.vendorLocations[vendor].stateFolder, entry),
|
|
16505
|
-
isLogin
|
|
16506
|
-
});
|
|
16507
|
-
return [...configEntries.map((entry) => linkFor(entry, false)), ...loginFiles.map((entry) => linkFor(entry, true))];
|
|
16508
|
-
});
|
|
16509
|
-
}
|
|
16510
|
-
function launchHomeEnv(role, host) {
|
|
16511
|
-
return Object.fromEntries(vendorsWithLaunchHome(role).flatMap((vendor) => {
|
|
16512
|
-
const envName = VENDOR_PROFILES[vendor].launchHomeEnvName;
|
|
16513
|
-
return envName === null ? [] : [[envName, launchHomeOf(host, vendor)]];
|
|
16514
|
-
}));
|
|
16515
|
-
}
|
|
16516
|
-
function vendorLoginFiles(role, host) {
|
|
16517
|
-
return role.vendors.flatMap((vendor) => vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].loginFiles));
|
|
16518
|
-
}
|
|
16519
|
-
function roleWritableRoots(role) {
|
|
16520
|
-
return [
|
|
16521
|
-
...role.writableRoots,
|
|
16522
|
-
...role.lockedCheckouts,
|
|
16523
|
-
...role.commitCheckouts.flatMap(({ checkout, gitDir }) => [checkout, gitDir])
|
|
16524
|
-
];
|
|
16525
|
-
}
|
|
16526
|
-
function alwaysWritablePaths(role, host) {
|
|
16527
|
-
return [
|
|
16528
|
-
host.tempDir,
|
|
16529
|
-
...roleWritableRoots(role),
|
|
16530
|
-
...vendorWritableFolders(role, host)
|
|
16531
|
-
];
|
|
16532
|
-
}
|
|
16533
|
-
function commitCheckoutWriteDenies({ checkout, gitDir }) {
|
|
16534
|
-
const gitPointer = path.join(checkout, ".git");
|
|
16535
|
-
const gitDirDenies = [path.join(gitDir, "hooks"), path.join(gitDir, "config")];
|
|
16536
|
-
if (path.resolve(gitPointer) === path.resolve(gitDir)) return gitDirDenies;
|
|
16537
|
-
return [gitPointer, ...gitDirDenies];
|
|
16538
|
-
}
|
|
16539
|
-
function writeDeniesWhenPresent(role, host) {
|
|
16540
|
-
const writablePaths = alwaysWritablePaths(role, host);
|
|
16541
|
-
const sharedHomeWrites = homePaths(host, SHARED_HOME_WRITE_ENTRIES).filter((sharedPath) => !isInsideAny(roleWritableRoots(role), sharedPath));
|
|
16542
|
-
const vendorConfig = role.vendors.flatMap((vendor) => [...vendorStatePaths(host, vendor, VENDOR_PROFILES[vendor].configEntries), ...host.vendorLocations[vendor].configFiles]).filter((configPath) => isInsideAny(writablePaths, configPath));
|
|
16543
|
-
return [
|
|
16544
|
-
...SHARED_TEMP_DIRS,
|
|
16545
|
-
...sharedHomeWrites,
|
|
16546
|
-
...vendorConfig,
|
|
16547
|
-
...role.commitCheckouts.flatMap(commitCheckoutWriteDenies)
|
|
16548
|
-
];
|
|
16549
|
-
}
|
|
16550
|
-
function lockedCheckoutWriteDenies(role) {
|
|
16551
|
-
return role.lockedCheckouts.flatMap((checkout) => [path.join(checkout, ".git"), path.join(checkout, ".claude")]);
|
|
16552
|
-
}
|
|
16553
|
-
function lockedClaudeMountPoints(role) {
|
|
16554
|
-
return role.lockedCheckouts.flatMap((checkout) => RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS.map((folder) => path.join(checkout, ".claude", folder)));
|
|
16555
|
-
}
|
|
16556
|
-
function guardrailsPlaceholderPaths(role) {
|
|
16557
|
-
return unique([...(role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : []).flatMap((workingFolder) => GUARDRAILS_PLACEHOLDER_NAMES.map((placeholderName) => path.join(workingFolder, placeholderName))), ...lockedCheckoutWriteDenies(role)]);
|
|
16558
|
-
}
|
|
16559
|
-
function homeEntriesNamedLike(host, homeEntries) {
|
|
16560
|
-
return host.homeEntryNames.filter((entryName) => homeEntries.some((homeEntry) => entryName.startsWith(homeEntry)));
|
|
16561
|
-
}
|
|
16562
|
-
function relocatedXdgConfigPaths(host, homeEntries) {
|
|
16563
|
-
const xdgConfigHome = host.relocatedXdgConfigHome;
|
|
16564
|
-
if (xdgConfigHome === null) return [];
|
|
16565
|
-
return homeEntries.filter((entry) => entry.startsWith(XDG_CONFIG_DEFAULT_HOME_PREFIX)).map((entry) => path.join(xdgConfigHome, entry.slice(8)));
|
|
16566
|
-
}
|
|
16567
|
-
function isStandardLevel(role) {
|
|
16568
|
-
return role.guardrailLevel === "standard";
|
|
16569
|
-
}
|
|
16570
|
-
function blockedCredentialHomeEntries(role) {
|
|
16571
|
-
const credentialHomeEntries = [...CREDENTIAL_HOME_ENTRIES, ...CLOUD_CREDENTIAL_HOME_ENTRIES];
|
|
16572
|
-
if (!isStandardLevel(role)) return credentialHomeEntries;
|
|
16573
|
-
return credentialHomeEntries.filter((entry) => !STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES.includes(entry));
|
|
16574
|
-
}
|
|
16575
|
-
function credentialWriteBlocks(role, host) {
|
|
16576
|
-
const credentialHomeEntries = blockedCredentialHomeEntries(role);
|
|
16577
|
-
return [...homePaths(host, credentialHomeEntries), ...relocatedXdgConfigPaths(host, credentialHomeEntries)];
|
|
16578
|
-
}
|
|
16579
|
-
function glimmervoidStateWriteBlocks(role, host) {
|
|
16580
|
-
const keptWritable = alwaysWritablePaths(role, host);
|
|
16581
|
-
const configFolder = path.dirname(host.glimmervoidConfigFile);
|
|
16582
|
-
const homeEntries = [
|
|
16583
|
-
...GLIMMERVOID_HOME_STATE_ENTRIES,
|
|
16584
|
-
...GLIMMERVOID_CONFIG_SIBLING_ENTRIES,
|
|
16585
|
-
...host.glimmervoidHomeEntryNames
|
|
16586
|
-
].map((entryName) => path.join(host.glimmervoidHome, entryName));
|
|
16587
|
-
const configSiblings = GLIMMERVOID_CONFIG_SIBLING_ENTRIES.map((entryName) => path.join(configFolder, entryName));
|
|
16588
|
-
return unique([
|
|
16589
|
-
host.glimmervoidConfigFile,
|
|
16590
|
-
...homeEntries,
|
|
16591
|
-
...configSiblings
|
|
16592
|
-
]).filter((entryPath) => !keptWritable.some((writable) => isPathInside(entryPath, writable)));
|
|
16593
|
-
}
|
|
16594
|
-
function standardWriteBlockCandidates(role, host) {
|
|
16595
|
-
if (!isStandardLevel(role)) return [];
|
|
16596
|
-
return unique([
|
|
16597
|
-
...credentialWriteBlocks(role, host),
|
|
16598
|
-
...glimmervoidStateWriteBlocks(role, host),
|
|
16599
|
-
...role.blockedPaths ?? []
|
|
16600
|
-
]);
|
|
16601
|
-
}
|
|
16602
|
-
function readDeniedPaths(role, host) {
|
|
16603
|
-
const otherVendors = GUARDRAILS_VENDORS.filter((vendor) => !role.vendors.includes(vendor));
|
|
16604
|
-
const otherVendorHomeEntries = [...otherVendors.flatMap((vendor) => VENDOR_PROFILES[vendor].homeEntries), ...UNWRAPPED_VENDOR_HOME_ENTRIES];
|
|
16605
|
-
const credentialHomeEntries = blockedCredentialHomeEntries(role);
|
|
16606
|
-
return [
|
|
16607
|
-
...homePaths(host, [
|
|
16608
|
-
...credentialHomeEntries,
|
|
16609
|
-
...otherVendorHomeEntries,
|
|
16610
|
-
...homeEntriesNamedLike(host, otherVendorHomeEntries)
|
|
16611
|
-
]),
|
|
16612
|
-
...relocatedXdgConfigPaths(host, credentialHomeEntries),
|
|
16613
|
-
...otherVendors.flatMap((vendor) => vendorHeldPaths(host, vendor)),
|
|
16614
|
-
...host.unwrappedVendorHomes,
|
|
16615
|
-
host.glimmervoidHome,
|
|
16616
|
-
...launchPrivateFolders(role, host),
|
|
16617
|
-
...role.readDenied
|
|
16618
|
-
];
|
|
16619
|
-
}
|
|
16620
|
-
function guardrailsPolicyProbePaths(role, host) {
|
|
16621
|
-
return unique([
|
|
16622
|
-
...writeDeniesWhenPresent(role, host),
|
|
16623
|
-
...vendorLoginFiles(role, host),
|
|
16624
|
-
...launchHomeLinkCandidates(role, host).map((link) => link.targetPath)
|
|
16625
|
-
]);
|
|
16626
|
-
}
|
|
16627
|
-
function isValidPort(port) {
|
|
16628
|
-
return Number.isInteger(port) && port >= 1 && port <= 65535;
|
|
16629
|
-
}
|
|
16630
|
-
function hostNamedPaths(host) {
|
|
16631
|
-
const relocatedXdgConfigHomes = host.relocatedXdgConfigHome === null ? [] : [host.relocatedXdgConfigHome];
|
|
16632
|
-
return [
|
|
16633
|
-
host.homeDir,
|
|
16634
|
-
host.glimmervoidHome,
|
|
16635
|
-
host.glimmervoidConfigFile,
|
|
16636
|
-
host.tempDir,
|
|
16637
|
-
host.launchHomeDir,
|
|
16638
|
-
...relocatedXdgConfigHomes,
|
|
16639
|
-
...host.unwrappedVendorHomes,
|
|
16640
|
-
...GUARDRAILS_VENDORS.flatMap((vendor) => vendorHeldPaths(host, vendor))
|
|
16641
|
-
];
|
|
16642
|
-
}
|
|
16643
|
-
function guardrailsRoleRefusal(role, host) {
|
|
16644
|
-
const launchCwds = role.vendorHome.scope === "launch" ? [role.vendorHome.cwd] : [];
|
|
16645
|
-
const relativePath = [
|
|
16646
|
-
...hostNamedPaths(host),
|
|
16647
|
-
...roleWritableRoots(role),
|
|
16648
|
-
...role.readDenied,
|
|
16649
|
-
...role.readableWithinDenied,
|
|
16650
|
-
...launchCwds
|
|
16651
|
-
].find((namedPath) => !path.isAbsolute(namedPath));
|
|
16652
|
-
if (relativePath !== void 0) return `guardrails policy path is not absolute: ${relativePath}`;
|
|
16653
|
-
const rootOverProtectedHome = [...roleWritableRoots(role), ...vendorWritableFolders(role, host)].find((root) => isPathInside(root, host.homeDir) || isPathInside(root, host.glimmervoidHome));
|
|
16654
|
-
if (rootOverProtectedHome !== void 0) return `writable root ${rootOverProtectedHome} contains the home folder or the Glimmervoid home`;
|
|
16655
|
-
const writablePaths = alwaysWritablePaths(role, host);
|
|
16656
|
-
const reallowedAncestor = role.readableWithinDenied.find((readable) => writablePaths.some((writable) => isPathInside(readable, writable, { allowEqual: false })));
|
|
16657
|
-
if (reallowedAncestor !== void 0) return `readable path ${reallowedAncestor} is an ancestor of a writable root`;
|
|
16658
|
-
if (role.network.access === "allowlist" && role.network.hookPort !== null && !isValidPort(role.network.hookPort)) return "hook listener port is invalid";
|
|
16659
|
-
const agentSessionId = role.vendorHome.scope === "launch" ? role.vendorHome.agentSessionId : null;
|
|
16660
|
-
if (agentSessionId !== null && !AGENT_SESSION_ID_SHAPE.test(agentSessionId)) return "agent session id is invalid";
|
|
16661
|
-
return null;
|
|
16662
|
-
}
|
|
16663
|
-
function networkPolicy(role) {
|
|
16664
|
-
if (role.network.access === "open") return isStandardLevel(role) ? { ...STANDARD_OPEN_NETWORK } : { ...STRICT_OPEN_NETWORK };
|
|
16665
|
-
if (role.network.access === "none") return {
|
|
16666
|
-
allowedDomains: [],
|
|
16667
|
-
deniedDomains: [],
|
|
16668
|
-
allowLocalBinding: false,
|
|
16669
|
-
allowAllUnixSockets: false
|
|
16670
|
-
};
|
|
16671
|
-
const hookEndpoint = role.network.hookPort === null ? [] : [`${HOOK_LOOPBACK_HOST}:${role.network.hookPort}`];
|
|
16672
|
-
const vendorDomains = role.vendors.flatMap((vendor) => VENDOR_PROFILES[vendor].apiDomains);
|
|
16673
|
-
return {
|
|
16674
|
-
allowedDomains: unique([
|
|
16675
|
-
...hookEndpoint,
|
|
16676
|
-
...vendorDomains,
|
|
16677
|
-
...role.network.domains
|
|
16678
|
-
]),
|
|
16679
|
-
deniedDomains: [],
|
|
16680
|
-
strictAllowlist: true,
|
|
16681
|
-
allowLocalBinding: false,
|
|
16682
|
-
allowAllUnixSockets: false
|
|
16683
|
-
};
|
|
16684
|
-
}
|
|
16685
|
-
function guardedEnvFor(role, host) {
|
|
16686
|
-
if (role.network.access === "allowlist") return {
|
|
16687
|
-
NO_PROXY: GUARDED_PROXY_BYPASS,
|
|
16688
|
-
no_proxy: GUARDED_PROXY_BYPASS,
|
|
16689
|
-
[HOOK_VIA_GUARDRAILS_PROXY_ENV]: "1"
|
|
16690
|
-
};
|
|
16691
|
-
if (role.network.access === "open") return { TMPDIR: host.tempDir };
|
|
16692
|
-
return {};
|
|
16693
|
-
}
|
|
16694
|
-
function filesystemWrites(role, host, writablePaths) {
|
|
16695
|
-
if (isStandardLevel(role)) return {
|
|
16696
|
-
allowWrite: literalEntries([WHOLE_FILESYSTEM, ...writablePaths]),
|
|
16697
|
-
denyWrite: literalEntries(host.writeBlockedPaths)
|
|
16698
|
-
};
|
|
16699
|
-
const isPresent = (candidate) => host.existingPaths.has(candidate);
|
|
16700
|
-
return {
|
|
16701
|
-
allowWrite: literalEntries(writablePaths),
|
|
16702
|
-
denyWrite: literalEntries([...writeDeniesWhenPresent(role, host).filter(isPresent), ...lockedCheckoutWriteDenies(role)])
|
|
16703
|
-
};
|
|
16704
|
-
}
|
|
16705
|
-
function buildGuardrailsLaunchPlan(role, host) {
|
|
16706
|
-
const refusal = guardrailsRoleRefusal(role, host);
|
|
16707
|
-
if (refusal !== null) return {
|
|
16708
|
-
ok: false,
|
|
16709
|
-
reason: refusal
|
|
16710
|
-
};
|
|
16711
|
-
const isPresent = (candidate) => host.existingPaths.has(candidate);
|
|
16712
|
-
const writablePaths = [...alwaysWritablePaths(role, host), ...vendorLoginFiles(role, host).filter(isPresent)];
|
|
16713
|
-
const readDenied = readDeniedPaths(role, host);
|
|
16714
|
-
const writableWithinDenied = writablePaths.filter((writable) => isInsideAny(readDenied, writable));
|
|
16715
|
-
return {
|
|
16716
|
-
ok: true,
|
|
16717
|
-
plan: {
|
|
16718
|
-
launcher: role.network.access === "open" ? "open-network" : "runtime-cli",
|
|
16719
|
-
policy: {
|
|
16720
|
-
network: networkPolicy(role),
|
|
16721
|
-
filesystem: {
|
|
16722
|
-
denyRead: literalEntries(readDenied),
|
|
16723
|
-
allowRead: literalEntries([...writableWithinDenied, ...role.readableWithinDenied]),
|
|
16724
|
-
...filesystemWrites(role, host, writablePaths)
|
|
16725
|
-
},
|
|
16726
|
-
terminalScope: isStandardLevel(role) ? "any" : "own",
|
|
16727
|
-
allowAppleEvents: isStandardLevel(role)
|
|
16728
|
-
},
|
|
16729
|
-
launchEnv: Object.assign({ CLAUDE_CODE_TMPDIR: host.tempDir }, ...role.vendors.map((vendor) => VENDOR_PROFILES[vendor].launchEnv), launchHomeEnv(role, host)),
|
|
16730
|
-
guardedEnv: guardedEnvFor(role, host),
|
|
16731
|
-
requiredDirectories: unique([
|
|
16732
|
-
host.tempDir,
|
|
16733
|
-
...vendorWritableFolders(role, host),
|
|
16734
|
-
...launchPrivateFolders(role, host)
|
|
16735
|
-
]),
|
|
16736
|
-
launchHomeLinks: launchHomeLinkCandidates(role, host).filter((link) => isPresent(link.targetPath))
|
|
16737
|
-
}
|
|
16738
|
-
};
|
|
16739
|
-
}
|
|
16740
|
-
//#endregion
|
|
16741
16760
|
//#region shared/repo.ts
|
|
16742
16761
|
var REPO_SLUG = "johncwaters/glimmervoid";
|
|
16743
16762
|
//#endregion
|
|
@@ -21200,6 +21219,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
|
|
|
21200
21219
|
};
|
|
21201
21220
|
let publishedActiveAgents = 0;
|
|
21202
21221
|
let publishedAwaitingBackgroundTasks = false;
|
|
21222
|
+
let publishedHasBackgroundWork = false;
|
|
21203
21223
|
const wakeups = /* @__PURE__ */ new Map();
|
|
21204
21224
|
let wakeupSeq = 0;
|
|
21205
21225
|
let wakeupExpiryTimer = null;
|
|
@@ -21231,12 +21251,20 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
|
|
|
21231
21251
|
function awaitingBackgroundTasks() {
|
|
21232
21252
|
return detectBackgroundAgents && gateHeldReady !== null && port.state() === "RUNNING" && tasks.isOnlyBackgroundTasks();
|
|
21233
21253
|
}
|
|
21254
|
+
function hasBackgroundWork() {
|
|
21255
|
+
if (activeAgentCount() > 0) return true;
|
|
21256
|
+
if (detectBackgroundAgents && tasks.hasLiveMonitor()) return true;
|
|
21257
|
+
return pendingWakeup() !== null;
|
|
21258
|
+
}
|
|
21234
21259
|
function publishAgentsChange() {
|
|
21260
|
+
if (port.isDestroyed()) return;
|
|
21235
21261
|
const activeAgents = activeAgentCount();
|
|
21236
21262
|
const awaiting = awaitingBackgroundTasks();
|
|
21237
|
-
|
|
21263
|
+
const backgroundWork = hasBackgroundWork();
|
|
21264
|
+
if (activeAgents === publishedActiveAgents && awaiting === publishedAwaitingBackgroundTasks && backgroundWork === publishedHasBackgroundWork) return;
|
|
21238
21265
|
publishedActiveAgents = activeAgents;
|
|
21239
21266
|
publishedAwaitingBackgroundTasks = awaiting;
|
|
21267
|
+
publishedHasBackgroundWork = backgroundWork;
|
|
21240
21268
|
port.emit("agents-change", {
|
|
21241
21269
|
activeAgents,
|
|
21242
21270
|
awaitingBackgroundTasks: awaiting
|
|
@@ -21463,6 +21491,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
|
|
|
21463
21491
|
wakeupExpiryTimer.unref();
|
|
21464
21492
|
}
|
|
21465
21493
|
function emitWakeupChange() {
|
|
21494
|
+
if (port.isDestroyed()) return;
|
|
21466
21495
|
port.emit("wakeup-change", { pendingWakeup: pendingWakeup() });
|
|
21467
21496
|
armWakeupExpiryTimer();
|
|
21468
21497
|
}
|
|
@@ -21487,6 +21516,7 @@ function createSessionBackgroundTracking({ detectBackgroundAgents, agentTtlMs, s
|
|
|
21487
21516
|
trackSubagent,
|
|
21488
21517
|
activeAgentCount,
|
|
21489
21518
|
awaitingBackgroundTasks,
|
|
21519
|
+
hasBackgroundWork,
|
|
21490
21520
|
emitAgentsChange,
|
|
21491
21521
|
clearAgents,
|
|
21492
21522
|
stashGateHeldReady,
|
|
@@ -22179,6 +22209,9 @@ var Session = class extends EventEmitter {
|
|
|
22179
22209
|
get hookSeen() {
|
|
22180
22210
|
return this._hookSeen;
|
|
22181
22211
|
}
|
|
22212
|
+
get hasBackgroundWork() {
|
|
22213
|
+
return this.backgroundTracking.hasBackgroundWork();
|
|
22214
|
+
}
|
|
22182
22215
|
get agentToken() {
|
|
22183
22216
|
return this._agentToken;
|
|
22184
22217
|
}
|
|
@@ -23342,6 +23375,7 @@ var GuardrailsLaunchOwner = z.object({
|
|
|
23342
23375
|
ownerHost: z.string(),
|
|
23343
23376
|
ownerPidNamespace: z.string().nullable(),
|
|
23344
23377
|
ownsTempDir: z.boolean(),
|
|
23378
|
+
keptTempFolderName: z.string().min(1).optional(),
|
|
23345
23379
|
logins: z.array(GuardrailsLaunchLogin),
|
|
23346
23380
|
placeholderPaths: z.array(z.string().min(1))
|
|
23347
23381
|
}).strict();
|
|
@@ -23453,11 +23487,45 @@ function bridgeSocketLauncherEnv(inheritedTempDirectory, platform) {
|
|
|
23453
23487
|
return { TMPDIR: SHORT_BRIDGE_SOCKET_FOLDER };
|
|
23454
23488
|
}
|
|
23455
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
|
|
23456
23525
|
//#region server/guardrails/guardrails-launch.ts
|
|
23457
23526
|
var LAUNCH_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
23458
23527
|
var GUARDED_ENV_COMMAND = "/usr/bin/env";
|
|
23459
23528
|
var POLICY_FOLDER = "guardrails-policies";
|
|
23460
|
-
var TEMP_FOLDER = "guardrails-temp";
|
|
23461
23529
|
var LAUNCH_HOME_FOLDER = "guardrails-homes";
|
|
23462
23530
|
var START_FOLDER = "start";
|
|
23463
23531
|
var OWNER_FILE_SUFFIX = ".owner.json";
|
|
@@ -23465,6 +23533,7 @@ var ENTER_FOLDER_SCRIPT = "cd \"$1\" && shift && exec \"$@\"";
|
|
|
23465
23533
|
var LOGIN_FILE_MODE = 384;
|
|
23466
23534
|
var ABSENT_PATH_DENY_PLATFORM = "darwin";
|
|
23467
23535
|
var OWN_PID_NAMESPACE_LINK = "/proc/self/ns/pid";
|
|
23536
|
+
var SESSION_TEMP_RETAIN_DAYS = 7;
|
|
23468
23537
|
async function isPresent(candidate) {
|
|
23469
23538
|
try {
|
|
23470
23539
|
await access(candidate);
|
|
@@ -23663,7 +23732,7 @@ async function sweepOrphanedGuardrailsLaunches(log = console) {
|
|
|
23663
23732
|
policyPath: path.join(policyDir, `${launchId}.json`),
|
|
23664
23733
|
ownerPath,
|
|
23665
23734
|
launchHomeDir: path.join(glimmervoidHome, LAUNCH_HOME_FOLDER, launchId),
|
|
23666
|
-
ownedTempDir: owner.ownsTempDir ? path.join(glimmervoidHome,
|
|
23735
|
+
ownedTempDir: owner.ownsTempDir ? path.join(glimmervoidHome, GUARDRAILS_TEMP_FOLDER, launchId) : null
|
|
23667
23736
|
}, owner, launchId, { onlyNewerLogins: true });
|
|
23668
23737
|
removedLaunchCount += 1;
|
|
23669
23738
|
} catch (error) {
|
|
@@ -23675,6 +23744,24 @@ async function sweepOrphanedGuardrailsLaunches(log = console) {
|
|
|
23675
23744
|
log.warn(`[guardrails] could not sweep leftover launch folders: ${errorMessage(error)}`);
|
|
23676
23745
|
}
|
|
23677
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
|
+
}
|
|
23678
23765
|
function launcherCommand(plan, policyPath) {
|
|
23679
23766
|
if (plan.launcher === "open-network") return {
|
|
23680
23767
|
file: process.execPath,
|
|
@@ -23708,11 +23795,19 @@ function enteringFolder(enterDir, file, args) {
|
|
|
23708
23795
|
...args
|
|
23709
23796
|
];
|
|
23710
23797
|
}
|
|
23711
|
-
|
|
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 }) {
|
|
23712
23803
|
if (!LAUNCH_ID_SHAPE.test(launchId)) return {
|
|
23713
23804
|
ok: false,
|
|
23714
23805
|
reason: "guardrails launch id is invalid"
|
|
23715
23806
|
};
|
|
23807
|
+
if (keptTempFolderName !== void 0 && !LAUNCH_ID_SHAPE.test(keptTempFolderName)) return {
|
|
23808
|
+
ok: false,
|
|
23809
|
+
reason: "guardrails temp folder name is invalid"
|
|
23810
|
+
};
|
|
23716
23811
|
try {
|
|
23717
23812
|
const policyDir = path.join(glimmervoidHomeDir$1(), POLICY_FOLDER);
|
|
23718
23813
|
await mkdir(policyDir, {
|
|
@@ -23725,8 +23820,8 @@ async function prepareGuardrailsLaunch({ role, launchId, tempDir, enterDir }) {
|
|
|
23725
23820
|
withRealRoots(role),
|
|
23726
23821
|
readOwnPidNamespace()
|
|
23727
23822
|
]);
|
|
23728
|
-
const ownsTempDir = tempDir === void 0;
|
|
23729
|
-
const launchTempDir =
|
|
23823
|
+
const ownsTempDir = tempDir === void 0 && keptTempFolderName === void 0;
|
|
23824
|
+
const launchTempDir = launchTempDirFor(glimmervoidHome, launchId, tempDir, keptTempFolderName);
|
|
23730
23825
|
const launchHomeDir = path.join(glimmervoidHome, LAUNCH_HOME_FOLDER, launchId);
|
|
23731
23826
|
const vendorLocations = await resolveVendorLocations(process.env, homeDir);
|
|
23732
23827
|
if (vendorLocations === null) return {
|
|
@@ -23783,6 +23878,7 @@ async function prepareGuardrailsLaunch({ role, launchId, tempDir, enterDir }) {
|
|
|
23783
23878
|
ownerHost: os.hostname(),
|
|
23784
23879
|
ownerPidNamespace,
|
|
23785
23880
|
ownsTempDir,
|
|
23881
|
+
...keptTempFolderName === void 0 ? {} : { keptTempFolderName },
|
|
23786
23882
|
logins: plan.launchHomeLinks.filter((link) => link.isLogin).map(({ linkPath, targetPath }) => ({
|
|
23787
23883
|
linkPath,
|
|
23788
23884
|
targetPath
|
|
@@ -28809,41 +28905,6 @@ async function commitAndLandFactoryLedger({ projectPath, ledger, targetBranch, m
|
|
|
28809
28905
|
}
|
|
28810
28906
|
}
|
|
28811
28907
|
//#endregion
|
|
28812
|
-
//#region server/prune-files.ts
|
|
28813
|
-
var MS_PER_DAY = 864e5;
|
|
28814
|
-
function idForEntry(entry, suffixes) {
|
|
28815
|
-
for (const suffix of suffixes) {
|
|
28816
|
-
if (suffix.length === 0) return entry;
|
|
28817
|
-
if (entry.endsWith(suffix)) return entry.slice(0, -suffix.length);
|
|
28818
|
-
}
|
|
28819
|
-
return null;
|
|
28820
|
-
}
|
|
28821
|
-
async function pruneAgedFiles({ directory, suffixes, retainDays, now = Date.now(), isRetainedId = () => false, entryMode = "file", fsPromises = fs.promises }) {
|
|
28822
|
-
let entries;
|
|
28823
|
-
try {
|
|
28824
|
-
entries = await fsPromises.readdir(directory);
|
|
28825
|
-
} catch {
|
|
28826
|
-
return [];
|
|
28827
|
-
}
|
|
28828
|
-
const cutoff = now - retainDays * MS_PER_DAY;
|
|
28829
|
-
const removedIds = [];
|
|
28830
|
-
for (const entry of entries) {
|
|
28831
|
-
const id = idForEntry(entry, suffixes);
|
|
28832
|
-
if (!id || isRetainedId(id)) continue;
|
|
28833
|
-
const filePath = path.join(directory, entry);
|
|
28834
|
-
try {
|
|
28835
|
-
if ((await fsPromises.stat(filePath)).mtimeMs >= cutoff) continue;
|
|
28836
|
-
if (entryMode === "directory") await fsPromises.rm(filePath, {
|
|
28837
|
-
recursive: true,
|
|
28838
|
-
force: true
|
|
28839
|
-
});
|
|
28840
|
-
if (entryMode === "file") await fsPromises.unlink(filePath);
|
|
28841
|
-
removedIds.push(id);
|
|
28842
|
-
} catch {}
|
|
28843
|
-
}
|
|
28844
|
-
return removedIds;
|
|
28845
|
-
}
|
|
28846
|
-
//#endregion
|
|
28847
28908
|
//#region server/factory/factory-decision-log.ts
|
|
28848
28909
|
function createFactoryDecisionLog({ homeDir = glimmervoidHomeDir$1(), now = Date.now, log = console, redact = (text) => text, onDecision } = {}) {
|
|
28849
28910
|
const prunedDayByProject = /* @__PURE__ */ new Map();
|
|
@@ -47168,6 +47229,7 @@ function createUploadsWiring({ configPath, liveSessionIds, setIntervalFn = DEFAU
|
|
|
47168
47229
|
isRetainedId: (id) => retainedSessionIds.has(id),
|
|
47169
47230
|
fsPromises: fs.promises
|
|
47170
47231
|
});
|
|
47232
|
+
await pruneLeftoverSessionTempFolders(path.dirname(uploadsRoot), retainedSessionIds);
|
|
47171
47233
|
}
|
|
47172
47234
|
async function start() {
|
|
47173
47235
|
if (timer) return;
|
|
@@ -55145,6 +55207,7 @@ function createSessionGuardrails({ getSettings, uploadsRoot, guardrailsRefusal =
|
|
|
55145
55207
|
const prepared = await prepareGuardrails({
|
|
55146
55208
|
role,
|
|
55147
55209
|
launchId: facts.launchId,
|
|
55210
|
+
keptTempFolderName: request.sessionId,
|
|
55148
55211
|
enterDir: cwd
|
|
55149
55212
|
});
|
|
55150
55213
|
if (!prepared.ok) return {
|