@lnar/cli 0.0.1-dev.e586780 → 0.0.1-dev.f1f5888
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/dist/api-client.js +2 -0
- package/dist/api-client.js.map +1 -1
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +68 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/daemon.d.ts +2 -0
- package/dist/commands/daemon.js +87 -1
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +19 -9
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/scan.js +12 -0
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/sync.js +3 -0
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/up.js +19 -0
- package/dist/commands/up.js.map +1 -1
- package/dist/machine-id.d.ts +2 -0
- package/dist/machine-id.js +48 -0
- package/dist/machine-id.js.map +1 -0
- package/dist/pending-client.d.ts +1 -1
- package/dist/scanners/claude-code-skills.d.ts +6 -0
- package/dist/scanners/claude-code-skills.js +201 -0
- package/dist/scanners/claude-code-skills.js.map +1 -0
- package/dist/scanners/claude-code.js +10 -3
- package/dist/scanners/claude-code.js.map +1 -1
- package/dist/scanners/index.js +3 -2
- package/dist/scanners/index.js.map +1 -1
- package/dist/sse-client.d.ts +72 -0
- package/dist/sse-client.js +174 -0
- package/dist/sse-client.js.map +1 -0
- package/dist/types.d.ts +43 -3
- package/dist/types.js +34 -2
- package/dist/types.js.map +1 -1
- package/dist/writers/claude-code.js +31 -10
- package/dist/writers/claude-code.js.map +1 -1
- package/dist/writers/registry.js +0 -4
- package/dist/writers/registry.js.map +1 -1
- package/package.json +1 -1
- package/dist/scanners/chatgpt.d.ts +0 -20
- package/dist/scanners/chatgpt.js +0 -49
- package/dist/scanners/chatgpt.js.map +0 -1
- package/dist/writers/chatgpt.d.ts +0 -8
- package/dist/writers/chatgpt.js +0 -12
- package/dist/writers/chatgpt.js.map +0 -1
package/dist/pending-client.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export type PendingAction = 'add_server' | 'remove_server' | 'install_plugin' | 'uninstall_plugin' | 'enable_plugin' | 'disable_plugin';
|
|
11
11
|
export type PendingStatus = 'pending' | 'applied' | 'failed' | 'cancelled';
|
|
12
|
-
export type AgentKind = 'claude_code' | 'codex' | 'cursor' | 'gemini_cli'
|
|
12
|
+
export type AgentKind = 'claude_code' | 'codex' | 'cursor' | 'gemini_cli';
|
|
13
13
|
export type SourceScope = 'global' | 'project' | 'local' | 'remote';
|
|
14
14
|
export type PluginScope = 'user' | 'local' | 'project';
|
|
15
15
|
export interface PendingSpec {
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code の skill インストール状態をスキャンする。
|
|
3
|
+
*
|
|
4
|
+
* skill とは: `<scope>/.claude/skills/<name>/SKILL.md` に置かれた agent 用の
|
|
5
|
+
* 「呼び出し可能な手順書」。各 SKILL.md は YAML frontmatter で `name` と
|
|
6
|
+
* `description` を宣言する。
|
|
7
|
+
*
|
|
8
|
+
* スキャン対象:
|
|
9
|
+
* - user: ~/.claude/skills/<name>/SKILL.md
|
|
10
|
+
* - project: <projectDir>/.claude/skills/<name>/SKILL.md
|
|
11
|
+
* ※ `<projectDir>` は `~/.claude.json#projects` に登録されたパスと
|
|
12
|
+
* 現在の cwd を巡回する (claude-code.ts の MCP スキャンと同じ流儀)
|
|
13
|
+
*
|
|
14
|
+
* 明示的に **対象外**:
|
|
15
|
+
* - ~/.claude/plugins/.../skills/<name>/SKILL.md (plugin 同梱)
|
|
16
|
+
* plugin の情報自体が別途 plugin scanner で取れているため、ここで二重送信しない。
|
|
17
|
+
*
|
|
18
|
+
* 値ではなく状態 (どの skill が入っていて、その frontmatter は何か) だけを送る。
|
|
19
|
+
* SKILL.md 本文は contentHash 経由で「変わったかどうか」だけ追跡する。
|
|
20
|
+
*/
|
|
21
|
+
import { createHash } from 'node:crypto';
|
|
22
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
23
|
+
import { homedir } from 'node:os';
|
|
24
|
+
import { join } from 'node:path';
|
|
25
|
+
import { readJsonIfExists } from './_normalize.js';
|
|
26
|
+
/**
|
|
27
|
+
* YAML frontmatter の最小パーサ。
|
|
28
|
+
*
|
|
29
|
+
* SKILL.md は実質的に `name:` と `description:` の 2 キーしか使わないので、
|
|
30
|
+
* 完全な YAML パーサは入れず、以下のサブセットだけ扱う:
|
|
31
|
+
* - `key: value` (single-line scalar)
|
|
32
|
+
* - `key: "value"` / `'value'` (quoted scalar)
|
|
33
|
+
* - `key: >` / `key: |` の後の indent された継続行 (folded / literal block scalar)
|
|
34
|
+
*
|
|
35
|
+
* これ以外 (リスト、ネスト、anchor 等) は SKILL.md には現れないので未対応。
|
|
36
|
+
* 想定外の構文が来たら値は空文字になり、上位で `null` 扱いされて drop される。
|
|
37
|
+
*/
|
|
38
|
+
const parseFrontmatter = (text) => {
|
|
39
|
+
// 先頭が `---\n` で始まらなければ frontmatter なし
|
|
40
|
+
if (!text.startsWith('---\n') && !text.startsWith('---\r\n'))
|
|
41
|
+
return null;
|
|
42
|
+
const lines = text.split(/\r?\n/);
|
|
43
|
+
// 最初の `---` を飛ばし、次の `---` (or `...`) までを frontmatter とみなす
|
|
44
|
+
let endIdx = -1;
|
|
45
|
+
for (let i = 1; i < lines.length; i++) {
|
|
46
|
+
const trimmed = lines[i]?.trim();
|
|
47
|
+
if (trimmed === '---' || trimmed === '...') {
|
|
48
|
+
endIdx = i;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (endIdx === -1)
|
|
53
|
+
return null;
|
|
54
|
+
const result = {};
|
|
55
|
+
let i = 1;
|
|
56
|
+
while (i < endIdx) {
|
|
57
|
+
const line = lines[i] ?? '';
|
|
58
|
+
const m = line.match(/^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/);
|
|
59
|
+
if (!m) {
|
|
60
|
+
i += 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const [, key, rawValueRaw] = m;
|
|
64
|
+
if (!key) {
|
|
65
|
+
i += 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const rawValue = (rawValueRaw ?? '').trim();
|
|
69
|
+
if (rawValue === '>' || rawValue === '|') {
|
|
70
|
+
// block scalar: 次の indented 行を全て集める
|
|
71
|
+
const collected = [];
|
|
72
|
+
const baseIndent = (lines[i + 1] ?? '').match(/^(\s*)/)?.[1]?.length ?? 0;
|
|
73
|
+
let j = i + 1;
|
|
74
|
+
while (j < endIdx) {
|
|
75
|
+
const nextLine = lines[j] ?? '';
|
|
76
|
+
if (nextLine.trim() === '') {
|
|
77
|
+
collected.push('');
|
|
78
|
+
j += 1;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const indent = nextLine.match(/^(\s*)/)?.[1]?.length ?? 0;
|
|
82
|
+
if (indent < Math.max(baseIndent, 1))
|
|
83
|
+
break;
|
|
84
|
+
collected.push(nextLine.slice(baseIndent));
|
|
85
|
+
j += 1;
|
|
86
|
+
}
|
|
87
|
+
result[key] =
|
|
88
|
+
rawValue === '>' ? collected.join(' ').replace(/\s+/g, ' ').trim() : collected.join('\n');
|
|
89
|
+
i = j;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// single-line: クォート除去のみ最小対応
|
|
93
|
+
result[key] = stripQuotes(rawValue);
|
|
94
|
+
i += 1;
|
|
95
|
+
}
|
|
96
|
+
const name = result.name?.trim();
|
|
97
|
+
const description = result.description?.trim();
|
|
98
|
+
if (!name || !description)
|
|
99
|
+
return null;
|
|
100
|
+
return { name, description };
|
|
101
|
+
};
|
|
102
|
+
const stripQuotes = (s) => {
|
|
103
|
+
if (s.length >= 2) {
|
|
104
|
+
const first = s[0];
|
|
105
|
+
const last = s[s.length - 1];
|
|
106
|
+
if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
|
|
107
|
+
return s.slice(1, -1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return s;
|
|
111
|
+
};
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// ファイルシステム走査
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
const hashContent = (text) => createHash('sha256').update(text).digest('hex').slice(0, 16);
|
|
116
|
+
const isDirectory = async (path) => {
|
|
117
|
+
try {
|
|
118
|
+
return (await stat(path)).isDirectory();
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const readSkillFile = async (skillsDir, childName, scope, projectPath) => {
|
|
125
|
+
// 想定構造: <skillsDir>/<childName>/SKILL.md
|
|
126
|
+
// childName 自体が直接 SKILL.md ということは Claude Code の仕様上ない。
|
|
127
|
+
const dir = join(skillsDir, childName);
|
|
128
|
+
if (!(await isDirectory(dir)))
|
|
129
|
+
return null;
|
|
130
|
+
const filePath = join(dir, 'SKILL.md');
|
|
131
|
+
let body;
|
|
132
|
+
try {
|
|
133
|
+
body = await readFile(filePath, 'utf-8');
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err.code === 'ENOENT')
|
|
137
|
+
return null;
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const front = parseFrontmatter(body);
|
|
141
|
+
if (front == null)
|
|
142
|
+
return null;
|
|
143
|
+
return {
|
|
144
|
+
name: front.name,
|
|
145
|
+
description: front.description,
|
|
146
|
+
scope,
|
|
147
|
+
projectPath: projectPath ?? null,
|
|
148
|
+
sourcePath: filePath,
|
|
149
|
+
contentHash: hashContent(body),
|
|
150
|
+
body,
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
const scanSkillsDirectory = async (skillsDir, scope, projectPath) => {
|
|
154
|
+
let entries;
|
|
155
|
+
try {
|
|
156
|
+
entries = await readdir(skillsDir);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
if (err.code === 'ENOENT')
|
|
160
|
+
return [];
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
const results = await Promise.all(entries.map((name) => readSkillFile(skillsDir, name, scope, projectPath)));
|
|
164
|
+
return results.filter((s) => s !== null);
|
|
165
|
+
};
|
|
166
|
+
const dedupeByPath = (skills) => {
|
|
167
|
+
// 巡回中に同じ project を重複して見ることがある (cwd と ~/.claude.json#projects の両方に
|
|
168
|
+
// 入っている場合など) ので、sourcePath で de-dup する。
|
|
169
|
+
const seen = new Map();
|
|
170
|
+
for (const s of skills) {
|
|
171
|
+
if (!seen.has(s.sourcePath))
|
|
172
|
+
seen.set(s.sourcePath, s);
|
|
173
|
+
}
|
|
174
|
+
return Array.from(seen.values());
|
|
175
|
+
};
|
|
176
|
+
export const scanClaudeCodeSkills = async (options = {}) => {
|
|
177
|
+
const home = options.home ?? homedir();
|
|
178
|
+
const cwd = options.cwd ?? process.cwd();
|
|
179
|
+
// user scope: ~/.claude/skills/
|
|
180
|
+
const userSkillsDir = join(home, '.claude', 'skills');
|
|
181
|
+
// project scope: ~/.claude.json#projects のキー + cwd を全部巡回。
|
|
182
|
+
// MCP スキャン (claude-code.ts) と同じ巡回ロジック。
|
|
183
|
+
const claudeJsonPath = join(home, '.claude.json');
|
|
184
|
+
const projectDirs = new Set();
|
|
185
|
+
projectDirs.add(cwd);
|
|
186
|
+
const root = await readJsonIfExists(claudeJsonPath);
|
|
187
|
+
if (root && typeof root === 'object' && !Array.isArray(root)) {
|
|
188
|
+
const projects = root.projects;
|
|
189
|
+
if (projects && typeof projects === 'object' && !Array.isArray(projects)) {
|
|
190
|
+
for (const dir of Object.keys(projects)) {
|
|
191
|
+
projectDirs.add(dir);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const [userSkills, ...projectSkillSets] = await Promise.all([
|
|
196
|
+
scanSkillsDirectory(userSkillsDir, 'user', null),
|
|
197
|
+
...Array.from(projectDirs).map((dir) => scanSkillsDirectory(join(dir, '.claude', 'skills'), 'project', dir)),
|
|
198
|
+
]);
|
|
199
|
+
return dedupeByPath([...userSkills, ...projectSkillSets.flat()]);
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=claude-code-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code-skills.js","sourceRoot":"","sources":["../../src/scanners/claude-code-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { promisify } from 'node:util';
|
|
|
5
5
|
import { hashConfig } from '../hash.js';
|
|
6
6
|
import { extractFromMcpServersField, readJsonIfExists } from './_normalize.js';
|
|
7
7
|
import { scanClaudeCodePlugins } from './claude-code-plugins.js';
|
|
8
|
+
import { scanClaudeCodeSkills } from './claude-code-skills.js';
|
|
8
9
|
const execAsync = promisify(exec);
|
|
9
10
|
export const claudeCodePaths = (home = homedir(), cwd = process.cwd()) => ({
|
|
10
11
|
global: join(home, '.claude.json'),
|
|
@@ -194,12 +195,13 @@ export const scanClaudeCode = async (options = {}) => {
|
|
|
194
195
|
const cwd = options.cwd ?? process.cwd();
|
|
195
196
|
const includeRemote = options.includeRemote ?? true;
|
|
196
197
|
const paths = claudeCodePaths(home, cwd);
|
|
197
|
-
const [projectShared, globalAndLocal, plugins, remote, installedPlugins] = await Promise.all([
|
|
198
|
+
const [projectShared, globalAndLocal, plugins, remote, installedPlugins, installedSkills] = await Promise.all([
|
|
198
199
|
readAllProjectShared(paths.global, cwd),
|
|
199
200
|
readGlobalClaudeJson(paths.global),
|
|
200
201
|
readPluginServers(paths.pluginsManifest),
|
|
201
202
|
includeRemote ? scanClaudeAiRemote() : Promise.resolve([]),
|
|
202
203
|
scanClaudeCodePlugins(home),
|
|
204
|
+
scanClaudeCodeSkills({ home, cwd }),
|
|
203
205
|
]);
|
|
204
206
|
const all = [
|
|
205
207
|
...projectShared,
|
|
@@ -208,7 +210,7 @@ export const scanClaudeCode = async (options = {}) => {
|
|
|
208
210
|
...plugins,
|
|
209
211
|
...remote,
|
|
210
212
|
];
|
|
211
|
-
if (all.length === 0 && installedPlugins.length === 0) {
|
|
213
|
+
if (all.length === 0 && installedPlugins.length === 0 && installedSkills.length === 0) {
|
|
212
214
|
// 検出ゼロでもファイルが一つでも存在すれば「Claude Code を使っているマシン」と
|
|
213
215
|
// みなして空 snapshot を返す。すべて読めなかった場合のみ null。
|
|
214
216
|
const anyConfigSeen = (await readJsonIfExists(paths.global)) !== null ||
|
|
@@ -216,6 +218,11 @@ export const scanClaudeCode = async (options = {}) => {
|
|
|
216
218
|
if (!anyConfigSeen)
|
|
217
219
|
return null;
|
|
218
220
|
}
|
|
219
|
-
return {
|
|
221
|
+
return {
|
|
222
|
+
agentKind: 'claude_code',
|
|
223
|
+
servers: all,
|
|
224
|
+
plugins: installedPlugins,
|
|
225
|
+
skills: installedSkills,
|
|
226
|
+
};
|
|
220
227
|
};
|
|
221
228
|
//# sourceMappingURL=claude-code.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/scanners/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/scanners/claude-code.ts"],"names":[],"mappings":"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"}
|
package/dist/scanners/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { scanChatgpt } from './chatgpt.js';
|
|
2
1
|
import { scanClaudeCode } from './claude-code.js';
|
|
3
2
|
import { scanCodex } from './codex.js';
|
|
4
3
|
import { scanCursor } from './cursor.js';
|
|
5
4
|
import { scanGeminiCli } from './gemini-cli.js';
|
|
5
|
+
// ChatGPT は OS keychain で設定が暗号化されており、現状読み取り API が無いため
|
|
6
|
+
// scanner / agent_kind から外している。再追加する場合は scanners/chatgpt.ts と
|
|
7
|
+
// writers/chatgpt.ts を復活させて runAllScanners と AgentKind enum に戻すこと。
|
|
6
8
|
export const runAllScanners = async (options = {}) => {
|
|
7
9
|
const results = await Promise.all([
|
|
8
10
|
scanClaudeCode(options),
|
|
9
11
|
scanCodex({ home: options.home }),
|
|
10
12
|
scanCursor(options),
|
|
11
13
|
scanGeminiCli(options),
|
|
12
|
-
scanChatgpt({ home: options.home }),
|
|
13
14
|
]);
|
|
14
15
|
return results.filter((r) => r !== null);
|
|
15
16
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOhD,sDAAsD;AACtD,8DAA8D;AAC9D,mEAAmE;AACnE,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,UAA0B,EAAE,EAA4B,EAAE;IAC7F,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChC,cAAc,CAAC,OAAO,CAAC;QACvB,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,UAAU,CAAC,OAAO,CAAC;QACnB,aAAa,CAAC,OAAO,CAAC;KACvB,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAsB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AAC/D,CAAC,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SSE client for daemon → API event channel.
|
|
3
|
+
*
|
|
4
|
+
* Node 20 にはネイティブの `EventSource` グローバルが無いため、`fetch` の
|
|
5
|
+
* `ReadableStream<Uint8Array>` を自前で SSE フレームにパースする。
|
|
6
|
+
* 依存を増やさず、必要な機能 (event name + data) だけを抜き出す最小実装。
|
|
7
|
+
*
|
|
8
|
+
* 重要な設計判断:
|
|
9
|
+
* - **canonical fetch パターン**: SSE はベストエフォート通知レイヤー。
|
|
10
|
+
* payload に頼らず、event を受けたら呼び出し元が必ず再 fetch する
|
|
11
|
+
* 責務を持つ。これにより exactly-once / 順序問題から解放される。
|
|
12
|
+
* - **exponential backoff**: 1s → 2s → 4s → ... cap 30s。401 はリトライ不可。
|
|
13
|
+
* - **再接続時の取りこぼし防止**: caller は connect-callback で必ず 1 回
|
|
14
|
+
* fetch を回す前提。SSE が落ちている間に発生したイベントは fallback
|
|
15
|
+
* poll が拾うので、SSE 側で catch-up を実装する必要は無い。
|
|
16
|
+
*/
|
|
17
|
+
import type { ApiError } from './api-client.js';
|
|
18
|
+
interface SseEvent {
|
|
19
|
+
/** SSE の `event:` フィールド。デフォルトは "message"。 */
|
|
20
|
+
type: string;
|
|
21
|
+
/** SSE の `data:` フィールドの結合結果 (連続行は `\n` で join)。 */
|
|
22
|
+
data: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SseClientOptions {
|
|
25
|
+
/** SSE エンドポイントの完全 URL (例: https://api.lnar.ai/v1/monitoring/daemon/events?hostname=...) */
|
|
26
|
+
url: string;
|
|
27
|
+
/** OAuth bearer token。 */
|
|
28
|
+
token: string;
|
|
29
|
+
/** イベント到着時に呼ばれる。例外は無視されない (caller で握る)。 */
|
|
30
|
+
onEvent: (event: SseEvent) => Promise<void> | void;
|
|
31
|
+
/** SSE がオープンしたタイミング (初回 + 各再接続時)。catch-up fetch を仕込むのに使う。 */
|
|
32
|
+
onOpen?: () => Promise<void> | void;
|
|
33
|
+
/** 致命的に止めるシグナル。AbortSignal を渡せば caller が close 可能。 */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
/** 初期 backoff (ms)。テスト時に短縮できるよう注入可能。default 1000。 */
|
|
36
|
+
initialBackoffMs?: number;
|
|
37
|
+
/** 最大 backoff (ms)。default 30000。 */
|
|
38
|
+
maxBackoffMs?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 1 行ずつ SSE フィールドを読み取って `SseEvent` を組み立てるパーサ。
|
|
42
|
+
* 仕様: https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
43
|
+
*
|
|
44
|
+
* 必要な部分だけ実装: event / data / 空行で flush。id / retry はサーバ側で
|
|
45
|
+
* 使っていないので無視。
|
|
46
|
+
*/
|
|
47
|
+
declare class SseFrameParser {
|
|
48
|
+
private buffer;
|
|
49
|
+
private currentEvent;
|
|
50
|
+
private currentData;
|
|
51
|
+
/** 受信したテキスト断片をフィードし、確定した event だけを返す。 */
|
|
52
|
+
feed(chunk: string): SseEvent[];
|
|
53
|
+
private flush;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 終端不能エラー (401 など) を表す例外。caller がリトライをやめる判断に使う。
|
|
57
|
+
*/
|
|
58
|
+
export declare class SseFatalError extends Error {
|
|
59
|
+
status: number;
|
|
60
|
+
constructor(message: string, status: number);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* SSE エンドポイントに常時接続し、event を caller に流し続ける。
|
|
64
|
+
*
|
|
65
|
+
* 戻り値の Promise は signal が abort されたとき、もしくは SseFatalError が
|
|
66
|
+
* 発生したときに解決する。通常運用では永久ループのため await は daemon の
|
|
67
|
+
* シャットダウンと組み合わせて使う。
|
|
68
|
+
*/
|
|
69
|
+
export declare const runSseClient: (options: SseClientOptions) => Promise<void>;
|
|
70
|
+
export declare const _SseFrameParserForTest: typeof SseFrameParser;
|
|
71
|
+
export type { SseEvent };
|
|
72
|
+
export type { ApiError };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SSE client for daemon → API event channel.
|
|
3
|
+
*
|
|
4
|
+
* Node 20 にはネイティブの `EventSource` グローバルが無いため、`fetch` の
|
|
5
|
+
* `ReadableStream<Uint8Array>` を自前で SSE フレームにパースする。
|
|
6
|
+
* 依存を増やさず、必要な機能 (event name + data) だけを抜き出す最小実装。
|
|
7
|
+
*
|
|
8
|
+
* 重要な設計判断:
|
|
9
|
+
* - **canonical fetch パターン**: SSE はベストエフォート通知レイヤー。
|
|
10
|
+
* payload に頼らず、event を受けたら呼び出し元が必ず再 fetch する
|
|
11
|
+
* 責務を持つ。これにより exactly-once / 順序問題から解放される。
|
|
12
|
+
* - **exponential backoff**: 1s → 2s → 4s → ... cap 30s。401 はリトライ不可。
|
|
13
|
+
* - **再接続時の取りこぼし防止**: caller は connect-callback で必ず 1 回
|
|
14
|
+
* fetch を回す前提。SSE が落ちている間に発生したイベントは fallback
|
|
15
|
+
* poll が拾うので、SSE 側で catch-up を実装する必要は無い。
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_INITIAL_BACKOFF_MS = 1000;
|
|
18
|
+
const DEFAULT_MAX_BACKOFF_MS = 30_000;
|
|
19
|
+
/**
|
|
20
|
+
* 1 行ずつ SSE フィールドを読み取って `SseEvent` を組み立てるパーサ。
|
|
21
|
+
* 仕様: https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
22
|
+
*
|
|
23
|
+
* 必要な部分だけ実装: event / data / 空行で flush。id / retry はサーバ側で
|
|
24
|
+
* 使っていないので無視。
|
|
25
|
+
*/
|
|
26
|
+
class SseFrameParser {
|
|
27
|
+
buffer = '';
|
|
28
|
+
currentEvent = null;
|
|
29
|
+
currentData = [];
|
|
30
|
+
/** 受信したテキスト断片をフィードし、確定した event だけを返す。 */
|
|
31
|
+
feed(chunk) {
|
|
32
|
+
this.buffer += chunk;
|
|
33
|
+
const events = [];
|
|
34
|
+
let lineEnd;
|
|
35
|
+
// CR / LF / CRLF いずれにも対応するため正規表現で分割。
|
|
36
|
+
while ((lineEnd = this.buffer.search(/\r\n|\r|\n/)) !== -1) {
|
|
37
|
+
const line = this.buffer.slice(0, lineEnd);
|
|
38
|
+
const sepLen = this.buffer.slice(lineEnd, lineEnd + 2) === '\r\n' ? 2 : 1;
|
|
39
|
+
this.buffer = this.buffer.slice(lineEnd + sepLen);
|
|
40
|
+
if (line === '') {
|
|
41
|
+
// 空行 = event 区切り
|
|
42
|
+
const event = this.flush();
|
|
43
|
+
if (event)
|
|
44
|
+
events.push(event);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// コメント行 (':' で始まる) は heartbeat 用なので無視。
|
|
48
|
+
if (line.startsWith(':'))
|
|
49
|
+
continue;
|
|
50
|
+
const colonIdx = line.indexOf(':');
|
|
51
|
+
const field = colonIdx === -1 ? line : line.slice(0, colonIdx);
|
|
52
|
+
// SSE 仕様: `:` の直後の単一スペースは省く。
|
|
53
|
+
let value = colonIdx === -1 ? '' : line.slice(colonIdx + 1);
|
|
54
|
+
if (value.startsWith(' '))
|
|
55
|
+
value = value.slice(1);
|
|
56
|
+
if (field === 'event') {
|
|
57
|
+
this.currentEvent = value;
|
|
58
|
+
}
|
|
59
|
+
else if (field === 'data') {
|
|
60
|
+
this.currentData.push(value);
|
|
61
|
+
}
|
|
62
|
+
// id / retry はサポート外。
|
|
63
|
+
}
|
|
64
|
+
return events;
|
|
65
|
+
}
|
|
66
|
+
flush() {
|
|
67
|
+
if (this.currentData.length === 0 && this.currentEvent == null)
|
|
68
|
+
return null;
|
|
69
|
+
const event = {
|
|
70
|
+
type: this.currentEvent ?? 'message',
|
|
71
|
+
data: this.currentData.join('\n'),
|
|
72
|
+
};
|
|
73
|
+
this.currentEvent = null;
|
|
74
|
+
this.currentData = [];
|
|
75
|
+
return event;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 終端不能エラー (401 など) を表す例外。caller がリトライをやめる判断に使う。
|
|
80
|
+
*/
|
|
81
|
+
export class SseFatalError extends Error {
|
|
82
|
+
status;
|
|
83
|
+
constructor(message, status) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.status = status;
|
|
86
|
+
this.name = 'SseFatalError';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* SSE エンドポイントに常時接続し、event を caller に流し続ける。
|
|
91
|
+
*
|
|
92
|
+
* 戻り値の Promise は signal が abort されたとき、もしくは SseFatalError が
|
|
93
|
+
* 発生したときに解決する。通常運用では永久ループのため await は daemon の
|
|
94
|
+
* シャットダウンと組み合わせて使う。
|
|
95
|
+
*/
|
|
96
|
+
export const runSseClient = async (options) => {
|
|
97
|
+
const initialBackoff = options.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS;
|
|
98
|
+
const maxBackoff = options.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
99
|
+
let backoff = initialBackoff;
|
|
100
|
+
while (!options.signal?.aborted) {
|
|
101
|
+
try {
|
|
102
|
+
await connectAndStream(options);
|
|
103
|
+
// 正常クローズ (サーバ側切断 / EOF) は即再接続する。
|
|
104
|
+
backoff = initialBackoff;
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (options.signal?.aborted)
|
|
108
|
+
return;
|
|
109
|
+
if (err instanceof SseFatalError && err.status === 401) {
|
|
110
|
+
// トークン期限切れなどは上位 daemon ループで refresh されるため
|
|
111
|
+
// ここでは終了して上位に任せる。
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
115
|
+
process.stderr.write(`lnar daemon: SSE disconnected (${message}); retry in ${Math.round(backoff / 1000)}s\n`);
|
|
116
|
+
await sleep(backoff, options.signal);
|
|
117
|
+
backoff = Math.min(backoff * 2, maxBackoff);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const sleep = (ms, signal) => new Promise((resolve) => {
|
|
122
|
+
if (signal?.aborted)
|
|
123
|
+
return resolve();
|
|
124
|
+
const timer = setTimeout(() => {
|
|
125
|
+
signal?.removeEventListener('abort', onAbort);
|
|
126
|
+
resolve();
|
|
127
|
+
}, ms);
|
|
128
|
+
const onAbort = () => {
|
|
129
|
+
clearTimeout(timer);
|
|
130
|
+
resolve();
|
|
131
|
+
};
|
|
132
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
133
|
+
});
|
|
134
|
+
const connectAndStream = async (options) => {
|
|
135
|
+
const response = await fetch(options.url, {
|
|
136
|
+
method: 'GET',
|
|
137
|
+
headers: {
|
|
138
|
+
Authorization: `Bearer ${options.token}`,
|
|
139
|
+
Accept: 'text/event-stream',
|
|
140
|
+
},
|
|
141
|
+
signal: options.signal,
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
const body = await response.text().catch(() => '');
|
|
145
|
+
if (response.status === 401 || response.status === 403) {
|
|
146
|
+
throw new SseFatalError(`SSE auth failed: ${response.status} ${body}`, response.status);
|
|
147
|
+
}
|
|
148
|
+
throw new Error(`SSE HTTP ${response.status}: ${body}`);
|
|
149
|
+
}
|
|
150
|
+
if (response.body == null) {
|
|
151
|
+
throw new Error('SSE response has no body');
|
|
152
|
+
}
|
|
153
|
+
if (options.onOpen) {
|
|
154
|
+
// open callback は parser 起動 *前* に走らせる。これにより SSE 接続中に
|
|
155
|
+
// 来たイベントよりも前に必ず 1 回の canonical fetch が動く。
|
|
156
|
+
await options.onOpen();
|
|
157
|
+
}
|
|
158
|
+
const decoder = new TextDecoder('utf-8');
|
|
159
|
+
const parser = new SseFrameParser();
|
|
160
|
+
const reader = response.body.getReader();
|
|
161
|
+
while (true) {
|
|
162
|
+
const { value, done } = await reader.read();
|
|
163
|
+
if (done)
|
|
164
|
+
return;
|
|
165
|
+
const text = decoder.decode(value, { stream: true });
|
|
166
|
+
const events = parser.feed(text);
|
|
167
|
+
for (const event of events) {
|
|
168
|
+
await options.onEvent(event);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
// テスト用: パーサ単体をエクスポートする (private クラスに匹敵)。
|
|
173
|
+
export const _SseFrameParserForTest = SseFrameParser;
|
|
174
|
+
//# sourceMappingURL=sse-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-client.js","sourceRoot":"","sources":["../src/sse-client.ts"],"names":[],"mappings":"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"}
|