@1agents/session-reader 0.6.1 → 0.7.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.
@@ -0,0 +1,20 @@
1
+ import http from 'node:http';
2
+ export declare const DEFAULT_WEB_PORT = 7780;
3
+ export interface WebOptions {
4
+ port?: number;
5
+ host?: string;
6
+ /** Workspace the UI treats as "当前工作区". Defaults to process.cwd(). */
7
+ cwd?: string;
8
+ /** Initial scope dropdown: cwd (default) or global. */
9
+ defaultScope?: 'cwd' | 'global';
10
+ /** Open the page in the default browser after listen. */
11
+ open?: boolean;
12
+ }
13
+ export interface SrUiBoot {
14
+ mode: 'standalone';
15
+ cwd: string;
16
+ title: string;
17
+ defaultScope: 'cwd' | 'global';
18
+ }
19
+ export declare function renderIndexHtml(boot: SrUiBoot): string;
20
+ export declare function serveWeb(options?: WebOptions): Promise<http.Server>;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * `1session web` — a standalone browser for the same session list, chat
3
+ * preview and file ledger the DSH plugin shows. Loopback by default; no
4
+ * DreamMate / DSH runtime required.
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import fs from 'node:fs';
8
+ import http from 'node:http';
9
+ import path from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { handleSessionApi } from './api.js';
12
+ export const DEFAULT_WEB_PORT = 7780;
13
+ function appJsPath() {
14
+ const here = path.dirname(fileURLToPath(import.meta.url));
15
+ const sibling = path.join(here, 'app.js');
16
+ // tsx from src/web → repo dist/src/web/app.js; compiled run → sibling.
17
+ const fromSrc = path.resolve(here, '../../dist/src/web/app.js');
18
+ if (fs.existsSync(fromSrc))
19
+ return fromSrc;
20
+ return sibling;
21
+ }
22
+ export function renderIndexHtml(boot) {
23
+ const bootJson = JSON.stringify(boot).replace(/</g, '\\u003c');
24
+ return `<!DOCTYPE html>
25
+ <html lang="zh-CN">
26
+ <head>
27
+ <meta charset="utf-8" />
28
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
29
+ <title>历史会话 · 1session</title>
30
+ <script>window.__SR_UI__=${bootJson};</script>
31
+ <script src="/app.js" defer></script>
32
+ </head>
33
+ <body></body>
34
+ </html>
35
+ `;
36
+ }
37
+ function openBrowser(url) {
38
+ const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
39
+ const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
40
+ spawn(cmd, args, { stdio: 'ignore', detached: true }).unref();
41
+ }
42
+ export async function serveWeb(options = {}) {
43
+ const host = options.host ?? '127.0.0.1';
44
+ const cwd = options.cwd ?? process.cwd();
45
+ const defaultScope = options.defaultScope ?? 'cwd';
46
+ const boot = {
47
+ mode: 'standalone',
48
+ cwd,
49
+ title: path.basename(cwd) || '当前工作区',
50
+ defaultScope,
51
+ };
52
+ const appJs = appJsPath();
53
+ const server = http.createServer(async (req, res) => {
54
+ const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
55
+ const pathname = url.pathname;
56
+ res.setHeader('Access-Control-Allow-Origin', '*');
57
+ res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
58
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
59
+ if (req.method === 'OPTIONS') {
60
+ res.statusCode = 204;
61
+ res.end();
62
+ return;
63
+ }
64
+ try {
65
+ if (pathname === '/' || pathname === '/index.html') {
66
+ const body = renderIndexHtml(boot);
67
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
68
+ res.end(body);
69
+ return;
70
+ }
71
+ if (pathname === '/app.js') {
72
+ if (!fs.existsSync(appJs)) {
73
+ res.writeHead(500, { 'content-type': 'text/plain; charset=utf-8' });
74
+ res.end('missing dist/src/web/app.js — run npm run build');
75
+ return;
76
+ }
77
+ res.writeHead(200, {
78
+ 'content-type': 'application/javascript; charset=utf-8',
79
+ 'cache-control': 'no-store',
80
+ });
81
+ res.end(fs.readFileSync(appJs));
82
+ return;
83
+ }
84
+ if (pathname.startsWith('/api/session-reader')) {
85
+ const apiPath = pathname.replace(/^\/api\/session-reader/, '') || '/';
86
+ const handled = await handleSessionApi(apiPath, url, res, { fallbackCwd: cwd });
87
+ if (handled)
88
+ return;
89
+ res.writeHead(404, { 'content-type': 'application/json; charset=utf-8' });
90
+ res.end(JSON.stringify({ error: 'Endpoint not found' }));
91
+ return;
92
+ }
93
+ res.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' });
94
+ res.end('Not found');
95
+ }
96
+ catch (err) {
97
+ const message = err instanceof Error ? err.message : String(err);
98
+ if (!res.headersSent) {
99
+ res.writeHead(500, { 'content-type': 'application/json; charset=utf-8' });
100
+ }
101
+ res.end(JSON.stringify({ error: message }));
102
+ }
103
+ });
104
+ const wanted = options.port ?? DEFAULT_WEB_PORT;
105
+ await new Promise((resolve, reject) => {
106
+ server.once('error', (error) => {
107
+ reject(error.code === 'EADDRINUSE'
108
+ ? new Error(`端口 ${wanted} 已被占用。换一个:1session web --port <n>;或先停掉占用它的进程:` +
109
+ `lsof -nP -iTCP:${wanted} -sTCP:LISTEN`)
110
+ : error);
111
+ });
112
+ server.listen(wanted, host, resolve);
113
+ });
114
+ const { port } = server.address();
115
+ const origin = `http://${host}:${port}`;
116
+ console.log('1session web — 独立历史会话浏览器');
117
+ console.log(` ${origin}`);
118
+ console.log(` 工作区 ${cwd}`);
119
+ console.log(' 列表只拉元数据,点击会话后再加载对话与文件。Ctrl+C 退出。');
120
+ if (host !== '127.0.0.1' && host !== 'localhost' && host !== '::1') {
121
+ console.warn(` ⚠️ 绑定在 ${host}:会话原文(代码、shell 历史、密钥)将对该网络开放。`);
122
+ }
123
+ if (options.open)
124
+ openBrowser(origin);
125
+ return server;
126
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1agents/session-reader",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Read Plane: cross-agent session discovery, turn inspection, workspace aggregation and distillation from raw local session files.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -29,6 +29,23 @@
29
29
  ".": {
30
30
  "types": "./dist/src/index.d.ts",
31
31
  "import": "./dist/src/index.js"
32
+ },
33
+ "./client": {
34
+ "types": "./dist/src/dsh/client.d.ts",
35
+ "default": "./dist/src/dsh/client.js"
36
+ },
37
+ "./dsh": {
38
+ "types": "./dist/src/dsh/index.d.ts",
39
+ "import": "./dist/src/dsh/index.js"
40
+ },
41
+ "./cordis.patch.yml": "./cordis.patch.yml"
42
+ },
43
+ "dsh": {
44
+ "bundle": {
45
+ "patch": "./cordis.patch.yml"
46
+ },
47
+ "client": {
48
+ "platform": "web"
32
49
  }
33
50
  },
