@tryglen/cli 0.33.0 → 0.36.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 +19 -19
- package/dist/_utils/agent-adapter.d.ts +2 -0
- package/dist/_utils/agent-adapter.js +3 -1
- package/dist/_utils/agent-adapter.js.map +1 -1
- package/dist/_utils/detect-transcript-format.d.ts +1 -1
- package/dist/_utils/detect-transcript-format.js.map +1 -1
- package/dist/_utils/install-receipt.d.ts +9 -1
- package/dist/_utils/install-receipt.js +19 -1
- package/dist/_utils/install-receipt.js.map +1 -1
- package/dist/_utils/jcode-bundle.d.ts +3 -0
- package/dist/_utils/jcode-bundle.js +23 -0
- package/dist/_utils/jcode-bundle.js.map +1 -0
- package/dist/_utils/jcode-event.d.ts +3 -0
- package/dist/_utils/jcode-event.js +82 -0
- package/dist/_utils/jcode-event.js.map +1 -0
- package/dist/_utils/jcode-hook-lines.d.ts +5 -0
- package/dist/_utils/jcode-hook-lines.js +11 -0
- package/dist/_utils/jcode-hook-lines.js.map +1 -0
- package/dist/_utils/jcode-hooks-toml.d.ts +8 -0
- package/dist/_utils/jcode-hooks-toml.js +156 -0
- package/dist/_utils/jcode-hooks-toml.js.map +1 -0
- package/dist/_utils/jcode-paths.d.ts +7 -0
- package/dist/_utils/jcode-paths.js +13 -0
- package/dist/_utils/jcode-paths.js.map +1 -0
- package/dist/_utils/jcode-setup.d.ts +27 -0
- package/dist/_utils/jcode-setup.js +158 -0
- package/dist/_utils/jcode-setup.js.map +1 -0
- package/dist/_utils/jcode-skills-sync.d.ts +8 -0
- package/dist/_utils/jcode-skills-sync.js +79 -0
- package/dist/_utils/jcode-skills-sync.js.map +1 -0
- package/dist/_utils/managed-block.d.ts +4 -0
- package/dist/_utils/managed-block.js +42 -0
- package/dist/_utils/managed-block.js.map +1 -0
- package/dist/_utils/parse-harbor-atif.js +2 -1
- package/dist/_utils/parse-harbor-atif.js.map +1 -1
- package/dist/_utils/parse-jcode-session.d.ts +14 -0
- package/dist/_utils/parse-jcode-session.js +128 -0
- package/dist/_utils/parse-jcode-session.js.map +1 -0
- package/dist/_utils/plugin-status.d.ts +1 -1
- package/dist/_utils/plugin-status.js +28 -0
- package/dist/_utils/plugin-status.js.map +1 -1
- package/dist/_utils/transcript-turns.d.ts +1 -1
- package/dist/bin.js +12 -6
- package/dist/bin.js.map +1 -1
- package/dist/commands/_utils/materialize-skill.d.ts +30 -0
- package/dist/commands/_utils/materialize-skill.js +237 -0
- package/dist/commands/_utils/materialize-skill.js.map +1 -0
- package/dist/commands/_utils/pack-skill-dir.d.ts +15 -0
- package/dist/commands/_utils/pack-skill-dir.js +190 -0
- package/dist/commands/_utils/pack-skill-dir.js.map +1 -0
- package/dist/commands/doctor.js +19 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/ingest.js +28 -18
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +55 -10
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/session-start.js +18 -8
- package/dist/commands/session-start.js.map +1 -1
- package/dist/commands/skill.d.ts +1 -0
- package/dist/commands/skill.js +171 -10
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/uninstall.js +4 -0
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +19 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/jcode/plugin.json +8 -0
- package/dist/jcode/preferred-tools.md +3 -0
- package/dist/jcode/prompt-overlay.md +15 -0
- package/dist/jcode/skills/code-search/SKILL.md +19 -0
- package/dist/jcode/skills/controls/SKILL.md +45 -0
- package/dist/jcode/skills/create-artifact/SKILL.md +11 -0
- package/dist/jcode/skills/create-skill/SKILL.md +41 -0
- package/dist/jcode/skills/feedback/SKILL.md +59 -0
- package/dist/jcode/skills/forget/SKILL.md +41 -0
- package/dist/jcode/skills/import-transcripts/SKILL.md +27 -0
- package/dist/jcode/skills/invite/SKILL.md +28 -0
- package/dist/jcode/skills/search/SKILL.md +35 -0
- package/dist/jcode/skills/session-takeover/SKILL.md +67 -0
- package/dist/jcode/skills/setup/SKILL.md +62 -0
- package/dist/jcode/skills/use-artifact/SKILL.md +11 -0
- package/dist/jcode/skills/use-skill/SKILL.md +10 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -11,25 +11,25 @@ glen login
|
|
|
11
11
|
|
|
12
12
|
## Commands
|
|
13
13
|
|
|
14
|
-
| Command
|
|
15
|
-
|
|
|
16
|
-
| `glen login`
|
|
17
|
-
| `glen logout`
|
|
18
|
-
| `glen status`
|
|
19
|
-
| `glen search "<query>"`
|
|
20
|
-
| `glen takeover <code>`
|
|
21
|
-
| `glen import <path…> [--dry-run]`
|
|
22
|
-
| `glen incognito on\|off`
|
|
23
|
-
| `glen org list`
|
|
24
|
-
| `glen org switch [slug]`
|
|
25
|
-
| `glen ingest [--agent <name>]`
|
|
26
|
-
| `glen install [--agent <claude\|codex\|cursor\|pi>]` | Set up or update glen for detected coding agents (plugin + hooks); idempotent, so re-running repairs a broken setup. `--claude-path <path>` / `--codex-path <path>` / `--pi-path <path>` point at a binary when auto-detection fails.
|
|
27
|
-
| `glen uninstall`
|
|
28
|
-
| `glen update`
|
|
29
|
-
| `glen doctor [--auto]`
|
|
30
|
-
| `glen statusline`
|
|
31
|
-
| `glen session-start [--agent <name>]`
|
|
32
|
-
| `glen version`
|
|
14
|
+
| Command | Description |
|
|
15
|
+
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
16
|
+
| `glen login` | Connect via browser sign-in; writes credentials and initial session state. |
|
|
17
|
+
| `glen logout` | Sign out and remove credentials + session state. |
|
|
18
|
+
| `glen status` | Show connection status, active org, incognito state, and CLI version. |
|
|
19
|
+
| `glen search "<query>"` | Search the team's shared glen memory. |
|
|
20
|
+
| `glen takeover <code>` | Redeem a transcript-page handoff into a fresh native Claude Code, Codex, Cursor, or Pi session, then open it. The complete transcript must fit; Glen never truncates or summarizes it. |
|
|
21
|
+
| `glen import <path…> [--dry-run]` | Import old local agent transcripts (Claude Code `~/.claude/projects`, Codex `~/.codex/sessions`, Cursor `state.vscdb`, Pi `~/.pi/agent/sessions`) into glen memory. Idempotent — re-running skips already-imported turns. `--dry-run` previews without writing. |
|
|
22
|
+
| `glen incognito on\|off` | Toggle incognito mode: while on, nothing is recorded (recall keeps working). |
|
|
23
|
+
| `glen org list` | List your organizations; active one is marked with `✓`. |
|
|
24
|
+
| `glen org switch [slug]` | Switch the active organization for this machine (interactive picker without `slug`). |
|
|
25
|
+
| `glen ingest [--agent <name>]` | Ingest a turn from stdin — used by agent hooks (`claude-code`, `codex`, `cursor`, `pi`, or `jcode`). |
|
|
26
|
+
| `glen install [--agent <claude\|codex\|cursor\|pi\|jcode>]` | Set up or update glen for detected coding agents (plugin + hooks); idempotent, so re-running repairs a broken setup. `--claude-path <path>` / `--codex-path <path>` / `--pi-path <path>` / `--jcode-path <path>` point at a binary when auto-detection fails. jcode has no plugin CLI — `--agent jcode` writes glen's hook lines into `~/.jcode/config.toml`, a managed block into `~/.jcode/prompt-overlay.md` and `preferred-tools.md`, and the skills into `~/.jcode/skills` (start a new jcode session afterwards). |
|
|
27
|
+
| `glen uninstall` | Permanently remove Glen's local plugins, marketplaces, hooks, PATH entries, credentials, state, caches, and global npm CLI. |
|
|
28
|
+
| `glen update` | Update the glen CLI **and** any installed glen plugins, and re-verify the Codex hook registration. Never installs a plugin that isn't already installed — that's `glen install`'s job. |
|
|
29
|
+
| `glen doctor [--auto]` | Print machine-readable `status:` lines (CLI version/latest/channel, login + org, per-agent plugin + hook state) plus `→` remedy lines — the setup skill branches on them. `--auto` runs background updates silently (used by hooks). |
|
|
30
|
+
| `glen statusline` | Output a single status line for the agent's UI status bar — used by hooks. |
|
|
31
|
+
| `glen session-start [--agent <name>]` | Output hook JSON for the agent's `SessionStart` event — used by hooks. |
|
|
32
|
+
| `glen version` | Print the CLI version. |
|
|
33
33
|
|
|
34
34
|
## Files
|
|
35
35
|
|
|
@@ -14,6 +14,8 @@ type AdapterOutput = {
|
|
|
14
14
|
* - "pi": same event-carried shape as codex — the events are authored by
|
|
15
15
|
* glen's own pi extension (packages/pi-plugin/extensions/glen.ts); pi's
|
|
16
16
|
* session file is a pi-specific JSONL tree glen doesn't parse.
|
|
17
|
+
* - "jcode": same event-carried shape — built by _utils/jcode-event.ts from
|
|
18
|
+
* JCODE_HOOK_* env plus the session file.
|
|
17
19
|
* - "claude-code" and generic/unknown: uses parseTranscript for priorAssistant
|
|
18
20
|
* and the user-message index (nextUserMessageIndex) that callers need for
|
|
19
21
|
* idempotency key derivation.
|
|
@@ -10,6 +10,8 @@ const str = (v) => typeof v === "string" && v ? v : null;
|
|
|
10
10
|
* - "pi": same event-carried shape as codex — the events are authored by
|
|
11
11
|
* glen's own pi extension (packages/pi-plugin/extensions/glen.ts); pi's
|
|
12
12
|
* session file is a pi-specific JSONL tree glen doesn't parse.
|
|
13
|
+
* - "jcode": same event-carried shape — built by _utils/jcode-event.ts from
|
|
14
|
+
* JCODE_HOOK_* env plus the session file.
|
|
13
15
|
* - "claude-code" and generic/unknown: uses parseTranscript for priorAssistant
|
|
14
16
|
* and the user-message index (nextUserMessageIndex) that callers need for
|
|
15
17
|
* idempotency key derivation.
|
|
@@ -29,7 +31,7 @@ const adaptAgentEvent = (agent, event, transcriptLines) => {
|
|
|
29
31
|
usesTranscript: false,
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
|
-
if (agent === "codex" || agent === "pi") {
|
|
34
|
+
if (agent === "codex" || agent === "pi" || agent === "jcode") {
|
|
33
35
|
const fields = {};
|
|
34
36
|
const model = str(event.model);
|
|
35
37
|
if (model)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/_utils/agent-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAaxD,gDAAgD;AAChD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAiB,EAAE,CACxC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/_utils/agent-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAaxD,gDAAgD;AAChD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAiB,EAAE,CACxC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,MAAM,eAAe,GAAG,CACtB,KAAyB,EACzB,KAAgB,EAChB,eAAkC,EACnB,EAAE;IACjB,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,yEAAyE;QACzE,oEAAoE;QACpE,8DAA8D;QAC9D,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QAChC,OAAO;YACL,aAAa,EAAE,MAAM;YACrB,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QAChC,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAClD,IAAI,cAAc;YAAE,MAAM,CAAC,cAAc,GAAG,cAAc,CAAC;QAC3D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,MAAM;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACnC,OAAO;YACL,aAAa,EAAE,MAAM;YACrB,cAAc,EACZ,OAAO,KAAK,CAAC,sBAAsB,KAAK,QAAQ;gBAC9C,CAAC,CAAC,KAAK,CAAC,sBAAsB;gBAC9B,CAAC,CAAC,IAAI;YACV,cAAc,EAAE,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,MAAM,EAAE,cAAc,EAAE,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAClD,IAAI,cAAc;QAAE,MAAM,CAAC,cAAc,GAAG,cAAc,CAAC;IAC3D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO;QACL,aAAa,EAAE,MAAM;QACrB,cAAc;QACd,cAAc,EAAE,IAAI;KACrB,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const detectTranscriptFormat: (filePath: string, sampleLines: readonly string[]) => "claude-code" | "codex" | "cursor" | "pi" | null;
|
|
1
|
+
declare const detectTranscriptFormat: (filePath: string, sampleLines: readonly string[]) => "claude-code" | "codex" | "cursor" | "pi" | "jcode" | null;
|
|
2
2
|
export { detectTranscriptFormat };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect-transcript-format.js","sourceRoot":"","sources":["../../src/_utils/detect-transcript-format.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,CAAC,IAAY,EAAgB,EAAE;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAC3C,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ;YAClD,CAAC,CAAE,MAAgB;YACnB,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,cAAc;IACd,eAAe;IACf,WAAW;IACX,cAAc;IACd,WAAW;CACZ,CAAC,CAAC;AAEH,yEAAyE;AACzE,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,yBAAyB;AACzB,MAAM,sBAAsB,GAAG,CAC7B,QAAgB,EAChB,WAA8B,
|
|
1
|
+
{"version":3,"file":"detect-transcript-format.js","sourceRoot":"","sources":["../../src/_utils/detect-transcript-format.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,CAAC,IAAY,EAAgB,EAAE;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAC3C,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ;YAClD,CAAC,CAAE,MAAgB;YACnB,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,cAAc;IACd,eAAe;IACf,WAAW;IACX,cAAc;IACd,WAAW;CACZ,CAAC,CAAC;AAEH,yEAAyE;AACzE,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,yBAAyB;AACzB,MAAM,sBAAsB,GAAG,CAC7B,QAAgB,EAChB,WAA8B,EAC8B,EAAE;IAC9D,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjD,OAAO,CACL,WAAW;SACR,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,SAAS,CAAC;SACd,MAAM,CAAC,CAAC,CAAC,EAAc,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,EAAyC,EAAE;QAChD,IAAI,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC;YAAE,OAAO,aAAa,CAAC;QAC/D,IACE,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;YAC/B,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;YAErE,OAAO,aAAa,CAAC;QACvB,IACE,CAAC,CAAC,IAAI,KAAK,SAAS;YACpB,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YAC7B,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ;YAEzB,OAAO,IAAI,CAAC;QACd,IACE,CAAC,CAAC,IAAI,KAAK,SAAS;YACpB,UAAU,IAAI,CAAC;YACf,CAAC,CAAC,OAAO,KAAK,IAAI;YAClB,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YAE7B,OAAO,IAAI,CAAC;QACd,IACE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAC1B,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAChC,SAAS,IAAI,CAAC;YAEd,OAAO,OAAO,CAAC;QACjB,IACE,CAAC,CAAC,IAAI,KAAK,SAAS;YACpB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YACxB,CAAC,CAAC,OAAO,CAAC,IAAI,CACZ,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,KAAK,IAAI;gBACV,OAAO,CAAC,KAAK,QAAQ;gBACrB,CAAE,CAAW,CAAC,IAAI,KAAK,YAAY;oBAChC,CAAW,CAAC,IAAI,KAAK,aAAa,CAAC,CACzC;YAED,OAAO,OAAO,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CACnC,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -11,8 +11,14 @@ type CodexFilesSnapshot = {
|
|
|
11
11
|
readonly configPath: string;
|
|
12
12
|
readonly configExisted: boolean;
|
|
13
13
|
};
|
|
14
|
+
type JcodeFilesSnapshot = {
|
|
15
|
+
readonly configToml: FileSnapshot;
|
|
16
|
+
readonly promptOverlay: FileSnapshot;
|
|
17
|
+
readonly preferredTools: FileSnapshot;
|
|
18
|
+
readonly skillDirs: readonly string[];
|
|
19
|
+
};
|
|
14
20
|
type PendingInstall = {
|
|
15
|
-
readonly agents: readonly ("claude" | "codex" | "cursor" | "pi")[];
|
|
21
|
+
readonly agents: readonly ("claude" | "codex" | "cursor" | "pi" | "jcode")[];
|
|
16
22
|
readonly outcome: "completed" | "warnings" | "instructions";
|
|
17
23
|
readonly occurredAt: string;
|
|
18
24
|
};
|
|
@@ -25,6 +31,7 @@ type InstallReceipt = {
|
|
|
25
31
|
readonly statePaths: string[];
|
|
26
32
|
readonly pendingInstall?: PendingInstall;
|
|
27
33
|
readonly installedAt?: string;
|
|
34
|
+
readonly jcodeFiles?: JcodeFilesSnapshot;
|
|
28
35
|
};
|
|
29
36
|
declare const installReceipt: {
|
|
30
37
|
path: () => string;
|
|
@@ -32,6 +39,7 @@ declare const installReceipt: {
|
|
|
32
39
|
recordShellProfile: (path: string) => Promise<Result<void, unknown>>;
|
|
33
40
|
recordClaudeSettings: (snapshot: FileSnapshot) => Promise<Result<void, unknown>>;
|
|
34
41
|
recordCodexFiles: (snapshot: CodexFilesSnapshot) => Promise<Result<void, unknown>>;
|
|
42
|
+
recordJcodeFiles: (snapshot: JcodeFilesSnapshot) => Promise<Result<void, unknown>>;
|
|
35
43
|
recordGitHook: (snapshot: FileSnapshot) => Promise<Result<void, unknown>>;
|
|
36
44
|
recordPendingInstall: (pendingInstall: PendingInstall) => Promise<Result<void, unknown>>;
|
|
37
45
|
clearPendingInstall: () => Promise<Result<void, unknown>>;
|
|
@@ -24,7 +24,8 @@ const isFileSnapshot = (value) => {
|
|
|
24
24
|
const isInstallAgent = (value) => value === "claude" ||
|
|
25
25
|
value === "codex" ||
|
|
26
26
|
value === "cursor" ||
|
|
27
|
-
value === "pi"
|
|
27
|
+
value === "pi" ||
|
|
28
|
+
value === "jcode";
|
|
28
29
|
const isInstallOutcome = (value) => value === "completed" || value === "warnings" || value === "instructions";
|
|
29
30
|
const isIsoTimestamp = (value) => {
|
|
30
31
|
if (typeof value !== "string")
|
|
@@ -88,6 +89,16 @@ const parseReceipt = (raw) => {
|
|
|
88
89
|
const installedAt = isIsoTimestamp(value.installedAt)
|
|
89
90
|
? value.installedAt
|
|
90
91
|
: null;
|
|
92
|
+
const jcode = value.jcodeFiles;
|
|
93
|
+
const jcodeFiles = jcode &&
|
|
94
|
+
typeof jcode === "object" &&
|
|
95
|
+
isFileSnapshot(jcode.configToml) &&
|
|
96
|
+
isFileSnapshot(jcode.promptOverlay) &&
|
|
97
|
+
isFileSnapshot(jcode.preferredTools) &&
|
|
98
|
+
Array.isArray(jcode.skillDirs) &&
|
|
99
|
+
jcode.skillDirs.every((d) => typeof d === "string")
|
|
100
|
+
? jcode
|
|
101
|
+
: null;
|
|
91
102
|
return {
|
|
92
103
|
version: 1,
|
|
93
104
|
shellProfiles: value.shellProfiles,
|
|
@@ -97,6 +108,7 @@ const parseReceipt = (raw) => {
|
|
|
97
108
|
statePaths: value.statePaths,
|
|
98
109
|
...(pendingInstall ? { pendingInstall } : {}),
|
|
99
110
|
...(installedAt ? { installedAt } : {}),
|
|
111
|
+
...(jcodeFiles ? { jcodeFiles } : {}),
|
|
100
112
|
};
|
|
101
113
|
};
|
|
102
114
|
const read = async () => {
|
|
@@ -132,6 +144,11 @@ const recordCodexFiles = async (snapshot) => update((current) => ({
|
|
|
132
144
|
...current,
|
|
133
145
|
codexFiles: current.codexFiles ?? snapshot,
|
|
134
146
|
}));
|
|
147
|
+
// First install wins, like codexFiles: `before` must stay the pre-glen bytes.
|
|
148
|
+
const recordJcodeFiles = async (snapshot) => update((current) => ({
|
|
149
|
+
...current,
|
|
150
|
+
jcodeFiles: current.jcodeFiles ?? snapshot,
|
|
151
|
+
}));
|
|
135
152
|
const recordGitHook = async (snapshot) => update((current) => {
|
|
136
153
|
const prior = current.gitHooks.find((hook) => hook.path === snapshot.path);
|
|
137
154
|
const gitHooks = prior
|
|
@@ -172,6 +189,7 @@ const installReceipt = {
|
|
|
172
189
|
})),
|
|
173
190
|
recordClaudeSettings,
|
|
174
191
|
recordCodexFiles,
|
|
192
|
+
recordJcodeFiles,
|
|
175
193
|
recordGitHook,
|
|
176
194
|
recordPendingInstall,
|
|
177
195
|
clearPendingInstall,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-receipt.js","sourceRoot":"","sources":["../../src/_utils/install-receipt.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,MAAM,EACN,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAe,WAAW,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"install-receipt.js","sourceRoot":"","sources":["../../src/_utils/install-receipt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
// The jcode plugin ships INSIDE the CLI tarball: `pnpm build` copies
|
|
5
|
+
// packages/jcode-plugin into dist/jcode (see package.json build:jcode). At
|
|
6
|
+
// runtime this module lives at dist/_utils/jcode-bundle.js, so the bundle is
|
|
7
|
+
// its parent's `jcode/` sibling. GLEN_JCODE_BUNDLE_DIR overrides it for tests
|
|
8
|
+
// (which run from src/, where no bundle exists) and points at
|
|
9
|
+
// packages/jcode-plugin — the same layout as the built bundle.
|
|
10
|
+
const jcodeBundleDir = () => process.env.GLEN_JCODE_BUNDLE_DIR ||
|
|
11
|
+
join(dirname(fileURLToPath(import.meta.url)), "..", "jcode");
|
|
12
|
+
// Version stamped on installed skill dirs so doctor can re-sync on drift.
|
|
13
|
+
const jcodeBundleVersion = () => {
|
|
14
|
+
try {
|
|
15
|
+
const manifest = JSON.parse(readFileSync(join(jcodeBundleDir(), "plugin.json"), "utf8"));
|
|
16
|
+
return typeof manifest.version === "string" ? manifest.version : null;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export { jcodeBundleDir, jcodeBundleVersion };
|
|
23
|
+
//# sourceMappingURL=jcode-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcode-bundle.js","sourceRoot":"","sources":["../../src/_utils/jcode-bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,qEAAqE;AACrE,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,8DAA8D;AAC9D,+DAA+D;AAC/D,MAAM,cAAc,GAAG,GAAW,EAAE,CAClC,OAAO,CAAC,GAAG,CAAC,qBAAqB;IACjC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAE/D,0EAA0E;AAC1E,MAAM,kBAAkB,GAAG,GAAkB,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CACnC,CAAC;QAC3B,OAAO,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { readJcodeTurn, readJcodeUserPrompt } from "./parse-jcode-session.js";
|
|
2
|
+
// jcode delivers hook events as JCODE_HOOK_* env vars with stdin at
|
|
3
|
+
// /dev/null: JCODE_HOOK_EVENT / _SESSION_ID / _CWD plus per-event fields, and
|
|
4
|
+
// JCODE_HOOK_PAYLOAD, a JSON mirror of every field (lowercased keys, capped
|
|
5
|
+
// at 16 KB). The individual vars win; the payload is the fallback.
|
|
6
|
+
const payloadOf = (env) => {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(env.JCODE_HOOK_PAYLOAD ?? "");
|
|
9
|
+
return parsed !== null && typeof parsed === "object"
|
|
10
|
+
? parsed
|
|
11
|
+
: {};
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const str = (value) => typeof value === "string" && value ? value : null;
|
|
18
|
+
const field = (env, suffix, key) => str(env[`JCODE_HOOK_${suffix}`]) ?? str(payloadOf(env)[key]);
|
|
19
|
+
// turn_end → glen's Stop shape (the pi/codex vocabulary: prompt + text
|
|
20
|
+
// inline). jcode fires turn_end BEFORE it flushes the assistant reply to the
|
|
21
|
+
// session snapshot (measured ~5-7s later), so the answer is sourced two ways:
|
|
22
|
+
// 1. Preferred — the full reply from the session file, waited for up to
|
|
23
|
+
// GLEN_JCODE_SESSION_RETRIES * 500ms (default ~15s; the hook is detached,
|
|
24
|
+
// so the wait never blocks jcode). This captures replies longer than the
|
|
25
|
+
// env's 4000-char cap.
|
|
26
|
+
// 2. Fallback — if the assistant hasn't landed in the file within that
|
|
27
|
+
// window, pair the prompt already in the file with the answer jcode
|
|
28
|
+
// passes in the hook env (LAST_ASSISTANT_TEXT, first 4000 chars). This
|
|
29
|
+
// guarantees the turn is recorded rather than silently dropped.
|
|
30
|
+
// Only when neither yields a prompt+answer is nothing sent.
|
|
31
|
+
const DEFAULT_SESSION_RETRIES = 30;
|
|
32
|
+
const readJcodeStopEvent = async (env) => {
|
|
33
|
+
const sessionId = field(env, "SESSION_ID", "session_id");
|
|
34
|
+
if (!sessionId || field(env, "EVENT", "event") !== "turn_end")
|
|
35
|
+
return null;
|
|
36
|
+
const cwd = field(env, "CWD", "cwd") ?? process.cwd();
|
|
37
|
+
const model = field(env, "MODEL", "model");
|
|
38
|
+
const configured = Number(env.GLEN_JCODE_SESSION_RETRIES);
|
|
39
|
+
const retries = Number.isFinite(configured)
|
|
40
|
+
? configured
|
|
41
|
+
: DEFAULT_SESSION_RETRIES;
|
|
42
|
+
const base = {
|
|
43
|
+
hook_event_name: "Stop",
|
|
44
|
+
session_id: sessionId,
|
|
45
|
+
cwd,
|
|
46
|
+
...(model ? { model } : {}),
|
|
47
|
+
};
|
|
48
|
+
const turn = await readJcodeTurn(sessionId, { retries });
|
|
49
|
+
if (turn)
|
|
50
|
+
return {
|
|
51
|
+
...base,
|
|
52
|
+
prompt: turn.prompt,
|
|
53
|
+
text: turn.text,
|
|
54
|
+
turn_id: turn.turnId,
|
|
55
|
+
};
|
|
56
|
+
// Assistant reply not flushed in time — pair the file's prompt with the
|
|
57
|
+
// env's answer so the turn is still captured.
|
|
58
|
+
const fallbackText = field(env, "LAST_ASSISTANT_TEXT", "last_assistant_text");
|
|
59
|
+
const userPrompt = await readJcodeUserPrompt(sessionId);
|
|
60
|
+
if (userPrompt && fallbackText)
|
|
61
|
+
return {
|
|
62
|
+
...base,
|
|
63
|
+
prompt: userPrompt.prompt,
|
|
64
|
+
text: fallbackText,
|
|
65
|
+
turn_id: userPrompt.turnId,
|
|
66
|
+
};
|
|
67
|
+
return fallbackText ? { ...base, text: fallbackText } : base;
|
|
68
|
+
};
|
|
69
|
+
const jcodeSessionStartEvent = (env) => {
|
|
70
|
+
const sessionId = field(env, "SESSION_ID", "session_id");
|
|
71
|
+
if (!sessionId || field(env, "EVENT", "event") !== "session_start")
|
|
72
|
+
return null;
|
|
73
|
+
const source = field(env, "SOURCE", "source");
|
|
74
|
+
return {
|
|
75
|
+
hook_event_name: "SessionStart",
|
|
76
|
+
session_id: sessionId,
|
|
77
|
+
cwd: field(env, "CWD", "cwd") ?? process.cwd(),
|
|
78
|
+
...(source ? { source } : {}),
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export { readJcodeStopEvent, jcodeSessionStartEvent };
|
|
82
|
+
//# sourceMappingURL=jcode-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcode-event.js","sourceRoot":"","sources":["../../src/_utils/jcode-event.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// FROZEN — pinned by ingest.contract.test.ts ("hook lines are frozen").
|
|
2
|
+
// jcode has no hooks.json: these are the exact strings `glen install --agent
|
|
3
|
+
// jcode` writes into the user's ~/.jcode/config.toml [hooks] table. Both
|
|
4
|
+
// events are jcode observers — spawned detached, stdout discarded, the event
|
|
5
|
+
// delivered as JCODE_HOOK_* env vars — so the commands never inject anything.
|
|
6
|
+
const GLEN_JCODE_HOOK_LINES = {
|
|
7
|
+
session_start: "glen session-start --agent jcode",
|
|
8
|
+
turn_end: "glen ingest --agent jcode",
|
|
9
|
+
};
|
|
10
|
+
export { GLEN_JCODE_HOOK_LINES };
|
|
11
|
+
//# sourceMappingURL=jcode-hook-lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcode-hook-lines.js","sourceRoot":"","sources":["../../src/_utils/jcode-hook-lines.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,qBAAqB,GAAG;IAC5B,aAAa,EAAE,kCAAkC;IACjD,QAAQ,EAAE,2BAA2B;CAC7B,CAAC;AAEX,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Result } from "./result.js";
|
|
2
|
+
type HooksTable = Readonly<Record<string, string | readonly string[]>>;
|
|
3
|
+
type HookLines = Readonly<Record<string, string>>;
|
|
4
|
+
declare const readHooksTable: (toml: string) => Result<HooksTable, string>;
|
|
5
|
+
declare const hasHookLines: (table: HooksTable, lines: HookLines) => boolean;
|
|
6
|
+
declare const upsertHookLines: (toml: string, lines: HookLines) => Result<string, string>;
|
|
7
|
+
declare const removeHookLines: (toml: string, lines: HookLines) => Result<string, string>;
|
|
8
|
+
export { readHooksTable, hasHookLines, upsertHookLines, removeHookLines };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { parse } from "smol-toml";
|
|
2
|
+
import { err, ok } from "./result.js";
|
|
3
|
+
const HOOKS_HEADER_RE = /^\s*\[\s*hooks\s*\]\s*(?:#.*)?$/;
|
|
4
|
+
const isTableHeader = (line) => line.trimStart().startsWith("[");
|
|
5
|
+
// TOML basic strings share JSON's escaping for everything our values contain.
|
|
6
|
+
const quote = (value) => JSON.stringify(value);
|
|
7
|
+
const parseToml = (toml) => {
|
|
8
|
+
try {
|
|
9
|
+
return ok(parse(toml));
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
return err(e instanceof Error ? e.message : String(e));
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const readHooksTable = (toml) => {
|
|
16
|
+
const parsed = parseToml(toml);
|
|
17
|
+
if (!parsed.ok)
|
|
18
|
+
return parsed;
|
|
19
|
+
const hooks = parsed.value.hooks;
|
|
20
|
+
if (hooks === undefined)
|
|
21
|
+
return ok({});
|
|
22
|
+
if (hooks === null || typeof hooks !== "object" || Array.isArray(hooks))
|
|
23
|
+
return err("`hooks` is not a table");
|
|
24
|
+
const table = {};
|
|
25
|
+
for (const [key, value] of Object.entries(hooks)) {
|
|
26
|
+
if (typeof value === "string")
|
|
27
|
+
table[key] = value;
|
|
28
|
+
else if (Array.isArray(value) &&
|
|
29
|
+
value.every((v) => typeof v === "string"))
|
|
30
|
+
table[key] = value;
|
|
31
|
+
}
|
|
32
|
+
return ok(table);
|
|
33
|
+
};
|
|
34
|
+
// True when `hooks.<key>` is present but its value is neither a string nor
|
|
35
|
+
// an array of strings (e.g. an inline table or a bare number) — a shape
|
|
36
|
+
// readHooksTable silently drops. Callers use this to refuse editing one of
|
|
37
|
+
// glen's own keys rather than treat a dropped value as absent and overwrite
|
|
38
|
+
// whatever the user configured there.
|
|
39
|
+
const hookKeyHasUnsupportedShape = (toml, key) => {
|
|
40
|
+
const parsed = parseToml(toml);
|
|
41
|
+
if (!parsed.ok)
|
|
42
|
+
return false; // invalid TOML is handled elsewhere
|
|
43
|
+
const hooks = parsed.value.hooks;
|
|
44
|
+
if (hooks === null || typeof hooks !== "object" || Array.isArray(hooks))
|
|
45
|
+
return false;
|
|
46
|
+
const raw = hooks;
|
|
47
|
+
if (!(key in raw))
|
|
48
|
+
return false;
|
|
49
|
+
const value = raw[key];
|
|
50
|
+
const supported = typeof value === "string" ||
|
|
51
|
+
(Array.isArray(value) && value.every((v) => typeof v === "string"));
|
|
52
|
+
return !supported;
|
|
53
|
+
};
|
|
54
|
+
const hasHookLines = (table, lines) => Object.entries(lines).every(([key, line]) => {
|
|
55
|
+
const current = table[key];
|
|
56
|
+
return typeof current === "string"
|
|
57
|
+
? current === line
|
|
58
|
+
: (current?.includes(line) ?? false);
|
|
59
|
+
});
|
|
60
|
+
// Line range [start, end] of `key = <value>` inside the [hooks] table. A
|
|
61
|
+
// multi-line array is followed to the line where the fragment parses.
|
|
62
|
+
const keySpan = (lines, tableStart, key) => {
|
|
63
|
+
const keyRe = new RegExp(`^\\s*(?:"${key}"|'${key}'|${key})\\s*=`);
|
|
64
|
+
const start = lines.findIndex((line, i) => i > tableStart &&
|
|
65
|
+
!lines.slice(tableStart + 1, i).some(isTableHeader) &&
|
|
66
|
+
keyRe.test(line));
|
|
67
|
+
if (start === -1)
|
|
68
|
+
return null;
|
|
69
|
+
const limit = Math.min(lines.length, start + 50);
|
|
70
|
+
const end = Array.from({ length: limit - start }, (_, k) => start + k).find((j) => parseToml(["[hooks]", ...lines.slice(start, j + 1)].join("\n")).ok);
|
|
71
|
+
return { start, end: end ?? start };
|
|
72
|
+
};
|
|
73
|
+
const withHooksHeader = (lines) => {
|
|
74
|
+
if (lines.some((line) => HOOKS_HEADER_RE.test(line)))
|
|
75
|
+
return lines;
|
|
76
|
+
const trimmed = lines.join("\n").trimEnd();
|
|
77
|
+
return trimmed.length === 0
|
|
78
|
+
? ["[hooks]"]
|
|
79
|
+
: [...trimmed.split("\n"), "", "[hooks]"];
|
|
80
|
+
};
|
|
81
|
+
const render = (key, values) => values.length === 1
|
|
82
|
+
? `${key} = ${quote(values[0] ?? "")}`
|
|
83
|
+
: `${key} = [${values.map(quote).join(", ")}]`;
|
|
84
|
+
const upsertHookLines = (toml, lines) => {
|
|
85
|
+
const table = readHooksTable(toml);
|
|
86
|
+
if (!table.ok)
|
|
87
|
+
return table;
|
|
88
|
+
const badKey = Object.keys(lines).find((key) => hookKeyHasUnsupportedShape(toml, key));
|
|
89
|
+
if (badKey)
|
|
90
|
+
return err(`hooks.${badKey} in ~/.jcode/config.toml is not a string or array of strings — glen won't touch it; fix that value and re-run`);
|
|
91
|
+
const out = withHooksHeader(toml.split("\n"));
|
|
92
|
+
const tableStart = out.findIndex((line) => HOOKS_HEADER_RE.test(line));
|
|
93
|
+
for (const [key, line] of Object.entries(lines)) {
|
|
94
|
+
const current = table.value[key];
|
|
95
|
+
const next = current === undefined
|
|
96
|
+
? [line]
|
|
97
|
+
: typeof current === "string"
|
|
98
|
+
? current === line
|
|
99
|
+
? null
|
|
100
|
+
: [current, line]
|
|
101
|
+
: current.includes(line)
|
|
102
|
+
? null
|
|
103
|
+
: [...current, line];
|
|
104
|
+
if (next === null)
|
|
105
|
+
continue;
|
|
106
|
+
const span = keySpan(out, tableStart, key);
|
|
107
|
+
if (span)
|
|
108
|
+
out.splice(span.start, span.end - span.start + 1, render(key, next));
|
|
109
|
+
else if (current !== undefined)
|
|
110
|
+
return err(`hooks.${key} is defined outside the [hooks] table (dotted key or inline table) — glen only edits the [hooks] table; move it under [hooks] and re-run`);
|
|
111
|
+
else
|
|
112
|
+
out.splice(tableStart + 1, 0, render(key, next));
|
|
113
|
+
}
|
|
114
|
+
const result = `${out.join("\n").replace(/\n*$/, "")}\n`;
|
|
115
|
+
const verify = readHooksTable(result);
|
|
116
|
+
if (!verify.ok)
|
|
117
|
+
return err(`edit produced invalid TOML: ${verify.error}`);
|
|
118
|
+
return hasHookLines(verify.value, lines)
|
|
119
|
+
? ok(result)
|
|
120
|
+
: err("edit did not take effect — the hook lines are still missing");
|
|
121
|
+
};
|
|
122
|
+
const removeHookLines = (toml, lines) => {
|
|
123
|
+
const table = readHooksTable(toml);
|
|
124
|
+
if (!table.ok)
|
|
125
|
+
return table;
|
|
126
|
+
const badKey = Object.keys(lines).find((key) => hookKeyHasUnsupportedShape(toml, key));
|
|
127
|
+
if (badKey)
|
|
128
|
+
return err(`hooks.${badKey} in ~/.jcode/config.toml is not a string or array of strings — glen won't touch it; fix that value and re-run`);
|
|
129
|
+
const out = toml.split("\n");
|
|
130
|
+
const tableStart = out.findIndex((line) => HOOKS_HEADER_RE.test(line));
|
|
131
|
+
if (tableStart === -1)
|
|
132
|
+
return ok(toml);
|
|
133
|
+
for (const [key, line] of Object.entries(lines)) {
|
|
134
|
+
const current = table.value[key];
|
|
135
|
+
if (current === undefined)
|
|
136
|
+
continue;
|
|
137
|
+
const before = typeof current === "string" ? [current] : current;
|
|
138
|
+
const remaining = before.filter((value) => value !== line);
|
|
139
|
+
if (remaining.length === before.length)
|
|
140
|
+
continue;
|
|
141
|
+
const span = keySpan(out, tableStart, key);
|
|
142
|
+
if (!span)
|
|
143
|
+
continue;
|
|
144
|
+
if (remaining.length === 0)
|
|
145
|
+
out.splice(span.start, span.end - span.start + 1);
|
|
146
|
+
else
|
|
147
|
+
out.splice(span.start, span.end - span.start + 1, `${key} = [${remaining.map(quote).join(", ")}]`);
|
|
148
|
+
}
|
|
149
|
+
const result = out.join("\n");
|
|
150
|
+
const verify = readHooksTable(result);
|
|
151
|
+
return verify.ok
|
|
152
|
+
? ok(result)
|
|
153
|
+
: err(`edit produced invalid TOML: ${verify.error}`);
|
|
154
|
+
};
|
|
155
|
+
export { readHooksTable, hasHookLines, upsertHookLines, removeHookLines };
|
|
156
|
+
//# sourceMappingURL=jcode-hooks-toml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcode-hooks-toml.js","sourceRoot":"","sources":["../../src/_utils/jcode-hooks-toml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClC,OAAO,EAAe,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAanD,MAAM,eAAe,GAAG,iCAAiC,CAAC;AAC1D,MAAM,aAAa,GAAG,CAAC,IAAY,EAAW,EAAE,CAC9C,IAAI,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACnC,8EAA8E;AAC9E,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAE/D,MAAM,SAAS,GAAG,CAAC,IAAY,EAA2C,EAAE;IAC1E,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAY,EAA8B,EAAE;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrE,OAAO,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACvC,MAAM,KAAK,GAA+C,EAAE,CAAC;IAC7D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aAC7C,IACH,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACpB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YAEtD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC,CAAC;AAEF,2EAA2E;AAC3E,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,sCAAsC;AACtC,MAAM,0BAA0B,GAAG,CAAC,IAAY,EAAE,GAAW,EAAW,EAAE;IACxE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC,CAAC,oCAAoC;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,SAAS,GACb,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,SAAS,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAiB,EAAE,KAAgB,EAAW,EAAE,CACpE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,OAAO,OAAO,KAAK,QAAQ;QAChC,CAAC,CAAC,OAAO,KAAK,IAAI;QAClB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEL,yEAAyE;AACzE,sEAAsE;AACtE,MAAM,OAAO,GAAG,CACd,KAAwB,EACxB,UAAkB,EAClB,GAAW,EAC4B,EAAE;IACzC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAC3B,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACV,CAAC,GAAG,UAAU;QACd,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CACnB,CAAC;IACF,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CACzE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAC1E,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC;AACtC,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,KAAe,EAAY,EAAE;IACpD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3C,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC,SAAS,CAAC;QACb,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,MAAyB,EAAU,EAAE,CAChE,MAAM,CAAC,MAAM,KAAK,CAAC;IACjB,CAAC,CAAC,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE;IACtC,CAAC,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAEnD,MAAM,eAAe,GAAG,CACtB,IAAY,EACZ,KAAgB,EACQ,EAAE;IAC1B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7C,0BAA0B,CAAC,IAAI,EAAE,GAAG,CAAC,CACtC,CAAC;IACF,IAAI,MAAM;QACR,OAAO,GAAG,CACR,SAAS,MAAM,+GAA+G,CAC/H,CAAC;IACJ,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,IAAI,GACR,OAAO,KAAK,SAAS;YACnB,CAAC,CAAC,CAAC,IAAI,CAAC;YACR,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ;gBAC3B,CAAC,CAAC,OAAO,KAAK,IAAI;oBAChB,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC;gBACnB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACtB,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,IAAI;YACN,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;aAClE,IAAI,OAAO,KAAK,SAAS;YAC5B,OAAO,GAAG,CACR,SAAS,GAAG,0IAA0I,CACvJ,CAAC;;YACC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC;IACzD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,GAAG,CAAC,+BAA+B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1E,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC;QACtC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;QACZ,CAAC,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CACtB,IAAY,EACZ,KAAgB,EACQ,EAAE;IAC1B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7C,0BAA0B,CAAC,IAAI,EAAE,GAAG,CAAC,CACtC,CAAC;IACF,IAAI,MAAM;QACR,OAAO,GAAG,CACR,SAAS,MAAM,+GAA+G,CAC/H,CAAC;IACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,IAAI,UAAU,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;QAC3D,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;YAAE,SAAS;QACjD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;;YAElD,GAAG,CAAC,MAAM,CACR,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EACzB,GAAG,GAAG,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAChD,CAAC;IACN,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,EAAE;QACd,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;QACZ,CAAC,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const jcodeHome: () => string;
|
|
2
|
+
declare const jcodeConfigTomlPath: () => string;
|
|
3
|
+
declare const jcodePromptOverlayPath: () => string;
|
|
4
|
+
declare const jcodePreferredToolsPath: () => string;
|
|
5
|
+
declare const jcodeSkillsDir: () => string;
|
|
6
|
+
declare const jcodeSessionsDir: () => string;
|
|
7
|
+
export { jcodeHome, jcodeConfigTomlPath, jcodePromptOverlayPath, jcodePreferredToolsPath, jcodeSkillsDir, jcodeSessionsDir, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
// JCODE_HOME mirrors jcode's own installer override (`${JCODE_HOME:-$HOME/.jcode}`)
|
|
4
|
+
// so glen's tests and the CI smoke sandbox the config the same way. An empty
|
|
5
|
+
// string counts as unset (|| not ??) so it can never yield a relative path.
|
|
6
|
+
const jcodeHome = () => process.env.JCODE_HOME || join(homedir(), ".jcode");
|
|
7
|
+
const jcodeConfigTomlPath = () => join(jcodeHome(), "config.toml");
|
|
8
|
+
const jcodePromptOverlayPath = () => join(jcodeHome(), "prompt-overlay.md");
|
|
9
|
+
const jcodePreferredToolsPath = () => join(jcodeHome(), "preferred-tools.md");
|
|
10
|
+
const jcodeSkillsDir = () => join(jcodeHome(), "skills");
|
|
11
|
+
const jcodeSessionsDir = () => join(jcodeHome(), "sessions");
|
|
12
|
+
export { jcodeHome, jcodeConfigTomlPath, jcodePromptOverlayPath, jcodePreferredToolsPath, jcodeSkillsDir, jcodeSessionsDir, };
|
|
13
|
+
//# sourceMappingURL=jcode-paths.js.map
|