@tryglen/cli 0.21.0 → 0.23.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 +3 -3
- package/dist/_utils/agent-adapter.d.ts +3 -0
- package/dist/_utils/agent-adapter.js +4 -1
- package/dist/_utils/agent-adapter.js.map +1 -1
- package/dist/_utils/agents-table.d.ts +4 -3
- package/dist/_utils/agents-table.js +18 -1
- package/dist/_utils/agents-table.js.map +1 -1
- package/dist/_utils/detect-transcript-format.d.ts +1 -1
- package/dist/_utils/detect-transcript-format.js +13 -2
- package/dist/_utils/detect-transcript-format.js.map +1 -1
- package/dist/_utils/glen-headers.js +7 -4
- package/dist/_utils/glen-headers.js.map +1 -1
- package/dist/_utils/parse-pi-transcript.d.ts +3 -0
- package/dist/_utils/parse-pi-transcript.js +113 -0
- package/dist/_utils/parse-pi-transcript.js.map +1 -0
- package/dist/_utils/plugin-status.d.ts +1 -1
- package/dist/_utils/plugin-status.js +46 -2
- package/dist/_utils/plugin-status.js.map +1 -1
- package/dist/_utils/state-line.js +3 -2
- package/dist/_utils/state-line.js.map +1 -1
- package/dist/_utils/state.d.ts +1 -1
- package/dist/_utils/state.js +1 -1
- package/dist/_utils/state.js.map +1 -1
- package/dist/_utils/sync-mode-from-server.d.ts +5 -5
- package/dist/_utils/sync-mode-from-server.js +12 -6
- package/dist/_utils/sync-mode-from-server.js.map +1 -1
- package/dist/_utils/transcript-turns.d.ts +1 -1
- package/dist/bin.js +24 -8
- package/dist/bin.js.map +1 -1
- package/dist/commands/artifact.d.ts +1 -0
- package/dist/commands/artifact.js +9 -2
- package/dist/commands/artifact.js.map +1 -1
- package/dist/commands/doctor.js +29 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/import.js +13 -9
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/ingest.js +60 -24
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +12 -6
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/pr-link.js +3 -1
- package/dist/commands/pr-link.js.map +1 -1
- package/dist/commands/search.js +7 -0
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/session-start.js +9 -6
- package/dist/commands/session-start.js.map +1 -1
- package/dist/commands/set-mode.d.ts +5 -5
- package/dist/commands/set-mode.js +12 -10
- package/dist/commands/set-mode.js.map +1 -1
- package/dist/commands/statusline.js +2 -0
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/uninstall.js +6 -1
- package/dist/commands/uninstall.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,12 +17,12 @@ glen login
|
|
|
17
17
|
| `glen logout` | Sign out and remove credentials + session state. |
|
|
18
18
|
| `glen status` | Show connection status, active org, incognito state, and CLI version. |
|
|
19
19
|
| `glen search "<query>"` | Search the team's shared glen memory. |
|
|
20
|
-
| `glen import <path…> [--dry-run]` | Import old local agent transcripts (Claude Code `~/.claude/projects`, Codex `~/.codex/sessions`, Cursor `state.vscdb`) into glen memory. Idempotent — re-running skips already-imported turns. `--dry-run` previews without writing. |
|
|
20
|
+
| `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. |
|
|
21
21
|
| `glen incognito on\|off` | Toggle incognito mode: while on, nothing is recorded (recall keeps working). |
|
|
22
22
|
| `glen org list` | List your organizations; active one is marked with `✓`. |
|
|
23
23
|
| `glen org switch [slug]` | Switch the active organization for this machine (interactive picker without `slug`). |
|
|
24
|
-
| `glen ingest [--agent <name>]` | Ingest a turn from stdin — used by agent hooks (`claude-code` or `
|
|
25
|
-
| `glen install [--agent <claude\|codex>]` | 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>` point at a binary when auto-detection fails. |
|
|
24
|
+
| `glen ingest [--agent <name>]` | Ingest a turn from stdin — used by agent hooks (`claude-code`, `codex`, `cursor`, or `pi`). |
|
|
25
|
+
| `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. |
|
|
26
26
|
| `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. |
|
|
27
27
|
| `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). |
|
|
28
28
|
| `glen statusline` | Output a single status line for the agent's UI status bar — used by hooks. |
|
|
@@ -11,6 +11,9 @@ type AdapterOutput = {
|
|
|
11
11
|
*
|
|
12
12
|
* - "codex": reads model/permission_mode/source + last_assistant_message
|
|
13
13
|
* directly from the event (no transcript file).
|
|
14
|
+
* - "pi": same event-carried shape as codex — the events are authored by
|
|
15
|
+
* glen's own pi extension (packages/pi-plugin/extensions/glen.ts); pi's
|
|
16
|
+
* session file is a pi-specific JSONL tree glen doesn't parse.
|
|
14
17
|
* - "claude-code" and generic/unknown: uses parseTranscript for priorAssistant
|
|
15
18
|
* and the user-message index (nextUserMessageIndex) that callers need for
|
|
16
19
|
* idempotency key derivation.
|
|
@@ -7,6 +7,9 @@ const str = (v) => typeof v === "string" && v ? v : null;
|
|
|
7
7
|
*
|
|
8
8
|
* - "codex": reads model/permission_mode/source + last_assistant_message
|
|
9
9
|
* directly from the event (no transcript file).
|
|
10
|
+
* - "pi": same event-carried shape as codex — the events are authored by
|
|
11
|
+
* glen's own pi extension (packages/pi-plugin/extensions/glen.ts); pi's
|
|
12
|
+
* session file is a pi-specific JSONL tree glen doesn't parse.
|
|
10
13
|
* - "claude-code" and generic/unknown: uses parseTranscript for priorAssistant
|
|
11
14
|
* and the user-message index (nextUserMessageIndex) that callers need for
|
|
12
15
|
* idempotency key derivation.
|
|
@@ -26,7 +29,7 @@ const adaptAgentEvent = (agent, event, transcriptLines) => {
|
|
|
26
29
|
usesTranscript: false,
|
|
27
30
|
};
|
|
28
31
|
}
|
|
29
|
-
if (agent === "codex") {
|
|
32
|
+
if (agent === "codex" || agent === "pi") {
|
|
30
33
|
const fields = {};
|
|
31
34
|
const model = str(event.model);
|
|
32
35
|
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;;;;;;;;;;;;GAYG;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,EAAE,CAAC;QACxC,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,10 +1,11 @@
|
|
|
1
|
+
declare const PI_PLUGIN_SOURCE = "git:github.com/Glen-Web-App/glen-pi-plugin";
|
|
1
2
|
type Agent = {
|
|
2
3
|
readonly name: string;
|
|
3
|
-
readonly bin: "claude" | "codex";
|
|
4
|
+
readonly bin: "claude" | "codex" | "pi";
|
|
4
5
|
readonly steps: readonly (readonly string[])[];
|
|
5
6
|
readonly updateSteps: readonly (readonly string[])[];
|
|
6
|
-
readonly postInstall: "claude" | "codex";
|
|
7
|
+
readonly postInstall: "claude" | "codex" | "pi";
|
|
7
8
|
};
|
|
8
9
|
declare const AGENTS: readonly Agent[];
|
|
9
|
-
export { AGENTS };
|
|
10
|
+
export { AGENTS, PI_PLUGIN_SOURCE };
|
|
10
11
|
export type { Agent };
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// AGENTS table — steps arrays drive the install sequence; updateSteps run
|
|
3
|
+
// instead when the glen plugin is already installed (converge semantics).
|
|
4
|
+
// Steps are run sequentially; a failed step (e.g. `marketplace add` already
|
|
5
|
+
// exists) must NOT block the following steps.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Pi has no marketplace — its package manager installs straight from the dist
|
|
8
|
+
// repo. One source string, shared by install/update/doctor/uninstall so the
|
|
9
|
+
// registration and its converge/removal steps can never drift.
|
|
10
|
+
const PI_PLUGIN_SOURCE = "git:github.com/Glen-Web-App/glen-pi-plugin";
|
|
1
11
|
const AGENTS = [
|
|
2
12
|
{
|
|
3
13
|
name: "Claude Code",
|
|
@@ -21,6 +31,13 @@ const AGENTS = [
|
|
|
21
31
|
updateSteps: [["plugin", "marketplace", "upgrade", "glen"]],
|
|
22
32
|
postInstall: "codex",
|
|
23
33
|
},
|
|
34
|
+
{
|
|
35
|
+
name: "Pi",
|
|
36
|
+
bin: "pi",
|
|
37
|
+
steps: [["install", PI_PLUGIN_SOURCE]],
|
|
38
|
+
updateSteps: [["update", PI_PLUGIN_SOURCE]],
|
|
39
|
+
postInstall: "pi",
|
|
40
|
+
},
|
|
24
41
|
];
|
|
25
|
-
export { AGENTS };
|
|
42
|
+
export { AGENTS, PI_PLUGIN_SOURCE };
|
|
26
43
|
//# sourceMappingURL=agents-table.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-table.js","sourceRoot":"","sources":["../../src/_utils/agents-table.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agents-table.js","sourceRoot":"","sources":["../../src/_utils/agents-table.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,8CAA8C;AAC9C,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,+DAA+D;AAC/D,MAAM,gBAAgB,GAAG,4CAA4C,CAAC;AAUtE,MAAM,MAAM,GAAqB;IAC/B;QACE,IAAI,EAAE,aAAa;QACnB,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE;YACL,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,sCAAsC,CAAC;YACxE,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC;SACnC;QACD,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAChD,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,IAAI,EAAE,OAAO;QACb,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE;YACL,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,gCAAgC,CAAC;YAClE,qEAAqE;YACrE,4DAA4D;YAC5D,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC;SAC/B;QACD,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3D,WAAW,EAAE,OAAO;KACrB;IACD;QACE,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACtC,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC3C,WAAW,EAAE,IAAI;KAClB;CACF,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const detectTranscriptFormat: (filePath: string, sampleLines: readonly string[]) => "claude-code" | "codex" | "cursor" | null;
|
|
1
|
+
declare const detectTranscriptFormat: (filePath: string, sampleLines: readonly string[]) => "claude-code" | "codex" | "cursor" | "pi" | null;
|
|
2
2
|
export { detectTranscriptFormat };
|
|
@@ -17,10 +17,12 @@ const CODEX_ENVELOPE_TYPES = new Set([
|
|
|
17
17
|
"compacted",
|
|
18
18
|
]);
|
|
19
19
|
// Sniff which agent wrote a transcript file. Cursor is identified by its
|
|
20
|
-
// SQLite container; the
|
|
20
|
+
// SQLite container; the JSONL formats are told apart by their envelopes:
|
|
21
21
|
// Claude Code lines carry uuid/parentUuid tree fields, Codex rollout lines a
|
|
22
22
|
// {timestamp, type, payload} wrapper (or, pre-envelope, bare Responses-API
|
|
23
|
-
// message items with input_text/output_text parts)
|
|
23
|
+
// message items with input_text/output_text parts), and pi session files a
|
|
24
|
+
// {type:"session", version, cwd} header plus id/parentId entries wrapping a
|
|
25
|
+
// nested message object.
|
|
24
26
|
const detectTranscriptFormat = (filePath, sampleLines) => {
|
|
25
27
|
if (filePath.endsWith(".vscdb"))
|
|
26
28
|
return "cursor";
|
|
@@ -34,6 +36,15 @@ const detectTranscriptFormat = (filePath, sampleLines) => {
|
|
|
34
36
|
if (typeof e.sessionId === "string" &&
|
|
35
37
|
(e.type === "user" || e.type === "assistant" || e.type === "summary"))
|
|
36
38
|
return "claude-code";
|
|
39
|
+
if (e.type === "session" &&
|
|
40
|
+
typeof e.version === "number" &&
|
|
41
|
+
typeof e.cwd === "string")
|
|
42
|
+
return "pi";
|
|
43
|
+
if (e.type === "message" &&
|
|
44
|
+
"parentId" in e &&
|
|
45
|
+
e.message !== null &&
|
|
46
|
+
typeof e.message === "object")
|
|
47
|
+
return "pi";
|
|
37
48
|
if (typeof e.type === "string" &&
|
|
38
49
|
CODEX_ENVELOPE_TYPES.has(e.type) &&
|
|
39
50
|
"payload" in e)
|
|
@@ -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,
|
|
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,EACoB,EAAE;IACpD,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"}
|
|
@@ -2,10 +2,13 @@ const buildGlenHeaders = ({ key, state, version, }) => ({
|
|
|
2
2
|
"x-api-key": key,
|
|
3
3
|
"x-glen-cli-version": version,
|
|
4
4
|
...(state?.activeOrgId ? { "x-glen-org-id": state.activeOrgId } : {}),
|
|
5
|
-
//
|
|
6
|
-
// nothing while still injecting, and `off` records nothing too (
|
|
7
|
-
// skip injection client-side).
|
|
8
|
-
|
|
5
|
+
// The no-record modes ride the same server header: `incognito` records
|
|
6
|
+
// nothing while still injecting, and `off` records nothing too (its hooks
|
|
7
|
+
// also skip injection client-side). `silent` must NOT send it — silent
|
|
8
|
+
// RECORDS; the server-side preference suppresses the surfacing instead.
|
|
9
|
+
...(state && (state.mode === "incognito" || state.mode === "off")
|
|
10
|
+
? { "x-glen-incognito": "true" }
|
|
11
|
+
: {}),
|
|
9
12
|
});
|
|
10
13
|
export { buildGlenHeaders };
|
|
11
14
|
//# sourceMappingURL=glen-headers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glen-headers.js","sourceRoot":"","sources":["../../src/_utils/glen-headers.ts"],"names":[],"mappings":"AAQA,MAAM,gBAAgB,GAAG,CAAC,EACxB,GAAG,EACH,KAAK,EACL,OAAO,GACS,EAA0B,EAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,GAAG;IAChB,oBAAoB,EAAE,OAAO;IAC7B,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,
|
|
1
|
+
{"version":3,"file":"glen-headers.js","sourceRoot":"","sources":["../../src/_utils/glen-headers.ts"],"names":[],"mappings":"AAQA,MAAM,gBAAgB,GAAG,CAAC,EACxB,GAAG,EACH,KAAK,EACL,OAAO,GACS,EAA0B,EAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,GAAG;IAChB,oBAAoB,EAAE,OAAO;IAC7B,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,wEAAwE;IACxE,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;QAC/D,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE;QAChC,CAAC,CAAC,EAAE,CAAC;CACR,CAAC,CAAC;AAEH,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const parseLine = (line) => {
|
|
2
|
+
try {
|
|
3
|
+
const parsed = JSON.parse(line);
|
|
4
|
+
return parsed !== null && typeof parsed === "object"
|
|
5
|
+
? parsed
|
|
6
|
+
: null;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const messageOf = (e) => e.message !== null && typeof e.message === "object"
|
|
13
|
+
? e.message
|
|
14
|
+
: null;
|
|
15
|
+
// Text of a pi message: a plain string (typical human prompt) or the
|
|
16
|
+
// concatenated `text` content blocks (assistant output; thinking/toolCall/
|
|
17
|
+
// image blocks are not conversation text).
|
|
18
|
+
const textOf = (content) => {
|
|
19
|
+
if (typeof content === "string")
|
|
20
|
+
return content;
|
|
21
|
+
if (!Array.isArray(content))
|
|
22
|
+
return "";
|
|
23
|
+
return content
|
|
24
|
+
.filter((p) => p !== null &&
|
|
25
|
+
typeof p === "object" &&
|
|
26
|
+
p.type === "text" &&
|
|
27
|
+
typeof p.text === "string")
|
|
28
|
+
.map((p) => p.text)
|
|
29
|
+
.join("\n");
|
|
30
|
+
};
|
|
31
|
+
// Pi entries form a tree via id → parentId (branching via /fork and tree
|
|
32
|
+
// navigation creates alternates). Follow the chain up from the active leaf —
|
|
33
|
+
// the last CONVERSATION entry (a message whose role is user/assistant) that is
|
|
34
|
+
// nobody's parent — so abandoned branches aren't imported twice. Restricting
|
|
35
|
+
// leaf candidates to conversation entries matters: bookkeeping entries
|
|
36
|
+
// (labels, custom extension state, model changes) can trail the file as
|
|
37
|
+
// childless nodes, and picking one of those would walk a one-entry branch.
|
|
38
|
+
// Falls back to file order when the chain is unwalkable (format drift).
|
|
39
|
+
const activeBranch = (entries) => {
|
|
40
|
+
const withId = entries.filter((e) => typeof e.id === "string");
|
|
41
|
+
const byId = new Map(withId.map((e) => [e.id, e]));
|
|
42
|
+
const parents = new Set(entries
|
|
43
|
+
.map((e) => e.parentId)
|
|
44
|
+
.filter((p) => typeof p === "string"));
|
|
45
|
+
const childless = [...withId]
|
|
46
|
+
.reverse()
|
|
47
|
+
.filter((e) => !parents.has(e.id));
|
|
48
|
+
const leaf = childless.find((e) => {
|
|
49
|
+
if (e.type !== "message")
|
|
50
|
+
return false;
|
|
51
|
+
const role = messageOf(e)?.role;
|
|
52
|
+
return role === "user" || role === "assistant";
|
|
53
|
+
}) ?? childless[0];
|
|
54
|
+
if (!leaf)
|
|
55
|
+
return entries;
|
|
56
|
+
const walk = (e, acc, seen) => {
|
|
57
|
+
if (!e || typeof e.id !== "string" || seen.has(e.id))
|
|
58
|
+
return acc;
|
|
59
|
+
return walk(typeof e.parentId === "string" ? byId.get(e.parentId) : undefined, [e, ...acc], new Set([...seen, e.id]));
|
|
60
|
+
};
|
|
61
|
+
const chain = walk(leaf, [], new Set());
|
|
62
|
+
return chain.length > 0 ? chain : entries;
|
|
63
|
+
};
|
|
64
|
+
// Parse one pi session file (~/.pi/agent/sessions/<munged-cwd>/
|
|
65
|
+
// <timestamp>_<uuid>.jsonl) into the normalized transcript shape. The first
|
|
66
|
+
// line is a {type:"session"} header carrying the session id and cwd; entry
|
|
67
|
+
// lines wrap AgentMessages ({type:"message", id, parentId, message}). Only
|
|
68
|
+
// user/assistant messages are conversation text — toolResult/bashExecution
|
|
69
|
+
// are tool chatter, and custom-role messages are extension-injected context
|
|
70
|
+
// (glen's own per-turn recall arrives as customType "glen-context"; importing
|
|
71
|
+
// it would feed glen's output back in as memory). Tolerant by design: unknown
|
|
72
|
+
// entry types, missing fields, and unparseable lines are skipped, never fatal.
|
|
73
|
+
const parsePiTranscript = (lines, fallbackSessionId) => {
|
|
74
|
+
const entries = lines.map(parseLine).filter((e) => e !== null);
|
|
75
|
+
const header = entries.find((e) => e.type === "session");
|
|
76
|
+
const conversation = activeBranch(entries.filter((e) => e.type !== "session")).filter((e) => {
|
|
77
|
+
if (e.type !== "message")
|
|
78
|
+
return false;
|
|
79
|
+
const role = messageOf(e)?.role;
|
|
80
|
+
return role === "user" || role === "assistant";
|
|
81
|
+
});
|
|
82
|
+
const messages = [];
|
|
83
|
+
for (const e of conversation) {
|
|
84
|
+
const message = messageOf(e);
|
|
85
|
+
if (!message)
|
|
86
|
+
continue;
|
|
87
|
+
if (message.role === "user") {
|
|
88
|
+
messages.push({ role: "user", text: textOf(message.content) });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
messages.push({ role: "assistant", text: textOf(message.content) });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (messages.every((m) => m.text.trim() === ""))
|
|
95
|
+
return null;
|
|
96
|
+
// Assistant messages carry the model that produced them; the last one wins
|
|
97
|
+
// (the model can change mid-session via /model).
|
|
98
|
+
const lastModel = [...conversation]
|
|
99
|
+
.reverse()
|
|
100
|
+
.map((e) => messageOf(e)?.model)
|
|
101
|
+
.find((m) => typeof m === "string");
|
|
102
|
+
return {
|
|
103
|
+
sessionId: (typeof header?.id === "string" ? header.id : undefined) ??
|
|
104
|
+
fallbackSessionId,
|
|
105
|
+
agent: "pi",
|
|
106
|
+
cwd: typeof header?.cwd === "string" ? header.cwd : undefined,
|
|
107
|
+
branch: undefined,
|
|
108
|
+
model: lastModel,
|
|
109
|
+
messages,
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
export { parsePiTranscript };
|
|
113
|
+
//# sourceMappingURL=parse-pi-transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-pi-transcript.js","sourceRoot":"","sources":["../../src/_utils/parse-pi-transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
type PluginStatus = "installed" | "not-installed" | "unknown";
|
|
2
|
-
declare const glenPluginStatus: (agentBin: "claude" | "codex") => PluginStatus;
|
|
2
|
+
declare const glenPluginStatus: (agentBin: "claude" | "codex" | "pi") => PluginStatus;
|
|
3
3
|
export { glenPluginStatus };
|
|
4
4
|
export type { PluginStatus };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
1
4
|
import { findBin } from "./find-bin.js";
|
|
2
5
|
import { runBin } from "./run-bin.js";
|
|
3
6
|
// A line whose first token is the glen plugin: claude lists `❯ glen@glen`
|
|
@@ -7,10 +10,51 @@ import { runBin } from "./run-bin.js";
|
|
|
7
10
|
// name, so `foo@glen`, `glenda`, or a description merely mentioning glen
|
|
8
11
|
// never false-positives.
|
|
9
12
|
const GLEN_PLUGIN_LINE = /^[\s>❯•*-]*glen(@\S+)?(\s|$)/im;
|
|
10
|
-
//
|
|
11
|
-
|
|
13
|
+
// Pi settings path (GLEN_PI_SETTINGS_PATH env var is for test overrides only).
|
|
14
|
+
const piSettingsPath = () => process.env.GLEN_PI_SETTINGS_PATH ??
|
|
15
|
+
join(homedir(), ".pi", "agent", "settings.json");
|
|
16
|
+
// Pi has no `plugin list` — `pi install` records the package in the `packages`
|
|
17
|
+
// array of ~/.pi/agent/settings.json (string or `{ source }` object entries),
|
|
18
|
+
// so that file is the source of truth. A missing file means pi has no packages
|
|
19
|
+
// at all (fresh install) → not-installed; an unreadable/corrupt file → unknown
|
|
20
|
+
// (callers fall back to attempting an install, which is idempotent).
|
|
21
|
+
const piPluginStatus = () => {
|
|
22
|
+
const raw = (() => {
|
|
23
|
+
try {
|
|
24
|
+
return readFileSync(piSettingsPath(), "utf8");
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
return e.code === "ENOENT" ? "" : null;
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
30
|
+
if (raw === null)
|
|
31
|
+
return "unknown";
|
|
32
|
+
if (raw === "")
|
|
33
|
+
return "not-installed";
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
const packages = Array.isArray(parsed.packages) ? parsed.packages : [];
|
|
37
|
+
const registered = packages.some((entry) => {
|
|
38
|
+
const source = typeof entry === "string"
|
|
39
|
+
? entry
|
|
40
|
+
: entry !== null && typeof entry === "object"
|
|
41
|
+
? entry.source
|
|
42
|
+
: undefined;
|
|
43
|
+
return typeof source === "string" && source.includes("glen-pi-plugin");
|
|
44
|
+
});
|
|
45
|
+
return registered ? "installed" : "not-installed";
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return "unknown";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
// Detects whether the glen plugin is installed for an agent — by parsing
|
|
52
|
+
// `<agent> plugin list` output (claude/codex), or by reading pi's settings
|
|
53
|
+
// file (pi has no plugin-list CLI). "unknown" (agent missing or check failed)
|
|
12
54
|
// lets callers fall back to attempting an install.
|
|
13
55
|
const glenPluginStatus = (agentBin) => {
|
|
56
|
+
if (agentBin === "pi")
|
|
57
|
+
return piPluginStatus();
|
|
14
58
|
const bin = findBin(agentBin);
|
|
15
59
|
if (!bin)
|
|
16
60
|
return "unknown";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-status.js","sourceRoot":"","sources":["../../src/_utils/plugin-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC,0EAA0E;AAC1E,uEAAuE;AACvE,4EAA4E;AAC5E,6EAA6E;AAC7E,yEAAyE;AACzE,yBAAyB;AACzB,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AAE1D,
|
|
1
|
+
{"version":3,"file":"plugin-status.js","sourceRoot":"","sources":["../../src/_utils/plugin-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const formatStateLine = (state) => {
|
|
2
2
|
if (!state)
|
|
3
3
|
return null;
|
|
4
|
-
// Off
|
|
5
|
-
|
|
4
|
+
// Off and silent inject nothing — no status line at all (off short-circuits
|
|
5
|
+
// anyway; silent must put zero bytes of glen into the model's context).
|
|
6
|
+
if (state.mode === "off" || state.mode === "silent")
|
|
6
7
|
return null;
|
|
7
8
|
// Org slugs are auto-generated ("acme-1234") — the NAME is the
|
|
8
9
|
// human-meaningful field, so prefer it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-line.js","sourceRoot":"","sources":["../../src/_utils/state-line.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,CAAC,KAAuB,EAAiB,EAAE;IACjE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"state-line.js","sourceRoot":"","sources":["../../src/_utils/state-line.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,CAAC,KAAuB,EAAiB,EAAE;IACjE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,4EAA4E;IAC5E,wEAAwE;IACxE,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjE,+DAA+D;IAC/D,wCAAwC;IACxC,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,WAAW,CAAC;IAC5E,OAAO,KAAK,CAAC,IAAI,KAAK,WAAW;QAC/B,CAAC,CAAC,eAAe,GAAG,2DAA2D;QAC/E,CAAC,CAAC,eAAe,GAAG,cAAc,CAAC;AACvC,CAAC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/_utils/state.d.ts
CHANGED
package/dist/_utils/state.js
CHANGED
|
@@ -2,7 +2,7 @@ import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fromPromise } from "./result.js";
|
|
5
|
-
const isGlenMode = (v) => v === "on" || v === "off" || v === "incognito";
|
|
5
|
+
const isGlenMode = (v) => v === "on" || v === "off" || v === "incognito" || v === "silent";
|
|
6
6
|
const statePath = () => process.env.GLEN_STATE_PATH ?? join(homedir(), ".glen", "state.json");
|
|
7
7
|
const readState = async () => {
|
|
8
8
|
const raw = await fromPromise(readFile(statePath(), "utf-8"));
|
package/dist/_utils/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/_utils/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/_utils/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { type GlenState } from "./state.js";
|
|
2
2
|
/**
|
|
3
3
|
* Mirror the server-side recording preference (the source of truth, echoed on
|
|
4
|
-
* every turn response as serverIncognito/serverIncognitoUpdatedAt)
|
|
5
|
-
* state, so a dashboard or other-machine toggle reaches this
|
|
6
|
-
* turn. Returns the freshest state for display (re-read
|
|
7
|
-
* caller read before its POST may be stale by now).
|
|
4
|
+
* every turn response as serverIncognito/serverSilent/serverIncognitoUpdatedAt)
|
|
5
|
+
* into local state, so a dashboard or other-machine toggle reaches this
|
|
6
|
+
* machine within one turn. Returns the freshest state for display (re-read
|
|
7
|
+
* here — the state the caller read before its POST may be stale by now).
|
|
8
8
|
*
|
|
9
9
|
* Rules:
|
|
10
10
|
* - `off` is machine-local (hooks short-circuit) and is never overridden remotely.
|
|
11
11
|
* - Last-writer-wins on SERVER timestamps: only apply an echo strictly newer
|
|
12
12
|
* than the last value this machine pushed/applied, so a stale in-flight turn
|
|
13
|
-
* can't undo a `glen incognito|on` that just ran.
|
|
13
|
+
* can't undo a `glen incognito|silent|on` that just ran.
|
|
14
14
|
* - No stored preference server-side (updatedAt null) → nothing authoritative;
|
|
15
15
|
* leave local state alone.
|
|
16
16
|
* - Best-effort: a failed state write just keeps the current state.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { readState, writeState } from "./state.js";
|
|
2
2
|
/**
|
|
3
3
|
* Mirror the server-side recording preference (the source of truth, echoed on
|
|
4
|
-
* every turn response as serverIncognito/serverIncognitoUpdatedAt)
|
|
5
|
-
* state, so a dashboard or other-machine toggle reaches this
|
|
6
|
-
* turn. Returns the freshest state for display (re-read
|
|
7
|
-
* caller read before its POST may be stale by now).
|
|
4
|
+
* every turn response as serverIncognito/serverSilent/serverIncognitoUpdatedAt)
|
|
5
|
+
* into local state, so a dashboard or other-machine toggle reaches this
|
|
6
|
+
* machine within one turn. Returns the freshest state for display (re-read
|
|
7
|
+
* here — the state the caller read before its POST may be stale by now).
|
|
8
8
|
*
|
|
9
9
|
* Rules:
|
|
10
10
|
* - `off` is machine-local (hooks short-circuit) and is never overridden remotely.
|
|
11
11
|
* - Last-writer-wins on SERVER timestamps: only apply an echo strictly newer
|
|
12
12
|
* than the last value this machine pushed/applied, so a stale in-flight turn
|
|
13
|
-
* can't undo a `glen incognito|on` that just ran.
|
|
13
|
+
* can't undo a `glen incognito|silent|on` that just ran.
|
|
14
14
|
* - No stored preference server-side (updatedAt null) → nothing authoritative;
|
|
15
15
|
* leave local state alone.
|
|
16
16
|
* - Best-effort: a failed state write just keeps the current state.
|
|
@@ -25,7 +25,13 @@ const syncModeFromServer = async (json) => {
|
|
|
25
25
|
if (typeof d.serverIncognitoUpdatedAt !== "string")
|
|
26
26
|
return state;
|
|
27
27
|
const updatedAt = d.serverIncognitoUpdatedAt;
|
|
28
|
-
|
|
28
|
+
// One preference row, one timestamp: serverIncognitoUpdatedAt covers both
|
|
29
|
+
// flags. An old server never sends serverSilent — treat missing as false.
|
|
30
|
+
const desired = d.serverIncognito
|
|
31
|
+
? "incognito"
|
|
32
|
+
: d.serverSilent === true
|
|
33
|
+
? "silent"
|
|
34
|
+
: "on";
|
|
29
35
|
if (state.mode === desired)
|
|
30
36
|
return state;
|
|
31
37
|
// ISO-8601 UTC timestamps compare correctly as strings.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-mode-from-server.js","sourceRoot":"","sources":["../../src/_utils/sync-mode-from-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAa,EAA6B,EAAE;IAC5E,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"sync-mode-from-server.js","sourceRoot":"","sources":["../../src/_utils/sync-mode-from-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAa,EAA6B,EAAE;IAC5E,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,CAAC,GAAG,IAIF,CAAC;IACT,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/D,IAAI,OAAO,CAAC,CAAC,wBAAwB,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjE,MAAM,SAAS,GAAG,CAAC,CAAC,wBAAwB,CAAC;IAC7C,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,OAAO,GAAsB,CAAC,CAAC,eAAe;QAClD,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI;YACvB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC;IACX,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACzC,wDAAwD;IACxD,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,SAAS,IAAI,KAAK,CAAC,aAAa;QACvE,OAAO,KAAK,CAAC;IACf,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;IACnE,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7B,CAAC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -4,7 +4,7 @@ type TranscriptMessage = {
|
|
|
4
4
|
};
|
|
5
5
|
type ParsedTranscript = {
|
|
6
6
|
readonly sessionId: string;
|
|
7
|
-
readonly agent: "claude-code" | "codex" | "cursor";
|
|
7
|
+
readonly agent: "claude-code" | "codex" | "cursor" | "pi";
|
|
8
8
|
readonly cwd: string | undefined;
|
|
9
9
|
readonly branch: string | undefined;
|
|
10
10
|
readonly model: string | undefined;
|