@lnar/cli 0.0.1-dev.1da013d → 0.0.1-dev.3982ccb
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 +16 -54
- package/dist/api-client.d.ts +19 -0
- package/dist/api-client.js +42 -0
- package/dist/api-client.js.map +1 -1
- package/dist/auth.d.ts +20 -0
- package/dist/auth.js +74 -0
- package/dist/auth.js.map +1 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +68 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.js +30 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/daemon.d.ts +2 -0
- package/dist/commands/daemon.js +100 -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/record.d.ts +11 -0
- package/dist/commands/record.js +136 -0
- package/dist/commands/record.js.map +1 -0
- 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/recording/bundle.d.ts +23 -0
- package/dist/recording/bundle.js +41 -0
- package/dist/recording/bundle.js.map +1 -0
- package/dist/recording/capture.d.ts +33 -0
- package/dist/recording/capture.js +173 -0
- package/dist/recording/capture.js.map +1 -0
- package/dist/recording/session.d.ts +27 -0
- package/dist/recording/session.js +81 -0
- package/dist/recording/session.js.map +1 -0
- package/dist/recording/types.d.ts +59 -0
- package/dist/recording/types.js +8 -0
- package/dist/recording/types.js.map +1 -0
- package/dist/run-client.d.ts +19 -0
- package/dist/run-client.js +44 -0
- package/dist/run-client.js.map +1 -0
- package/dist/run-worker.d.ts +25 -0
- package/dist/run-worker.js +85 -0
- package/dist/run-worker.js.map +1 -0
- package/dist/runtime/actions.d.ts +13 -0
- package/dist/runtime/actions.js +107 -0
- package/dist/runtime/actions.js.map +1 -0
- package/dist/runtime/client.d.ts +3 -0
- package/dist/runtime/client.js +85 -0
- package/dist/runtime/client.js.map +1 -0
- package/dist/runtime/login.d.ts +20 -0
- package/dist/runtime/login.js +34 -0
- package/dist/runtime/login.js.map +1 -0
- package/dist/runtime/loop.d.ts +28 -0
- package/dist/runtime/loop.js +68 -0
- package/dist/runtime/loop.js.map +1 -0
- package/dist/runtime/playbook.d.ts +49 -0
- package/dist/runtime/playbook.js +73 -0
- package/dist/runtime/playbook.js.map +1 -0
- package/dist/runtime/runner.d.ts +20 -0
- package/dist/runtime/runner.js +54 -0
- package/dist/runtime/runner.js.map +1 -0
- package/dist/runtime/types.d.ts +69 -0
- package/dist/runtime/types.js +10 -0
- package/dist/runtime/types.js.map +1 -0
- 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/service/install.js +72 -13
- package/dist/service/install.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 +10 -2
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -2,5 +2,7 @@ export type LoginOptions = {
|
|
|
2
2
|
apiBaseUrl?: string;
|
|
3
3
|
clientId?: string;
|
|
4
4
|
scopes?: ReadonlyArray<string>;
|
|
5
|
+
/** true なら認可 URL を自動でブラウザに開かない (env `LNAR_NO_BROWSER=1` 相当)。 */
|
|
6
|
+
noBrowser?: boolean;
|
|
5
7
|
};
|
|
6
8
|
export declare const runLogin: (options?: LoginOptions) => Promise<void>;
|
package/dist/commands/login.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { openBrowser } from '../browser.js';
|
|
1
2
|
import { DEFAULT_API_BASE_URL, DEFAULT_CLIENT_ID, saveConfig } from '../config.js';
|
|
2
|
-
import { OAuthError, pollForToken, requestDeviceAuthorization, sleep
|
|
3
|
+
import { OAuthError, pollForToken, requestDeviceAuthorization, sleep } from '../oauth-client.js';
|
|
3
4
|
const DEFAULT_SCOPES = ['monitoring:read', 'monitoring:write'];
|
|
4
5
|
const resolveBaseUrl = (override) => {
|
|
5
6
|
const value = override ?? process.env.LNAR_API_BASE_URL ?? DEFAULT_API_BASE_URL;
|
|
@@ -11,15 +12,22 @@ const resolveBaseUrl = (override) => {
|
|
|
11
12
|
}
|
|
12
13
|
return value;
|
|
13
14
|
};
|
|
14
|
-
const printAuthorizationInstructions = (verificationUri, verificationUriComplete, userCode, expiresInSeconds) => {
|
|
15
|
+
const printAuthorizationInstructions = (verificationUri, verificationUriComplete, userCode, expiresInSeconds, browserOpened) => {
|
|
15
16
|
const minutes = Math.max(1, Math.round(expiresInSeconds / 60));
|
|
16
17
|
process.stdout.write('\n');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
if (browserOpened) {
|
|
19
|
+
process.stdout.write('Opening your browser to authorize this device…\n');
|
|
20
|
+
process.stdout.write('If it does not open automatically, visit:\n');
|
|
21
|
+
process.stdout.write(` ${verificationUriComplete}\n\n`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
process.stdout.write('To authorize this device, visit:\n');
|
|
25
|
+
process.stdout.write(` ${verificationUri}\n`);
|
|
26
|
+
process.stdout.write('and enter the code:\n\n');
|
|
27
|
+
process.stdout.write(` ${userCode}\n\n`);
|
|
28
|
+
process.stdout.write('Or open the URL with the code pre-filled:\n');
|
|
29
|
+
process.stdout.write(` ${verificationUriComplete}\n\n`);
|
|
30
|
+
}
|
|
23
31
|
process.stdout.write(`Waiting for authorization (this code expires in ${minutes} minute${minutes === 1 ? '' : 's'})…\n`);
|
|
24
32
|
};
|
|
25
33
|
export const runLogin = async (options = {}) => {
|
|
@@ -37,7 +45,9 @@ export const runLogin = async (options = {}) => {
|
|
|
37
45
|
}
|
|
38
46
|
throw err;
|
|
39
47
|
}
|
|
40
|
-
|
|
48
|
+
const shouldOpenBrowser = !(options.noBrowser ?? process.env.LNAR_NO_BROWSER === '1');
|
|
49
|
+
const browserOpened = shouldOpenBrowser && openBrowser(auth.verification_uri_complete);
|
|
50
|
+
printAuthorizationInstructions(auth.verification_uri, auth.verification_uri_complete, auth.user_code, auth.expires_in, browserOpened);
|
|
41
51
|
// RFC 8628 §3.5: ポーリング間隔はサーバ指定の `interval` 以上、
|
|
42
52
|
// `slow_down` を受け取ったら +5 秒 (サーバ側で自動加算済みだが、念のためここでも対応)。
|
|
43
53
|
let intervalSeconds = Math.max(1, auth.interval || 5);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type RecordCommandOptions = {
|
|
2
|
+
url?: string;
|
|
3
|
+
out?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
purpose?: string;
|
|
6
|
+
noUpload?: boolean;
|
|
7
|
+
headless?: boolean;
|
|
8
|
+
video?: boolean;
|
|
9
|
+
trace?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const runRecord: (options?: RecordCommandOptions) => Promise<void>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `lnar record` — ローカルブラウザでデモ操作を記録し、バンドルを lnar にアップロードする。
|
|
3
|
+
*
|
|
4
|
+
* Demo-to-MCP (Phase 1)。記録したバンドルは後段で gemini-3.5-flash が解析し、
|
|
5
|
+
* タスク手順書 (playbook) → ブラウザ操作 MCP の生成に使う。
|
|
6
|
+
*/
|
|
7
|
+
import { mkdir, rm } from 'node:fs/promises';
|
|
8
|
+
import { homedir, tmpdir } from 'node:os';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { stdin, stdout } from 'node:process';
|
|
11
|
+
import { createInterface } from 'node:readline/promises';
|
|
12
|
+
import { ApiError, createRecording, uploadRecordingBundle } from '../api-client.js';
|
|
13
|
+
import { NotLoggedInError, resolveAuth } from '../auth.js';
|
|
14
|
+
import { packBundle } from '../recording/bundle.js';
|
|
15
|
+
import { recordSession } from '../recording/session.js';
|
|
16
|
+
const MAX_PURPOSE = 2000;
|
|
17
|
+
/**
|
|
18
|
+
* 録画後に「この作業の目的」を尋ねる。--purpose 指定時はそれを使い、対話端末
|
|
19
|
+
* (TTY) でなければスキップする。目的は解析プロンプトに渡され playbook 精度を高める。
|
|
20
|
+
*/
|
|
21
|
+
const resolvePurpose = async (option) => {
|
|
22
|
+
if (option != null && option.trim() !== '')
|
|
23
|
+
return option.trim().slice(0, MAX_PURPOSE);
|
|
24
|
+
if (!stdin.isTTY)
|
|
25
|
+
return null;
|
|
26
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
27
|
+
try {
|
|
28
|
+
stdout.write('\nこの作業の目的を入力してください (任意、Enter でスキップ):\n');
|
|
29
|
+
const answer = await rl.question('> ');
|
|
30
|
+
const trimmed = answer.trim();
|
|
31
|
+
return trimmed === '' ? null : trimmed.slice(0, MAX_PURPOSE);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
rl.close();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const fsSafeTimestamp = () => new Date().toISOString().replace(/[:.]/g, '-');
|
|
38
|
+
/** Enter キー or ブラウザ終了で停止するシグナルを作る。 */
|
|
39
|
+
const makeWaitForStop = () => (page, context) => new Promise((resolve) => {
|
|
40
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
41
|
+
let done = false;
|
|
42
|
+
const finish = () => {
|
|
43
|
+
if (done)
|
|
44
|
+
return;
|
|
45
|
+
done = true;
|
|
46
|
+
rl.close();
|
|
47
|
+
resolve();
|
|
48
|
+
};
|
|
49
|
+
stdout.write('\n● 録画中。ブラウザで操作してください。\n');
|
|
50
|
+
stdout.write(' 終了するには、このターミナルで Enter を押すかブラウザを閉じてください。\n\n');
|
|
51
|
+
// ブラウザ close 起因で先に rl.close() されると question が reject するため、
|
|
52
|
+
// 成功/reject どちらでも finish() を呼び unhandled rejection を防ぐ。
|
|
53
|
+
void rl.question('').then(finish, finish);
|
|
54
|
+
context.on('close', finish);
|
|
55
|
+
page.on('close', finish);
|
|
56
|
+
});
|
|
57
|
+
export const runRecord = async (options = {}) => {
|
|
58
|
+
const upload = options.noUpload !== true;
|
|
59
|
+
// アップロードする場合は先に認証を解決 (記録後に失敗して取り直しを避ける)。
|
|
60
|
+
let auth = null;
|
|
61
|
+
if (upload) {
|
|
62
|
+
try {
|
|
63
|
+
auth = await resolveAuth();
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err instanceof NotLoggedInError) {
|
|
67
|
+
process.stderr.write(`lnar: ${err.message}\n`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const createdAt = new Date().toISOString();
|
|
74
|
+
const name = options.name ?? `recording-${fsSafeTimestamp()}`;
|
|
75
|
+
const outDir = options.out ?? join(process.cwd(), `lnar-${name}`);
|
|
76
|
+
const profileDir = join(homedir(), '.config', 'lnar', 'record-profile');
|
|
77
|
+
await mkdir(outDir, { recursive: true });
|
|
78
|
+
const result = await recordSession({
|
|
79
|
+
outDir,
|
|
80
|
+
name,
|
|
81
|
+
startUrl: options.url ?? null,
|
|
82
|
+
profileDir,
|
|
83
|
+
headless: options.headless,
|
|
84
|
+
recordVideo: options.video,
|
|
85
|
+
recordTrace: options.trace,
|
|
86
|
+
createdAt,
|
|
87
|
+
waitForStop: makeWaitForStop(),
|
|
88
|
+
});
|
|
89
|
+
process.stdout.write(`\n録画完了: ${result.manifest.actionCount} アクション, ` +
|
|
90
|
+
`${result.manifest.screenshots.length} キーフレーム` +
|
|
91
|
+
`${result.manifest.video ? ', 動画あり' : ''}\n`);
|
|
92
|
+
process.stdout.write(`バンドル: ${result.dir}\n`);
|
|
93
|
+
if (!upload || auth == null) {
|
|
94
|
+
process.stdout.write('(--no-upload: アップロードはスキップしました)\n');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// 録画後に作業の目的を尋ねる (解析プロンプトに渡し playbook 精度を高める)。
|
|
98
|
+
const purpose = await resolvePurpose(options.purpose);
|
|
99
|
+
// アップロード用の一時 tar.gz。成功/失敗/exit のいずれでも掃除する
|
|
100
|
+
// (process.exit は finally を実行しないため、exit 前にも明示的に削除する)。
|
|
101
|
+
let tarPath = null;
|
|
102
|
+
const cleanupTar = async () => {
|
|
103
|
+
if (tarPath)
|
|
104
|
+
await rm(tarPath, { force: true }).catch(() => { });
|
|
105
|
+
};
|
|
106
|
+
try {
|
|
107
|
+
const created = await createRecording(auth.baseUrl, auth.token, {
|
|
108
|
+
name,
|
|
109
|
+
startUrl: result.manifest.startUrl,
|
|
110
|
+
purpose,
|
|
111
|
+
manifest: result.manifest,
|
|
112
|
+
actions: result.actions,
|
|
113
|
+
});
|
|
114
|
+
tarPath = join(tmpdir(), `lnar-recording-${created.id}.tar.gz`);
|
|
115
|
+
await packBundle(result.dir, tarPath);
|
|
116
|
+
// アップロード時にサーバー側で即解析される (画像は保存されない)。
|
|
117
|
+
const analyzed = await uploadRecordingBundle(auth.baseUrl, auth.token, created.id, tarPath);
|
|
118
|
+
process.stdout.write(`アップロード・解析完了: recording ${analyzed.id} (status=${analyzed.status})\n`);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
if (err instanceof ApiError) {
|
|
122
|
+
await cleanupTar();
|
|
123
|
+
if (err.status === 401) {
|
|
124
|
+
process.stderr.write('lnar: not authorized (token may be expired). Run `lnar login`.\n');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
process.stderr.write(`lnar: ${err.message}\n`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
await cleanupTar();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/commands/record.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/scan.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { hostname } from 'node:os';
|
|
2
|
+
import { loadOrCreateMachineId } from '../machine-id.js';
|
|
2
3
|
import { runAllScanners } from '../scanners/index.js';
|
|
4
|
+
const truncate = (s, max) => s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
|
3
5
|
const formatHuman = (result) => {
|
|
4
6
|
if (result.agents.length === 0) {
|
|
5
7
|
return 'No AI agents with MCP servers detected on this machine.';
|
|
@@ -16,14 +18,24 @@ const formatHuman = (result) => {
|
|
|
16
18
|
const scope = `[${s.sourceScope}]`.padEnd(10);
|
|
17
19
|
lines.push(` - ${s.name.padEnd(24)} ${transport} ${scope} ${target}`);
|
|
18
20
|
}
|
|
21
|
+
if (agent.skills && agent.skills.length > 0) {
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push(` skills (${agent.skills.length})`);
|
|
24
|
+
for (const sk of agent.skills) {
|
|
25
|
+
const scope = `[${sk.scope}]`.padEnd(10);
|
|
26
|
+
lines.push(` - ${sk.name.padEnd(28)} ${scope} ${truncate(sk.description, 64)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
19
29
|
lines.push('');
|
|
20
30
|
}
|
|
21
31
|
return lines.join('\n');
|
|
22
32
|
};
|
|
23
33
|
export const runScan = async (options = {}) => {
|
|
24
34
|
const agents = await runAllScanners();
|
|
35
|
+
const machineId = await loadOrCreateMachineId();
|
|
25
36
|
const result = {
|
|
26
37
|
hostname: hostname(),
|
|
38
|
+
machineId,
|
|
27
39
|
scannedAt: new Date().toISOString(),
|
|
28
40
|
agents,
|
|
29
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAOtD,MAAM,WAAW,GAAG,CAAC,MAAkB,EAAU,EAAE;IACjD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,yDAAyD,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAAa,CAAC,SAAS,MAAM,CAAC,QAAQ,gBAAgB,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IACzF,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,UAAU,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CACjG,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,SAAS,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,UAA8B,EAAE,EAAiB,EAAE;IAC/E,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,MAAM,GAAe;QACzB,QAAQ,EAAE,QAAQ,EAAE;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM;KACP,CAAC;IACF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hostname } from 'node:os';
|
|
2
2
|
import { ApiError, postSnapshot } from '../api-client.js';
|
|
3
3
|
import { DEFAULT_CLIENT_ID, loadConfig, saveConfig } from '../config.js';
|
|
4
|
+
import { loadOrCreateMachineId } from '../machine-id.js';
|
|
4
5
|
import { OAuthError, refreshAccessToken } from '../oauth-client.js';
|
|
5
6
|
import { runAllScanners } from '../scanners/index.js';
|
|
6
7
|
const ACCESS_TOKEN_REFRESH_SKEW_SECONDS = 60;
|
|
@@ -60,8 +61,10 @@ export const runSync = async (options = {}) => {
|
|
|
60
61
|
}
|
|
61
62
|
const config = await refreshIfNeeded(initial);
|
|
62
63
|
const agents = await runAllScanners();
|
|
64
|
+
const machineId = await loadOrCreateMachineId();
|
|
63
65
|
const scan = {
|
|
64
66
|
hostname: hostname(),
|
|
67
|
+
machineId,
|
|
65
68
|
scannedAt: new Date().toISOString(),
|
|
66
69
|
agents,
|
|
67
70
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/up.js
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 1. `~/.config/lnar/auth.json` を読んで、認証済みでなければ device flow を起動する
|
|
5
5
|
* 2. OS の常駐サービスとして登録 (macOS=launchd / Linux=systemd / Windows=Task Scheduler)
|
|
6
|
+
* 3. インストール直後に初回 sync を 1 回だけ同期実行し、daemon の最初の cycle を
|
|
7
|
+
* 待たずダッシュボードへの反映を即時化する。Tailscale が `tailscale up` で
|
|
8
|
+
* 同期的に "phone home" するのと同じ思想。失敗しても daemon 側 polling が
|
|
9
|
+
* 後続 cycle で再試行するので、ここはベストエフォート扱いにする。
|
|
6
10
|
*
|
|
7
11
|
* 認証済みかどうかは「資格情報ファイルが存在し、accessToken or apiKey が入っているか」で
|
|
8
12
|
* 判断する。トークンの有効期限は daemon 側の API クライアントが refresh するので、
|
|
@@ -12,6 +16,20 @@
|
|
|
12
16
|
import { loadConfig } from '../config.js';
|
|
13
17
|
import { runDaemonInstall } from '../service/install.js';
|
|
14
18
|
import { runLogin } from './login.js';
|
|
19
|
+
import { runSync } from './sync.js';
|
|
20
|
+
const runInitialSync = async () => {
|
|
21
|
+
process.stdout.write('\nRunning initial sync…\n');
|
|
22
|
+
try {
|
|
23
|
+
await runSync();
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
// runSync は ApiError / 401 では process.exit(1) を直接呼ぶので、ここに到達する
|
|
27
|
+
// のは予期しない例外のみ。daemon サービスのインストール自体は成功しているので、
|
|
28
|
+
// 続く polling cycle が同じ scan を再試行できる。lnar up 自体は warn で済ませる。
|
|
29
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
30
|
+
process.stderr.write(`lnar up: initial sync failed (${message}). The daemon will retry on its next cycle.\n`);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
15
33
|
export const runUp = async (options = {}) => {
|
|
16
34
|
const config = await loadConfig();
|
|
17
35
|
if (config == null) {
|
|
@@ -23,5 +41,6 @@ export const runUp = async (options = {}) => {
|
|
|
23
41
|
process.stdout.write(`Using existing credentials (${config.apiBaseUrl}).\n\n`);
|
|
24
42
|
}
|
|
25
43
|
await runDaemonInstall();
|
|
44
|
+
await runInitialSync();
|
|
26
45
|
};
|
|
27
46
|
//# sourceMappingURL=up.js.map
|
package/dist/commands/up.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"up.js","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"up.js","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAqB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,cAAc,GAAG,KAAK,IAAmB,EAAE;IAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8DAA8D;QAC9D,6CAA6C;QAC7C,4DAA4D;QAC5D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iCAAiC,OAAO,+CAA+C,CACxF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EAAE,UAAqB,EAAE,EAAiB,EAAE;IACpE,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACxF,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,MAAM,CAAC,UAAU,QAAQ,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,gBAAgB,EAAE,CAAC;IACzB,MAAM,cAAc,EAAE,CAAC;AACzB,CAAC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* マシンに永続化される一意 ID。hostname は macOS のネットワーク状況で
|
|
8
|
+
* `xxx.local` ↔ `xxx.kkbnj1.kt.home.ne.jp` のように切り替わって別マシンと
|
|
9
|
+
* みなされるため、agent 同一性の判定には使えない。代わりに UUID v4 を生成して
|
|
10
|
+
* `~/.config/lnar/machine.json` に保存し、これをサーバー側 dedupe キーにする。
|
|
11
|
+
*
|
|
12
|
+
* - 初回呼び出し時に UUID を生成して書き込む
|
|
13
|
+
* - 2 回目以降は読み込んで返す
|
|
14
|
+
* - ファイル破損時は新規生成して上書き (機微情報は持たないので破壊的でよい)
|
|
15
|
+
*/
|
|
16
|
+
const MachineFile = z.object({
|
|
17
|
+
machineId: z.string().uuid(),
|
|
18
|
+
createdAt: z.string(),
|
|
19
|
+
});
|
|
20
|
+
export const machineIdPath = (home = homedir()) => join(home, '.config', 'lnar', 'machine.json');
|
|
21
|
+
const tryRead = async (path) => {
|
|
22
|
+
try {
|
|
23
|
+
const text = await readFile(path, 'utf-8');
|
|
24
|
+
const parsed = MachineFile.parse(JSON.parse(text));
|
|
25
|
+
return parsed.machineId;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const code = err.code;
|
|
29
|
+
if (code === 'ENOENT')
|
|
30
|
+
return null;
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const write = async (path, machineId) => {
|
|
35
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
36
|
+
const payload = { machineId, createdAt: new Date().toISOString() };
|
|
37
|
+
await writeFile(path, JSON.stringify(payload, null, 2), { mode: 0o600 });
|
|
38
|
+
};
|
|
39
|
+
export const loadOrCreateMachineId = async (home = homedir()) => {
|
|
40
|
+
const path = machineIdPath(home);
|
|
41
|
+
const existing = await tryRead(path);
|
|
42
|
+
if (existing != null)
|
|
43
|
+
return existing;
|
|
44
|
+
const machineId = randomUUID();
|
|
45
|
+
await write(path, machineId);
|
|
46
|
+
return machineId;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=machine-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machine-id.js","sourceRoot":"","sources":["../src/machine-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;GASG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,OAAO,EAAE,EAAU,EAAE,CAChE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAEhD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAY,EAA0B,EAAE;IAC7D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,SAAS,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,KAAK,EAAE,IAAY,EAAE,SAAiB,EAAiB,EAAE;IACrE,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACnE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,OAAe,OAAO,EAAE,EAAmB,EAAE;IACvF,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IACtC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,MAAM,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC7B,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
|
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,23 @@
|
|
|
1
|
+
import type { RecordedAction, RecordingManifest } from './types.js';
|
|
2
|
+
export interface BuildManifestParams {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly startUrl: string | null;
|
|
5
|
+
readonly createdAt: string;
|
|
6
|
+
readonly viewport: {
|
|
7
|
+
readonly width: number;
|
|
8
|
+
readonly height: number;
|
|
9
|
+
};
|
|
10
|
+
readonly actions: ReadonlyArray<RecordedAction>;
|
|
11
|
+
readonly video: string | null;
|
|
12
|
+
readonly trace: string | null;
|
|
13
|
+
readonly screenshots: ReadonlyArray<string>;
|
|
14
|
+
}
|
|
15
|
+
/** manifest を組み立てる純関数。 */
|
|
16
|
+
export declare function buildManifest(params: BuildManifestParams): RecordingManifest;
|
|
17
|
+
/** manifest.json と actions.json をバンドルディレクトリに書き出す。 */
|
|
18
|
+
export declare function writeBundleMetadata(dir: string, manifest: RecordingManifest, actions: ReadonlyArray<RecordedAction>): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* バンドルディレクトリを tar.gz に固めてアップロード用パスを返す。
|
|
21
|
+
* `cwd` 配下を `.` として格納するため、展開時にトップレベルがフラットになる。
|
|
22
|
+
*/
|
|
23
|
+
export declare function packBundle(dir: string, outFile: string): Promise<string>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 録画バンドルの組み立てと書き出し。
|
|
3
|
+
*
|
|
4
|
+
* バンドル構成:
|
|
5
|
+
* <dir>/manifest.json メタデータ
|
|
6
|
+
* <dir>/actions.json RecordedAction[]
|
|
7
|
+
* <dir>/screenshots/NNNN.png キーフレーム
|
|
8
|
+
* <dir>/video.webm 動画 (取得できた場合)
|
|
9
|
+
* <dir>/trace.zip Playwright trace (取得できた場合)
|
|
10
|
+
*/
|
|
11
|
+
import { writeFile } from 'node:fs/promises';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { create as tarCreate } from 'tar';
|
|
14
|
+
/** manifest を組み立てる純関数。 */
|
|
15
|
+
export function buildManifest(params) {
|
|
16
|
+
return {
|
|
17
|
+
version: 1,
|
|
18
|
+
name: params.name,
|
|
19
|
+
startUrl: params.startUrl,
|
|
20
|
+
createdAt: params.createdAt,
|
|
21
|
+
viewport: params.viewport,
|
|
22
|
+
actionCount: params.actions.length,
|
|
23
|
+
video: params.video,
|
|
24
|
+
trace: params.trace,
|
|
25
|
+
screenshots: [...params.screenshots],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** manifest.json と actions.json をバンドルディレクトリに書き出す。 */
|
|
29
|
+
export async function writeBundleMetadata(dir, manifest, actions) {
|
|
30
|
+
await writeFile(join(dir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
31
|
+
await writeFile(join(dir, 'actions.json'), `${JSON.stringify(actions, null, 2)}\n`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* バンドルディレクトリを tar.gz に固めてアップロード用パスを返す。
|
|
35
|
+
* `cwd` 配下を `.` として格納するため、展開時にトップレベルがフラットになる。
|
|
36
|
+
*/
|
|
37
|
+
export async function packBundle(dir, outFile) {
|
|
38
|
+
await tarCreate({ gzip: true, file: outFile, cwd: dir }, ['.']);
|
|
39
|
+
return outFile;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/recording/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,KAAK,CAAC;AAc1C,0BAA0B;AAC1B,MAAM,UAAU,aAAa,CAAC,MAA2B;IACvD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;QAClC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAW,EACX,QAA2B,EAC3B,OAAsC;IAEtC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACtF,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,OAAe;IAC3D,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from 'playwright';
|
|
2
|
+
import type { RecordedAction } from './types.js';
|
|
3
|
+
/** 全ページに注入する記録スクリプト (self-contained・依存なし)。 */
|
|
4
|
+
export declare const INIT_SCRIPT = "() => {\n if (window.__lnarRecorderInstalled) return;\n window.__lnarRecorderInstalled = true;\n var MAXV = 300;\n function esc(s){ return (window.CSS && CSS.escape) ? CSS.escape(s) : String(s).replace(/[^a-zA-Z0-9_-]/g, '\\\\$&'); }\n function selectorFor(el){\n if (!el || el.nodeType !== 1) return undefined;\n var tid = el.getAttribute && el.getAttribute('data-testid');\n if (tid) return '[data-testid=\"' + esc(tid) + '\"]';\n if (el.id) return '#' + esc(el.id);\n var parts = [], cur = el, depth = 0;\n while (cur && cur.nodeType === 1 && depth < 4) {\n var part = cur.tagName.toLowerCase();\n var parent = cur.parentElement;\n if (parent) {\n var sibs = Array.prototype.filter.call(parent.children, function(c){ return c.tagName === cur.tagName; });\n if (sibs.length > 1) part += ':nth-of-type(' + (sibs.indexOf(cur) + 1) + ')';\n }\n parts.unshift(part);\n cur = cur.parentElement;\n depth++;\n }\n return parts.join(' > ');\n }\n function labelFor(el){\n if (!el || !el.getAttribute) return undefined;\n var a = el.getAttribute('aria-label') || el.getAttribute('placeholder') || el.getAttribute('name');\n if (a) return String(a).slice(0, 80);\n var t = (el.innerText || el.value || '').trim();\n return t ? t.slice(0, 80) : undefined;\n }\n function isSensitive(el){\n var type = ((el.getAttribute && el.getAttribute('type')) || '').toLowerCase();\n if (type === 'password') return true;\n var ac = ((el.getAttribute && el.getAttribute('autocomplete')) || '').toLowerCase();\n if (/password|cc-|one-time-code/.test(ac)) return true;\n var idn = (((el.name || '') + ' ' + (el.id || '')).toLowerCase());\n return /pass|otp|secret|token|card|cvv|ssn/.test(idn);\n }\n function send(p){ try { window.__lnarRecord(JSON.stringify(p)); } catch (e) {} }\n document.addEventListener('click', function(e){\n var el = e.target;\n send({ kind: 'click', x: Math.round(e.clientX), y: Math.round(e.clientY), selector: selectorFor(el), label: labelFor(el) });\n }, true);\n document.addEventListener('change', function(e){\n var el = e.target;\n if (!el || !('value' in el)) return;\n var sens = isSensitive(el);\n send({ kind: 'input', selector: selectorFor(el), label: labelFor(el), sensitive: sens, value: sens ? '***' : String(el.value).slice(0, MAXV) });\n }, true);\n document.addEventListener('submit', function(e){\n send({ kind: 'submit', selector: selectorFor(e.target), label: labelFor(e.target) });\n }, true);\n document.addEventListener('keydown', function(e){\n if (e.key === 'Enter' || e.key === 'Tab' || e.key === 'Escape') {\n send({ kind: 'keydown', key: e.key, selector: selectorFor(e.target) });\n }\n }, true);\n}";
|
|
5
|
+
export interface RecorderOptions {
|
|
6
|
+
readonly screenshotsDir: string;
|
|
7
|
+
readonly maxScreenshots?: number;
|
|
8
|
+
/** テスト用の時刻ソース。既定は Date.now。 */
|
|
9
|
+
readonly now?: () => number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 録画状態を保持し、ページ内イベント / ナビゲーションを RecordedAction に変換する。
|
|
13
|
+
*/
|
|
14
|
+
export declare class Recorder {
|
|
15
|
+
private readonly options;
|
|
16
|
+
readonly actions: RecordedAction[];
|
|
17
|
+
readonly screenshots: string[];
|
|
18
|
+
private readonly startMs;
|
|
19
|
+
private readonly now;
|
|
20
|
+
private readonly maxScreenshots;
|
|
21
|
+
private shotCount;
|
|
22
|
+
constructor(options: RecorderOptions);
|
|
23
|
+
private capture;
|
|
24
|
+
/** ページ内イベントを受けてアクションを記録する。 */
|
|
25
|
+
handleInPage(page: Page, payloadJson: string): Promise<void>;
|
|
26
|
+
/** main frame のナビゲーションを記録する。 */
|
|
27
|
+
handleNavigate(page: Page, url: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* context にレコーダを取り付ける。exposeBinding → addInitScript の順で行うこと。
|
|
31
|
+
* 取り付け後に作成/遷移したページが記録対象になる。
|
|
32
|
+
*/
|
|
33
|
+
export declare function attachRecorder(context: BrowserContext, recorder: Recorder): Promise<void>;
|