34
51
  "bin": {
@@ -37,6 +54,7 @@
37
54
  "files": [
38
55
  "dist",
39
56
  "skills",
57
+ "cordis.patch.yml",
40
58
  "README.md"
41
59
  ],
42
60
  "publishConfig": {
@@ -44,9 +62,9 @@
44
62
  "provenance": true
45
63
  },
46
64
  "scripts": {
47
- "build": "tsc -p tsconfig.build.json",
65
+ "build": "tsc -p tsconfig.build.json && node scripts/bundle-client.js",
48
66
  "typecheck": "tsc -p tsconfig.json --noEmit",
49
- "test": "node --import tsx --test test/session-reader.test.ts",
67
+ "test": "node --import tsx --test test/session-reader.test.ts test/dsh-adapter.test.ts test/web.test.ts",
50
68
  "prepack": "npm run build",
51
69
  "1session": "tsx bin/1session.ts"
52
70
  },
@@ -55,11 +73,14 @@
55
73
  },
56
74
  "devDependencies": {
57
75
  "@types/node": "^22.10.2",
76
+ "esbuild": "^0.28.2",
58
77
  "tsx": "^4.19.2",
59
78
  "typescript": "^5.7.2"
60
79
  },
61
80
  "dependencies": {
81
+ "@1agents/chat-ui": "^0.1.0",
62
82
  "@1agents/dreammate-network": "^0.3.0",
63
- "@1agents/dreammate-node": "^0.3.0"
83
+ "@1agents/dreammate-node": "^0.4.0",
84
+ "preact": "^10.19.6"
64
85
  }
