glimmervoid 0.38.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/glimmervoid.js +24 -30
- package/dist/chunks/{adapters-B0EJp_oE.js → adapters-B9tP9MXC.js} +27 -15
- package/dist/chunks/{adapters-BIbF8RJB.js → adapters-Buu6yI71.js} +1 -1
- package/dist/chunks/{agent-api-cli-B5Tm0wXO.js → agent-api-cli-2_RwTTTJ.js} +4 -66
- package/dist/chunks/{agent-api-cli-BDu1CxZf.js → agent-api-cli-PfCov-qb.js} +1 -1
- package/dist/chunks/agent-api-core-D2HLgBEe.js +180 -0
- package/dist/chunks/{agent-setup-cli-C9MMiask.js → agent-setup-cli-C1nFdgFg.js} +2 -2
- package/dist/chunks/config-store-8Z9vkWvf.js +1 -0
- package/dist/chunks/{config-store-CKcDJebD.js → config-store-n23JDU4E.js} +64 -269
- package/dist/chunks/{contracts-HVCEJfxs.js → contracts-DYQW11de.js} +1018 -171
- package/dist/chunks/{git-version-rWZjF2Px.js → git-version-DXozXVnb.js} +2 -2
- package/dist/chunks/{grok-y65HOvlU.js → grok-DeGAXgZF.js} +8 -9
- package/dist/chunks/{guardrails-deps-Cb-ki4EU.js → guardrails-deps-CLxK4J-g.js} +1 -1
- package/dist/chunks/{hook-tools-BkxllUHE.js → hook-tools-Dl7-r2Eb.js} +1 -1
- package/dist/chunks/{json-file-CIJf0Cel.js → json-file-DFCTvPjj.js} +3 -7
- package/dist/chunks/{main-DeiiNNI7.js → main-D4uwk-_M.js} +15574 -20328
- package/dist/chunks/{pair-cli-B9hHUHLl.js → pair-cli-D9DZBqk0.js} +2 -2
- package/dist/chunks/{remote-config-DlquYoVe.js → remote-config-DiLwnzBq.js} +2 -2
- 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/{session-BlT68ppa.js → session-D2EbiysG.js} +20 -32
- package/dist/chunks/{session-routes-CT1JrjoT.js → session-routes-BQAZzMKZ.js} +3 -8
- package/dist/chunks/{settings-cli-C5i9v59a.js → settings-cli-DP4t-I9U.js} +3 -3
- package/dist/chunks/{ssh-sign-cli-C74BGTQS.js → ssh-sign-cli-D2RIs-iN.js} +2 -2
- package/dist/client/assets/index-C0YUJwjz.css +2 -0
- package/dist/client/assets/index-w8lG-tk2.js +148 -0
- package/dist/client/assets/xterm-kR64YvZ-.js +79 -0
- package/dist/client/assets/zod-BRLv4KqJ.js +55 -0
- package/dist/client/index.html +5 -2
- package/dist/scripts/postinstall-path-check.js +21 -3
- package/dist/server/index.js +1 -1
- package/dist/session/hook-tool-relay.js +1 -1
- package/package.json +2 -3
- package/dist/chunks/agent-api-core-B_mUSenR.js +0 -341
- package/dist/chunks/browser-config-BrBT8269.js +0 -762
- package/dist/chunks/config-CjawSOBk.js +0 -219
- package/dist/chunks/config-store-B6mX2phK.js +0 -1
- package/dist/chunks/factory-D7ryES9n.js +0 -240
- package/dist/chunks/knowledge-graph-cli-ByUJoKw_.js +0 -1354
- package/dist/chunks/rtk-resolver-B8BPgN9L.js +0 -1
- package/dist/client/assets/index-ChXRDbjt.js +0 -275
- package/dist/client/assets/index-DA251uL1.css +0 -1
package/dist/bin/glimmervoid.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { o as nodePtyRebuildHint, r as firstLine, t as probeNodePty } from "../chunks/node-pty-preflight-C8QIlrtU.js";
|
|
3
3
|
import { i as errorText } from "../chunks/text-DoirglWV.js";
|
|
4
4
|
import { a as packageRoot } from "../chunks/runtime-paths-BkeftE60.js";
|
|
5
|
-
import { t as AGENT_API_VERBS } from "../chunks/session-
|
|
5
|
+
import { t as AGENT_API_VERBS } from "../chunks/session-D2EbiysG.js";
|
|
6
6
|
import { i as execSync } from "../chunks/child-process-safe-CbQnyh7D.js";
|
|
7
7
|
import { t as renderTable } from "../chunks/ascii-figure-core-pDAwtlKO.js";
|
|
8
8
|
import { n as glimmervoidHomeDir, t as decideConfigPath } from "../chunks/config-path-core-DFt-TemS.js";
|
|
9
|
-
import { i as parseCommandLine, r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-
|
|
10
|
-
import { i as guardrailsDoctorRows, r as probeGuardrailsDependencies } from "../chunks/guardrails-deps-
|
|
9
|
+
import { i as parseCommandLine, r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-DXozXVnb.js";
|
|
10
|
+
import { i as guardrailsDoctorRows, r as probeGuardrailsDependencies } from "../chunks/guardrails-deps-CLxK4J-g.js";
|
|
11
11
|
import { i as pnpmGlobalBinDir, n as npmGlobalBinDir, r as onPath, t as formatPathNotice } from "../chunks/path-doctor-C23VAqeu.js";
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
@@ -41,15 +41,8 @@ Inside a Glimmervoid session:
|
|
|
41
41
|
push Land this session's commits on the integration branch and push it
|
|
42
42
|
edit <path> Open a text file for the operator to edit in the dashboard
|
|
43
43
|
limits List which of these commands answer here and what the guardrails block
|
|
44
|
-
factory status Print each factory intent's tickets, state, last reason and next action
|
|
45
|
-
factory retry <id> Reopen the parked tickets of a factory intent
|
|
46
|
-
factory setup Prove and save the factory checks of this session's repository
|
|
47
|
-
factory queue <file> Queue a factory intent (a spec cut.ts file or Factory tab request) on this session's repository
|
|
48
44
|
ssh-sign Sign a commit with the operator's forwarded ssh agent (git runs this)
|
|
49
45
|
|
|
50
|
-
Experimental:
|
|
51
|
-
kg [command] Typed knowledge and task graph (Settings > Lanes > Knowledge graph)
|
|
52
|
-
|
|
53
46
|
Options:
|
|
54
47
|
--port <number> Server port (default: 3000)
|
|
55
48
|
--config <path> Config file (default: ~/.glimmervoid/config.json)
|
|
@@ -76,19 +69,15 @@ var SUBCOMMAND_RUNNERS = new Map([
|
|
|
76
69
|
return 0;
|
|
77
70
|
}],
|
|
78
71
|
["pair", async (subcommandArgs) => {
|
|
79
|
-
const { runPairCli } = await import("../chunks/pair-cli-
|
|
72
|
+
const { runPairCli } = await import("../chunks/pair-cli-D9DZBqk0.js");
|
|
80
73
|
return runPairCli(subcommandArgs);
|
|
81
74
|
}],
|
|
82
75
|
["agent", async (subcommandArgs) => {
|
|
83
|
-
const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-
|
|
76
|
+
const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-C1nFdgFg.js");
|
|
84
77
|
return runAgentSetupCli(subcommandArgs);
|
|
85
78
|
}],
|
|
86
|
-
["kg", async (subcommandArgs) => {
|
|
87
|
-
const { runKnowledgeGraphCommand } = await import("../chunks/knowledge-graph-cli-ByUJoKw_.js");
|
|
88
|
-
return runKnowledgeGraphCommand(subcommandArgs);
|
|
89
|
-
}],
|
|
90
79
|
["settings", async (subcommandArgs) => {
|
|
91
|
-
const { runSettingsCommand } = await import("../chunks/settings-cli-
|
|
80
|
+
const { runSettingsCommand } = await import("../chunks/settings-cli-DP4t-I9U.js");
|
|
92
81
|
return runSettingsCommand(subcommandArgs);
|
|
93
82
|
}],
|
|
94
83
|
["visions", async (subcommandArgs) => {
|
|
@@ -96,21 +85,26 @@ var SUBCOMMAND_RUNNERS = new Map([
|
|
|
96
85
|
return runVisionsCli(subcommandArgs);
|
|
97
86
|
}],
|
|
98
87
|
["ssh-sign", async (subcommandArgs) => {
|
|
99
|
-
const { runSshSignCli } = await import("../chunks/ssh-sign-cli-
|
|
88
|
+
const { runSshSignCli } = await import("../chunks/ssh-sign-cli-D2RIs-iN.js");
|
|
100
89
|
return runSshSignCli(subcommandArgs);
|
|
101
90
|
}],
|
|
102
|
-
["factory", async (subcommandArgs) => {
|
|
103
|
-
const { runAgentApiCli } = await import("../chunks/agent-api-cli-BDu1CxZf.js");
|
|
104
|
-
return runAgentApiCli(["factory", ...subcommandArgs]);
|
|
105
|
-
}],
|
|
106
91
|
...AGENT_API_VERBS.map((verb) => [verb, async (subcommandArgs, subcommandName) => {
|
|
107
|
-
const { runAgentApiCli } = await import("../chunks/agent-api-cli-
|
|
92
|
+
const { runAgentApiCli } = await import("../chunks/agent-api-cli-PfCov-qb.js");
|
|
108
93
|
return runAgentApiCli([subcommandName, ...subcommandArgs]);
|
|
109
94
|
}])
|
|
110
95
|
]);
|
|
96
|
+
var AGENT_INSTALL_COMMAND_BY_ID = {
|
|
97
|
+
"claude-code": "npm install -g @anthropic-ai/claude-code",
|
|
98
|
+
codex: "npm install -g @openai/codex"
|
|
99
|
+
};
|
|
100
|
+
function missingAgentText(agentId) {
|
|
101
|
+
const installCommand = AGENT_INSTALL_COMMAND_BY_ID[agentId];
|
|
102
|
+
if (!installCommand) return "not found on PATH";
|
|
103
|
+
return `not found on PATH; install with: ${installCommand}`;
|
|
104
|
+
}
|
|
111
105
|
async function printSessionLimits() {
|
|
112
106
|
if (!process.env["GLIMMERVOID_AGENT_URL"]) return;
|
|
113
|
-
const { sessionLimitsHelpLines } = await import("../chunks/agent-api-cli-
|
|
107
|
+
const { sessionLimitsHelpLines } = await import("../chunks/agent-api-cli-PfCov-qb.js");
|
|
114
108
|
const limitsLines = await sessionLimitsHelpLines();
|
|
115
109
|
console.log(`\n${limitsLines.join("\n")}`);
|
|
116
110
|
}
|
|
@@ -167,7 +161,7 @@ async function readDeclaredCustomAgents() {
|
|
|
167
161
|
declared: [],
|
|
168
162
|
error: null
|
|
169
163
|
};
|
|
170
|
-
const { loadConfigFile } = await import("../chunks/config-store-
|
|
164
|
+
const { loadConfigFile } = await import("../chunks/config-store-8Z9vkWvf.js");
|
|
171
165
|
try {
|
|
172
166
|
const loaded = loadConfigFile(decided.path, { exitOnError: false });
|
|
173
167
|
if (!loaded.config) return {
|
|
@@ -243,15 +237,15 @@ async function runDoctor() {
|
|
|
243
237
|
}
|
|
244
238
|
switchSection("Agents");
|
|
245
239
|
try {
|
|
246
|
-
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-
|
|
240
|
+
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-Buu6yI71.js");
|
|
247
241
|
const declaredCustomAgents = await readDeclaredCustomAgents();
|
|
248
242
|
if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
|
|
249
243
|
setCustomAgents(declaredCustomAgents.declared);
|
|
250
244
|
for (const id of listAgentIds()) {
|
|
251
245
|
const { label, path: resolvedPath } = describeAgentResolvability(id);
|
|
252
|
-
line(`${id} (${label})`, resolvedPath ??
|
|
246
|
+
line(`${id} (${label})`, resolvedPath ?? missingAgentText(id));
|
|
253
247
|
}
|
|
254
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
248
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-C1nFdgFg.js");
|
|
255
249
|
const grokSetup = inspectGrokAgentSetup();
|
|
256
250
|
line("grok hook setup", `${grokSetup.classification}: ${grokSetup.filePath}`);
|
|
257
251
|
} catch (err) {
|
|
@@ -259,7 +253,7 @@ async function runDoctor() {
|
|
|
259
253
|
}
|
|
260
254
|
switchSection("rtk");
|
|
261
255
|
try {
|
|
262
|
-
const { getRtkPath } = await import("../chunks/rtk-resolver-
|
|
256
|
+
const { getRtkPath } = await import("../chunks/rtk-resolver-BGE6Hd_L.js");
|
|
263
257
|
line("rtk", getRtkPath() || "not installed (Glimmervoid installs it when the rtk setting is on)");
|
|
264
258
|
} catch (err) {
|
|
265
259
|
line("rtk", `probe failed: ${firstLine(errorText(err))}`);
|
|
@@ -268,7 +262,7 @@ async function runDoctor() {
|
|
|
268
262
|
try {
|
|
269
263
|
const { resolvePackageBin } = await import("../chunks/runtime-paths-DSmormp7.js");
|
|
270
264
|
const { execFileSync } = await import("../chunks/child-process-safe-ChRmWAJP.js");
|
|
271
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
265
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-C1nFdgFg.js");
|
|
272
266
|
const binPath = resolvePackageBin("cc-safety-net", "cc-safety-net");
|
|
273
267
|
line("Sane YOLO", binPath || "not installed");
|
|
274
268
|
if (binPath) line("cc-safety-net version", execFileSync(process.execPath, [binPath, "--version"], {
|
|
@@ -3,11 +3,11 @@ import { r as execFileSync } from "./child-process-safe-CbQnyh7D.js";
|
|
|
3
3
|
import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-command-Cc40FiZI.js";
|
|
4
4
|
import { s as rawTextOr } from "./coerce-NSst8oRP.js";
|
|
5
5
|
import { r as nextBackoffMs } from "./backoff-DjVpfHk7.js";
|
|
6
|
-
import { l as supervisionLine } from "./session-routes-
|
|
7
|
-
import {
|
|
6
|
+
import { l as supervisionLine } from "./session-routes-BQAZzMKZ.js";
|
|
7
|
+
import { i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, s as buildAgentEnv, t as grok } from "./grok-DeGAXgZF.js";
|
|
8
8
|
import { t as buildHookCommand } from "./hook-command-core-qTNK-xMF.js";
|
|
9
|
-
import "./contracts-
|
|
10
|
-
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-
|
|
9
|
+
import "./contracts-DYQW11de.js";
|
|
10
|
+
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
//#region session/adapters/claude-code.ts
|
|
@@ -204,13 +204,6 @@ var claudeCode = {
|
|
|
204
204
|
};
|
|
205
205
|
//#endregion
|
|
206
206
|
//#region server/usage/core/usage-scan-core.ts
|
|
207
|
-
function laneSpendStatus({ isTrackingEnabled, scan }) {
|
|
208
|
-
if (!isTrackingEnabled) return "tracking-off";
|
|
209
|
-
if (scan === null) return "scanner-missing";
|
|
210
|
-
if (scan.lastOutcome === "io-failed") return "read-failing";
|
|
211
|
-
if (!scan.isHistoryCaughtUp || scan.lastOutcome === null) return "catching-up";
|
|
212
|
-
return "known";
|
|
213
|
-
}
|
|
214
207
|
function scopedClaudeRoots(scopeDirs, claudeDirs) {
|
|
215
208
|
if (!scopeDirs || scopeDirs.length === 0) return null;
|
|
216
209
|
const isInside = (candidate, parent) => candidate.startsWith(`${parent}${path.sep}`);
|
|
@@ -473,9 +466,11 @@ function mayContributeHooks(configText) {
|
|
|
473
466
|
function userConfigFolders(env) {
|
|
474
467
|
return codexHomes(env, null);
|
|
475
468
|
}
|
|
476
|
-
|
|
469
|
+
var TOML_LITERAL_STRING_FORBIDDEN = /[\x00-\x08\x0a-\x1f\x27\x7f]/;
|
|
470
|
+
function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, bypassHookTrust = false, hookTools = [], hookToolRelayPath = HOOK_TOOL_RELAY_PATH, userHooks = [] } = {}) {
|
|
477
471
|
const args = bypassHookTrust ? [TRUST_BYPASS_FLAG] : [];
|
|
478
472
|
const preToolUseGroups = [];
|
|
473
|
+
const groupsByEvent = /* @__PURE__ */ new Map();
|
|
479
474
|
for (const event of events) {
|
|
480
475
|
const command = buildHookCommand(relayPath, event);
|
|
481
476
|
if (!command) return null;
|
|
@@ -483,13 +478,30 @@ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, bypassHoo
|
|
|
483
478
|
preToolUseGroups.push(`{hooks=[{type='command',command='${command}'}]}`);
|
|
484
479
|
continue;
|
|
485
480
|
}
|
|
486
|
-
|
|
481
|
+
groupsByEvent.set(event, [`{hooks=[{type='command',command='${command}'}]}`]);
|
|
487
482
|
}
|
|
488
483
|
const groups = hookTools.flatMap((tool) => {
|
|
489
484
|
const group = HOOK_TOOLS[tool.id].codexGroup(tool, hookToolRelayPath);
|
|
490
485
|
return group ? [group] : [];
|
|
491
486
|
});
|
|
492
|
-
|
|
487
|
+
preToolUseGroups.push(...groups);
|
|
488
|
+
for (const hook of userHooks) {
|
|
489
|
+
if (!hook.enabled || hook.type !== "command" || !hook.command) continue;
|
|
490
|
+
if (TOML_LITERAL_STRING_FORBIDDEN.test(hook.command) || hook.matcher !== void 0 && TOML_LITERAL_STRING_FORBIDDEN.test(hook.matcher)) {
|
|
491
|
+
console.warn(`[codex] hook ${hook.id} skipped: command or matcher cannot be expressed as a TOML literal string`);
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
const group = `{${hook.matcher === void 0 ? "" : `matcher='${hook.matcher}',`}hooks=[{type='command',command='${hook.command}'}]}`;
|
|
495
|
+
if (hook.event === "PreToolUse") {
|
|
496
|
+
preToolUseGroups.push(group);
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
const eventGroups = groupsByEvent.get(hook.event) ?? [];
|
|
500
|
+
eventGroups.push(group);
|
|
501
|
+
groupsByEvent.set(hook.event, eventGroups);
|
|
502
|
+
}
|
|
503
|
+
for (const [event, eventGroups] of groupsByEvent) args.push("-c", `hooks.${event}=[${eventGroups.join(",")}]`);
|
|
504
|
+
args.push(...mergeCodexPreToolUse(preToolUseGroups));
|
|
493
505
|
return args;
|
|
494
506
|
}
|
|
495
507
|
var hooks = {
|
|
@@ -790,4 +802,4 @@ function resetCommandCache() {
|
|
|
790
802
|
resolvedCommands.clear();
|
|
791
803
|
}
|
|
792
804
|
//#endregion
|
|
793
|
-
export {
|
|
805
|
+
export { splitLines as A, isUsageFile as C, scopedClaudeRoots as D, resolveProjectsDirs as E, shouldEvaluateDespiteIoFailures as O, grokRootCandidates as S, projectDirCandidates as T, continuationDelayMs as _, describeAgentResolvability as a, expandTilde as b, isKnownAgentId as c, resolveAdapter as d, setCustomAgents as f, codexSessionIdFromPath as g, codexRootCandidates as h, customAgentFingerprint as i, claudeCode as j, shouldPersistWarehouse as k, listAgentIds as l, codexHomes as m, cachedAgentResolvability as n, getAdapter as o, codexFallbackRoots as p, commandFor as r, hookProfileOf as s, DEFAULT_AGENT_ID as t, resetCommandCache as u, decideFileRead as v, passOutcome as w, grokHomes as x, dedupeCodexFiles as y };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-
|
|
1
|
+
export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-B9tP9MXC.js";
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import { t as errorCode } from "./text-DoirglWV.js";
|
|
2
|
-
import {
|
|
2
|
+
import { n as AGENT_URL_ENV, o as AgentLimitsReply } from "./session-D2EbiysG.js";
|
|
3
3
|
import { i as resolveHookTarget } from "./hook-relay-core-DA_bz2KA.js";
|
|
4
4
|
import { n as decideGuardrailsProxy } from "./guardrails-proxy-core-BI3rdY-m.js";
|
|
5
|
-
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
6
5
|
import { t as parseJsonOrNull } from "./json-core-dfa_7Fak.js";
|
|
7
|
-
import { a as formatSessionLimits } from "./session-routes-
|
|
8
|
-
import {
|
|
9
|
-
import { readFileSync } from "node:fs";
|
|
6
|
+
import { a as formatSessionLimits } from "./session-routes-BQAZzMKZ.js";
|
|
7
|
+
import { l as isAgentApiVerb } from "./agent-api-core-D2HLgBEe.js";
|
|
10
8
|
import path from "node:path";
|
|
11
9
|
import http from "node:http";
|
|
12
10
|
//#region server/agent-api-cli.ts
|
|
13
11
|
var AGENT_PATH_PREFIX = "/agent/";
|
|
14
12
|
var HELP_LIMITS_TIMEOUT_MS = 2e3;
|
|
15
13
|
var HELP_LIMITS_UNKNOWN_LINE = "This session: Glimmervoid did not report its limits, so run glimmervoid limits to see why";
|
|
16
|
-
function ticketBody(rest) {
|
|
17
|
-
const parsed = AgentTicketRequest.safeParse({ workId: rest[0] });
|
|
18
|
-
return parsed.success ? parsed.data : null;
|
|
19
|
-
}
|
|
20
14
|
var BODY_BUILDERS = {
|
|
21
15
|
spawn: (rest) => {
|
|
22
16
|
const prompt = rest.join(" ").trim();
|
|
@@ -32,42 +26,8 @@ var BODY_BUILDERS = {
|
|
|
32
26
|
const docPath = rest.join(" ").trim();
|
|
33
27
|
return docPath ? { path: path.resolve(docPath) } : null;
|
|
34
28
|
},
|
|
35
|
-
limits: () => ({})
|
|
36
|
-
dispatch: (rest) => {
|
|
37
|
-
const parsed = AgentDispatchRequest.safeParse(rest[0] === "--ready" ? { readyIntent: rest[1] } : { workId: rest[0] });
|
|
38
|
-
return parsed.success ? parsed.data : null;
|
|
39
|
-
},
|
|
40
|
-
reopen: (rest) => ticketBody(rest),
|
|
41
|
-
cancel: (rest) => ticketBody(rest),
|
|
42
|
-
"factory-status": (rest) => {
|
|
43
|
-
if (rest.length === 0) return {};
|
|
44
|
-
if (rest.length !== 2 || rest[0] !== "--project") return null;
|
|
45
|
-
const parsed = AgentFactoryStatusRequest.safeParse({ projectId: rest[1] });
|
|
46
|
-
return parsed.success ? parsed.data : null;
|
|
47
|
-
},
|
|
48
|
-
"factory-retry": (rest) => {
|
|
49
|
-
if (rest.length !== 1) return null;
|
|
50
|
-
const parsed = AgentFactoryRetryRequest.safeParse({ intentId: rest[0] });
|
|
51
|
-
return parsed.success ? parsed.data : null;
|
|
52
|
-
},
|
|
53
|
-
"factory-setup": (rest) => rest.length === 0 ? {} : null,
|
|
54
|
-
"factory-queue": (rest) => {
|
|
55
|
-
if (rest.length !== 1) return null;
|
|
56
|
-
const intent = parseJsonOrNull(readFileSync(rest[0], "utf8"));
|
|
57
|
-
if (!isRecord(intent)) return null;
|
|
58
|
-
const { name: _name, type: _type, requestId: _requestId, projectId: _projectId, ...request } = intent;
|
|
59
|
-
return request;
|
|
60
|
-
}
|
|
29
|
+
limits: () => ({})
|
|
61
30
|
};
|
|
62
|
-
var FACTORY_USAGE = Object.freeze({
|
|
63
|
-
"factory-status": "status [--project <projectId>]",
|
|
64
|
-
"factory-retry": "retry <intentId>",
|
|
65
|
-
"factory-setup": "setup",
|
|
66
|
-
"factory-queue": "queue <intent.json>"
|
|
67
|
-
});
|
|
68
|
-
function isFactoryVerb(verb) {
|
|
69
|
-
return verb in FACTORY_USAGE;
|
|
70
|
-
}
|
|
71
31
|
function bodySaysOk(text) {
|
|
72
32
|
try {
|
|
73
33
|
const parsed = JSON.parse(text);
|
|
@@ -82,13 +42,6 @@ function limitsLines(replyText) {
|
|
|
82
42
|
return formatSessionLimits(limits.data);
|
|
83
43
|
}
|
|
84
44
|
function printableReply(verb, replyText) {
|
|
85
|
-
if (isFactoryVerb(verb)) {
|
|
86
|
-
const reply = parseJsonOrNull(replyText);
|
|
87
|
-
if (typeof reply !== "object" || reply === null) return replyText;
|
|
88
|
-
if ("text" in reply && typeof reply.text === "string") return reply.text;
|
|
89
|
-
if ("error" in reply && typeof reply.error === "string") return reply.error;
|
|
90
|
-
return replyText;
|
|
91
|
-
}
|
|
92
45
|
if (verb !== "limits") return replyText;
|
|
93
46
|
return limitsLines(replyText)?.join("\n") ?? replyText;
|
|
94
47
|
}
|
|
@@ -188,13 +141,6 @@ async function sessionLimitsHelpLines({ timeoutMs = HELP_LIMITS_TIMEOUT_MS } = {
|
|
|
188
141
|
}
|
|
189
142
|
}
|
|
190
143
|
async function runAgentApiCli(args) {
|
|
191
|
-
if (args[0] === "factory") {
|
|
192
|
-
if (!(`factory-${args[1]}` in FACTORY_USAGE)) {
|
|
193
|
-
console.error(`glimmervoid factory: expected ${Object.values(FACTORY_USAGE).join(", or ")}`);
|
|
194
|
-
return 1;
|
|
195
|
-
}
|
|
196
|
-
return runAgentApiCli([`factory-${args[1]}`, ...args.slice(2)]);
|
|
197
|
-
}
|
|
198
144
|
const verb = args[0];
|
|
199
145
|
if (!verb || !isAgentApiVerb(verb)) {
|
|
200
146
|
console.error(`glimmervoid: ${verb || "that"} is not an agent command`);
|
|
@@ -202,14 +148,6 @@ async function runAgentApiCli(args) {
|
|
|
202
148
|
}
|
|
203
149
|
const body = BODY_BUILDERS[verb](args.slice(1));
|
|
204
150
|
if (!body) {
|
|
205
|
-
if (isFactoryVerb(verb)) {
|
|
206
|
-
console.error(`glimmervoid factory: expected ${FACTORY_USAGE[verb]}`);
|
|
207
|
-
return 1;
|
|
208
|
-
}
|
|
209
|
-
if (isOrchestratorAgentVerb(verb)) {
|
|
210
|
-
console.error(`glimmervoid ${verb}: expected a work id matching wrk-[0-9a-f]{16}`);
|
|
211
|
-
return 1;
|
|
212
|
-
}
|
|
213
151
|
if (verb === "edit") {
|
|
214
152
|
console.error("glimmervoid edit: this command needs a file path, for example \"glimmervoid edit drafts/post.md\"");
|
|
215
153
|
return 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { n as runAgentApiCli, r as sessionLimitsHelpLines } from "./agent-api-cli-
|
|
1
|
+
export { n as runAgentApiCli, r as sessionLimitsHelpLines } from "./agent-api-cli-2_RwTTTJ.js";
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { a as AgentEditRequest, i as AgentAttentionRequest, s as AgentSpawnRequest, t as AGENT_API_VERBS } from "./session-D2EbiysG.js";
|
|
2
|
+
import { c as spawnRoute, i as editRoute, n as attentionRoute, s as pushRoute, t as NO_OWN_WORKTREE_REASON } from "./session-routes-BQAZzMKZ.js";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
var MAX_SPAWNS_IN_FLIGHT = 1;
|
|
5
|
+
var SPAWNABLE_DEPTH = 0;
|
|
6
|
+
var REFUSAL_REASON = "unknown session";
|
|
7
|
+
var INVALID_BODY_STATUS = 400;
|
|
8
|
+
var PUSH_REFUSED_STATUS = 409;
|
|
9
|
+
var PUSH_REFUSAL_COPY = Object.freeze({
|
|
10
|
+
"no-worktree": () => NO_OWN_WORKTREE_REASON,
|
|
11
|
+
"merge-in-progress": () => "a merge for this session is already running, so try again when it ends",
|
|
12
|
+
"not-continuable": () => "this session cannot be merged in its current state",
|
|
13
|
+
destroyed: () => "this session is ending",
|
|
14
|
+
"nothing-to-commit": () => "no commit on this branch is missing from the integration branch, so commit your work first",
|
|
15
|
+
"rebase-conflict": ({ base, conflicts = [] }) => `this branch conflicts with ${base} in ${conflicts.join(", ") || "one or more files"}, so rebase onto ${base}, resolve the conflicts, commit, then push again`,
|
|
16
|
+
"not-fast-forward": ({ base }) => `${base} could not be fast-forwarded to this branch, and a push is never forced`,
|
|
17
|
+
"base-diverged": ({ base }) => `the local ${base} and origin/${base} have diverged, which the operator has to reconcile`
|
|
18
|
+
});
|
|
19
|
+
function tokensMatch(presented, expected) {
|
|
20
|
+
if (presented.length !== expected.length) return false;
|
|
21
|
+
try {
|
|
22
|
+
return crypto.timingSafeEqual(Buffer.from(presented, "utf8"), Buffer.from(expected, "utf8"));
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function refused() {
|
|
28
|
+
return {
|
|
29
|
+
ok: false,
|
|
30
|
+
status: 404,
|
|
31
|
+
reason: REFUSAL_REASON
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function decideAgentRequest({ sessionId, presentedToken, expectedToken, isLoopback }) {
|
|
35
|
+
if (!isLoopback) return refused();
|
|
36
|
+
if (!sessionId) return refused();
|
|
37
|
+
if (!expectedToken) return refused();
|
|
38
|
+
if (!presentedToken) return refused();
|
|
39
|
+
if (!tokensMatch(presentedToken, expectedToken)) return refused();
|
|
40
|
+
return { ok: true };
|
|
41
|
+
}
|
|
42
|
+
function refuseByRole(route) {
|
|
43
|
+
if (route.answers) return { ok: true };
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
status: 403,
|
|
47
|
+
reason: route.reason
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function decideSpawnAllowance({ liveChildren, lifetimeSpawns, inFlight, depth, isEphemeral }) {
|
|
51
|
+
const role = refuseByRole(spawnRoute({
|
|
52
|
+
isEphemeral,
|
|
53
|
+
isSpawnedChild: depth !== SPAWNABLE_DEPTH
|
|
54
|
+
}));
|
|
55
|
+
if (!role.ok) return role;
|
|
56
|
+
if (inFlight >= MAX_SPAWNS_IN_FLIGHT) return {
|
|
57
|
+
ok: false,
|
|
58
|
+
status: 429,
|
|
59
|
+
reason: "a spawn is already in flight"
|
|
60
|
+
};
|
|
61
|
+
if (liveChildren >= 3) return {
|
|
62
|
+
ok: false,
|
|
63
|
+
status: 429,
|
|
64
|
+
reason: `at most 3 spawned sessions may be live at once`
|
|
65
|
+
};
|
|
66
|
+
if (lifetimeSpawns >= 10) return {
|
|
67
|
+
ok: false,
|
|
68
|
+
status: 429,
|
|
69
|
+
reason: `this session has used its 10 spawns`
|
|
70
|
+
};
|
|
71
|
+
return { ok: true };
|
|
72
|
+
}
|
|
73
|
+
function decideAttentionAllowance(caller) {
|
|
74
|
+
return refuseByRole(attentionRoute(caller));
|
|
75
|
+
}
|
|
76
|
+
function decideEditAllowance(caller) {
|
|
77
|
+
return refuseByRole(editRoute(caller));
|
|
78
|
+
}
|
|
79
|
+
function describePushRouteRefusal(caller) {
|
|
80
|
+
const route = pushRoute(caller);
|
|
81
|
+
if (route.answers) return null;
|
|
82
|
+
return {
|
|
83
|
+
status: PUSH_REFUSED_STATUS,
|
|
84
|
+
body: {
|
|
85
|
+
ok: false,
|
|
86
|
+
reason: route.code,
|
|
87
|
+
error: route.reason
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function isAgentApiVerb(verb) {
|
|
92
|
+
return AGENT_API_VERBS.includes(verb);
|
|
93
|
+
}
|
|
94
|
+
function refuseInvalidBody(issues) {
|
|
95
|
+
return {
|
|
96
|
+
ok: false,
|
|
97
|
+
status: INVALID_BODY_STATUS,
|
|
98
|
+
error: issues[0]?.message || "invalid request"
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseAgentVerb(verb, payload) {
|
|
102
|
+
if (!isAgentApiVerb(verb)) return {
|
|
103
|
+
ok: false,
|
|
104
|
+
status: 404,
|
|
105
|
+
error: REFUSAL_REASON
|
|
106
|
+
};
|
|
107
|
+
if (verb === "board" || verb === "push" || verb === "limits") return {
|
|
108
|
+
ok: true,
|
|
109
|
+
verb
|
|
110
|
+
};
|
|
111
|
+
if (verb === "attention") {
|
|
112
|
+
const parsed = AgentAttentionRequest.safeParse(payload);
|
|
113
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
114
|
+
return {
|
|
115
|
+
ok: true,
|
|
116
|
+
verb,
|
|
117
|
+
request: parsed.data
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (verb === "edit") {
|
|
121
|
+
const parsed = AgentEditRequest.safeParse(payload);
|
|
122
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
123
|
+
return {
|
|
124
|
+
ok: true,
|
|
125
|
+
verb,
|
|
126
|
+
request: parsed.data
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const parsed = AgentSpawnRequest.safeParse(payload);
|
|
130
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
131
|
+
return {
|
|
132
|
+
ok: true,
|
|
133
|
+
verb,
|
|
134
|
+
request: parsed.data
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function describePushLanding(landing) {
|
|
138
|
+
if (!landing.merged) {
|
|
139
|
+
const reason = landing.reason || "unknown";
|
|
140
|
+
const explain = PUSH_REFUSAL_COPY[reason];
|
|
141
|
+
return {
|
|
142
|
+
status: PUSH_REFUSED_STATUS,
|
|
143
|
+
body: {
|
|
144
|
+
ok: false,
|
|
145
|
+
reason,
|
|
146
|
+
error: explain ? explain(landing) : `the merge stopped: ${reason}`
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (landing.pushed) return {
|
|
151
|
+
status: 200,
|
|
152
|
+
body: {
|
|
153
|
+
ok: true,
|
|
154
|
+
landedOn: landing.base ?? null,
|
|
155
|
+
pushed: true
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
return {
|
|
159
|
+
status: 200,
|
|
160
|
+
body: {
|
|
161
|
+
ok: true,
|
|
162
|
+
landedOn: landing.base ?? null,
|
|
163
|
+
pushed: false,
|
|
164
|
+
note: "landed locally and nothing was pushed, because the repository has no origin remote or origin did not take a fast-forward"
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function deriveChildSessionName(parentName, existingNames) {
|
|
169
|
+
const base = `${String(parentName || "").trim() || "session"} agent`;
|
|
170
|
+
const taken = new Set(existingNames);
|
|
171
|
+
let candidate = base;
|
|
172
|
+
let suffix = 1;
|
|
173
|
+
while (taken.has(candidate)) {
|
|
174
|
+
suffix += 1;
|
|
175
|
+
candidate = `${base} ${suffix}`;
|
|
176
|
+
}
|
|
177
|
+
return candidate;
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
export { decideSpawnAllowance as a, describePushRouteRefusal as c, decideEditAllowance as i, isAgentApiVerb as l, decideAgentRequest as n, deriveChildSessionName as o, decideAttentionAllowance as r, describePushLanding as s, REFUSAL_REASON as t, parseAgentVerb as u };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as isMissingFileError, r as errorMessage } from "./text-DoirglWV.js";
|
|
2
|
-
import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-
|
|
3
|
-
import { p as writeTextAtomicSync } from "./json-file-
|
|
2
|
+
import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-DeGAXgZF.js";
|
|
3
|
+
import { p as writeTextAtomicSync } from "./json-file-DFCTvPjj.js";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
//#region server/agent-setup-cli.ts
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { s as loadConfigFile } from "./config-store-n23JDU4E.js";
|