glimmervoid 0.30.0 → 0.31.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/README.md +1 -1
- package/dist/bin/glimmervoid.js +140 -57
- package/dist/chunks/{adapters-Dho1VSY5.js → adapters-ClA_GbtA.js} +1 -1
- package/dist/chunks/{adapters-zPDx1Xox.js → adapters-gn7ulNO4.js} +32 -12
- package/dist/chunks/agent-api-cli-DAA7Jx8N.js +135 -0
- package/dist/chunks/{agent-api-core-Dz0r21y9.js → agent-api-core-hVcT26JW.js} +10 -1
- package/dist/chunks/{agent-setup-cli-B5Atxr3F.js → agent-setup-cli-CiJSDWSo.js} +11 -28
- package/dist/chunks/backoff-DjVpfHk7.js +14 -0
- package/dist/chunks/child-process-safe-BKPZ-5qQ.js +2 -0
- package/dist/chunks/coerce-NSst8oRP.js +32 -0
- package/dist/chunks/{contracts-DGkKNh9W.js → config-W1Sv-iPK.js} +358 -1682
- package/dist/chunks/{config-store-mm7MgzoL.js → config-store-BCy4FHNG.js} +583 -327
- package/dist/chunks/config-store-DbBp7LJZ.js +2 -0
- package/dist/chunks/contracts-3LkrilQX.js +2078 -0
- package/dist/chunks/{grok-DuU8xVLZ.js → grok-CXKeSt2z.js} +24 -20
- package/dist/chunks/{hook-relay-core-BHfYFnYV.js → hook-relay-core-DA_bz2KA.js} +10 -5
- package/dist/chunks/{hook-tools-pSJia7ks.js → hook-tools-UX2fmt81.js} +3 -5
- package/dist/chunks/{ingest-editor-core-BuI1gMF_.js → ingest-editor-core-vR6Wv6bP.js} +24 -13
- package/dist/chunks/json-core-dfa_7Fak.js +23 -0
- package/dist/chunks/json-file-oEH9vt-0.js +352 -0
- package/dist/chunks/knowledge-graph-cli-D2tt5hPn.js +1354 -0
- package/dist/chunks/{loopback-post-C7C22eYi.js → loopback-post-DepQfdcM.js} +40 -26
- package/dist/chunks/{main-CuIZQPhZ.js → main-DyTCWIu2.js} +28498 -21129
- package/dist/chunks/{node-pty-preflight-CK1knGIR.js → node-pty-preflight-C8QIlrtU.js} +4 -6
- package/dist/chunks/{pair-cli-w-gCAF-1.js → pair-cli-BbCBfd6l.js} +4 -3
- package/dist/chunks/paths-CeJl2Vcg.js +55 -0
- package/dist/chunks/{remote-config-C2ytQwrs.js → remote-config-DKIH_VxM.js} +36 -40
- package/dist/chunks/{rtk-hook-core-Bl6gYHPN.js → rtk-hook-core-BmEz2aq9.js} +3 -5
- package/dist/chunks/{rtk-resolver-CLo-gZzw.js → rtk-resolver-BGDzw5XK.js} +2 -2
- package/dist/chunks/rtk-resolver-D4Nke1Fr.js +2 -0
- package/dist/chunks/{runtime-paths-Ci_ksSkj.js → runtime-paths-BPoxENmK.js} +2 -6
- package/dist/chunks/runtime-paths-DU5jBEEO.js +2 -0
- package/dist/chunks/{sandbox-deps-Dd5-kZnf.js → sandbox-deps-BPKE-ylr.js} +16 -13
- package/dist/chunks/sandbox-proxy-core-hnQgKR0T.js +27 -0
- package/dist/chunks/{session-Cez8aIWg.js → session-fc4pFbon.js} +8 -2
- package/dist/chunks/text-DoirglWV.js +21 -0
- package/dist/chunks/timer-deps-u2DAQLok.js +15 -0
- package/dist/chunks/{visions-cli-BXQFIBCX.js → visions-cli-CT5rjiwf.js} +1 -1
- package/dist/chunks/{visions-setup-CvVnOe1r.js → visions-setup-BmOkI-QE.js} +20 -357
- package/dist/client/assets/index-C6KD8lgZ.css +1 -0
- package/dist/client/assets/index-CThQEAEy.js +249 -0
- package/dist/client/fonts/CommitMono-OFL.txt +92 -0
- package/dist/client/fonts/commit-mono-400-italic.woff2 +0 -0
- package/dist/client/fonts/commit-mono-400-regular.woff2 +0 -0
- package/dist/client/fonts/commit-mono-700-italic.woff2 +0 -0
- package/dist/client/fonts/commit-mono-700-regular.woff2 +0 -0
- package/dist/client/index.html +7 -24
- package/dist/client/octicons-LICENSE.txt +21 -0
- package/dist/scripts/postinstall-path-check.js +1 -1
- package/dist/server/index.js +3 -3
- package/dist/session/command-hook-relay.js +1 -1
- package/dist/session/hook-relay.js +3 -3
- package/dist/session/hook-tool-relay.js +2 -2
- package/dist/session/sandbox-open-launcher.js +79 -0
- package/dist/session/statusline-relay.js +8 -18
- package/dist/session/visions-relay.js +20 -11
- package/package.json +4 -1
- package/dist/chunks/agent-api-cli-D0MmtEdz.js +0 -71
- package/dist/chunks/child-process-safe-DvQjXsgz.js +0 -2
- package/dist/chunks/config-store-CC8T3okC.js +0 -2
- package/dist/chunks/ingest-core-DWI1Mbu4.js +0 -342
- package/dist/chunks/rtk-resolver-CMQAidlI.js +0 -2
- package/dist/chunks/runtime-paths-JLrZ3wyi.js +0 -2
- package/dist/client/assets/index-B1MFijjb.css +0 -1
- package/dist/client/assets/index-CU1iPPdn.js +0 -249
- package/dist/chunks/{child-process-safe-DRGsp0TE.js → child-process-safe-Ch-Zgxqs.js} +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ Update a clone with `git pull --ff-only && npm ci && npm run build`, then restar
|
|
|
57
57
|
- **Claude Code CLI** on PATH, or another supported agent below.
|
|
58
58
|
- **git** on PATH, for per-session worktrees.
|
|
59
59
|
- **Linux only:** `build-essential` and `python3` for node-pty.
|
|
60
|
-
- **Linux only:** `bubblewrap` (`bwrap`) and `
|
|
60
|
+
- **Linux only:** `bubblewrap` (`bwrap`), `socat` and `ripgrep` (`rg`) for the sandbox that sandboxed sessions and factory checks run in (`sudo apt install bubblewrap socat ripgrep`). `glimmervoid doctor` reports all three.
|
|
61
61
|
|
|
62
62
|
## Supported agents
|
|
63
63
|
|
package/dist/bin/glimmervoid.js
CHANGED
|
@@ -1,15 +1,93 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { o as nodePtyRebuildHint, t as probeNodePty } from "../chunks/node-pty-preflight-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { o as nodePtyRebuildHint, r as firstLine, t as probeNodePty } from "../chunks/node-pty-preflight-C8QIlrtU.js";
|
|
3
|
+
import { i as errorText } from "../chunks/text-DoirglWV.js";
|
|
4
|
+
import { a as packageRoot } from "../chunks/runtime-paths-BPoxENmK.js";
|
|
5
|
+
import { t as AGENT_API_VERBS } from "../chunks/session-fc4pFbon.js";
|
|
6
|
+
import { i as execSync } from "../chunks/child-process-safe-Ch-Zgxqs.js";
|
|
6
7
|
import { t as renderTable } from "../chunks/ascii-figure-core-pDAwtlKO.js";
|
|
7
8
|
import { n as glimmervoidHomeDir, t as decideConfigPath } from "../chunks/config-path-core-DFt-TemS.js";
|
|
8
|
-
import { i as sandboxDoctorRows, r as probeSandboxDependencies } from "../chunks/sandbox-deps-
|
|
9
|
+
import { i as sandboxDoctorRows, r as probeSandboxDependencies } from "../chunks/sandbox-deps-BPKE-ylr.js";
|
|
9
10
|
import { i as pnpmGlobalBinDir, n as npmGlobalBinDir, r as onPath, t as formatPathNotice } from "../chunks/path-doctor-C23VAqeu.js";
|
|
10
11
|
import fs from "node:fs";
|
|
11
12
|
import path from "node:path";
|
|
12
13
|
import os from "node:os";
|
|
14
|
+
//#region server/core/command-line-core.ts
|
|
15
|
+
var SUBCOMMANDS_HONORING_TRAILING_GLOBAL_OPTIONS = /* @__PURE__ */ new Set([
|
|
16
|
+
"doctor",
|
|
17
|
+
"pair",
|
|
18
|
+
"visions"
|
|
19
|
+
]);
|
|
20
|
+
var SUBCOMMANDS_HONORING_A_LEADING_HELP_OR_VERSION = new Set(AGENT_API_VERBS);
|
|
21
|
+
var OPTIONS_TAKING_A_VALUE = {
|
|
22
|
+
"--config": "configPath",
|
|
23
|
+
"--port": "port"
|
|
24
|
+
};
|
|
25
|
+
function scanGlobalOption(argv, index, state) {
|
|
26
|
+
const token = argv[index];
|
|
27
|
+
const valueKey = OPTIONS_TAKING_A_VALUE[token];
|
|
28
|
+
if (valueKey) {
|
|
29
|
+
const value = argv[index + 1];
|
|
30
|
+
if (value !== void 0) state[valueKey] = value;
|
|
31
|
+
return index + 2;
|
|
32
|
+
}
|
|
33
|
+
if (token === "--help" || token === "-h") state.wantsHelp = true;
|
|
34
|
+
if (token === "--version") state.wantsVersion = true;
|
|
35
|
+
if (token === "--doctor") state.wantsDoctor = true;
|
|
36
|
+
return index + 1;
|
|
37
|
+
}
|
|
38
|
+
function scanTrailingGlobalOptions(subcommandArgs, state) {
|
|
39
|
+
let index = 0;
|
|
40
|
+
while (index < subcommandArgs.length) {
|
|
41
|
+
if (!subcommandArgs[index].startsWith("-")) {
|
|
42
|
+
index += 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
index = scanGlobalOption(subcommandArgs, index, state);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function scanLeadingHelpOrVersion(subcommandArgs, state) {
|
|
49
|
+
const firstArgument = subcommandArgs[0];
|
|
50
|
+
if (firstArgument === "--help" || firstArgument === "-h") state.wantsHelp = true;
|
|
51
|
+
if (firstArgument === "--version") state.wantsVersion = true;
|
|
52
|
+
}
|
|
53
|
+
function parseCommandLine(argv) {
|
|
54
|
+
const state = {
|
|
55
|
+
configPath: null,
|
|
56
|
+
port: null,
|
|
57
|
+
wantsHelp: false,
|
|
58
|
+
wantsVersion: false,
|
|
59
|
+
wantsDoctor: false
|
|
60
|
+
};
|
|
61
|
+
let index = 0;
|
|
62
|
+
while (index < argv.length && argv[index].startsWith("-")) index = scanGlobalOption(argv, index, state);
|
|
63
|
+
const name = argv[index];
|
|
64
|
+
const subcommandArgs = argv.slice(index + 1);
|
|
65
|
+
if (name !== void 0 && SUBCOMMANDS_HONORING_TRAILING_GLOBAL_OPTIONS.has(name)) scanTrailingGlobalOptions(subcommandArgs, state);
|
|
66
|
+
if (name !== void 0 && SUBCOMMANDS_HONORING_A_LEADING_HELP_OR_VERSION.has(name)) scanLeadingHelpOrVersion(subcommandArgs, state);
|
|
67
|
+
if (state.wantsHelp) return { kind: "help" };
|
|
68
|
+
if (state.wantsVersion) return { kind: "version" };
|
|
69
|
+
const globalOptions = {
|
|
70
|
+
configPath: state.configPath,
|
|
71
|
+
port: state.port
|
|
72
|
+
};
|
|
73
|
+
if (state.wantsDoctor) return {
|
|
74
|
+
kind: "subcommand",
|
|
75
|
+
name: "doctor",
|
|
76
|
+
subcommandArgs: [],
|
|
77
|
+
globalOptions
|
|
78
|
+
};
|
|
79
|
+
if (name === void 0) return {
|
|
80
|
+
kind: "server",
|
|
81
|
+
globalOptions
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
kind: "subcommand",
|
|
85
|
+
name,
|
|
86
|
+
subcommandArgs,
|
|
87
|
+
globalOptions
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
13
91
|
//#region bin/glimmervoid.ts
|
|
14
92
|
var args = process.argv.slice(2);
|
|
15
93
|
var pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
@@ -28,6 +106,7 @@ Commands:
|
|
|
28
106
|
spawn <prompt> From inside a Glimmervoid session, start a sibling session on that prompt
|
|
29
107
|
attention <note> From inside a Glimmervoid session, flag it as needing the operator
|
|
30
108
|
board From inside a Glimmervoid session, list the live sessions
|
|
109
|
+
kg [command] Experimental typed knowledge and task graph (Settings > Lanes > Knowledge graph)
|
|
31
110
|
|
|
32
111
|
Options:
|
|
33
112
|
--name <label> Label for the device being paired (with: pair)
|
|
@@ -35,71 +114,75 @@ Options:
|
|
|
35
114
|
--config <path> Path to config file (default: ~/.glimmervoid/config.json)
|
|
36
115
|
--version Show version number
|
|
37
116
|
--help, -h Show this help message`;
|
|
38
|
-
|
|
117
|
+
var commandLine = parseCommandLine(args);
|
|
118
|
+
if (commandLine.kind === "help") {
|
|
39
119
|
console.log(USAGE);
|
|
40
120
|
process.exit(0);
|
|
41
121
|
}
|
|
42
|
-
if (
|
|
122
|
+
if (commandLine.kind === "version") {
|
|
43
123
|
console.log(pkg.version);
|
|
44
124
|
process.exit(0);
|
|
45
125
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (idx !== -1 && idx + 1 < args.length) return args[idx + 1];
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
var configArg = getArgValue("--config");
|
|
52
|
-
if (configArg) process.env.GLIMMERVOID_CONFIG = configArg;
|
|
53
|
-
var portArg = getArgValue("--port");
|
|
54
|
-
if (portArg) process.env.GLIMMERVOID_PORT = portArg;
|
|
126
|
+
if (commandLine.globalOptions.configPath) process.env.GLIMMERVOID_CONFIG = commandLine.globalOptions.configPath;
|
|
127
|
+
if (commandLine.globalOptions.port) process.env.GLIMMERVOID_PORT = commandLine.globalOptions.port;
|
|
55
128
|
var SUBCOMMAND_RUNNERS = new Map([
|
|
56
129
|
["doctor", async () => {
|
|
57
130
|
await runDoctor();
|
|
58
131
|
return 0;
|
|
59
132
|
}],
|
|
60
|
-
["pair", async (
|
|
61
|
-
const { runPairCli } = await import("../chunks/pair-cli-
|
|
62
|
-
return runPairCli(
|
|
133
|
+
["pair", async (subcommandArgs) => {
|
|
134
|
+
const { runPairCli } = await import("../chunks/pair-cli-BbCBfd6l.js");
|
|
135
|
+
return runPairCli(subcommandArgs);
|
|
136
|
+
}],
|
|
137
|
+
["agent", async (subcommandArgs) => {
|
|
138
|
+
const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-CiJSDWSo.js");
|
|
139
|
+
return runAgentSetupCli(subcommandArgs);
|
|
63
140
|
}],
|
|
64
|
-
["
|
|
65
|
-
const {
|
|
66
|
-
return
|
|
141
|
+
["kg", async (subcommandArgs) => {
|
|
142
|
+
const { runKnowledgeGraphCommand } = await import("../chunks/knowledge-graph-cli-D2tt5hPn.js");
|
|
143
|
+
return runKnowledgeGraphCommand(subcommandArgs);
|
|
67
144
|
}],
|
|
68
|
-
["visions", async (
|
|
69
|
-
const { runVisionsCli } = await import("../chunks/visions-cli-
|
|
70
|
-
return runVisionsCli(
|
|
145
|
+
["visions", async (subcommandArgs) => {
|
|
146
|
+
const { runVisionsCli } = await import("../chunks/visions-cli-CT5rjiwf.js");
|
|
147
|
+
return runVisionsCli(subcommandArgs);
|
|
71
148
|
}],
|
|
72
|
-
...AGENT_API_VERBS.map((verb) => [verb, async (
|
|
73
|
-
const { runAgentApiCli } = await import("../chunks/agent-api-cli-
|
|
74
|
-
return runAgentApiCli(
|
|
149
|
+
...AGENT_API_VERBS.map((verb) => [verb, async (subcommandArgs, subcommandName) => {
|
|
150
|
+
const { runAgentApiCli } = await import("../chunks/agent-api-cli-DAA7Jx8N.js");
|
|
151
|
+
return runAgentApiCli([subcommandName, ...subcommandArgs]);
|
|
75
152
|
}])
|
|
76
153
|
]);
|
|
154
|
+
function flushStream(stream) {
|
|
155
|
+
return new Promise((resolve) => {
|
|
156
|
+
stream.once("error", () => resolve());
|
|
157
|
+
stream.write("", () => resolve());
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async function exitAfterOutputDrains(exitCode) {
|
|
161
|
+
await Promise.all([flushStream(process.stdout), flushStream(process.stderr)]);
|
|
162
|
+
process.exit(exitCode);
|
|
163
|
+
}
|
|
164
|
+
async function runSubcommandToExitCode(runSubcommand, subcommandArgs, subcommandName) {
|
|
165
|
+
try {
|
|
166
|
+
return await runSubcommand(subcommandArgs, subcommandName);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.error(errorText(err));
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
77
172
|
async function dispatchCommandLine() {
|
|
78
|
-
|
|
79
|
-
if (!requestedSubcommand || requestedSubcommand.startsWith("-")) {
|
|
173
|
+
if (commandLine.kind !== "subcommand") {
|
|
80
174
|
await import("../server/index.js");
|
|
81
175
|
return;
|
|
82
176
|
}
|
|
83
|
-
const runSubcommand = SUBCOMMAND_RUNNERS.get(
|
|
177
|
+
const runSubcommand = SUBCOMMAND_RUNNERS.get(commandLine.name);
|
|
84
178
|
if (!runSubcommand) {
|
|
85
|
-
console.error(`Unknown command: ${
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
process.exit(await runSubcommand(args));
|
|
90
|
-
} catch (err) {
|
|
91
|
-
console.error(messageOf(err));
|
|
92
|
-
process.exit(1);
|
|
179
|
+
console.error(`Unknown command: ${commandLine.name}\n${USAGE}`);
|
|
180
|
+
await exitAfterOutputDrains(1);
|
|
181
|
+
return;
|
|
93
182
|
}
|
|
183
|
+
await exitAfterOutputDrains(await runSubcommandToExitCode(runSubcommand, commandLine.subcommandArgs, commandLine.name));
|
|
94
184
|
}
|
|
95
185
|
await dispatchCommandLine();
|
|
96
|
-
function messageOf(error) {
|
|
97
|
-
if (error instanceof Error && error.message) return error.message;
|
|
98
|
-
return String(error);
|
|
99
|
-
}
|
|
100
|
-
function firstLineOf(error) {
|
|
101
|
-
return messageOf(error).split("\n")[0];
|
|
102
|
-
}
|
|
103
186
|
function decideReadOnlyConfigPath() {
|
|
104
187
|
return decideConfigPath({
|
|
105
188
|
env: process.env,
|
|
@@ -118,7 +201,7 @@ async function readDeclaredCustomAgents() {
|
|
|
118
201
|
declared: [],
|
|
119
202
|
error: null
|
|
120
203
|
};
|
|
121
|
-
const { loadConfigFile } = await import("../chunks/config-store-
|
|
204
|
+
const { loadConfigFile } = await import("../chunks/config-store-DbBp7LJZ.js");
|
|
122
205
|
try {
|
|
123
206
|
const loaded = loadConfigFile(decided.path, { exitOnError: false });
|
|
124
207
|
if (!loaded.config) return {
|
|
@@ -132,7 +215,7 @@ async function readDeclaredCustomAgents() {
|
|
|
132
215
|
} catch (err) {
|
|
133
216
|
return {
|
|
134
217
|
declared: [],
|
|
135
|
-
error: `could not read ${decided.path}: ${
|
|
218
|
+
error: `could not read ${decided.path}: ${firstLine(errorText(err))}`
|
|
136
219
|
};
|
|
137
220
|
}
|
|
138
221
|
}
|
|
@@ -194,7 +277,7 @@ async function runDoctor() {
|
|
|
194
277
|
}
|
|
195
278
|
switchSection("Agents");
|
|
196
279
|
try {
|
|
197
|
-
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-
|
|
280
|
+
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-ClA_GbtA.js");
|
|
198
281
|
const declaredCustomAgents = await readDeclaredCustomAgents();
|
|
199
282
|
if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
|
|
200
283
|
setCustomAgents(declaredCustomAgents.declared);
|
|
@@ -202,24 +285,24 @@ async function runDoctor() {
|
|
|
202
285
|
const { label, path: resolvedPath } = describeAgentResolvability(id);
|
|
203
286
|
line(`${id} (${label})`, resolvedPath ?? "not found on PATH");
|
|
204
287
|
}
|
|
205
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
288
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-CiJSDWSo.js");
|
|
206
289
|
const grokSetup = inspectGrokAgentSetup();
|
|
207
290
|
line("grok hook setup", `${grokSetup.classification}: ${grokSetup.filePath}`);
|
|
208
291
|
} catch (err) {
|
|
209
|
-
line("agents", `probe failed: ${
|
|
292
|
+
line("agents", `probe failed: ${firstLine(errorText(err))}`);
|
|
210
293
|
}
|
|
211
294
|
switchSection("rtk");
|
|
212
295
|
try {
|
|
213
|
-
const { getRtkPath } = await import("../chunks/rtk-resolver-
|
|
296
|
+
const { getRtkPath } = await import("../chunks/rtk-resolver-D4Nke1Fr.js");
|
|
214
297
|
line("rtk", getRtkPath() || "not installed (Glimmervoid installs it when the rtk setting is on)");
|
|
215
298
|
} catch (err) {
|
|
216
|
-
line("rtk", `probe failed: ${
|
|
299
|
+
line("rtk", `probe failed: ${firstLine(errorText(err))}`);
|
|
217
300
|
}
|
|
218
301
|
switchSection("Sane YOLO");
|
|
219
302
|
try {
|
|
220
|
-
const { resolvePackageBin } = await import("../chunks/runtime-paths-
|
|
221
|
-
const { execFileSync } = await import("../chunks/child-process-safe-
|
|
222
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
303
|
+
const { resolvePackageBin } = await import("../chunks/runtime-paths-DU5jBEEO.js");
|
|
304
|
+
const { execFileSync } = await import("../chunks/child-process-safe-BKPZ-5qQ.js");
|
|
305
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-CiJSDWSo.js");
|
|
223
306
|
const binPath = resolvePackageBin("cc-safety-net", "cc-safety-net");
|
|
224
307
|
line("Sane YOLO", binPath || "not installed");
|
|
225
308
|
if (binPath) line("cc-safety-net version", execFileSync(process.execPath, [binPath, "--version"], {
|
|
@@ -229,7 +312,7 @@ async function runDoctor() {
|
|
|
229
312
|
line("Codex hook trust", "Sane YOLO is inactive unless Codex trusts the injected hooks.");
|
|
230
313
|
line("Grok Sane YOLO", inspectGrokAgentSetup().saneYoloReady ? "installed" : "inactive; run glimmervoid agent setup grok");
|
|
231
314
|
} catch (err) {
|
|
232
|
-
line("Sane YOLO", `probe failed: ${
|
|
315
|
+
line("Sane YOLO", `probe failed: ${firstLine(errorText(err))}`);
|
|
233
316
|
}
|
|
234
317
|
switchSection("Native module");
|
|
235
318
|
const nodePty = await probeNodePty();
|
|
@@ -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-gn7ulNO4.js";
|
|
2
2
|
export { describeAgentResolvability, listAgentIds, setCustomAgents };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { o as relayPath } from "./runtime-paths-
|
|
2
|
-
import { _ as
|
|
3
|
-
import { r as execFileSync } from "./child-process-safe-
|
|
1
|
+
import { o as relayPath } from "./runtime-paths-BPoxENmK.js";
|
|
2
|
+
import { _ as firstDetailLine, l as PendingPromptQuestion, s as PROMPT_DETAIL_HIDDEN_CHARACTERS, v as toolDetailFieldValue } from "./session-fc4pFbon.js";
|
|
3
|
+
import { r as execFileSync } from "./child-process-safe-Ch-Zgxqs.js";
|
|
4
4
|
import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-command-Cc40FiZI.js";
|
|
5
|
-
import {
|
|
5
|
+
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
6
|
+
import { c as buildAgentEnv, i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, t as grok } from "./grok-CXKeSt2z.js";
|
|
6
7
|
import { t as buildHookCommand } from "./hook-command-core-DclEoE9e.js";
|
|
7
|
-
import "./contracts-
|
|
8
|
-
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-
|
|
8
|
+
import "./contracts-3LkrilQX.js";
|
|
9
|
+
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-UX2fmt81.js";
|
|
9
10
|
import fs from "node:fs";
|
|
10
11
|
//#region session/core/anti-slop-prompt.ts
|
|
11
12
|
var ANTI_SLOP_NOTE = [
|
|
@@ -87,9 +88,6 @@ function mapHookPromptDetail(event, payload) {
|
|
|
87
88
|
question: answerableQuestionOf(toolName, payload?.tool_input)
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
|
-
function isRecord(value) {
|
|
91
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
92
|
-
}
|
|
93
91
|
function answerableQuestionOf(toolName, toolInput) {
|
|
94
92
|
if (toolName !== "AskUserQuestion" || !isRecord(toolInput)) return null;
|
|
95
93
|
const questions = toolInput.questions;
|
|
@@ -123,6 +121,8 @@ function isWholeBashCommandShown(toolName, toolInput, fieldValue, summary) {
|
|
|
123
121
|
function mapHookToSignal$1(event, payload) {
|
|
124
122
|
switch (String(event || "").toLowerCase()) {
|
|
125
123
|
case "sessionstart": return "session-start";
|
|
124
|
+
case "precompact": return "compaction-start";
|
|
125
|
+
case "postcompact": return "compaction-end";
|
|
126
126
|
case "sessionend": return "session-end";
|
|
127
127
|
case "userpromptsubmit": return "resume";
|
|
128
128
|
case "stop": return "ready";
|
|
@@ -178,7 +178,15 @@ var settingsArgs = (settingsPath) => ["--settings", settingsPath];
|
|
|
178
178
|
function buildArgs$1({ dangerouslySkipPermissions = false, resumeSessionId = null, extraArgs = [], antiSlopPrompt = false, initialPrompt = null } = {}) {
|
|
179
179
|
const args = dangerouslySkipPermissions ? ["--dangerously-skip-permissions"] : [];
|
|
180
180
|
if (resumeSessionId) args.push("--resume", resumeSessionId);
|
|
181
|
-
|
|
181
|
+
for (let index = 0; index < extraArgs.length; index += 1) {
|
|
182
|
+
const argument = extraArgs[index];
|
|
183
|
+
if (resumeSessionId && argument === "--session-id") {
|
|
184
|
+
index += 1;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (resumeSessionId && argument.startsWith("--session-id=")) continue;
|
|
188
|
+
args.push(argument);
|
|
189
|
+
}
|
|
182
190
|
args.push(...buildAntiSlopArgs(antiSlopPrompt));
|
|
183
191
|
if (initialPrompt != null) args.push(initialPrompt);
|
|
184
192
|
return args;
|
|
@@ -344,10 +352,22 @@ var SKIP_PERMISSIONS_ARGS = [
|
|
|
344
352
|
"-s",
|
|
345
353
|
"workspace-write"
|
|
346
354
|
];
|
|
347
|
-
|
|
355
|
+
var OUTER_SANDBOX_ARGS = ["-s", "danger-full-access"];
|
|
356
|
+
var OUTER_SANDBOX_SKIP_PERMISSIONS_ARGS = [
|
|
357
|
+
"-a",
|
|
358
|
+
"never",
|
|
359
|
+
...OUTER_SANDBOX_ARGS
|
|
360
|
+
];
|
|
361
|
+
function permissionArgs(dangerouslySkipPermissions, hasOuterSandbox) {
|
|
362
|
+
if (hasOuterSandbox && dangerouslySkipPermissions) return OUTER_SANDBOX_SKIP_PERMISSIONS_ARGS;
|
|
363
|
+
if (hasOuterSandbox) return OUTER_SANDBOX_ARGS;
|
|
364
|
+
if (dangerouslySkipPermissions) return SKIP_PERMISSIONS_ARGS;
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
function buildArgs({ dangerouslySkipPermissions = false, resumeSessionId = null, extraArgs = [], initialPrompt = null, hasOuterSandbox = false } = {}) {
|
|
348
368
|
const args = [...UPDATE_CHECK_ARGS];
|
|
349
369
|
if (resumeSessionId) args.push("resume", resumeSessionId);
|
|
350
|
-
|
|
370
|
+
args.push(...permissionArgs(dangerouslySkipPermissions, hasOuterSandbox));
|
|
351
371
|
if (extraArgs.length > 0) args.push(...extraArgs);
|
|
352
372
|
if (initialPrompt != null) args.push(initialPrompt);
|
|
353
373
|
return args;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { t as errorCode } from "./text-DoirglWV.js";
|
|
2
|
+
import { a as AgentDispatchRequest, n as AGENT_URL_ENV } from "./session-fc4pFbon.js";
|
|
3
|
+
import { i as resolveHookTarget } from "./hook-relay-core-DA_bz2KA.js";
|
|
4
|
+
import { n as decideSandboxProxy } from "./sandbox-proxy-core-hnQgKR0T.js";
|
|
5
|
+
import { a as isAgentApiVerb } from "./agent-api-core-hVcT26JW.js";
|
|
6
|
+
import http from "node:http";
|
|
7
|
+
//#region server/agent-api-cli.ts
|
|
8
|
+
var AGENT_PATH_PREFIX = "/agent/";
|
|
9
|
+
var BODY_BUILDERS = {
|
|
10
|
+
spawn: (rest) => {
|
|
11
|
+
const prompt = rest.join(" ").trim();
|
|
12
|
+
return prompt ? { prompt } : null;
|
|
13
|
+
},
|
|
14
|
+
attention: (rest) => {
|
|
15
|
+
const note = rest.join(" ").trim();
|
|
16
|
+
return note ? { note } : null;
|
|
17
|
+
},
|
|
18
|
+
board: () => ({}),
|
|
19
|
+
dispatch: (rest) => {
|
|
20
|
+
const parsed = AgentDispatchRequest.safeParse(rest[0] === "--ready" ? { readyIntent: rest[1] } : { workId: rest[0] });
|
|
21
|
+
return parsed.success ? parsed.data : null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
function bodySaysOk(text) {
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(text);
|
|
27
|
+
return typeof parsed === "object" && parsed !== null && parsed.ok === true;
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function verbEndpoint(rawUrl, verb) {
|
|
33
|
+
const target = resolveHookTarget(rawUrl, verb, AGENT_PATH_PREFIX);
|
|
34
|
+
if (!target.url) return { ok: false };
|
|
35
|
+
const endpoint = new URL(target.url);
|
|
36
|
+
const token = endpoint.searchParams.get("t") || "";
|
|
37
|
+
endpoint.search = "";
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
endpoint,
|
|
41
|
+
token
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function postDirectly(endpoint, headers, bodyText) {
|
|
45
|
+
const response = await fetch(endpoint, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers,
|
|
48
|
+
body: bodyText
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
hasSuccessStatus: response.ok,
|
|
52
|
+
text: await response.text()
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function postThroughSandboxProxy(sandboxProxy, endpoint, headers, bodyText) {
|
|
56
|
+
const proxyHeaders = sandboxProxy.authorization ? { "proxy-authorization": sandboxProxy.authorization } : {};
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const request = http.request({
|
|
59
|
+
host: sandboxProxy.hostname,
|
|
60
|
+
port: sandboxProxy.port,
|
|
61
|
+
method: "POST",
|
|
62
|
+
path: endpoint.href,
|
|
63
|
+
headers: {
|
|
64
|
+
...headers,
|
|
65
|
+
...proxyHeaders,
|
|
66
|
+
host: endpoint.host,
|
|
67
|
+
"content-length": String(Buffer.byteLength(bodyText))
|
|
68
|
+
}
|
|
69
|
+
}, (response) => {
|
|
70
|
+
const chunks = [];
|
|
71
|
+
response.on("data", (chunk) => {
|
|
72
|
+
chunks.push(chunk);
|
|
73
|
+
});
|
|
74
|
+
response.on("error", reject);
|
|
75
|
+
response.on("end", () => {
|
|
76
|
+
const statusCode = response.statusCode ?? 0;
|
|
77
|
+
resolve({
|
|
78
|
+
hasSuccessStatus: statusCode >= 200 && statusCode < 300,
|
|
79
|
+
text: Buffer.concat(chunks).toString("utf8")
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
request.on("error", reject);
|
|
84
|
+
request.end(bodyText);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function wasConnectionRefused(error) {
|
|
88
|
+
return errorCode(error?.cause) === "ECONNREFUSED";
|
|
89
|
+
}
|
|
90
|
+
async function postToAgentIngress(endpoint, token, body) {
|
|
91
|
+
const headers = {
|
|
92
|
+
"content-type": "application/json",
|
|
93
|
+
authorization: `Bearer ${token}`
|
|
94
|
+
};
|
|
95
|
+
const bodyText = JSON.stringify(body);
|
|
96
|
+
try {
|
|
97
|
+
return await postDirectly(endpoint, headers, bodyText);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (!wasConnectionRefused(error)) throw error;
|
|
100
|
+
const sandboxProxy = decideSandboxProxy(process.env);
|
|
101
|
+
if (!sandboxProxy) throw error;
|
|
102
|
+
return postThroughSandboxProxy(sandboxProxy, endpoint, headers, bodyText);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function runAgentApiCli(args) {
|
|
106
|
+
const verb = args[0];
|
|
107
|
+
if (!verb || !isAgentApiVerb(verb)) {
|
|
108
|
+
console.error(`glimmervoid: ${verb || "that"} is not an agent command`);
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
const body = BODY_BUILDERS[verb](args.slice(1));
|
|
112
|
+
if (!body) {
|
|
113
|
+
if (verb === "dispatch") {
|
|
114
|
+
console.error("glimmervoid dispatch: expected a work id matching wrk-[0-9a-f]{16}");
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
console.error(`glimmervoid ${verb}: this command needs text, for example "glimmervoid ${verb} check the failing test"`);
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
const rawUrl = process.env[AGENT_URL_ENV];
|
|
121
|
+
if (!rawUrl) {
|
|
122
|
+
console.error(`glimmervoid: ${AGENT_URL_ENV} is not set, so this is not a Glimmervoid session with the agent API turned on`);
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
const target = verbEndpoint(rawUrl, verb);
|
|
126
|
+
if (!target.ok) {
|
|
127
|
+
console.error(`glimmervoid: ${AGENT_URL_ENV} must be a loopback http url under ${AGENT_PATH_PREFIX}, so nothing was sent`);
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
const reply = await postToAgentIngress(target.endpoint, target.token, body);
|
|
131
|
+
console.log(reply.text);
|
|
132
|
+
return reply.hasSuccessStatus && bodySaysOk(reply.text) ? 0 : 1;
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { runAgentApiCli };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as AgentDispatchRequest, i as AgentAttentionRequest, o as AgentSpawnRequest, t as AGENT_API_VERBS } from "./session-fc4pFbon.js";
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
var MAX_SPAWNS_IN_FLIGHT = 1;
|
|
4
4
|
var SPAWNABLE_DEPTH = 0;
|
|
@@ -67,6 +67,15 @@ function parseAgentVerb(verb, payload) {
|
|
|
67
67
|
status: 404,
|
|
68
68
|
error: REFUSAL_REASON
|
|
69
69
|
};
|
|
70
|
+
if (verb === "dispatch") {
|
|
71
|
+
const parsed = AgentDispatchRequest.safeParse(payload);
|
|
72
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
73
|
+
return {
|
|
74
|
+
ok: true,
|
|
75
|
+
verb,
|
|
76
|
+
request: parsed.data
|
|
77
|
+
};
|
|
78
|
+
}
|
|
70
79
|
if (verb === "board") return {
|
|
71
80
|
ok: true,
|
|
72
81
|
verb
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import { a as
|
|
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-CXKeSt2z.js";
|
|
3
|
+
import { p as writeTextAtomicSync } from "./json-file-oEH9vt-0.js";
|
|
2
4
|
import fs from "node:fs";
|
|
3
5
|
import path from "node:path";
|
|
4
|
-
import crypto from "node:crypto";
|
|
5
6
|
//#region server/agent-setup-cli.ts
|
|
6
7
|
var USAGE = "Usage: glimmervoid agent setup grok";
|
|
7
|
-
function errorCode(error) {
|
|
8
|
-
const code = error?.code;
|
|
9
|
-
return typeof code === "string" ? code : void 0;
|
|
10
|
-
}
|
|
11
|
-
function errorMessage(error) {
|
|
12
|
-
return error instanceof Error ? error.message : String(error);
|
|
13
|
-
}
|
|
14
8
|
function setupInputs(env = process.env) {
|
|
15
9
|
return {
|
|
16
10
|
filePath: grok.hooksFilePath(env),
|
|
@@ -26,7 +20,7 @@ function inspectGrokAgentSetup({ env = process.env, readFileSync = fs.readFileSy
|
|
|
26
20
|
try {
|
|
27
21
|
contents = readFileSync(inputs.filePath, "utf8");
|
|
28
22
|
} catch (error) {
|
|
29
|
-
if (
|
|
23
|
+
if (isMissingFileError(error, { includeNotDir: false })) return {
|
|
30
24
|
filePath: inputs.filePath,
|
|
31
25
|
classification: "absent"
|
|
32
26
|
};
|
|
@@ -59,7 +53,7 @@ function ensureWritableHooksDirectory(directory, fileSystem) {
|
|
|
59
53
|
assertRealDirectory(currentDirectory, fileSystem);
|
|
60
54
|
continue;
|
|
61
55
|
} catch (directoryError) {
|
|
62
|
-
if (
|
|
56
|
+
if (!isMissingFileError(directoryError, { includeNotDir: false })) throw directoryError;
|
|
63
57
|
}
|
|
64
58
|
fileSystem.mkdirSync(currentDirectory, { mode: 448 });
|
|
65
59
|
assertRealDirectory(currentDirectory, fileSystem);
|
|
@@ -69,23 +63,12 @@ function ensureWritableHooksDirectory(directory, fileSystem) {
|
|
|
69
63
|
} catch {}
|
|
70
64
|
}
|
|
71
65
|
function replaceFileAtomically(filePath, contents, fileSystem) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
fileSystem.renameSync(temporaryPath, filePath);
|
|
80
|
-
} catch (writeError) {
|
|
81
|
-
try {
|
|
82
|
-
fileSystem.rmSync(temporaryPath, { force: true });
|
|
83
|
-
} catch {}
|
|
84
|
-
throw writeError;
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
fileSystem.chmodSync(filePath, 384);
|
|
88
|
-
} catch {}
|
|
66
|
+
writeTextAtomicSync(filePath, contents, {
|
|
67
|
+
mode: 384,
|
|
68
|
+
exclusive: true,
|
|
69
|
+
enforceMode: true,
|
|
70
|
+
fsSync: fileSystem
|
|
71
|
+
});
|
|
89
72
|
}
|
|
90
73
|
function runGrokSetup({ env, fileSystem, log, error }) {
|
|
91
74
|
const inputs = setupInputs(env);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region shared/backoff.ts
|
|
2
|
+
var DEFAULT_BASE_MS = 6e4;
|
|
3
|
+
var DEFAULT_MAX_MS = 18e5;
|
|
4
|
+
var MAX_DOUBLING_ATTEMPT = 20;
|
|
5
|
+
function nextBackoffMs({ attempt = 1, baseMs = DEFAULT_BASE_MS, maxMs = DEFAULT_MAX_MS, retryAfterMs = null, random = Math.random, jitter = "full" } = {}) {
|
|
6
|
+
if (typeof retryAfterMs === "number" && Number.isFinite(retryAfterMs) && retryAfterMs > 0) return Math.min(retryAfterMs, maxMs);
|
|
7
|
+
const exponent = Math.max(0, Math.min(attempt, MAX_DOUBLING_ATTEMPT) - 1);
|
|
8
|
+
const ceiling = Math.min(maxMs, baseMs * 2 ** exponent);
|
|
9
|
+
if (jitter === "none") return ceiling;
|
|
10
|
+
if (jitter === "half") return Math.round(ceiling * (.5 + .5 * random()));
|
|
11
|
+
return Math.round(random() * ceiling);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { DEFAULT_MAX_MS as n, nextBackoffMs as r, DEFAULT_BASE_MS as t };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region shared/coerce.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function textOr(value, fallback) {
|
|
6
|
+
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
7
|
+
}
|
|
8
|
+
function rawTextOr(value, fallback) {
|
|
9
|
+
return typeof value === "string" && value.length > 0 ? value : fallback;
|
|
10
|
+
}
|
|
11
|
+
function numberOr(value, fallback) {
|
|
12
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
13
|
+
}
|
|
14
|
+
function positiveNumberOr(value, fallback) {
|
|
15
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
16
|
+
}
|
|
17
|
+
function nonNegativeIntOr(value, fallback) {
|
|
18
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return fallback;
|
|
19
|
+
return Math.floor(value);
|
|
20
|
+
}
|
|
21
|
+
function coercedNumberOr(value, fallback) {
|
|
22
|
+
const number = Number(value);
|
|
23
|
+
if (!Number.isFinite(number)) return fallback;
|
|
24
|
+
return number;
|
|
25
|
+
}
|
|
26
|
+
function positiveIntOr(value, fallback) {
|
|
27
|
+
const number = Number(value);
|
|
28
|
+
if (!Number.isFinite(number) || number <= 0) return fallback;
|
|
29
|
+
return Math.floor(number);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { positiveIntOr as a, textOr as c, numberOr as i, isRecord as n, positiveNumberOr as o, nonNegativeIntOr as r, rawTextOr as s, coercedNumberOr as t };
|