65
86
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: 1session
3
- description: Search and read the user's past AI coding sessions across Claude Code, Codex, Antigravity, Grok and DeepSeek Harness (dsh) from their raw local session files, using the `1session` CLI. Use this whenever the user refers to work they did in an earlier session rather than in this conversation — "上次/之前/昨天我们改了什么", "那个报错后来怎么解决的", "我在哪个会话里提过 X", "这个功能是哪一轮加的", "codex 那边做到哪了", "grok/dsh 那边呢", "跨项目找一下", "整理一下最近几天的会话/写个周报". Also reach for it proactively, before asking the user to re-explain context they have obviously already established with some agent on this machine — the answer is usually already on disk. Read-only: it never modifies or resumes a session.
3
+ description: 通过 1session CLI 从本地原始会话文件中检索并读取用户在 Claude Code、Codex、Antigravity、Grok 和 DeepSeek Harness (dsh) 中沉淀的历史 AI 编程会话。每当用户提及之前会话中完成的工作而非当前对话内容时激活此技能——例如“上次/之前/昨天我们改了什么”、“那个报错后来怎么解决的”、“我在哪个会话里提过 X”、“这个功能是哪一轮加的”、“codex 那边做到哪了”、“grok/dsh 那边呢”、“跨项目找一下”、“整理一下最近几天的会话/写个周报”。在要求用户重复解释本机上已有明确记录的上下文之前,也应主动调用此技能——答案通常已保存在磁盘中。纯只读设计:绝不修改或恢复历史会话。本技能还包含自身的自举运行与分发逻辑:在未安装 1session CLI 时自动降级为 npx 随用随走,并支持将包全局安装以及一键同步技能至全部五款 Agent——因此当用户要求安装、升级、卸载、分享或分发 1session / session-reader,或报告未找到 1session 命令时也可使用本技能。
4
4
  ---
5
5
 
6
6
  # 1session — the cross-agent Read Plane
@@ -19,15 +19,52 @@ normalizes all of them and answers questions about what actually happened.
19
19
  Everything is derived from the raw files at read time. Nothing is written back to
20
20
  them, no daemon is involved, and no session is ever resumed or modified.
21
21
 
22
- ## Before the first call
22
+ ## Bootstrap: get the CLI, then answer the question
23
23
 
24
- Run `1session help`. If the command is missing, fall back to
25
- `npx -y @1agents/session-reader` in place of `1session` everywhere below, and
26
- mention the one-time fix once: `npm i -g @1agents/session-reader`.
24
+ This skill travels on its own. Someone may have dropped `SKILL.md` into an agent
25
+ on a machine where the `1session` CLI does not exist, so the first call is a
26
+ probe rather than an assumption:
27
27
 
