@lnar/cli 0.0.1-dev.27db913 → 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/dist/api-client.d.ts +19 -0
- package/dist/api-client.js +40 -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/cli.js +25 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/daemon.js +13 -0
- package/dist/commands/daemon.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/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/package.json +9 -1
package/dist/api-client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RecordedAction, RecordingManifest } from './recording/types.js';
|
|
1
2
|
import type { ScanResult } from './types.js';
|
|
2
3
|
export type SnapshotResponse = {
|
|
3
4
|
agents: Array<{
|
|
@@ -15,3 +16,21 @@ export declare class ApiError extends Error {
|
|
|
15
16
|
constructor(status: number, body: string);
|
|
16
17
|
}
|
|
17
18
|
export declare const postSnapshot: (baseUrl: string, apiKey: string, scan: ScanResult) => Promise<SnapshotResponse>;
|
|
19
|
+
export type RecordingResponse = {
|
|
20
|
+
id: string;
|
|
21
|
+
status: string;
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
/** 録画メタデータ + 操作トレースを登録し、recording id を得る (status=pending)。 */
|
|
25
|
+
export declare const createRecording: (baseUrl: string, apiKey: string, input: {
|
|
26
|
+
name: string;
|
|
27
|
+
startUrl: string | null;
|
|
28
|
+
purpose?: string | null;
|
|
29
|
+
manifest: RecordingManifest;
|
|
30
|
+
actions: ReadonlyArray<RecordedAction>;
|
|
31
|
+
}) => Promise<RecordingResponse>;
|
|
32
|
+
/**
|
|
33
|
+
* バンドル tar.gz を raw body で PUT する。サーバー側で即解析され、解析済み録画
|
|
34
|
+
* (status=analyzed / playbook 付き) が返る。画像は S3 に保存されない。
|
|
35
|
+
*/
|
|
36
|
+
export declare const uploadRecordingBundle: (baseUrl: string, apiKey: string, recordingId: string, tarPath: string) => Promise<RecordingResponse>;
|
package/dist/api-client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
1
2
|
export class ApiError extends Error {
|
|
2
3
|
status;
|
|
3
4
|
body;
|
|
@@ -34,4 +35,43 @@ export const postSnapshot = async (baseUrl, apiKey, scan) => {
|
|
|
34
35
|
}
|
|
35
36
|
return (await response.json());
|
|
36
37
|
};
|
|
38
|
+
const recordingHeaders = (apiKey) => ({
|
|
39
|
+
Authorization: `Bearer ${apiKey}`,
|
|
40
|
+
});
|
|
41
|
+
/** 録画メタデータ + 操作トレースを登録し、recording id を得る (status=pending)。 */
|
|
42
|
+
export const createRecording = async (baseUrl, apiKey, input) => {
|
|
43
|
+
const url = new URL('/v1/recordings', baseUrl).toString();
|
|
44
|
+
const response = await fetch(url, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { ...recordingHeaders(apiKey), 'Content-Type': 'application/json' },
|
|
47
|
+
body: JSON.stringify({
|
|
48
|
+
name: input.name,
|
|
49
|
+
start_url: input.startUrl,
|
|
50
|
+
purpose: input.purpose ?? null,
|
|
51
|
+
manifest: input.manifest,
|
|
52
|
+
actions: input.actions,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
throw new ApiError(response.status, await response.text().catch(() => ''));
|
|
57
|
+
}
|
|
58
|
+
return (await response.json());
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* バンドル tar.gz を raw body で PUT する。サーバー側で即解析され、解析済み録画
|
|
62
|
+
* (status=analyzed / playbook 付き) が返る。画像は S3 に保存されない。
|
|
63
|
+
*/
|
|
64
|
+
export const uploadRecordingBundle = async (baseUrl, apiKey, recordingId, tarPath) => {
|
|
65
|
+
const url = new URL(`/v1/recordings/${recordingId}/bundle`, baseUrl).toString();
|
|
66
|
+
const body = await readFile(tarPath);
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
method: 'PUT',
|
|
69
|
+
headers: { ...recordingHeaders(apiKey), 'Content-Type': 'application/gzip' },
|
|
70
|
+
body,
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
throw new ApiError(response.status, await response.text().catch(() => ''));
|
|
74
|
+
}
|
|
75
|
+
return (await response.json());
|
|
76
|
+
};
|
|
37
77
|
//# sourceMappingURL=api-client.js.map
|
package/dist/api-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 認証情報の解決。
|
|
3
|
+
*
|
|
4
|
+
* 保存済み config を読み、必要なら OAuth access token を refresh し、API 呼び出し用の
|
|
5
|
+
* Bearer 値を返す。`sync` コマンドと同じ方針 (期限切れ + refresh 不可なら再ログイン案内)。
|
|
6
|
+
*/
|
|
7
|
+
import { type StoredConfig } from './config.js';
|
|
8
|
+
export declare class NotLoggedInError extends Error {
|
|
9
|
+
constructor(message?: string);
|
|
10
|
+
}
|
|
11
|
+
/** API 呼び出し用の Bearer 値を取り出す。 */
|
|
12
|
+
export declare const bearerFor: (config: StoredConfig) => string;
|
|
13
|
+
export interface ResolvedAuth {
|
|
14
|
+
readonly baseUrl: string;
|
|
15
|
+
readonly token: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 認証を解決する。未ログインなら NotLoggedInError を投げる。
|
|
19
|
+
*/
|
|
20
|
+
export declare const resolveAuth: () => Promise<ResolvedAuth>;
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 認証情報の解決。
|
|
3
|
+
*
|
|
4
|
+
* 保存済み config を読み、必要なら OAuth access token を refresh し、API 呼び出し用の
|
|
5
|
+
* Bearer 値を返す。`sync` コマンドと同じ方針 (期限切れ + refresh 不可なら再ログイン案内)。
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_CLIENT_ID, loadConfig, saveConfig } from './config.js';
|
|
8
|
+
import { OAuthError, refreshAccessToken } from './oauth-client.js';
|
|
9
|
+
const ACCESS_TOKEN_REFRESH_SKEW_SECONDS = 60;
|
|
10
|
+
export class NotLoggedInError extends Error {
|
|
11
|
+
constructor(message = 'not logged in. Run `lnar login` first.') {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'NotLoggedInError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const isAccessTokenExpired = (config) => {
|
|
17
|
+
if (!config.accessTokenExpiresAt)
|
|
18
|
+
return false;
|
|
19
|
+
const expires = Date.parse(config.accessTokenExpiresAt);
|
|
20
|
+
if (Number.isNaN(expires))
|
|
21
|
+
return true;
|
|
22
|
+
return expires - Date.now() < ACCESS_TOKEN_REFRESH_SKEW_SECONDS * 1000;
|
|
23
|
+
};
|
|
24
|
+
const refreshIfNeeded = async (config) => {
|
|
25
|
+
if (!config.accessToken)
|
|
26
|
+
return config;
|
|
27
|
+
if (!isAccessTokenExpired(config))
|
|
28
|
+
return config;
|
|
29
|
+
if (!config.refreshToken) {
|
|
30
|
+
throw new NotLoggedInError('access token expired and no refresh token. Run `lnar login`.');
|
|
31
|
+
}
|
|
32
|
+
const clientId = config.clientId ?? DEFAULT_CLIENT_ID;
|
|
33
|
+
let token;
|
|
34
|
+
try {
|
|
35
|
+
token = await refreshAccessToken(config.apiBaseUrl, clientId, config.refreshToken);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err instanceof OAuthError && err.errorCode === 'invalid_grant') {
|
|
39
|
+
throw new NotLoggedInError('refresh token expired or revoked. Run `lnar login`.');
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
const accessTokenExpiresAt = new Date(Date.now() + token.expires_in * 1000).toISOString();
|
|
44
|
+
const next = {
|
|
45
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
46
|
+
accessToken: token.access_token,
|
|
47
|
+
refreshToken: token.refresh_token ?? config.refreshToken,
|
|
48
|
+
accessTokenExpiresAt,
|
|
49
|
+
scopes: token.scope ? token.scope.split(' ') : config.scopes,
|
|
50
|
+
clientId,
|
|
51
|
+
};
|
|
52
|
+
await saveConfig(next);
|
|
53
|
+
return { ...next, savedAt: new Date().toISOString() };
|
|
54
|
+
};
|
|
55
|
+
/** API 呼び出し用の Bearer 値を取り出す。 */
|
|
56
|
+
export const bearerFor = (config) => {
|
|
57
|
+
if (config.accessToken)
|
|
58
|
+
return config.accessToken;
|
|
59
|
+
if (config.apiKey)
|
|
60
|
+
return config.apiKey;
|
|
61
|
+
throw new NotLoggedInError('no credentials available. Run `lnar login`.');
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* 認証を解決する。未ログインなら NotLoggedInError を投げる。
|
|
65
|
+
*/
|
|
66
|
+
export const resolveAuth = async () => {
|
|
67
|
+
const initial = await loadConfig();
|
|
68
|
+
if (initial == null) {
|
|
69
|
+
throw new NotLoggedInError();
|
|
70
|
+
}
|
|
71
|
+
const config = await refreshIfNeeded(initial);
|
|
72
|
+
return { baseUrl: config.apiBaseUrl, token: bearerFor(config) };
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { runDaemon } from './commands/daemon.js';
|
|
4
4
|
import { runDown } from './commands/down.js';
|
|
5
5
|
import { runLogin } from './commands/login.js';
|
|
6
|
+
import { runRecord } from './commands/record.js';
|
|
6
7
|
import { runScan } from './commands/scan.js';
|
|
7
8
|
import { runStatus } from './commands/status.js';
|
|
8
9
|
import { runSync } from './commands/sync.js';
|
|
@@ -74,6 +75,30 @@ program
|
|
|
74
75
|
.action(async (opts) => {
|
|
75
76
|
await runSync({ dryRun: Boolean(opts.dryRun) });
|
|
76
77
|
});
|
|
78
|
+
program
|
|
79
|
+
.command('record')
|
|
80
|
+
.description('Record a browser demo locally and upload it to lnar (Demo-to-MCP). You operate your own browser; the captured actions/keyframes become the material for generating a browser-automation MCP.')
|
|
81
|
+
.option('--url <url>', 'Start URL to open in the recording browser')
|
|
82
|
+
.option('--name <name>', 'Recording name (default: recording-<timestamp>)')
|
|
83
|
+
.option('--purpose <text>', 'Purpose of the task (improves playbook analysis; prompted after recording if omitted)')
|
|
84
|
+
.option('--out <dir>', 'Output bundle directory (default: ./lnar-<name>)')
|
|
85
|
+
.option('--headless', 'Run the browser headless (not recommended for interactive demos)')
|
|
86
|
+
.option('--video', 'Also record a video of the session (off by default; included in the upload when set)')
|
|
87
|
+
.option('--trace', 'Also record a Playwright trace (off by default)')
|
|
88
|
+
.option('--no-upload', 'Produce the bundle locally but do not upload to lnar')
|
|
89
|
+
.action(async (opts) => {
|
|
90
|
+
await runRecord({
|
|
91
|
+
url: opts.url,
|
|
92
|
+
name: opts.name,
|
|
93
|
+
purpose: opts.purpose,
|
|
94
|
+
out: opts.out,
|
|
95
|
+
headless: Boolean(opts.headless),
|
|
96
|
+
video: Boolean(opts.video),
|
|
97
|
+
trace: Boolean(opts.trace),
|
|
98
|
+
// commander の --no-upload は opts.upload=false で渡る
|
|
99
|
+
noUpload: opts.upload === false,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
77
102
|
// ---------------------------------------------------------------------------
|
|
78
103
|
// Hidden internal command: launchd / systemd / Task Scheduler が exec する実体。
|
|
79
104
|
// ユーザー向けには `lnar up` が完全に隠蔽するため、--help に出さない。
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/daemon.js
CHANGED
|
@@ -4,6 +4,7 @@ import { DEFAULT_CLIENT_ID, loadConfig, saveConfig } from '../config.js';
|
|
|
4
4
|
import { loadOrCreateMachineId } from '../machine-id.js';
|
|
5
5
|
import { OAuthError, refreshAccessToken } from '../oauth-client.js';
|
|
6
6
|
import { listPendingForHost, reportApplied, reportFailed, } from '../pending-client.js';
|
|
7
|
+
import { executePendingRuns } from '../run-worker.js';
|
|
7
8
|
import { runAllScanners } from '../scanners/index.js';
|
|
8
9
|
import { runSseClient, SseFatalError } from '../sse-client.js';
|
|
9
10
|
import { getWriter } from '../writers/registry.js';
|
|
@@ -101,6 +102,18 @@ const applyPending = async (config, change) => {
|
|
|
101
102
|
const runOnce = async (config) => {
|
|
102
103
|
// 1. 最新スナップショットを送信 → サーバ側 agent ID が最新化される
|
|
103
104
|
await runScanAndSync(config);
|
|
105
|
+
// 1.5. 録画 run-job をローカル実行する (Demo-to-MCP)。失敗しても以降の
|
|
106
|
+
// スキャン / pending 適用は継続させる (機能を分離する)。
|
|
107
|
+
try {
|
|
108
|
+
const ran = await executePendingRuns(config.apiBaseUrl, bearerFor(config), hostname());
|
|
109
|
+
if (ran > 0) {
|
|
110
|
+
process.stdout.write(`lnar daemon: executed ${ran} recording run(s)\n`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
115
|
+
process.stderr.write(`lnar daemon: recording runs error: ${message}\n`);
|
|
116
|
+
}
|
|
104
117
|
// 2. 自 host 向けの pending を取得
|
|
105
118
|
const host = hostname();
|
|
106
119
|
const pending = await listPendingForHost(config.apiBaseUrl, bearerFor(config), host);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAqB,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,kBAAkB,EAElB,aAAa,EACb,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASnD,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAE7C,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAC1C,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,MAAM,oBAAoB,GAAG,CAAC,MAAoB,EAAW,EAAE;IAC7D,IAAI,CAAC,MAAM,CAAC,oBAAoB;QAAE,OAAO,KAAK,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iCAAiC,GAAG,IAAI,CAAC;AACzE,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,MAAoB,EAAyB,EAAE;IAC5E,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IACvC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACtD,IAAI,
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.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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"}
|
|
@@ -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>;
|