@tryglen/cli 0.5.2 → 0.6.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/README.md +3 -3
- package/dist/_utils/agents-table.d.ts +10 -0
- package/dist/_utils/agents-table.js +26 -0
- package/dist/_utils/agents-table.js.map +1 -0
- package/dist/_utils/cli-error.d.ts +11 -0
- package/dist/_utils/cli-error.js +24 -0
- package/dist/_utils/cli-error.js.map +1 -0
- package/dist/_utils/codex-app-server.js +4 -1
- package/dist/_utils/codex-app-server.js.map +1 -1
- package/dist/_utils/config.js +3 -1
- package/dist/_utils/config.js.map +1 -1
- package/dist/_utils/credentials.d.ts +1 -1
- package/dist/_utils/credentials.js +8 -3
- package/dist/_utils/credentials.js.map +1 -1
- package/dist/_utils/ensure-global-cli.d.ts +7 -5
- package/dist/_utils/ensure-global-cli.js +47 -17
- package/dist/_utils/ensure-global-cli.js.map +1 -1
- package/dist/_utils/find-bin.d.ts +6 -0
- package/dist/_utils/find-bin.js +85 -0
- package/dist/_utils/find-bin.js.map +1 -0
- package/dist/_utils/http.d.ts +10 -3
- package/dist/_utils/http.js +56 -5
- package/dist/_utils/http.js.map +1 -1
- package/dist/_utils/loopback-server.d.ts +1 -1
- package/dist/_utils/loopback-server.js +17 -2
- package/dist/_utils/loopback-server.js.map +1 -1
- package/dist/_utils/open-browser.js +3 -0
- package/dist/_utils/open-browser.js.map +1 -1
- package/dist/_utils/plugin-status.d.ts +4 -0
- package/dist/_utils/plugin-status.js +23 -0
- package/dist/_utils/plugin-status.js.map +1 -0
- package/dist/_utils/run-bin.d.ts +13 -0
- package/dist/_utils/run-bin.js +51 -0
- package/dist/_utils/run-bin.js.map +1 -0
- package/dist/_utils/state-line.js +3 -1
- package/dist/_utils/state-line.js.map +1 -1
- package/dist/_utils/state.d.ts +1 -1
- package/dist/_utils/state.js +8 -2
- package/dist/_utils/state.js.map +1 -1
- package/dist/_utils/update.d.ts +20 -2
- package/dist/_utils/update.js +111 -15
- package/dist/_utils/update.js.map +1 -1
- package/dist/_utils/version.js +12 -1
- package/dist/_utils/version.js.map +1 -1
- package/dist/_utils/which.d.ts +3 -2
- package/dist/_utils/which.js +5 -12
- package/dist/_utils/which.js.map +1 -1
- package/dist/bin.js +44 -22
- package/dist/bin.js.map +1 -1
- package/dist/commands/doctor.d.ts +6 -3
- package/dist/commands/doctor.js +68 -54
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/incognito.d.ts +2 -1
- package/dist/commands/incognito.js +16 -4
- package/dist/commands/incognito.js.map +1 -1
- package/dist/commands/ingest.d.ts +1 -5
- package/dist/commands/ingest.js +47 -16
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/install.d.ts +5 -1
- package/dist/commands/install.js +114 -62
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +2 -1
- package/dist/commands/login.js +41 -10
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts +2 -1
- package/dist/commands/logout.js +20 -5
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/onboard.d.ts +2 -1
- package/dist/commands/onboard.js +7 -3
- package/dist/commands/onboard.js.map +1 -1
- package/dist/commands/org.d.ts +3 -2
- package/dist/commands/org.js +40 -9
- package/dist/commands/org.js.map +1 -1
- package/dist/commands/search.d.ts +2 -4
- package/dist/commands/search.js +25 -16
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/session-start.d.ts +6 -3
- package/dist/commands/session-start.js +16 -6
- package/dist/commands/session-start.js.map +1 -1
- package/dist/commands/status.d.ts +2 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.d.ts +7 -5
- package/dist/commands/statusline.js +18 -8
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/uninstall.d.ts +2 -1
- package/dist/commands/uninstall.js +8 -3
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts +10 -3
- package/dist/commands/update.js +111 -12
- package/dist/commands/update.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { cac } from "cac";
|
|
3
|
+
import { formatCliError } from "./_utils/cli-error.js";
|
|
3
4
|
import { cliVersion } from "./_utils/version.js";
|
|
4
5
|
const cli = cac("glen");
|
|
5
6
|
cli.command("login", "Connect glen via browser sign-in").action(async () => {
|
|
6
7
|
const { login } = await import("./commands/login.js");
|
|
7
8
|
const result = await login();
|
|
8
9
|
if (!result.ok) {
|
|
9
|
-
process.stderr.write(
|
|
10
|
+
process.stderr.write(formatCliError(result.error));
|
|
10
11
|
process.exit(1);
|
|
11
12
|
}
|
|
12
13
|
});
|
|
@@ -16,7 +17,7 @@ cli
|
|
|
16
17
|
const { logout } = await import("./commands/logout.js");
|
|
17
18
|
const result = await logout();
|
|
18
19
|
if (!result.ok) {
|
|
19
|
-
process.stderr.write(
|
|
20
|
+
process.stderr.write(formatCliError(result.error));
|
|
20
21
|
process.exit(1);
|
|
21
22
|
}
|
|
22
23
|
});
|
|
@@ -32,8 +33,8 @@ cli
|
|
|
32
33
|
const { search } = await import("./commands/search.js");
|
|
33
34
|
const result = await search(query);
|
|
34
35
|
if (!result.ok) {
|
|
35
|
-
process.stderr.write(
|
|
36
|
-
process.exit(
|
|
36
|
+
process.stderr.write(formatCliError(result.error));
|
|
37
|
+
process.exit(1);
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
cli
|
|
@@ -42,7 +43,7 @@ cli
|
|
|
42
43
|
const { incognito } = await import("./commands/incognito.js");
|
|
43
44
|
const r = await incognito(state);
|
|
44
45
|
if (!r.ok) {
|
|
45
|
-
process.stderr.write(
|
|
46
|
+
process.stderr.write(formatCliError(r.error));
|
|
46
47
|
process.exit(1);
|
|
47
48
|
}
|
|
48
49
|
});
|
|
@@ -50,10 +51,15 @@ cli
|
|
|
50
51
|
.command("ingest", "Ingest a turn from stdin (used by agent hooks)")
|
|
51
52
|
.option("--agent <agent>", "Agent type: claude-code | codex")
|
|
52
53
|
.action(async (options) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
try {
|
|
55
|
+
const { ingest } = await import("./commands/ingest.js");
|
|
56
|
+
await ingest(options.agent);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Hook must never block a prompt — swallow and exit clean. ingest
|
|
60
|
+
// itself emits agent-facing hints for every known failure mode.
|
|
61
|
+
}
|
|
62
|
+
process.exit(0);
|
|
57
63
|
});
|
|
58
64
|
cli
|
|
59
65
|
.command("org <action> [slug]", "Manage organizations: list | switch [slug]")
|
|
@@ -62,7 +68,7 @@ cli
|
|
|
62
68
|
const { orgList } = await import("./commands/org.js");
|
|
63
69
|
const r = await orgList();
|
|
64
70
|
if (!r.ok) {
|
|
65
|
-
process.stderr.write(
|
|
71
|
+
process.stderr.write(formatCliError(r.error));
|
|
66
72
|
process.exit(1);
|
|
67
73
|
}
|
|
68
74
|
return;
|
|
@@ -71,7 +77,7 @@ cli
|
|
|
71
77
|
const { orgSwitch } = await import("./commands/org.js");
|
|
72
78
|
const r = await orgSwitch(slug);
|
|
73
79
|
if (!r.ok) {
|
|
74
|
-
process.stderr.write(
|
|
80
|
+
process.stderr.write(formatCliError(r.error));
|
|
75
81
|
process.exit(1);
|
|
76
82
|
}
|
|
77
83
|
return;
|
|
@@ -82,38 +88,52 @@ cli
|
|
|
82
88
|
cli
|
|
83
89
|
.command("install", "Detect coding agents and install glen plugins")
|
|
84
90
|
.option("--agent <agent>", "Install for one agent non-interactively: claude (alias: claude-code) | codex")
|
|
91
|
+
.option("--codex-path <path>", "Absolute path to the codex binary (when auto-detection fails)")
|
|
92
|
+
.option("--claude-path <path>", "Absolute path to the claude binary (when auto-detection fails)")
|
|
85
93
|
.action(async (options) => {
|
|
86
|
-
// cac yields `true` for a bare
|
|
87
|
-
// it reaches install (which expects a string
|
|
94
|
+
// cac yields `true` for a bare flag with no value — reject it before
|
|
95
|
+
// it reaches install (which expects a string or undefined).
|
|
88
96
|
if (options.agent === true) {
|
|
89
97
|
process.stderr.write("glen install: --agent requires a value (claude | codex)\n");
|
|
90
98
|
process.exit(1);
|
|
91
99
|
}
|
|
100
|
+
if (options.codexPath === true || options.claudePath === true) {
|
|
101
|
+
process.stderr.write("glen install: --codex-path/--claude-path require a value (an absolute path to the binary)\n");
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
92
104
|
const agent = typeof options.agent === "string" ? options.agent : undefined;
|
|
93
105
|
const { install } = await import("./commands/install.js");
|
|
94
|
-
const result = await install(agent
|
|
95
|
-
|
|
106
|
+
const result = await install(agent, {
|
|
107
|
+
codex: typeof options.codexPath === "string" ? options.codexPath : undefined,
|
|
108
|
+
claude: typeof options.claudePath === "string"
|
|
109
|
+
? options.claudePath
|
|
110
|
+
: undefined,
|
|
111
|
+
});
|
|
112
|
+
if (!result.ok) {
|
|
113
|
+
process.stderr.write(formatCliError(result.error));
|
|
96
114
|
process.exit(1);
|
|
115
|
+
}
|
|
97
116
|
});
|
|
98
117
|
cli
|
|
99
118
|
.command("uninstall", "Remove glen hooks from Codex's user config and print plugin removal steps")
|
|
100
119
|
.action(async () => {
|
|
101
120
|
const { uninstall } = await import("./commands/uninstall.js");
|
|
102
121
|
const result = await uninstall();
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
if (!result.ok) {
|
|
123
|
+
process.stderr.write(formatCliError(result.error));
|
|
105
124
|
process.exit(1);
|
|
125
|
+
}
|
|
106
126
|
});
|
|
107
127
|
cli.command("version", "Print the CLI version").action(() => {
|
|
108
128
|
process.stdout.write(`${cliVersion}\n`);
|
|
109
129
|
});
|
|
110
130
|
cli
|
|
111
|
-
.command("update", "Update the glen CLI
|
|
131
|
+
.command("update", "Update the glen CLI and any installed glen plugins")
|
|
112
132
|
.action(async () => {
|
|
113
133
|
const { update } = await import("./commands/update.js");
|
|
114
134
|
const result = await update();
|
|
115
135
|
if (!result.ok) {
|
|
116
|
-
process.stderr.write(
|
|
136
|
+
process.stderr.write(formatCliError(result.error));
|
|
117
137
|
process.exit(1);
|
|
118
138
|
}
|
|
119
139
|
});
|
|
@@ -124,7 +144,7 @@ cli
|
|
|
124
144
|
const { doctor } = await import("./commands/doctor.js");
|
|
125
145
|
const result = await doctor(options.auto === true);
|
|
126
146
|
if (!result.ok) {
|
|
127
|
-
process.stderr.write(
|
|
147
|
+
process.stderr.write(formatCliError(result.error));
|
|
128
148
|
process.exit(1);
|
|
129
149
|
}
|
|
130
150
|
});
|
|
@@ -137,7 +157,7 @@ cli
|
|
|
137
157
|
}
|
|
138
158
|
catch {
|
|
139
159
|
// Statusline must never break the host UI — output the safe fallback.
|
|
140
|
-
process.stdout.write(
|
|
160
|
+
process.stdout.write('🏔️ glen — ask me to "set up glen"');
|
|
141
161
|
}
|
|
142
162
|
process.exit(0);
|
|
143
163
|
});
|
|
@@ -154,7 +174,7 @@ cli
|
|
|
154
174
|
process.stdout.write(JSON.stringify({
|
|
155
175
|
hookSpecificOutput: {
|
|
156
176
|
hookEventName: "SessionStart",
|
|
157
|
-
additionalContext: "[glen] not
|
|
177
|
+
additionalContext: "[glen] not set up — use the glen-setup skill",
|
|
158
178
|
},
|
|
159
179
|
}));
|
|
160
180
|
}
|
|
@@ -164,7 +184,9 @@ cli
|
|
|
164
184
|
// without blocking the calling turn.
|
|
165
185
|
cli.command("__self-update", "(internal)").action(async () => {
|
|
166
186
|
const { runSelfUpdate } = await import("./_utils/update.js");
|
|
187
|
+
// Detached background run: nobody reads the structured result — exit clean.
|
|
167
188
|
runSelfUpdate();
|
|
189
|
+
process.exit(0);
|
|
168
190
|
});
|
|
169
191
|
// Internal: spawned detached by `glen doctor --auto` to re-merge + re-trust
|
|
170
192
|
// the codex user-layer hooks without blocking the calling turn.
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAExB,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,kCAAkC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IACzE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import type { CliError } from "../_utils/cli-error.js";
|
|
1
2
|
import { type Result } from "../_utils/result.js";
|
|
2
3
|
/**
|
|
3
4
|
* `glen doctor [--auto]`
|
|
4
5
|
*
|
|
5
|
-
* Default mode: prints
|
|
6
|
-
*
|
|
6
|
+
* Default mode: prints machine-readable `status:` lines plus ` → ...`
|
|
7
|
+
* remedy lines. STABLE OUTPUT CONTRACT — the glen-setup skill branches on
|
|
8
|
+
* the exact `status:` prefixes and field names below; never change them
|
|
9
|
+
* without updating the skill in lockstep.
|
|
7
10
|
*
|
|
8
11
|
* `--auto` (quiet) mode: runs maybeSpawnBackgroundUpdate, best-effort
|
|
9
12
|
* detached spawns for plugin update commands, and (marker-gated, 24h-TTL'd
|
|
10
13
|
* via the repair trace) the detached codex user-layer hooks self-heal.
|
|
11
14
|
* No stdout output. Used by the session-start hook so it never blocks a turn.
|
|
12
15
|
*/
|
|
13
|
-
declare const doctor: (auto?: boolean) => Promise<Result<void,
|
|
16
|
+
declare const doctor: (auto?: boolean) => Promise<Result<void, CliError>>;
|
|
14
17
|
export { doctor };
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { isCodexHooksInstalled } from "../_utils/codex-hooks-setup.js";
|
|
3
3
|
import { readRepairTrace } from "../_utils/codex-repair-trace.js";
|
|
4
|
+
import { readCredentials } from "../_utils/credentials.js";
|
|
5
|
+
import { findBin } from "../_utils/find-bin.js";
|
|
6
|
+
import { glenPluginStatus } from "../_utils/plugin-status.js";
|
|
4
7
|
import { ok } from "../_utils/result.js";
|
|
5
8
|
import { readState } from "../_utils/state.js";
|
|
6
|
-
import { fetchLatest, isNpmGlobalInstall, maybeSpawnBackgroundUpdate, } from "../_utils/update.js";
|
|
9
|
+
import { fetchLatest, isNpmGlobalInstall, maybeSpawnBackgroundUpdate, newer, } from "../_utils/update.js";
|
|
7
10
|
import { cliVersion } from "../_utils/version.js";
|
|
8
11
|
import { isInstalled } from "../_utils/which.js";
|
|
9
12
|
/**
|
|
10
13
|
* `glen doctor [--auto]`
|
|
11
14
|
*
|
|
12
|
-
* Default mode: prints
|
|
13
|
-
*
|
|
15
|
+
* Default mode: prints machine-readable `status:` lines plus ` → ...`
|
|
16
|
+
* remedy lines. STABLE OUTPUT CONTRACT — the glen-setup skill branches on
|
|
17
|
+
* the exact `status:` prefixes and field names below; never change them
|
|
18
|
+
* without updating the skill in lockstep.
|
|
14
19
|
*
|
|
15
20
|
* `--auto` (quiet) mode: runs maybeSpawnBackgroundUpdate, best-effort
|
|
16
21
|
* detached spawns for plugin update commands, and (marker-gated, 24h-TTL'd
|
|
@@ -24,10 +29,7 @@ const doctor = async (auto = false) => {
|
|
|
24
29
|
// Upgrade claude plugin if claude is installed
|
|
25
30
|
if (isInstalled("claude")) {
|
|
26
31
|
try {
|
|
27
|
-
const c = spawn("claude", ["plugin", "update", "glen@glen"], {
|
|
28
|
-
detached: true,
|
|
29
|
-
stdio: "ignore",
|
|
30
|
-
});
|
|
32
|
+
const c = spawn(findBin("claude") ?? "claude", ["plugin", "update", "glen@glen"], { detached: true, stdio: "ignore" });
|
|
31
33
|
c.on("error", () => {
|
|
32
34
|
/* best-effort — ENOENT etc. arrives async; never crash the hook */
|
|
33
35
|
});
|
|
@@ -40,10 +42,7 @@ const doctor = async (auto = false) => {
|
|
|
40
42
|
// Upgrade codex plugin if codex is installed
|
|
41
43
|
if (isInstalled("codex")) {
|
|
42
44
|
try {
|
|
43
|
-
const c = spawn("codex", ["plugin", "marketplace", "upgrade", "glen"], {
|
|
44
|
-
detached: true,
|
|
45
|
-
stdio: "ignore",
|
|
46
|
-
});
|
|
45
|
+
const c = spawn(findBin("codex") ?? "codex", ["plugin", "marketplace", "upgrade", "glen"], { detached: true, stdio: "ignore" });
|
|
47
46
|
c.on("error", () => {
|
|
48
47
|
/* best-effort — ENOENT etc. arrives async; never crash the hook */
|
|
49
48
|
});
|
|
@@ -78,55 +77,70 @@ const doctor = async (auto = false) => {
|
|
|
78
77
|
}
|
|
79
78
|
return ok(undefined);
|
|
80
79
|
}
|
|
81
|
-
//
|
|
80
|
+
// -------------------------------------------------------------------------
|
|
81
|
+
// Normal diagnostic mode — STABLE OUTPUT CONTRACT (see docblock): the
|
|
82
|
+
// glen-setup skill parses the `status:` lines; keep prefixes/fields EXACT.
|
|
83
|
+
// -------------------------------------------------------------------------
|
|
82
84
|
process.stdout.write("glen doctor\n\n");
|
|
83
|
-
process.stdout.write(`Version: ${cliVersion}\n`);
|
|
84
85
|
const latest = await fetchLatest();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
: "other (local/pnpm/yarn/…)";
|
|
89
|
-
process.stdout.write(`Install channel: ${channel}\n`);
|
|
90
|
-
if (latest && latest !== cliVersion) {
|
|
91
|
-
process.stdout.write(`\nUpdate available: v${latest}.\n`);
|
|
92
|
-
if (isNpmGlobalInstall()) {
|
|
93
|
-
process.stdout.write(" Run `glen update` to install it.\n");
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
process.stdout.write(" Update with your package manager (e.g. npm i -g @tryglen/cli@latest).\n");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
86
|
+
const channel = isNpmGlobalInstall() ? "npm-global" : "other";
|
|
87
|
+
process.stdout.write(`status: cli=${cliVersion} latest=${latest ?? "unknown"} channel=${channel}\n`);
|
|
88
|
+
const creds = await readCredentials();
|
|
99
89
|
const state = await readState();
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
const orgField = state
|
|
91
|
+
? `"${state.activeOrgName ?? state.activeOrgSlug ?? state.activeOrgId}"`
|
|
92
|
+
: "missing";
|
|
93
|
+
process.stdout.write(`status: login=${creds ? "ok" : "missing"} org=${orgField}\n`);
|
|
94
|
+
const claudeDetected = isInstalled("claude");
|
|
95
|
+
const claudePlugin = claudeDetected ? glenPluginStatus("claude") : null;
|
|
96
|
+
process.stdout.write(claudeDetected
|
|
97
|
+
? `status: claude=detected plugin=${claudePlugin}\n`
|
|
98
|
+
: "status: claude=not-found\n");
|
|
99
|
+
const codexDetected = isInstalled("codex");
|
|
100
|
+
const codexPlugin = codexDetected ? glenPluginStatus("codex") : null;
|
|
101
|
+
const hooksRegistered = codexDetected && (await isCodexHooksInstalled());
|
|
102
|
+
process.stdout.write(codexDetected
|
|
103
|
+
? `status: codex=detected plugin=${codexPlugin} hooks=${hooksRegistered ? "registered" : "not-registered"}\n`
|
|
104
|
+
: "status: codex=not-found\n");
|
|
105
|
+
// codex-self-heal line: printed only when hooks=registered.
|
|
106
|
+
const trace = hooksRegistered ? await readRepairTrace() : null;
|
|
107
|
+
const selfHealFailed = hooksRegistered && trace !== null && !trace.ok;
|
|
108
|
+
if (hooksRegistered) {
|
|
109
|
+
const selfHeal = trace === null
|
|
110
|
+
? "never-ran"
|
|
111
|
+
: trace.ok
|
|
112
|
+
? "ok"
|
|
113
|
+
: `failed: ${trace.error ?? "unknown"}`;
|
|
114
|
+
process.stdout.write(`status: codex-self-heal=${selfHeal}\n`);
|
|
104
115
|
}
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
// Remedy lines — one per problem, in check order.
|
|
117
|
+
const remedies = [];
|
|
118
|
+
if (latest && newer(latest, cliVersion))
|
|
119
|
+
remedies.push("run `glen update`");
|
|
120
|
+
if (!creds)
|
|
121
|
+
remedies.push("run `glen login`");
|
|
122
|
+
if (creds && !state)
|
|
123
|
+
remedies.push("run `glen org list` then `glen org switch <slug>`");
|
|
124
|
+
for (const [bin, detected, plugin] of [
|
|
125
|
+
["claude", claudeDetected, claudePlugin],
|
|
126
|
+
["codex", codexDetected, codexPlugin],
|
|
127
|
+
]) {
|
|
128
|
+
if (detected && plugin === "not-installed")
|
|
129
|
+
remedies.push(`run \`glen install --agent ${bin}\``);
|
|
130
|
+
if (!detected)
|
|
131
|
+
remedies.push(`if ${bin} IS installed: run \`which ${bin}\`, then \`glen install --${bin}-path <path>\``);
|
|
107
132
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const hooksInstalled = await isCodexHooksInstalled();
|
|
116
|
-
process.stdout.write(hooksInstalled
|
|
117
|
-
? " codex: detected — user-layer hooks registered (re-run `glen install` to repair)\n"
|
|
118
|
-
: " codex: detected — hooks NOT registered; run `glen install`\n" +
|
|
119
|
-
" (Codex ignores plugin-manifest hooks — openai/codex#16430)\n");
|
|
120
|
-
if (hooksInstalled) {
|
|
121
|
-
const trace = await readRepairTrace();
|
|
122
|
-
if (trace && !trace.ok) {
|
|
123
|
-
process.stdout.write(` last self-heal FAILED (${trace.error ?? "unknown"}) — run \`glen install\` to repair\n`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
process.stdout.write(" update plugin: `codex plugin marketplace upgrade glen`\n");
|
|
133
|
+
if (codexDetected && !hooksRegistered)
|
|
134
|
+
remedies.push("run `glen install --agent codex`");
|
|
135
|
+
if (selfHealFailed)
|
|
136
|
+
remedies.push("run `glen install --agent codex`");
|
|
137
|
+
if (remedies.length === 0) {
|
|
138
|
+
process.stdout.write("\nEverything looks good. Run `glen update` anytime to refresh plugins.\n");
|
|
139
|
+
return ok(undefined);
|
|
127
140
|
}
|
|
128
|
-
|
|
129
|
-
|
|
141
|
+
process.stdout.write("\n");
|
|
142
|
+
for (const remedy of remedies) {
|
|
143
|
+
process.stdout.write(` → ${remedy}\n`);
|
|
130
144
|
}
|
|
131
145
|
return ok(undefined);
|
|
132
146
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CliError } from "../_utils/cli-error.js";
|
|
1
2
|
import { type Result } from "../_utils/result.js";
|
|
2
|
-
declare const incognito: (stateArg: string) => Promise<Result<void,
|
|
3
|
+
declare const incognito: (stateArg: string) => Promise<Result<void, CliError>>;
|
|
3
4
|
export { incognito };
|
|
@@ -1,15 +1,27 @@
|
|
|
1
|
+
import { causeOf, cliErr } from "../_utils/cli-error.js";
|
|
1
2
|
import { err, ok } from "../_utils/result.js";
|
|
2
|
-
import { readState, writeState } from "../_utils/state.js";
|
|
3
|
+
import { readState, statePath, writeState } from "../_utils/state.js";
|
|
3
4
|
const incognito = async (stateArg) => {
|
|
4
5
|
if (stateArg !== "on" && stateArg !== "off")
|
|
5
|
-
return err(
|
|
6
|
+
return err(cliErr({
|
|
7
|
+
what: `invalid argument "${stateArg}"`,
|
|
8
|
+
remedy: "use: glen incognito on | off",
|
|
9
|
+
}));
|
|
6
10
|
const current = await readState();
|
|
7
11
|
if (!current)
|
|
8
|
-
return err(
|
|
12
|
+
return err(cliErr({
|
|
13
|
+
what: "no active organization",
|
|
14
|
+
remedy: "run `glen org switch` (or `glen login`) first",
|
|
15
|
+
}));
|
|
9
16
|
const next = { ...current, incognito: stateArg === "on" };
|
|
10
17
|
const w = await writeState(next);
|
|
11
18
|
if (!w.ok)
|
|
12
|
-
return err(
|
|
19
|
+
return err(cliErr({
|
|
20
|
+
what: "could not save incognito state",
|
|
21
|
+
why: causeOf(w.error),
|
|
22
|
+
path: statePath(),
|
|
23
|
+
remedy: "check ownership of ~/.glen (e.g. `sudo chown -R $USER ~/.glen`) and retry",
|
|
24
|
+
}));
|
|
13
25
|
process.stdout.write(next.incognito
|
|
14
26
|
? "🏔️ Incognito ON — glen records nothing until you run `glen incognito off`.\n"
|
|
15
27
|
: "🏔️ Incognito off — glen is recording again.\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incognito.js","sourceRoot":"","sources":["../../src/commands/incognito.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"incognito.js","sourceRoot":"","sources":["../../src/commands/incognito.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAe,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEtE,MAAM,SAAS,GAAG,KAAK,EAAE,QAAgB,EAAmC,EAAE;IAC5E,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,KAAK;QACzC,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,qBAAqB,QAAQ,GAAG;YACtC,MAAM,EAAE,8BAA8B;SACvC,CAAC,CACH,CAAC;IACJ,MAAM,OAAO,GAAG,MAAM,SAAS,EAAE,CAAC;IAClC,IAAI,CAAC,OAAO;QACV,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,+CAA+C;SACxD,CAAC,CACH,CAAC;IACJ,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ,KAAK,IAAI,EAAE,CAAC;IAC1D,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,CAAC,CAAC,EAAE;QACP,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,gCAAgC;YACtC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;YACrB,IAAI,EAAE,SAAS,EAAE;YACjB,MAAM,EACJ,2EAA2E;SAC9E,CAAC,CACH,CAAC;IACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS;QACZ,CAAC,CAAC,+EAA+E;QACjF,CAAC,CAAC,gDAAgD,CACrD,CAAC;IACF,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
import { type Result } from "../_utils/result.js";
|
|
2
|
-
|
|
3
|
-
readonly code: number;
|
|
4
|
-
readonly message: string;
|
|
5
|
-
};
|
|
6
|
-
declare const ingest: (agent?: string) => Promise<Result<void, IngestError>>;
|
|
2
|
+
declare const ingest: (agent?: string) => Promise<Result<void, never>>;
|
|
7
3
|
export { ingest };
|
package/dist/commands/ingest.js
CHANGED
|
@@ -8,23 +8,38 @@ import { gitContext } from "../_utils/git-context.js";
|
|
|
8
8
|
import { buildGlenHeaders } from "../_utils/glen-headers.js";
|
|
9
9
|
import { httpJson } from "../_utils/http.js";
|
|
10
10
|
import { parseTranscript } from "../_utils/parse-transcript.js";
|
|
11
|
-
import {
|
|
11
|
+
import { fromPromise, ok } from "../_utils/result.js";
|
|
12
12
|
import { formatStateLine } from "../_utils/state-line.js";
|
|
13
13
|
import { readState } from "../_utils/state.js";
|
|
14
|
-
import {
|
|
14
|
+
import { cachedNewerVersion, handle426InHook, maybeSpawnBackgroundUpdate, } from "../_utils/update.js";
|
|
15
15
|
import { cliVersion } from "../_utils/version.js";
|
|
16
16
|
const readStdin = async () => {
|
|
17
|
+
if (process.stdin.isTTY)
|
|
18
|
+
return ""; // manual run in a terminal — don't hang
|
|
17
19
|
const chunks = [];
|
|
18
20
|
for await (const chunk of process.stdin)
|
|
19
21
|
chunks.push(chunk);
|
|
20
22
|
return Buffer.concat(chunks).toString("utf8");
|
|
21
23
|
};
|
|
24
|
+
// Appended to agent-facing failure hints: when the TTL'd update-check cache
|
|
25
|
+
// already knows about a newer version, suggest `glen update` (never hits the
|
|
26
|
+
// network — hooks must stay fast).
|
|
27
|
+
const updateAddendum = () => {
|
|
28
|
+
const v = cachedNewerVersion();
|
|
29
|
+
return v
|
|
30
|
+
? ` Note: glen v${v} is available (you have v${cliVersion}) — \`glen update\` may fix this.`
|
|
31
|
+
: "";
|
|
32
|
+
};
|
|
22
33
|
const readTranscriptLines = async (path) => {
|
|
23
34
|
const r = await fromPromise(readFile(path, "utf8"));
|
|
24
35
|
if (!r.ok)
|
|
25
36
|
return [];
|
|
26
37
|
return r.value.split("\n").filter(Boolean);
|
|
27
38
|
};
|
|
39
|
+
// Hook invariant: ingest NEVER returns an error and bin.ts NEVER exits
|
|
40
|
+
// nonzero for it — a nonzero hook exit blocks the user's prompt (exit 2 is
|
|
41
|
+
// Claude Code's blocking code). Every failure mode instead emits an
|
|
42
|
+
// agent-facing hint via emit() and resolves ok.
|
|
28
43
|
const ingest = async (agent) => {
|
|
29
44
|
void maybeSpawnBackgroundUpdate();
|
|
30
45
|
const stdinRaw = await readStdin();
|
|
@@ -55,13 +70,11 @@ const ingest = async (agent) => {
|
|
|
55
70
|
};
|
|
56
71
|
const creds = await readCredentials();
|
|
57
72
|
if (!creds) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
return err({ code: 1, message: "not connected" });
|
|
73
|
+
// One shared path for every agent: emit the hint (codex gets the JSON
|
|
74
|
+
// envelope, claude-code gets plain stdout) and exit clean — a non-zero
|
|
75
|
+
// exit blocks the prompt (Claude) or drops the output (Codex).
|
|
76
|
+
emit("[glen] not connected — run `glen login`");
|
|
77
|
+
return ok(undefined);
|
|
65
78
|
}
|
|
66
79
|
const state = await readState();
|
|
67
80
|
const transcriptPath = typeof event.transcript_path === "string"
|
|
@@ -112,24 +125,42 @@ const ingest = async (agent) => {
|
|
|
112
125
|
body: JSON.stringify(body),
|
|
113
126
|
timeoutMs: config.ingestTimeoutMs,
|
|
114
127
|
});
|
|
115
|
-
if (!res.ok)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
// Fail open: stderr breadcrumb for humans, context hint for the agent.
|
|
130
|
+
process.stderr.write(`glen: ingest failed (${res.error.detail}). Memory was not recorded this turn.\n`);
|
|
131
|
+
emit(`[glen] memory capture failed this turn (${res.error.detail}). ` +
|
|
132
|
+
`If this keeps happening, tell the user to check their connection.${updateAddendum()}`);
|
|
133
|
+
return ok(undefined);
|
|
134
|
+
}
|
|
135
|
+
if (res.value.status === 426) {
|
|
136
|
+
// Server-forced minimum version: NEVER update synchronously inside a hook
|
|
137
|
+
// (Claude's 60s timeout would kill it) — background update + hint instead.
|
|
138
|
+
// When the spawn is gated (auto-update disabled / not npm-global) nothing
|
|
139
|
+
// is updating, so tell the agent the user must update manually.
|
|
140
|
+
const spawned = handle426InHook();
|
|
141
|
+
emit(spawned
|
|
142
|
+
? "[glen] glen is updating itself in the background — this turn was not recorded; retry your prompt in a minute."
|
|
143
|
+
: "[glen] glen needs an update before memories can be captured — tell the user to run `npm i -g @tryglen/cli@latest`.");
|
|
144
|
+
return ok(undefined);
|
|
145
|
+
}
|
|
119
146
|
if (res.value.status === 401 || res.value.status === 403) {
|
|
120
147
|
if (res.value.rawText.includes("no active organization")) {
|
|
121
148
|
// Server reports no org bound — hint the user and fail open so the hook
|
|
122
149
|
// never blocks the turn.
|
|
123
150
|
process.stderr.write("[glen] no active organization — run `glen org switch`\n");
|
|
151
|
+
emit("[glen] no active organization — run `glen org switch`");
|
|
124
152
|
return ok(undefined);
|
|
125
153
|
}
|
|
126
|
-
// Don't clear credentials here — a concurrent
|
|
127
|
-
// saved a fresh key.
|
|
128
|
-
|
|
154
|
+
// Expired/revoked key. Don't clear credentials here — a concurrent
|
|
155
|
+
// `glen login` may have just saved a fresh key. Instruct the agent.
|
|
156
|
+
emit(`[glen] ACTION NEEDED: this machine's glen connection expired or was revoked — memories are NOT being captured. Tell the user to run \`glen login\` to reconnect.${updateAddendum()}`);
|
|
157
|
+
return ok(undefined);
|
|
129
158
|
}
|
|
130
159
|
if (!res.value.isOk) {
|
|
131
160
|
// Fail open (don't block the prompt), but surface the error so it's not invisible.
|
|
132
161
|
process.stderr.write(`glen: ingest failed (HTTP ${res.value.status}). Memory was not recorded this turn.\n`);
|
|
162
|
+
emit(`[glen] memory capture failed this turn (HTTP ${res.value.status}). ` +
|
|
163
|
+
`If this keeps happening, tell the user to check their connection.${updateAddendum()}`);
|
|
133
164
|
return ok(undefined);
|
|
134
165
|
}
|
|
135
166
|
const stateLine = formatStateLine(state);
|