glimmervoid 0.34.0 → 0.34.1
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 +3 -3
- package/dist/chunks/{adapters-_HwpLy0R.js → adapters-CgbcceU3.js} +1 -1
- package/dist/chunks/{adapters-BY8slY95.js → adapters-D-cRFZ_Q.js} +1 -1
- package/dist/chunks/{config-store-CggAQLUB.js → config-store-D0lRWsAM.js} +1 -1
- package/dist/chunks/config-store-DwTxLe8Y.js +2 -0
- package/dist/chunks/{contracts-D1wLN5iO.js → contracts-DZV9H8px.js} +24 -0
- package/dist/chunks/{main-Dh4udE7P.js → main-VMWdsGC6.js} +178 -119
- package/dist/chunks/{pair-cli-Nnrd0il_.js → pair-cli-CI848omy.js} +2 -2
- package/dist/chunks/{remote-config-DKMQEIZh.js → remote-config-Y6YtqoiO.js} +1 -1
- package/dist/client/assets/index-b9goyXSa.js +254 -0
- package/dist/client/index.html +1 -1
- package/dist/server/index.js +1 -1
- package/dist/session/sandbox-open-launcher.js +22 -8
- package/package.json +1 -1
- package/dist/chunks/config-store-BmdXeUz1.js +0 -2
- package/dist/client/assets/index-BiTwrj1H.js +0 -254
package/dist/bin/glimmervoid.js
CHANGED
|
@@ -135,7 +135,7 @@ var SUBCOMMAND_RUNNERS = new Map([
|
|
|
135
135
|
return 0;
|
|
136
136
|
}],
|
|
137
137
|
["pair", async (subcommandArgs) => {
|
|
138
|
-
const { runPairCli } = await import("../chunks/pair-cli-
|
|
138
|
+
const { runPairCli } = await import("../chunks/pair-cli-CI848omy.js");
|
|
139
139
|
return runPairCli(subcommandArgs);
|
|
140
140
|
}],
|
|
141
141
|
["agent", async (subcommandArgs) => {
|
|
@@ -209,7 +209,7 @@ async function readDeclaredCustomAgents() {
|
|
|
209
209
|
declared: [],
|
|
210
210
|
error: null
|
|
211
211
|
};
|
|
212
|
-
const { loadConfigFile } = await import("../chunks/config-store-
|
|
212
|
+
const { loadConfigFile } = await import("../chunks/config-store-DwTxLe8Y.js");
|
|
213
213
|
try {
|
|
214
214
|
const loaded = loadConfigFile(decided.path, { exitOnError: false });
|
|
215
215
|
if (!loaded.config) return {
|
|
@@ -285,7 +285,7 @@ async function runDoctor() {
|
|
|
285
285
|
}
|
|
286
286
|
switchSection("Agents");
|
|
287
287
|
try {
|
|
288
|
-
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-
|
|
288
|
+
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-CgbcceU3.js");
|
|
289
289
|
const declaredCustomAgents = await readDeclaredCustomAgents();
|
|
290
290
|
if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
|
|
291
291
|
setCustomAgents(declaredCustomAgents.declared);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as describeAgentResolvability, d as setCustomAgents, l as listAgentIds } from "./adapters-
|
|
1
|
+
import { a as describeAgentResolvability, d as setCustomAgents, l as listAgentIds } from "./adapters-D-cRFZ_Q.js";
|
|
2
2
|
export { describeAgentResolvability, listAgentIds, setCustomAgents };
|
|
@@ -5,7 +5,7 @@ import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-c
|
|
|
5
5
|
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
6
6
|
import { c as buildAgentEnv, i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, t as grok } from "./grok-BYKnBgdr.js";
|
|
7
7
|
import { t as buildHookCommand } from "./hook-command-core-DclEoE9e.js";
|
|
8
|
-
import "./contracts-
|
|
8
|
+
import "./contracts-DZV9H8px.js";
|
|
9
9
|
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-UX2fmt81.js";
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
//#region session/adapters/claude-code.ts
|
|
@@ -4,7 +4,7 @@ import { n as glimmervoidHomeDir$1, t as decideConfigPath } from "./config-path-
|
|
|
4
4
|
import { a as positiveIntOr, c as textOr, n as isRecord } from "./coerce-NSst8oRP.js";
|
|
5
5
|
import { d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-oEH9vt-0.js";
|
|
6
6
|
import { St as normalizeLegacyConfigNumbers, f as BranchGcFileSettings, i as Config, l as configIssueMessage, m as DEFAULT_FACTORY_PROTECTED_PATHS, n as BUILTIN_AGENT_IDS, p as DEFAULT_FACTORY_CHECKS, s as RUNTIME_CONFIG_SCALAR_KEYS, t as AGENT_ID_SHAPE_MESSAGE } from "./config-DTwMFUjx.js";
|
|
7
|
-
import { V as FeatureFlagsResponse, W as TELEMETRY_KILL_SWITCH_FLAG } from "./contracts-
|
|
7
|
+
import { V as FeatureFlagsResponse, W as TELEMETRY_KILL_SWITCH_FLAG } from "./contracts-DZV9H8px.js";
|
|
8
8
|
import fs from "node:fs";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import os from "node:os";
|
|
@@ -1370,6 +1370,15 @@ var clientVariants = [
|
|
|
1370
1370
|
id: sessionId,
|
|
1371
1371
|
newName: z.string()
|
|
1372
1372
|
}),
|
|
1373
|
+
loose("get-workspace-repos", {
|
|
1374
|
+
id: sessionId,
|
|
1375
|
+
requestId
|
|
1376
|
+
}),
|
|
1377
|
+
loose("set-workspace-repos", {
|
|
1378
|
+
id: sessionId,
|
|
1379
|
+
repos: z.array(z.string()),
|
|
1380
|
+
requestId
|
|
1381
|
+
}),
|
|
1373
1382
|
loose("set-session-title", {
|
|
1374
1383
|
id: sessionId,
|
|
1375
1384
|
title: TaskTitle
|
|
@@ -1511,6 +1520,8 @@ Object.freeze([
|
|
|
1511
1520
|
"hooks-report",
|
|
1512
1521
|
"save-hook-result",
|
|
1513
1522
|
"delete-hook-result",
|
|
1523
|
+
"workspace-repos",
|
|
1524
|
+
"set-workspace-repos-result",
|
|
1514
1525
|
"hooks-updated",
|
|
1515
1526
|
"state-change",
|
|
1516
1527
|
"session-added",
|
|
@@ -1635,6 +1646,19 @@ var serverVariants = [
|
|
|
1635
1646
|
error: optionalError,
|
|
1636
1647
|
id: z.string().optional()
|
|
1637
1648
|
}),
|
|
1649
|
+
loose("workspace-repos", {
|
|
1650
|
+
requestId,
|
|
1651
|
+
id: sessionId,
|
|
1652
|
+
ok: z.boolean(),
|
|
1653
|
+
repos: z.array(z.string()),
|
|
1654
|
+
error: optionalError
|
|
1655
|
+
}),
|
|
1656
|
+
loose("set-workspace-repos-result", {
|
|
1657
|
+
requestId,
|
|
1658
|
+
id: sessionId,
|
|
1659
|
+
ok: z.boolean(),
|
|
1660
|
+
error: optionalError
|
|
1661
|
+
}),
|
|
1638
1662
|
loose("hooks-updated", { count: z.number().int().nonnegative() }),
|
|
1639
1663
|
loose("state-change", {
|
|
1640
1664
|
id: sessionId,
|
|
@@ -20,12 +20,12 @@ import { a as decideTicketAction, i as decideSpawnAllowance, l as isOrchestrator
|
|
|
20
20
|
import { s as GLIMMERVOID_SECRET_KEYS } from "./grok-BYKnBgdr.js";
|
|
21
21
|
import { _ as isQueueAdmissionTimeout, a as jsonStateLoadError, c as loadedJsonValue, d as writeJsonAtomicSync, f as writeTextAtomic, g as createSpawnGate, h as createSerialQueue, 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 } from "./json-file-oEH9vt-0.js";
|
|
22
22
|
import { $ as TeamReviewCompareFiles, A as MyPrSearchResponse, At as CoherenceWorkInspect, B as PostingPlan, C as MyPrMergeMethod, Ct as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, D as MyPrMergeWhenReadyRequest, E as MyPrMergeStateResponse, F as CommitSha, G as ReviewDraft, H as QueuedReview, I as DECIDING_REVIEW_STATES, J as ReviewThreadId, K as ReviewFinding, L as FindingSeverity, M as MyPrThreadsResponse, N as MyPrsState, Ot as CoherenceTicketCreated, P as MyPrsStatus, R as GithubReviewDecision, Tt as CoherenceOrient, U as ReviewChecksState, V as PrDetail, W as ReviewComment, X as SearchedPr, Y as ReviewVerdict, Z as TeamReviewActionRequest, _ as WorkflowSearchNode, a as ConfigUpdate, at as TeamReviewThreadsRepository, b as MyPrAutoRebase, bt as USAGE_COST_MODES, c as TASK_TITLE_SOURCE_PRIORITY, ct as hasStandingViewerApproval, d as BRANCH_GC_CONTROL_NUMERIC_KEYS, dt as shortSha$1, et as TeamReviewResolveResponse, ft as GH_SEGMENT, g as WorkflowLabelName, h as WorkflowCommentBody, ht as repoParts, it as TeamReviewThreadResult, j as MyPrThreadNode, k as MyPrSearchNode, kt as CoherenceWorkCreated, l as configIssueMessage, lt as FULL_SHA_RE, m as DEFAULT_FACTORY_PROTECTED_PATHS, mt as REPO_SLUG_RE, nt as TeamReviewStatus, o as PersistedTaskTitle, ot as canApproveAfterComment, p as DEFAULT_FACTORY_CHECKS, pt as NODE_ID_RE, q as ReviewResult, r as BrowserConfig, rt as TeamReviewThreadCommentsResponse, s as RUNTIME_CONFIG_SCALAR_KEYS, st as decisionAsIfApprovalRequired, tt as TeamReviewStateEntry, u as BRANCH_GC_CONTROL_BOOLEAN_KEYS, ut as HEX_SHA_RE, v as WorkflowsSettings, w as MyPrMergeRequest, wt as USAGE_INTEGER_RANGES, x as MyPrKeepMergeableRequest, xt as USAGE_VENDOR_KEYS, y as WorkflowsState, yt as USAGE_BUDGET_KEYS, z as GithubReviewState } from "./config-DTwMFUjx.js";
|
|
23
|
-
import { $ as sessionIdFromBranch, A as snapshotEvents, B as classifySessionExit, C as createIngestStore, D as resolveIngestConfig, E as publishEvent, F as adapterBucket, G as nodeMajorVersion, H as decideRemoteTelemetryState, I as buildAiGenerationEvents, J as stableConfigKey, K as parsePosthogReleaseId, L as buildBrowserExceptionProperties, M as FIRST_RUN_NOTICE, N as TELEMETRY_BATCH_URL, O as ringStats, P as TELEMETRY_FLAGS_URL, Q as planWorktreeGc, R as buildExceptionProperties, S as buildContextDigest, T as latestSeq, U as decideTelemetryConsent, V as decideIsDevInstall, W as exceptionFingerprint, X as matchedPrefix, Y as DEFAULT_BRANCH_GC_PREFIXES, Z as planBranchGc, _ as INGEST_SPEC, a as ensureProjectIds, b as DEFAULT_DIGEST_BUDGET_CHARS, d as assetForPlatform, et as usablePrefixes, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as createConfigStore, j as localDayKey, k as scrubText, m as installTargetPath, n as DEFAULT_CONFIG, o as generateProjectId, p as findEscapingArchiveMember, q as resolveProjectToken, s as glimmervoidHomeDir$1, t as ABORT_CONFIG_SAVE, tt as worktreeIntegrationTips, v as mergeSettingsBlock, w as enabledSourceNames, x as SOURCE_DEFAULTS, y as validateSettingsBlock, z as buildFactoryDecisionEvent } from "./config-store-
|
|
24
|
-
import { $ as FactoryHarnessVerdict, A as BenchmarkActionRequest, B as PrCheckoutCaseInput, C as IssueKey, D as IssuesStatus, E as IssuesState, F as BenchmarkStatus, G as TelemetryState, H as PendingCrashReport, I as BenchmarkSuite, J as FACTORY_ERROR_MAX_CHARS, K as FACTORY_DECISION_OUTPUT_MAX_BYTES, L as CommitComparison, M as BenchmarkId, N as BenchmarkJudgement, O as ChangeMap, P as BenchmarkRun, Q as FactoryHarnessStateLine, R as MergedPrListing, S as GithubIssueResponse, T as IssuesSearchResponse, U as TELEMETRY_EVENT_SCHEMAS, X as FactoryConsequences, Y as FACTORY_PROTECTED_PATH_FLOOR, Z as FactoryControlRequest, _ as PlanDecision, a as ClientMessage, at as FactoryWorkerEvent, b as planTitle, c as UpdateJournal, d as TraceRecord, et as FactoryLaneState, f as PLAN_BODY_CAP_BYTES, g as PLAN_TOOL_NAME, h as PLAN_RESULT_HOOK_EVENT, i as CONTROL_FRAME_MAX_BYTES, it as FactoryReviewerOutput, j as BenchmarkCase, k as changeMapFactId, l as MAX_RAW_LINE_CHARS, m as PLAN_HOOK_OUTPUT_MAX_CHARS, n as HookEnvelope, nt as FactoryQueueIntentRequest, o as DIFF_ANNOTATION_NOTE_MAX_CHARS, ot as isSingleFactoryPathSegment, p as PLAN_HOOK_EVENT, q as FactoryDecisionLogLine, r as parseDataClientMessage, rt as FactoryReviewVerdict, s as InstallFlavor, t as HTTP_URL_RE, tt as FactoryProjectState, u as TraceCheckpoint, v as PlanRevision, w as IssueUpdate, x as GithubIssuePullRequestsRepository, y as parseExitPlanModeHookPayload, z as MinedPrReviewData } from "./contracts-
|
|
25
|
-
import { a as describeAgentResolvability, c as isKnownAgentId, d as setCustomAgents, f as claudeCode, i as customAgentFingerprint, l as listAgentIds, n as cachedAgentResolvability, o as getAdapter, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resolveAdapter } from "./adapters-
|
|
23
|
+
import { $ as sessionIdFromBranch, A as snapshotEvents, B as classifySessionExit, C as createIngestStore, D as resolveIngestConfig, E as publishEvent, F as adapterBucket, G as nodeMajorVersion, H as decideRemoteTelemetryState, I as buildAiGenerationEvents, J as stableConfigKey, K as parsePosthogReleaseId, L as buildBrowserExceptionProperties, M as FIRST_RUN_NOTICE, N as TELEMETRY_BATCH_URL, O as ringStats, P as TELEMETRY_FLAGS_URL, Q as planWorktreeGc, R as buildExceptionProperties, S as buildContextDigest, T as latestSeq, U as decideTelemetryConsent, V as decideIsDevInstall, W as exceptionFingerprint, X as matchedPrefix, Y as DEFAULT_BRANCH_GC_PREFIXES, Z as planBranchGc, _ as INGEST_SPEC, a as ensureProjectIds, b as DEFAULT_DIGEST_BUDGET_CHARS, d as assetForPlatform, et as usablePrefixes, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as createConfigStore, j as localDayKey, k as scrubText, m as installTargetPath, n as DEFAULT_CONFIG, o as generateProjectId, p as findEscapingArchiveMember, q as resolveProjectToken, s as glimmervoidHomeDir$1, t as ABORT_CONFIG_SAVE, tt as worktreeIntegrationTips, v as mergeSettingsBlock, w as enabledSourceNames, x as SOURCE_DEFAULTS, y as validateSettingsBlock, z as buildFactoryDecisionEvent } from "./config-store-D0lRWsAM.js";
|
|
24
|
+
import { $ as FactoryHarnessVerdict, A as BenchmarkActionRequest, B as PrCheckoutCaseInput, C as IssueKey, D as IssuesStatus, E as IssuesState, F as BenchmarkStatus, G as TelemetryState, H as PendingCrashReport, I as BenchmarkSuite, J as FACTORY_ERROR_MAX_CHARS, K as FACTORY_DECISION_OUTPUT_MAX_BYTES, L as CommitComparison, M as BenchmarkId, N as BenchmarkJudgement, O as ChangeMap, P as BenchmarkRun, Q as FactoryHarnessStateLine, R as MergedPrListing, S as GithubIssueResponse, T as IssuesSearchResponse, U as TELEMETRY_EVENT_SCHEMAS, X as FactoryConsequences, Y as FACTORY_PROTECTED_PATH_FLOOR, Z as FactoryControlRequest, _ as PlanDecision, a as ClientMessage, at as FactoryWorkerEvent, b as planTitle, c as UpdateJournal, d as TraceRecord, et as FactoryLaneState, f as PLAN_BODY_CAP_BYTES, g as PLAN_TOOL_NAME, h as PLAN_RESULT_HOOK_EVENT, i as CONTROL_FRAME_MAX_BYTES, it as FactoryReviewerOutput, j as BenchmarkCase, k as changeMapFactId, l as MAX_RAW_LINE_CHARS, m as PLAN_HOOK_OUTPUT_MAX_CHARS, n as HookEnvelope, nt as FactoryQueueIntentRequest, o as DIFF_ANNOTATION_NOTE_MAX_CHARS, ot as isSingleFactoryPathSegment, p as PLAN_HOOK_EVENT, q as FactoryDecisionLogLine, r as parseDataClientMessage, rt as FactoryReviewVerdict, s as InstallFlavor, t as HTTP_URL_RE, tt as FactoryProjectState, u as TraceCheckpoint, v as PlanRevision, w as IssueUpdate, x as GithubIssuePullRequestsRepository, y as parseExitPlanModeHookPayload, z as MinedPrReviewData } from "./contracts-DZV9H8px.js";
|
|
25
|
+
import { a as describeAgentResolvability, c as isKnownAgentId, d as setCustomAgents, f as claudeCode, i as customAgentFingerprint, l as listAgentIds, n as cachedAgentResolvability, o as getAdapter, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resolveAdapter } from "./adapters-D-cRFZ_Q.js";
|
|
26
26
|
import { t as HOOK_TOOLS } from "./hook-tools-UX2fmt81.js";
|
|
27
27
|
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";
|
|
28
|
-
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-
|
|
28
|
+
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-Y6YtqoiO.js";
|
|
29
29
|
import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-CfgNHiG3.js";
|
|
30
30
|
import { t as getRtkPath } from "./rtk-resolver-jJxy_Mrt.js";
|
|
31
31
|
import { createRequire } from "node:module";
|
|
@@ -3465,6 +3465,11 @@ function decideWasActiveFlip(to, event, pendingRestart) {
|
|
|
3465
3465
|
if (!pendingRestart && (event === "user_kill" || to === STATES.DONE || to === STATES.FAILED)) return false;
|
|
3466
3466
|
return null;
|
|
3467
3467
|
}
|
|
3468
|
+
function haveSameWorkspaceRepos(projectRepos, sessionRepos) {
|
|
3469
|
+
const configured = projectRepos ?? [];
|
|
3470
|
+
const running = sessionRepos ?? [];
|
|
3471
|
+
return configured.length === running.length && configured.every((repoPath, index) => repoPath === running[index]);
|
|
3472
|
+
}
|
|
3468
3473
|
function shouldStartAfterModify(previousState) {
|
|
3469
3474
|
return previousState !== STATES.DORMANT;
|
|
3470
3475
|
}
|
|
@@ -3492,7 +3497,8 @@ function diffProjects(currentSessions, newProjects, dependencies) {
|
|
|
3492
3497
|
const resolvedAgentId = dependencies.resolveAgentId(project.agent);
|
|
3493
3498
|
const agentChanged = resolvedAgentId !== session.agentId || agentFingerprintOf(resolvedAgentId) !== capturedAgentFingerprintOf(id);
|
|
3494
3499
|
const hookTrustChanged = project.codexBypassHookTrust === true !== session.bypassHookTrust;
|
|
3495
|
-
|
|
3500
|
+
const workspaceReposChanged = !haveSameWorkspaceRepos(project.repos, session.workspaceRepos);
|
|
3501
|
+
if (pathChanged || permissionsChanged || agentChanged || hookTrustChanged || workspaceReposChanged) {
|
|
3496
3502
|
modified.push(project);
|
|
3497
3503
|
continue;
|
|
3498
3504
|
}
|
|
@@ -4793,7 +4799,15 @@ function runAutoResume(sessions, config, spawnGate, logger = console) {
|
|
|
4793
4799
|
}
|
|
4794
4800
|
return Promise.all(runs);
|
|
4795
4801
|
}
|
|
4796
|
-
function
|
|
4802
|
+
function releaseDroppedWorkspaceMembers(oldSession, newSession, currentSessionFor) {
|
|
4803
|
+
return Promise.resolve(oldSession._killReap).catch(() => {}).then(() => {
|
|
4804
|
+
const liveSession = currentSessionFor?.(oldSession.id) ?? newSession;
|
|
4805
|
+
const keepRepoPaths = isSameDirectoryPath(liveSession.path, oldSession.path) ? liveSession.workspaceRepos ?? [] : [];
|
|
4806
|
+
return oldSession.releaseDroppedWorkspaceMembers(keepRepoPaths);
|
|
4807
|
+
}).catch((error) => console.warn(`[config] releasing dropped workspace members failed for ${oldSession.name}: ${errorMessage(error)}`));
|
|
4808
|
+
}
|
|
4809
|
+
function carryWorktreeAcrossRecreate(oldSession, newSession, currentSessionFor) {
|
|
4810
|
+
if (oldSession?.workspaceRepos) return releaseDroppedWorkspaceMembers(oldSession, newSession, currentSessionFor);
|
|
4797
4811
|
const carry = oldSession?.getWorktreeCarry?.();
|
|
4798
4812
|
if (!oldSession || !carry) return;
|
|
4799
4813
|
if (isSameDirectoryPath(newSession.path, oldSession.path)) {
|
|
@@ -4961,7 +4975,7 @@ function createSessionRegistry(dependencies) {
|
|
|
4961
4975
|
sessions.set(project.id, newSession);
|
|
4962
4976
|
captureAgentFingerprint(project);
|
|
4963
4977
|
dependencies.wireSessionEvents(newSession);
|
|
4964
|
-
dependencies.carryWorktreeAcrossRecreate(oldSession, newSession);
|
|
4978
|
+
dependencies.carryWorktreeAcrossRecreate(oldSession, newSession, getSession);
|
|
4965
4979
|
dependencies.broadcastControl({
|
|
4966
4980
|
type: "session-modified",
|
|
4967
4981
|
...projectSessionCard(newSession, {
|
|
@@ -14092,6 +14106,7 @@ var CLOUD_CREDENTIAL_HOME_ENTRIES = Object.freeze([
|
|
|
14092
14106
|
".netrc",
|
|
14093
14107
|
".npmrc"
|
|
14094
14108
|
]);
|
|
14109
|
+
var STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES = Object.freeze(["Library/Keychains"]);
|
|
14095
14110
|
var XDG_CONFIG_DEFAULT_HOME_PREFIX = ".config/";
|
|
14096
14111
|
var SHARED_TEMP_DIRS = Object.freeze(["/tmp/claude", "/private/tmp/claude"]);
|
|
14097
14112
|
var SHARED_HOME_WRITE_ENTRIES = Object.freeze([".npm/_logs"]);
|
|
@@ -14158,6 +14173,11 @@ var RUNTIME_MANDATORY_CLAUDE_DENY_FOLDERS = Object.freeze(["commands", "agents"]
|
|
|
14158
14173
|
var SANDBOXED_PROXY_BYPASS = "localhost,::1,169.254.0.0/16,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16";
|
|
14159
14174
|
var HOOK_LOOPBACK_HOST = "127.0.0.1";
|
|
14160
14175
|
var AGENT_SESSION_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
14176
|
+
var STANDARD_OPEN_NETWORK = Object.freeze({
|
|
14177
|
+
allowAllUnixSockets: true,
|
|
14178
|
+
allowMachLookup: ["*"]
|
|
14179
|
+
});
|
|
14180
|
+
var STRICT_OPEN_NETWORK = Object.freeze({ allowAllUnixSockets: false });
|
|
14161
14181
|
function unique(entries) {
|
|
14162
14182
|
return [...new Set(entries)];
|
|
14163
14183
|
}
|
|
@@ -14275,8 +14295,13 @@ function relocatedXdgConfigPaths(host, homeEntries) {
|
|
|
14275
14295
|
function isStandardLevel(role) {
|
|
14276
14296
|
return role.guardrailLevel === "standard";
|
|
14277
14297
|
}
|
|
14278
|
-
function
|
|
14298
|
+
function blockedCredentialHomeEntries(role) {
|
|
14279
14299
|
const credentialHomeEntries = [...CREDENTIAL_HOME_ENTRIES, ...CLOUD_CREDENTIAL_HOME_ENTRIES];
|
|
14300
|
+
if (!isStandardLevel(role)) return credentialHomeEntries;
|
|
14301
|
+
return credentialHomeEntries.filter((entry) => !STANDARD_LEVEL_USABLE_CREDENTIAL_ENTRIES.includes(entry));
|
|
14302
|
+
}
|
|
14303
|
+
function credentialWriteBlocks(role, host) {
|
|
14304
|
+
const credentialHomeEntries = blockedCredentialHomeEntries(role);
|
|
14280
14305
|
return [...homePaths(host, credentialHomeEntries), ...relocatedXdgConfigPaths(host, credentialHomeEntries)];
|
|
14281
14306
|
}
|
|
14282
14307
|
function glimmervoidStateWriteBlocks(role, host) {
|
|
@@ -14297,7 +14322,7 @@ function glimmervoidStateWriteBlocks(role, host) {
|
|
|
14297
14322
|
function standardWriteBlockCandidates(role, host) {
|
|
14298
14323
|
if (!isStandardLevel(role)) return [];
|
|
14299
14324
|
return unique([
|
|
14300
|
-
...credentialWriteBlocks(host),
|
|
14325
|
+
...credentialWriteBlocks(role, host),
|
|
14301
14326
|
...glimmervoidStateWriteBlocks(role, host),
|
|
14302
14327
|
...role.blockedPaths ?? []
|
|
14303
14328
|
]);
|
|
@@ -14305,7 +14330,7 @@ function standardWriteBlockCandidates(role, host) {
|
|
|
14305
14330
|
function readDeniedPaths(role, host) {
|
|
14306
14331
|
const otherVendors = SANDBOX_VENDORS.filter((vendor) => !role.vendors.includes(vendor));
|
|
14307
14332
|
const otherVendorHomeEntries = [...otherVendors.flatMap((vendor) => VENDOR_PROFILES[vendor].homeEntries), ...UNWRAPPED_VENDOR_HOME_ENTRIES];
|
|
14308
|
-
const credentialHomeEntries =
|
|
14333
|
+
const credentialHomeEntries = blockedCredentialHomeEntries(role);
|
|
14309
14334
|
return [
|
|
14310
14335
|
...homePaths(host, [
|
|
14311
14336
|
...credentialHomeEntries,
|
|
@@ -14364,7 +14389,7 @@ function sandboxRoleRefusal(role, host) {
|
|
|
14364
14389
|
return null;
|
|
14365
14390
|
}
|
|
14366
14391
|
function networkPolicy(role) {
|
|
14367
|
-
if (role.network.access === "open") return {
|
|
14392
|
+
if (role.network.access === "open") return isStandardLevel(role) ? { ...STANDARD_OPEN_NETWORK } : { ...STRICT_OPEN_NETWORK };
|
|
14368
14393
|
if (role.network.access === "none") return {
|
|
14369
14394
|
allowedDomains: [],
|
|
14370
14395
|
deniedDomains: [],
|
|
@@ -14425,7 +14450,9 @@ function buildSandboxLaunchPlan(role, host) {
|
|
|
14425
14450
|
denyRead: literalEntries(readDenied),
|
|
14426
14451
|
allowRead: literalEntries([...writableWithinDenied, ...role.readableWithinDenied]),
|
|
14427
14452
|
...filesystemWrites(role, host, writablePaths)
|
|
14428
|
-
}
|
|
14453
|
+
},
|
|
14454
|
+
terminalScope: isStandardLevel(role) ? "any" : "own",
|
|
14455
|
+
allowAppleEvents: isStandardLevel(role)
|
|
14429
14456
|
},
|
|
14430
14457
|
launchEnv: Object.assign({ CLAUDE_CODE_TMPDIR: host.tempDir }, ...role.vendors.map((vendor) => VENDOR_PROFILES[vendor].launchEnv), launchHomeEnv(role, host)),
|
|
14431
14458
|
sandboxedEnv: sandboxedEnvFor(role, host),
|
|
@@ -14473,33 +14500,6 @@ function parseTagVersion(ref) {
|
|
|
14473
14500
|
if (!matched) return null;
|
|
14474
14501
|
return matched[1];
|
|
14475
14502
|
}
|
|
14476
|
-
function parseLsRemoteTags(stdout) {
|
|
14477
|
-
if (typeof stdout !== "string") return null;
|
|
14478
|
-
const tagsByVersion = /* @__PURE__ */ new Map();
|
|
14479
|
-
for (const line of stdout.split("\n")) {
|
|
14480
|
-
const fields = line.trim().split(/\s+/);
|
|
14481
|
-
if (fields.length < 2) continue;
|
|
14482
|
-
const sha = normalizeSha(fields[0]);
|
|
14483
|
-
if (!sha) continue;
|
|
14484
|
-
const ref = fields[1];
|
|
14485
|
-
const version = parseTagVersion(ref);
|
|
14486
|
-
if (!version) continue;
|
|
14487
|
-
if (tagsByVersion.get(version) && !ref.endsWith("^{}")) continue;
|
|
14488
|
-
tagsByVersion.set(version, {
|
|
14489
|
-
version,
|
|
14490
|
-
sha
|
|
14491
|
-
});
|
|
14492
|
-
}
|
|
14493
|
-
let latest = null;
|
|
14494
|
-
for (const entry of tagsByVersion.values()) {
|
|
14495
|
-
if (!latest) {
|
|
14496
|
-
latest = entry;
|
|
14497
|
-
continue;
|
|
14498
|
-
}
|
|
14499
|
-
if (compareSemver(entry.version, latest.version) > 0) latest = entry;
|
|
14500
|
-
}
|
|
14501
|
-
return latest;
|
|
14502
|
-
}
|
|
14503
14503
|
function isNpxCachePath(packageRoot) {
|
|
14504
14504
|
if (typeof packageRoot !== "string") return false;
|
|
14505
14505
|
return packageRoot.split(/[\\/]/).includes(NPX_CACHE_DIRECTORY_NAME);
|
|
@@ -14574,19 +14574,6 @@ function compareSemver(a, b) {
|
|
|
14574
14574
|
}
|
|
14575
14575
|
return 0;
|
|
14576
14576
|
}
|
|
14577
|
-
function parseLatestReleaseTag(doc) {
|
|
14578
|
-
if (!doc || typeof doc !== "object") return null;
|
|
14579
|
-
const version = parseTagVersion(doc.tag_name);
|
|
14580
|
-
if (!version) return null;
|
|
14581
|
-
return {
|
|
14582
|
-
version,
|
|
14583
|
-
sha: null
|
|
14584
|
-
};
|
|
14585
|
-
}
|
|
14586
|
-
function decideReleaseSource(flavor) {
|
|
14587
|
-
if (flavor === "npm-global" || flavor === "npx") return "npm-registry";
|
|
14588
|
-
return "github-tags";
|
|
14589
|
-
}
|
|
14590
14577
|
function parseRegistryLatest(doc) {
|
|
14591
14578
|
if (!doc || typeof doc !== "object") return null;
|
|
14592
14579
|
const registryDocument = doc;
|
|
@@ -17269,6 +17256,10 @@ function planWorkspaceMembers({ folder, sessionId, repoPaths }) {
|
|
|
17269
17256
|
}
|
|
17270
17257
|
};
|
|
17271
17258
|
}
|
|
17259
|
+
function listDroppedRepoPaths(previousRepoPaths, nextRepoPaths) {
|
|
17260
|
+
const nextRepoKeys = new Set(nextRepoPaths.map((repoPath) => caseFoldedPathKey(path.resolve(repoPath))));
|
|
17261
|
+
return previousRepoPaths.filter((repoPath) => !nextRepoKeys.has(caseFoldedPathKey(path.resolve(repoPath))));
|
|
17262
|
+
}
|
|
17272
17263
|
function renderWorkspaceAgentsMd({ sessionName, branch, members }) {
|
|
17273
17264
|
const lines = [
|
|
17274
17265
|
`# ${sessionName}`,
|
|
@@ -17291,6 +17282,34 @@ async function writeWhenAbsent(filePath, contents) {
|
|
|
17291
17282
|
if (error.code !== "EEXIST") throw error;
|
|
17292
17283
|
});
|
|
17293
17284
|
}
|
|
17285
|
+
var WORKSPACE_MAP_FILE = "AGENTS.md";
|
|
17286
|
+
var WORKSPACE_POINTER_FILE = "CLAUDE.md";
|
|
17287
|
+
var WORKSPACE_MAP_HASH_FILE = ".glimmervoid-map-hash";
|
|
17288
|
+
var GENERATED_WORKSPACE_FILES = /* @__PURE__ */ new Set([
|
|
17289
|
+
WORKSPACE_MAP_FILE,
|
|
17290
|
+
WORKSPACE_POINTER_FILE,
|
|
17291
|
+
WORKSPACE_MAP_HASH_FILE
|
|
17292
|
+
]);
|
|
17293
|
+
function hashWorkspaceMap(contents) {
|
|
17294
|
+
return crypto.createHash("sha256").update(contents).digest("hex");
|
|
17295
|
+
}
|
|
17296
|
+
async function readWhenPresent(filePath) {
|
|
17297
|
+
return fs.promises.readFile(filePath, "utf8").catch((error) => {
|
|
17298
|
+
if (error.code === "ENOENT") return null;
|
|
17299
|
+
throw error;
|
|
17300
|
+
});
|
|
17301
|
+
}
|
|
17302
|
+
async function writeWorkspaceMap(folder, contents) {
|
|
17303
|
+
const mapPath = path.join(folder, WORKSPACE_MAP_FILE);
|
|
17304
|
+
const hashPath = path.join(folder, WORKSPACE_MAP_HASH_FILE);
|
|
17305
|
+
const existingMap = await readWhenPresent(mapPath);
|
|
17306
|
+
const recordedHash = (await readWhenPresent(hashPath))?.trim() ?? null;
|
|
17307
|
+
const renderedHash = hashWorkspaceMap(contents);
|
|
17308
|
+
if (existingMap !== null && existingMap !== contents && hashWorkspaceMap(existingMap) !== recordedHash) return;
|
|
17309
|
+
if (existingMap === contents && recordedHash === renderedHash) return;
|
|
17310
|
+
await fs.promises.writeFile(mapPath, contents);
|
|
17311
|
+
await fs.promises.writeFile(hashPath, `${renderedHash}\n`);
|
|
17312
|
+
}
|
|
17294
17313
|
function createSessionWorkspaceMembers({ plan, sessionName, shareList, gitWorkspace }) {
|
|
17295
17314
|
let activeProvision = null;
|
|
17296
17315
|
async function provisionBody() {
|
|
@@ -17313,12 +17332,12 @@ function createSessionWorkspaceMembers({ plan, sessionName, shareList, gitWorksp
|
|
|
17313
17332
|
base: ensured.base
|
|
17314
17333
|
});
|
|
17315
17334
|
}
|
|
17316
|
-
await
|
|
17335
|
+
await writeWorkspaceMap(plan.folder, renderWorkspaceAgentsMd({
|
|
17317
17336
|
sessionName,
|
|
17318
17337
|
branch: plan.branch,
|
|
17319
17338
|
members
|
|
17320
17339
|
}));
|
|
17321
|
-
await writeWhenAbsent(path.join(plan.folder,
|
|
17340
|
+
await writeWhenAbsent(path.join(plan.folder, WORKSPACE_POINTER_FILE), WORKSPACE_CLAUDE_MD);
|
|
17322
17341
|
return {
|
|
17323
17342
|
ok: true,
|
|
17324
17343
|
members
|
|
@@ -17339,10 +17358,12 @@ function createSessionWorkspaceMembers({ plan, sessionName, shareList, gitWorksp
|
|
|
17339
17358
|
});
|
|
17340
17359
|
return attempt;
|
|
17341
17360
|
}
|
|
17342
|
-
async function release() {
|
|
17361
|
+
async function release({ keepRepoPaths = [] } = {}) {
|
|
17343
17362
|
if (activeProvision) await activeProvision;
|
|
17363
|
+
const keptRepoKeys = new Set(keepRepoPaths.map((repoPath) => caseFoldedPathKey(path.resolve(repoPath))));
|
|
17344
17364
|
const keptDirs = [];
|
|
17345
17365
|
for (const member of plan.members) {
|
|
17366
|
+
if (keptRepoKeys.has(caseFoldedPathKey(member.repoPath))) continue;
|
|
17346
17367
|
if (!await fs.promises.stat(member.dir).then(() => true, () => false)) continue;
|
|
17347
17368
|
if (!(await gitWorkspace.removeWorkspaceMember({
|
|
17348
17369
|
projectPath: member.repoPath,
|
|
@@ -17351,7 +17372,7 @@ function createSessionWorkspaceMembers({ plan, sessionName, shareList, gitWorksp
|
|
|
17351
17372
|
})).ok) keptDirs.push(member.dir);
|
|
17352
17373
|
}
|
|
17353
17374
|
const entries = await fs.promises.readdir(plan.folder).catch(() => []);
|
|
17354
|
-
if (entries.some((entry) =>
|
|
17375
|
+
if (entries.some((entry) => !GENERATED_WORKSPACE_FILES.has(entry))) return { keptDirs };
|
|
17355
17376
|
for (const entry of entries) await fs.promises.rm(path.join(plan.folder, entry), { force: true });
|
|
17356
17377
|
await fs.promises.rmdir(plan.folder).catch(() => {});
|
|
17357
17378
|
return { keptDirs };
|
|
@@ -17825,10 +17846,14 @@ function createSessionWorktreeLifecycle({ id, projectPath, integrationBranch = n
|
|
|
17825
17846
|
lifecycleState.isWorktree = false;
|
|
17826
17847
|
setMergeStatus(status);
|
|
17827
17848
|
}
|
|
17828
|
-
async function releaseWorkspaceMembers(members) {
|
|
17829
|
-
const released = await members.release();
|
|
17849
|
+
async function releaseWorkspaceMembers(members, keepRepoPaths = []) {
|
|
17850
|
+
const released = await members.release({ keepRepoPaths });
|
|
17830
17851
|
if (released.keptDirs.length > 0) console.warn(`[session ${id}] kept workspace members with uncommitted work: ${released.keptDirs.join(", ")}`);
|
|
17831
17852
|
}
|
|
17853
|
+
async function releaseDroppedWorkspaceMembers(keepRepoPaths) {
|
|
17854
|
+
if (!workspaceMembers?.ok) return;
|
|
17855
|
+
await releaseWorkspaceMembers(workspaceMembers.members, keepRepoPaths);
|
|
17856
|
+
}
|
|
17832
17857
|
async function discardWorktree() {
|
|
17833
17858
|
if (workspaceMembers?.ok) return releaseWorkspaceMembers(workspaceMembers.members);
|
|
17834
17859
|
stopWatching();
|
|
@@ -18601,7 +18626,8 @@ function createSessionWorktreeLifecycle({ id, projectPath, integrationBranch = n
|
|
|
18601
18626
|
mergeWorktree,
|
|
18602
18627
|
mergeAndContinue,
|
|
18603
18628
|
adoptWorktree,
|
|
18604
|
-
discardWorktree
|
|
18629
|
+
discardWorktree,
|
|
18630
|
+
releaseDroppedWorkspaceMembers
|
|
18605
18631
|
};
|
|
18606
18632
|
return api;
|
|
18607
18633
|
}
|
|
@@ -19106,6 +19132,7 @@ var Session = class extends EventEmitter {
|
|
|
19106
19132
|
_initialPrompt;
|
|
19107
19133
|
_extraClaudeArgs;
|
|
19108
19134
|
_resumeSessionId;
|
|
19135
|
+
workspaceRepos;
|
|
19109
19136
|
_transcriptPath;
|
|
19110
19137
|
_lastClaudeSessionReport;
|
|
19111
19138
|
_suppressResumeCapture;
|
|
@@ -19239,6 +19266,7 @@ var Session = class extends EventEmitter {
|
|
|
19239
19266
|
this._initialPrompt = initialPrompt;
|
|
19240
19267
|
this._extraClaudeArgs = Array.isArray(extraClaudeArgs) ? extraClaudeArgs : [];
|
|
19241
19268
|
this._resumeSessionId = resumeSessionId || null;
|
|
19269
|
+
this.workspaceRepos = workspaceRepos ? [...workspaceRepos] : null;
|
|
19242
19270
|
this._transcriptPath = null;
|
|
19243
19271
|
this._lastClaudeSessionReport = null;
|
|
19244
19272
|
this._suppressResumeCapture = false;
|
|
@@ -19849,6 +19877,9 @@ var Session = class extends EventEmitter {
|
|
|
19849
19877
|
discardWorktreeIfClean() {
|
|
19850
19878
|
return this.worktreeLifecycle.discardIfClean();
|
|
19851
19879
|
}
|
|
19880
|
+
releaseDroppedWorkspaceMembers(keepRepoPaths) {
|
|
19881
|
+
return this.worktreeLifecycle.releaseDroppedWorkspaceMembers(keepRepoPaths);
|
|
19882
|
+
}
|
|
19852
19883
|
pasteMergePrompt() {
|
|
19853
19884
|
return this.worktreeLifecycle.pasteMergePrompt();
|
|
19854
19885
|
}
|
|
@@ -47883,6 +47914,89 @@ function registerControlHandlers(controlWss, deps) {
|
|
|
47883
47914
|
});
|
|
47884
47915
|
if (freshConfig) applyConfigReload(freshConfig);
|
|
47885
47916
|
}
|
|
47917
|
+
function handleGetWorkspaceRepos(msg, ws) {
|
|
47918
|
+
const project = findConfiguredProject(msg.id);
|
|
47919
|
+
if (!project?.repos) {
|
|
47920
|
+
replyTo(ws, msg, "workspace-repos", {
|
|
47921
|
+
id: msg.id,
|
|
47922
|
+
ok: false,
|
|
47923
|
+
repos: [],
|
|
47924
|
+
error: "This session is not a workspace"
|
|
47925
|
+
});
|
|
47926
|
+
return;
|
|
47927
|
+
}
|
|
47928
|
+
replyTo(ws, msg, "workspace-repos", {
|
|
47929
|
+
id: msg.id,
|
|
47930
|
+
ok: true,
|
|
47931
|
+
repos: project.repos,
|
|
47932
|
+
error: null
|
|
47933
|
+
});
|
|
47934
|
+
}
|
|
47935
|
+
async function findDroppedMemberWithUncommittedWork(workspaceFolder, droppedRepoPaths) {
|
|
47936
|
+
for (const repoPath of droppedRepoPaths) {
|
|
47937
|
+
const memberName = path.basename(path.resolve(repoPath));
|
|
47938
|
+
const memberDir = path.join(workspaceFolder, memberName);
|
|
47939
|
+
if (!await fs.promises.stat(memberDir).then(() => true, () => false)) continue;
|
|
47940
|
+
const memberStatus = await runGit([
|
|
47941
|
+
"--no-optional-locks",
|
|
47942
|
+
"status",
|
|
47943
|
+
"--porcelain"
|
|
47944
|
+
], { cwd: memberDir });
|
|
47945
|
+
if (!memberStatus.ok) throw memberStatus.error;
|
|
47946
|
+
if (memberStatus.out !== "") return memberName;
|
|
47947
|
+
}
|
|
47948
|
+
return null;
|
|
47949
|
+
}
|
|
47950
|
+
async function handleSetWorkspaceRepos(msg, ws) {
|
|
47951
|
+
const reply = (error) => replyTo(ws, msg, "set-workspace-repos-result", {
|
|
47952
|
+
id: msg.id,
|
|
47953
|
+
ok: error === null,
|
|
47954
|
+
error
|
|
47955
|
+
});
|
|
47956
|
+
const project = findConfiguredProject(msg.id);
|
|
47957
|
+
const session = sessions.get(msg.id);
|
|
47958
|
+
if (!project?.repos || !session) {
|
|
47959
|
+
reply("This session is not a workspace");
|
|
47960
|
+
return;
|
|
47961
|
+
}
|
|
47962
|
+
const missingRepo = msg.repos.find((repoPath) => !isExistingDirectory(repoPath));
|
|
47963
|
+
if (missingRepo) {
|
|
47964
|
+
reply(`Repository path does not exist: ${missingRepo}`);
|
|
47965
|
+
return;
|
|
47966
|
+
}
|
|
47967
|
+
const planned = planWorkspaceMembers({
|
|
47968
|
+
folder: project.path,
|
|
47969
|
+
sessionId: project.id,
|
|
47970
|
+
repoPaths: msg.repos
|
|
47971
|
+
});
|
|
47972
|
+
if (!planned.ok) {
|
|
47973
|
+
reply(planned.error);
|
|
47974
|
+
return;
|
|
47975
|
+
}
|
|
47976
|
+
const nextRepos = planned.plan.members.map((member) => member.repoPath);
|
|
47977
|
+
try {
|
|
47978
|
+
const dirtyMemberName = await findDroppedMemberWithUncommittedWork(project.path, listDroppedRepoPaths(project.repos, nextRepos));
|
|
47979
|
+
if (dirtyMemberName) {
|
|
47980
|
+
reply(`${dirtyMemberName} has uncommitted changes. Commit or discard them before removing it from the workspace.`);
|
|
47981
|
+
return;
|
|
47982
|
+
}
|
|
47983
|
+
} catch (error) {
|
|
47984
|
+
reply(`Could not check the workspace for uncommitted changes: ${errorMessage(error)}`);
|
|
47985
|
+
return;
|
|
47986
|
+
}
|
|
47987
|
+
const freshConfig = configStore.save((cfg) => {
|
|
47988
|
+
const configured = cfg.projects.find((entry) => entry.id === project.id);
|
|
47989
|
+
if (!configured) return ABORT_CONFIG_SAVE;
|
|
47990
|
+
configured.repos = nextRepos;
|
|
47991
|
+
});
|
|
47992
|
+
if (!freshConfig) {
|
|
47993
|
+
reply(`Could not save session "${project.name}"`);
|
|
47994
|
+
return;
|
|
47995
|
+
}
|
|
47996
|
+
applyConfigReload(freshConfig);
|
|
47997
|
+
console.log(`[control] Workspace repositories updated via UI: ${project.name} (${nextRepos.length} repos)`);
|
|
47998
|
+
reply(null);
|
|
47999
|
+
}
|
|
47886
48000
|
function handleSetSessionTitle(msg, ws) {
|
|
47887
48001
|
const session = findSession(msg);
|
|
47888
48002
|
const parsedTitle = TaskTitle.safeParse(msg.title);
|
|
@@ -48840,6 +48954,8 @@ function registerControlHandlers(controlWss, deps) {
|
|
|
48840
48954
|
"resume-conversation": handleResumeConversation,
|
|
48841
48955
|
"remove-session": handleRemoveSession,
|
|
48842
48956
|
"rename-session": handleRenameSession,
|
|
48957
|
+
"get-workspace-repos": handleGetWorkspaceRepos,
|
|
48958
|
+
"set-workspace-repos": handleSetWorkspaceRepos,
|
|
48843
48959
|
"set-session-title": handleSetSessionTitle,
|
|
48844
48960
|
"reorder-sessions": handleReorderSessions,
|
|
48845
48961
|
"ping": handlePing,
|
|
@@ -49601,12 +49717,9 @@ function markInterrupted(journal, { reason, now }) {
|
|
|
49601
49717
|
}
|
|
49602
49718
|
//#endregion
|
|
49603
49719
|
//#region server/update-check.ts
|
|
49604
|
-
var GIT_REMOTE_URL = `https://github.com/${REPO_SLUG}.git`;
|
|
49605
|
-
var GITHUB_LATEST_RELEASE_URL = `https://api.github.com/repos/${REPO_SLUG}/releases/latest`;
|
|
49606
49720
|
var NPM_REGISTRY_LATEST_URL = "https://registry.npmjs.org/glimmervoid/latest";
|
|
49607
49721
|
var DEFAULT_TIMEOUT_MS = 8e3;
|
|
49608
49722
|
var GIT_HEAD_TIMEOUT_MS = 3e3;
|
|
49609
|
-
var LS_REMOTE_TIMEOUT_MS = 5e3;
|
|
49610
49723
|
var RELEASE_ANCESTRY_TIMEOUT_MS = 3e3;
|
|
49611
49724
|
var MAIN_CHANNEL_BUDGET_MS = DEFAULT_TIMEOUT_MS;
|
|
49612
49725
|
var MAIN_FETCH_TIMEOUT_MS = Math.floor(MAIN_CHANNEL_BUDGET_MS / 2);
|
|
@@ -49614,6 +49727,7 @@ var MAIN_REMOTE_TIP_TIMEOUT_MS = Math.floor(MAIN_CHANNEL_BUDGET_MS / 4);
|
|
|
49614
49727
|
var MAIN_BEHIND_COUNT_TIMEOUT_MS = Math.floor(MAIN_CHANNEL_BUDGET_MS / 4);
|
|
49615
49728
|
var STATE_FILE_NAME = "update-check.json";
|
|
49616
49729
|
var STATE_TTL_MS = 216e5;
|
|
49730
|
+
var RELEASE_SOURCE = "npm-registry";
|
|
49617
49731
|
function defaultStatePath() {
|
|
49618
49732
|
return path.join(glimmervoidHomeDir$1(), STATE_FILE_NAME);
|
|
49619
49733
|
}
|
|
@@ -49757,59 +49871,6 @@ async function resolveLatestRegistryVersion({ fetchFn, signal }) {
|
|
|
49757
49871
|
};
|
|
49758
49872
|
}
|
|
49759
49873
|
}
|
|
49760
|
-
async function resolveLatestRelease({ flavor, runCommand, fetchFn, signal }) {
|
|
49761
|
-
if (decideReleaseSource(flavor) === "npm-registry") return resolveLatestRegistryVersion({
|
|
49762
|
-
fetchFn,
|
|
49763
|
-
signal
|
|
49764
|
-
});
|
|
49765
|
-
const fromRemote = parseLsRemoteTags((await runGitProbe(runCommand, [
|
|
49766
|
-
"ls-remote",
|
|
49767
|
-
"--tags",
|
|
49768
|
-
GIT_REMOTE_URL
|
|
49769
|
-
], {
|
|
49770
|
-
timeout: LS_REMOTE_TIMEOUT_MS,
|
|
49771
|
-
signal
|
|
49772
|
-
})).out);
|
|
49773
|
-
if (fromRemote) return {
|
|
49774
|
-
...fromRemote,
|
|
49775
|
-
behindCount: null,
|
|
49776
|
-
reason: null
|
|
49777
|
-
};
|
|
49778
|
-
try {
|
|
49779
|
-
const response = await fetchFn(GITHUB_LATEST_RELEASE_URL, {
|
|
49780
|
-
signal,
|
|
49781
|
-
headers: {
|
|
49782
|
-
Accept: "application/vnd.github+json",
|
|
49783
|
-
"User-Agent": "glimmervoid-update-check"
|
|
49784
|
-
}
|
|
49785
|
-
});
|
|
49786
|
-
if (!response?.ok) return {
|
|
49787
|
-
version: null,
|
|
49788
|
-
sha: null,
|
|
49789
|
-
behindCount: null,
|
|
49790
|
-
reason: "release-check-failed"
|
|
49791
|
-
};
|
|
49792
|
-
const release = parseLatestReleaseTag(await response.json());
|
|
49793
|
-
if (!release) return {
|
|
49794
|
-
version: null,
|
|
49795
|
-
sha: null,
|
|
49796
|
-
behindCount: null,
|
|
49797
|
-
reason: "release-check-failed"
|
|
49798
|
-
};
|
|
49799
|
-
return {
|
|
49800
|
-
...release,
|
|
49801
|
-
behindCount: null,
|
|
49802
|
-
reason: null
|
|
49803
|
-
};
|
|
49804
|
-
} catch {
|
|
49805
|
-
return {
|
|
49806
|
-
version: null,
|
|
49807
|
-
sha: null,
|
|
49808
|
-
behindCount: null,
|
|
49809
|
-
reason: "release-check-failed"
|
|
49810
|
-
};
|
|
49811
|
-
}
|
|
49812
|
-
}
|
|
49813
49874
|
function upstreamBranch(upstream) {
|
|
49814
49875
|
const slashIndex = upstream.indexOf("/");
|
|
49815
49876
|
if (slashIndex < 0 || slashIndex === upstream.length - 1) return null;
|
|
@@ -49982,13 +50043,11 @@ async function checkForUpdate({ currentVersion, updateChannel = "release", fetch
|
|
|
49982
50043
|
});
|
|
49983
50044
|
const cached = readCheckState(statePath);
|
|
49984
50045
|
const cacheOutrunByInstall = normalizeSha(cached?.latestSha) !== null && normalizeSha(cached?.latestSha) === installed.installedSha;
|
|
49985
|
-
const expectedReleaseSource = updateChannel === "release" ?
|
|
50046
|
+
const expectedReleaseSource = updateChannel === "release" ? RELEASE_SOURCE : null;
|
|
49986
50047
|
const isCacheFromSameSource = expectedReleaseSource === null || cached?.releaseSource === expectedReleaseSource;
|
|
49987
50048
|
if (cached?.channel === updateChannel && isCacheFromSameSource && !cacheOutrunByInstall && isCheckFresh(cached.lastCheckAt, now, ttlMs)) return finish(installed, targetFromCache(cached), currentVersion, updateChannel, platform, now, packageRoot$1, runCommand, signal);
|
|
49988
50049
|
signal.throwIfAborted();
|
|
49989
|
-
const latestTarget = updateChannel === "main" ? await resolveLatestMain(installed, packageRoot$1, runCommand, fetchOrigin, signal) : await
|
|
49990
|
-
flavor: installed.flavor,
|
|
49991
|
-
runCommand,
|
|
50050
|
+
const latestTarget = updateChannel === "main" ? await resolveLatestMain(installed, packageRoot$1, runCommand, fetchOrigin, signal) : await resolveLatestRegistryVersion({
|
|
49992
50051
|
fetchFn,
|
|
49993
50052
|
signal
|
|
49994
50053
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as errorMessage } from "./text-DoirglWV.js";
|
|
2
|
-
import { l as resolveConfigPath } from "./config-store-
|
|
3
|
-
import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-
|
|
2
|
+
import { l as resolveConfigPath } from "./config-store-D0lRWsAM.js";
|
|
3
|
+
import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-Y6YtqoiO.js";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
//#region server/text-format.ts
|
|
6
6
|
function trimIso(iso) {
|
|
@@ -3,7 +3,7 @@ import { i as equalsIgnoringCaseOnWindows, t as canonicalizePath } from "./paths
|
|
|
3
3
|
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
4
4
|
import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
|
|
5
5
|
import { a as jsonStateLoadError, d as writeJsonAtomicSync, l as sleepSync, s as loadJsonStateFileSync, u as writeJsonAtomic } from "./json-file-oEH9vt-0.js";
|
|
6
|
-
import { s as glimmervoidHomeDir } from "./config-store-
|
|
6
|
+
import { s as glimmervoidHomeDir } from "./config-store-D0lRWsAM.js";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
import crypto from "node:crypto";
|