28
- The first run on a machine parses every session (~10s for a few hundred); after
29
- that an index makes each call sub-second. If a call feels slow, it is that first
30
- build, not a hang.
28
+ ```bash
29
+ 1session help
30
+ ```
31
+
32
+ If that fails, **do not stop to install before answering.** `npx` runs the same
33
+ CLI with nothing installed:
34
+
35
+ ```bash
36
+ npx -y @1agents/session-reader@latest list --global --limit 10
37
+ ```
38
+
39
+ Substitute `npx -y @1agents/session-reader@latest` for `1session` everywhere
40
+ below, answer the question the user actually asked, and offer the permanent
41
+ install once, afterwards. Someone asking where last week's bug got fixed wants
42
+ the bug, not a setup errand.
43
+
44
+ The permanent install, when they want it:
45
+
46
+ ```bash
47
+ npm i -g @1agents/session-reader # requires Node >= 22.15
48
+ 1session skill install # put this skill into every agent on the machine
49
+ ```
50
+
51
+ Node below 22.15 is a hard stop rather than a warning — the reader needs
52
+ `node:sqlite` for the index and `node:zlib`'s zstd to read dsh's compressed
53
+ sessions, and `npx` does not rescue an old runtime either. Check `node -v`, say
54
+ plainly that Node needs upgrading, and don't improvise around it.
55
+
56
+ That second command is what makes this spread: one run installs the skill into
57
+ Claude Code, Codex, Antigravity, Grok and dsh at once, so whichever agent the
58
+ user opens next already knows their history is readable. Run it after a global
59
+ install, **not** through `npx` — npx installs the package into a cache directory
60
+ that npm later garbage-collects, and the skill links would dangle with it.
61
+
62
+ `references/install.md` has the rest: PATH and permission failures, link vs copy,
63
+ upgrading, uninstalling, and what to hand someone who wants this on their own
64
+ machine. Read it when an install misbehaves or the user asks how to share this.
65
+
66
+ The first real run parses every session (~10s for a few hundred); an index makes
67
+ each call after that sub-second. A slow first call is that build, not a hang.
31
68
 
32
69
  ## Pick the command from the question
33
70
 
@@ -42,6 +79,7 @@ whole ladder by reflex:
42
79
  | "find where we talked about X / which turn was that" | `turns` |
43
80
  | "what exactly did it do at step N" | `turn <n>`, then `--event k` |
44
81
  | "what did all the agents do in this project" | `workspace` |
82
+ | "open a browser / web UI for sessions" (no DSH) | `web` |
45
83
 
46
84
  "What happened in that session" and "find where we talked about X" look like the
47
85
  same question and are not. `overview` compresses a session into statistics and
@@ -42,6 +42,48 @@
42
42
  "Gives a drill-down handle — a turn/event number or an exact command the user can run to see the evidence",
43
43
  "Reports how it was verified (tests green / the commit) rather than only describing the change"
44
44
  ]
45
+ },
46
+ {
47
+ "id": 3,
48
+ "name": "missing-cli-still-answers",
49
+ "prompt": "上周我在这台机器上调一个超时的问题,后来是怎么解决的?(顺便说一句,我这台机器上好像没装过什么 1session,`1session` 这个命令敲下去是 command not found)",
50
+ "expected_output": "Recognizes the CLI is absent, immediately falls back to `npx -y @1agents/session-reader@latest ...` to actually answer the timeout question, and only then mentions the permanent install as a one-time follow-up — rather than stopping to install first or declaring it cannot help.",
51
+ "files": [],
52
+ "assertions": [
53
+ "Falls back to npx (`npx -y @1agents/session-reader@latest ...`) instead of stopping at the missing command",
54
+ "Actually attempts to answer the user's timeout question rather than turning the turn into a setup errand",
55
+ "Mentions the permanent install (`npm i -g @1agents/session-reader`) as an optional follow-up, not as a precondition",
56
+ "Does not run a global npm install without the user agreeing to it first",
57
+ "Does not claim the question is unanswerable because the CLI is missing"
58
+ ]
59
+ },
60
+ {
61
+ "id": 4,
62
+ "name": "distribute-to-a-colleague",
63
+ "prompt": "同事看我能翻出以前会话的记录,也想在他 mac 上用。我要发给他什么?他那边只装了 claude code 和 codex,另外他 node 好像还是 20。",
64
+ "expected_output": "Gives the two-line install (npm i -g, then `1session skill install`), explains that the second line is what puts the skill into Claude Code and Codex, and flags that Node 20 is below the 22.15 floor so he must upgrade Node first — npx will not work around it either.",
65
+ "files": [],
66
+ "assertions": [
67
+ "Gives `npm i -g @1agents/session-reader` as the install command",
68
+ "Includes `1session skill install` and explains it is what puts the skill into the colleague's agents, not just the CLI",
69
+ "Flags Node 20 as below the >= 22.15 requirement and says it must be upgraded",
70
+ "Does not suggest npx as a way around the old Node version (it runs on the same runtime and fails identically)",
71
+ "Does not invent an install path that does not exist (no curl|sh script, no brew formula, no manual git clone as the primary route)"
72
+ ]
73
+ },
74
+ {
75
+ "id": 5,
76
+ "name": "npx-skill-install-trap",
77
+ "prompt": "我不想全局装东西,能不能直接用 npx 把这个 skill 装到我的 claude 和 codex 里就好?",
78
+ "expected_output": "Warns that `skill install` in its default link mode would point at the npx cache directory, which npm garbage-collects — the skill would silently vanish later. Offers `--copy` as the npx-compatible route, or a global install as the robust one.",
79
+ "files": [],
80
+ "assertions": [
81
+ "Warns that a link-mode install via npx points into the npx cache (~/.npm/_npx/...) which npm later prunes",
82
+ "Names the consequence concretely: the skill silently disappears from the agents afterwards",
83
+ "Offers `--copy` as the way to make an npx-based install survive, and/or a global install as the robust alternative",
84
+ "Mentions `--agent claude,codex` or otherwise respects that the user only wants those two",
85
+ "Does not simply tell the user to run `npx ... skill install` with no caveat"
86
+ ]
45
87
  }
46
88
  ]
47
- }
89
+ }
@@ -141,6 +141,22 @@ The file ledger never contains `candidate` paths — a path only enters after a
141
141
  write is proven. Here-doc bodies are stripped before command analysis, so source
142
142
  code being written to a file cannot masquerade as a redirect or an `ssh` host.
143
143
 
144
+ ## Standalone web UI
145
+
146
+ ```
147
+ 1session web [--port 7780] [--host 127.0.0.1] [--open] [--scope <path>|cwd|global]
148
+ ```
149
+
150
+ A local browser for the same session list, chat preview and file ledger the DSH
151
+ plugin shows. Does not require DSH. Default bind is loopback `127.0.0.1:7780`.
152
+
153
+ The listing is metadata-only; clicking a row loads that session's turns and
154
+ files. `--open` launches the default browser. `--scope global` starts the UI
155
+ on every workspace; a path scopes "当前工作区" to that directory.
156
+
157
+ This is not `1session serve`. `serve` is the DreamMate Network JSON service;
158
+ `web` is a human-facing page.
159
+
144
160
  ## Index and graph
145
161
 
146
162
  ```
@@ -0,0 +1,195 @@
1
+ # Installing and spreading 1session
2
+
3
+ Read this when the probe in SKILL.md fails in a way the two-line fallback does
4
+ not cover, or when the user asks how to get this onto another machine or into
5
+ another agent.
6
+
7
+ - [What it needs](#what-it-needs)
8
+ - [Three ways to run it](#three-ways-to-run-it)
9
+ - [Spreading the skill to every agent](#spreading-the-skill-to-every-agent)
10
+ - [Upgrading](#upgrading)
11
+ - [Uninstalling](#uninstalling)
12
+ - [Handing it to someone else](#handing-it-to-someone-else)
13
+ - [Troubleshooting](#troubleshooting)
14
+
15
+ ## What it needs
16
+
17
+ **Node.js >= 22.15**, and nothing else. The version floor is real, not
18
+ defensive: the index is `node:sqlite` and dsh's sessions are zstd-compressed,
19
+ which only landed in `node:zlib` in 22.15. On an older runtime the package
20
+ installs and then fails at the first call, so check first:
21
+
22
+ ```bash
23
+ node -v
24
+ ```
25
+
26
+ If it is below 22.15, say so and stop. `npx` runs the same code on the same
27
+ runtime and will fail identically — there is no way around it except upgrading
28
+ Node (`nvm install 22`, `brew upgrade node`, or whatever that machine uses).
29
+
30
+ Everything else is already on the machine. The only runtime dependency is
31
+ `@1agents/dreammate-network` (12 kB, zero dependencies of its own), which npm
32
+ pulls in automatically. There is no daemon, no service to start, no config file,
33
+ and no account. The reader opens session files the agents already wrote and
34
+ never writes back to them.
35
+
36
+ macOS, Linux and WSL all work. On native Windows the paths it reads
37
+ (`~/.claude`, `~/.codex`, …) resolve through `os.homedir()`, but it is the least
38
+ exercised platform — if something looks wrong there, check that the agent in
39
+ question actually stores sessions under the Windows home directory before
40
+ assuming the reader is broken.
41
+
42
+ ## Three ways to run it
43
+
44
+ **Zero install (`npx`).** Correct for a one-off answer, for a machine you are
45
+ only visiting, and for the first call before anyone has agreed to install
46
+ anything:
47
+
48
+ ```bash
49
+ npx -y @1agents/session-reader@latest list --global --limit 10
50
+ ```
51
+
52
+ Every command in SKILL.md works with this prefix substituted for `1session`.
53
+ The cost is a few seconds of download per invocation and a cache directory npm
54
+ cleans up on its own schedule — fine for answering, wrong as a permanent setup
55
+ (see the warning under [spreading](#spreading-the-skill-to-every-agent)).
56
+
57
+ **Global install.** The normal choice for a machine the user works on daily:
58
+
59
+ ```bash
60
+ npm i -g @1agents/session-reader
61
+ 1session help # verify: prints the command list
62
+ ```
63
+
64
+ **As a library.** The parsers and ledgers are exported, so a script can consume
65
+ sessions without shelling out:
66
+
67
+ ```bash
68
+ npm i @1agents/session-reader
69
+ ```
70
+
71
+ ```js
72
+ import { listSessions } from '@1agents/session-reader';
73
+ ```
74
+
75
+ Reach for this only when the user is building something on top of session data.
76
+ For answering questions about the past, the CLI is both cheaper and denser.
77
+
78
+ ## Spreading the skill to every agent
79
+
80
+ The package ships this skill inside it, and the CLI installs it into every
81
+ agent's skills directory in one call:
82
+
83
+ ```bash
84
+ 1session skill install # all agents found on this machine
85
+ 1session skill status # what is installed where, and whether it is current
86
+ 1session skill uninstall # remove it again
87
+ ```
88
+
89
+ | Agent | Where it lands |
90
+ | --- | --- |
91
+ | claude | `~/.claude/skills/1session` |
92
+ | codex | `~/.codex/skills/1session` |
93
+ | antigravity | `~/.gemini/antigravity/skills/1session` (**not** `~/.gemini/skills`, which is gemini-cli's) |
94
+ | grok | `~/.grok/skills/1session` |
95
+ | dsh | `~/.dsh/skills/1session` |
96
+
97
+ All five load `<dir>/<name>/SKILL.md` with the same YAML frontmatter, so it is
98
+ genuinely one file serving five agents, not five ports of it.
99
+
100
+ **Do not run `skill install` through `npx`.** In link mode — the default — the
101
+ installed entry is a symlink back to wherever the package lives, and under npx
102
+ that is a cache directory like `~/.npm/_npx/<hash>/node_modules/…` which npm
103
+ garbage-collects. The skill works right up until the day the cache is pruned and
104
+ then silently disappears from all five agents. Install the package globally
105
+ first and then run `skill install`; if you truly must bootstrap through npx, use
106
+ `--copy` so the bytes are owned by the agent rather than borrowed from a cache.
107
+
108
+ Link mode is otherwise the better default: after `npm i -g …@latest`, every
109
+ agent is already looking at the new skill with nothing to re-run. Use `--copy`
110
+ when an agent's loader does not follow symlinks — the symptom is `skill status`
111
+ reporting a healthy link while the agent itself never mentions the skill. The
112
+ cost of a copy is that upgrades no longer propagate; `skill status` marks a copy
113
+ that has drifted from the installed package, so the drift is visible rather than
114
+ silent.
115
+
116
+ Other flags:
117
+
118
+ | Flag | Why |
119
+ | --- | --- |
120
+ | `--agent claude,codex` | Only these. Named agents get their skills directory created even if the agent is not installed yet, which is how you set a machine up before installing the agent. |
121
+ | `--copy` | Copy instead of symlink. |
122
+ | `--force` | Overwrite a same-named entry that this installer did not create, or convert an existing copy into a link. Without it, both cases are refused rather than clobbered. |
123
+ | `--dry-run` | Print the plan and touch nothing. Worth doing first on someone else's machine. |
124
+ | `--json` | Machine-readable result. |
125
+
126
+ Agents that are not installed are skipped rather than failed, so a machine with
127
+ only Claude Code reports three skips and one install, and that is success.
128
+
129
+ ## Upgrading
130
+
131
+ ```bash
132
+ npm i -g @1agents/session-reader@latest
133
+ ```
134
+
135
+ Linked skills are current the moment that finishes. Copied ones need
136
+ `1session skill install --copy --force` afterwards; `1session skill status` is
137
+ what tells you which case you are in.
138
+
139
+ The index rebuilds itself when the parser version moves, so an upgrade that
140
+ changes how sessions are read costs one slower call and needs no manual
141
+ clearing. To force it: `1session index --all --global`.
142
+
143
+ ## Uninstalling
144
+
145
+ ```bash
146
+ 1session skill uninstall # remove the skill from the agents
147
+ npm rm -g @1agents/session-reader
148
+ rm -rf ~/.1agents/session-reader # the index; sessions themselves are untouched
149
+ ```
150
+
151
+ `skill uninstall` only removes entries it could have created (its own links and
152
+ copies); anything else needs `--force`, which exists so a hand-written skill of
153
+ the same name is never deleted by accident. Nothing here touches the agents'
154
+ session files — the reader has never written to them.
155
+
156
+ ## Handing it to someone else
157
+
158
+ The whole thing is one npm package, so the shortest correct instruction is two
159
+ lines:
160
+
161
+ ```bash
162
+ npm i -g @1agents/session-reader
163
+ 1session skill install
164
+ ```
165
+
166
+ That is the version to paste into a chat or a README. It gets them the CLI and
167
+ puts the skill into every agent they have, which is the part people forget: a
168
+ colleague who installs only the CLI has to remember it exists, while one who ran
169
+ both lines has their agent remember for them.
170
+
171
+ If they cannot install globally (locked-down machine, shared box), the npx form
172
+ plus `skill install --copy` gets them to the same place with the package living
173
+ in a cache instead of `/usr/local`.
174
+
175
+ If they want to read the source or file a bug:
176
+ <https://github.com/scottzx/session-reader>.
177
+
178
+ When you are the one setting this up on a user's machine, prefer offering these
179
+ commands over running them unasked — a global npm install changes their system.
180
+ Running the read-only CLI to answer a question is not the same kind of act as
181
+ installing software, and the difference is worth respecting.
182
+
183
+ ## Troubleshooting
184
+
185
+ | Symptom | What is actually wrong |
186
+ | --- | --- |
187
+ | `1session: command not found` right after `npm i -g` | npm's global bin directory is not on `PATH`. It is `$(npm prefix -g)/bin` — `npm bin -g` was removed in npm 9, so use the prefix form — and it goes in the shell profile. Meanwhile `npx -y @1agents/session-reader@latest …` works unchanged. |
188
+ | `EACCES` / permission denied during `npm i -g` | The global prefix is root-owned. Do not reach for `sudo npm` — repoint the prefix (`npm config set prefix ~/.npm-global`, then put `~/.npm-global/bin` on `PATH`) or use a Node version manager, both of which leave the system directories alone. |
189
+ | Installs fine, then throws on the first real command | Almost always Node < 22.15 — `node:sqlite` or zstd missing. Check `node -v`. |
190
+ | `skill status` shows a healthy link, but the agent never uses the skill | That agent's loader does not follow symlinks. `1session skill install --copy --force`. |
191
+ | The skill vanished from every agent at once | It was installed in link mode from an npx cache that npm has since pruned. Install the package globally, then `1session skill install --force`. |
192
+ | `skill install` reports `blocked` | Something else already owns that name — a hand-written skill, or a copy where a link is wanted. Look at it before passing `--force`. |
193
+ | The first call takes ~10s | That is the initial index build over every session on the machine, not a hang. Subsequent calls are sub-second. |
194
+ | Results look stale or wrong | `1session index --all --global` rebuilds, and `--no-index` on any command reads the raw files directly — if those two disagree, that is a real bug worth reporting. |
195
+ | `list` returns nothing in a directory that definitely had sessions | Scope, not installation. `list` defaults to the pwd subtree; add `--global`. |