@peekdev/cli 0.1.0-alpha.1 → 0.1.0-alpha.11
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/LICENSE +202 -0
- package/README.md +90 -0
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +10 -0
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +97 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/sessions.d.ts.map +1 -1
- package/dist/commands/sessions.js +129 -11
- package/dist/commands/sessions.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/db.d.ts +46 -5
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +78 -7
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/extension-id.d.ts +30 -0
- package/dist/lib/extension-id.d.ts.map +1 -0
- package/dist/lib/extension-id.js +78 -0
- package/dist/lib/extension-id.js.map +1 -0
- package/dist/lib/format/index.d.ts +11 -1
- package/dist/lib/format/index.d.ts.map +1 -1
- package/dist/lib/format/index.js +22 -20
- package/dist/lib/format/index.js.map +1 -1
- package/dist/lib/format/json.d.ts +26 -1
- package/dist/lib/format/json.d.ts.map +1 -1
- package/dist/lib/format/json.js +39 -2
- package/dist/lib/format/json.js.map +1 -1
- package/dist/lib/format/markdown.d.ts.map +1 -1
- package/dist/lib/format/markdown.js +17 -0
- package/dist/lib/format/markdown.js.map +1 -1
- package/dist/lib/format/playwright.d.ts +13 -0
- package/dist/lib/format/playwright.d.ts.map +1 -0
- package/dist/lib/format/playwright.js +37 -0
- package/dist/lib/format/playwright.js.map +1 -0
- package/dist/lib/native-host-wrapper.d.ts +23 -0
- package/dist/lib/native-host-wrapper.d.ts.map +1 -0
- package/dist/lib/native-host-wrapper.js +45 -0
- package/dist/lib/native-host-wrapper.js.map +1 -0
- package/dist/lib/peek-home.d.ts +8 -0
- package/dist/lib/peek-home.d.ts.map +1 -1
- package/dist/lib/peek-home.js +10 -0
- package/dist/lib/peek-home.js.map +1 -1
- package/dist/lib/prompt.d.ts +13 -0
- package/dist/lib/prompt.d.ts.map +1 -1
- package/dist/lib/prompt.js +40 -0
- package/dist/lib/prompt.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +14 -5
- package/dist/version.js.map +1 -1
- package/package.json +16 -12
|
@@ -2,10 +2,20 @@
|
|
|
2
2
|
// §C.1). Opens the shared DB read-mostly via @peekdev/mcp's openDb, runs the
|
|
3
3
|
// pure query/format helpers, and prints / writes. Arg parsing uses the built-in
|
|
4
4
|
// node:util parseArgs (no dependency).
|
|
5
|
+
//
|
|
6
|
+
// P-18 (alpha.7): every subcommand's parseArgs call MUST declare `--help` as a
|
|
7
|
+
// known option. Pre-fix, passing `--help` to a subcommand crashed with
|
|
8
|
+
// `TypeError: Unknown option '--help'` because node:util parseArgs rejects
|
|
9
|
+
// unknown flags by default. Each subcommand now defines its own `printHelp`
|
|
10
|
+
// (so the usage matches the subcommand's actual options) and `--help` short-
|
|
11
|
+
// circuits to exit 0 before any other work. `list` also adds `--json` for
|
|
12
|
+
// machine-readable output (audit log already has it; show/export/delete
|
|
13
|
+
// don't need it — show is interactive, export writes its own format-
|
|
14
|
+
// controlled file, delete is unary).
|
|
5
15
|
import { writeFileSync } from 'node:fs';
|
|
6
16
|
import { parseArgs } from 'node:util';
|
|
7
17
|
import { openDb } from '@peekdev/mcp/db';
|
|
8
|
-
import { deleteSession, deleteSessionsOlderThan, getSessionDetail, listSessions, } from '../lib/db.js';
|
|
18
|
+
import { deleteSession, deleteSessionsOlderThan, getSessionDetail, listSessions, listSessionsWithCounts, } from '../lib/db.js';
|
|
9
19
|
import { cutoffBefore } from '../lib/duration.js';
|
|
10
20
|
import { EXPORT_FORMATS, formatSession, isExportFormat, } from '../lib/format/index.js';
|
|
11
21
|
import { formatBytes, pad } from '../lib/output.js';
|
|
@@ -19,11 +29,64 @@ function printUsage() {
|
|
|
19
29
|
'Usage: peek sessions <command>',
|
|
20
30
|
'',
|
|
21
31
|
'Commands:',
|
|
22
|
-
' list [--origin <url>] [--limit 20] List recent sessions (newest first)',
|
|
23
|
-
' show <session-id>
|
|
32
|
+
' list [--origin <url>] [--limit 20] [--json] List recent sessions (newest first)',
|
|
33
|
+
' show <session-id> Show one session (metadata + errors)',
|
|
24
34
|
` export <session-id> --format <${EXPORT_FORMATS.join('|')}> [--out <file>]`,
|
|
25
|
-
' delete <session-id>
|
|
26
|
-
' delete --all-older-than <dur>
|
|
35
|
+
' delete <session-id> Delete one session',
|
|
36
|
+
' delete --all-older-than <dur> Delete sessions older than e.g. 7d',
|
|
37
|
+
'',
|
|
38
|
+
"Run 'peek sessions <command> --help' for command-specific options.",
|
|
39
|
+
'',
|
|
40
|
+
].join('\n'));
|
|
41
|
+
}
|
|
42
|
+
function printListHelp() {
|
|
43
|
+
process.stdout.write([
|
|
44
|
+
'Usage: peek sessions list [options]',
|
|
45
|
+
'',
|
|
46
|
+
'Options:',
|
|
47
|
+
' --origin <url> Filter to a single origin (scheme://host[:port])',
|
|
48
|
+
' --limit <n> Max rows to return (default 20, must be > 0)',
|
|
49
|
+
' --json Emit rows as a JSON array instead of a table',
|
|
50
|
+
' --help Show this help and exit',
|
|
51
|
+
'',
|
|
52
|
+
].join('\n'));
|
|
53
|
+
}
|
|
54
|
+
function printShowHelp() {
|
|
55
|
+
process.stdout.write([
|
|
56
|
+
'Usage: peek sessions show <session-id>',
|
|
57
|
+
'',
|
|
58
|
+
'Print one session as Markdown (the same shape `--format markdown` exports).',
|
|
59
|
+
'',
|
|
60
|
+
'Options:',
|
|
61
|
+
' --help Show this help and exit',
|
|
62
|
+
'',
|
|
63
|
+
].join('\n'));
|
|
64
|
+
}
|
|
65
|
+
function printExportHelp() {
|
|
66
|
+
process.stdout.write([
|
|
67
|
+
'Usage: peek sessions export <session-id> [options]',
|
|
68
|
+
'',
|
|
69
|
+
'Options:',
|
|
70
|
+
` --format <${EXPORT_FORMATS.join('|')}> Export format (default: markdown)`,
|
|
71
|
+
' --out <file> Write to file instead of stdout',
|
|
72
|
+
' --help Show this help and exit',
|
|
73
|
+
'',
|
|
74
|
+
'Formats:',
|
|
75
|
+
' markdown Structured AI-paste (default)',
|
|
76
|
+
' json Machine-readable, same schema as the MCP get_session_* tools',
|
|
77
|
+
' playwright Runnable Playwright `test(...)` script (K.2 alpha.7)',
|
|
78
|
+
' html Self-contained replay viewer (deferred — see --help error)',
|
|
79
|
+
'',
|
|
80
|
+
].join('\n'));
|
|
81
|
+
}
|
|
82
|
+
function printDeleteHelp() {
|
|
83
|
+
process.stdout.write([
|
|
84
|
+
'Usage: peek sessions delete <session-id>',
|
|
85
|
+
' peek sessions delete --all-older-than <duration>',
|
|
86
|
+
'',
|
|
87
|
+
'Options:',
|
|
88
|
+
' --all-older-than <dur> Delete every session older than e.g. 7d, 24h, 30m',
|
|
89
|
+
' --help Show this help and exit',
|
|
27
90
|
'',
|
|
28
91
|
].join('\n'));
|
|
29
92
|
}
|
|
@@ -33,9 +96,15 @@ function runList(argv) {
|
|
|
33
96
|
options: {
|
|
34
97
|
origin: { type: 'string' },
|
|
35
98
|
limit: { type: 'string' },
|
|
99
|
+
json: { type: 'boolean' },
|
|
100
|
+
help: { type: 'boolean' },
|
|
36
101
|
},
|
|
37
102
|
allowPositionals: false,
|
|
38
103
|
});
|
|
104
|
+
if (values.help) {
|
|
105
|
+
printListHelp();
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
39
108
|
const limit = values.limit !== undefined ? Number(values.limit) : 20;
|
|
40
109
|
if (!Number.isInteger(limit) || limit <= 0) {
|
|
41
110
|
process.stderr.write('peek sessions list: --limit must be a positive integer\n');
|
|
@@ -43,10 +112,35 @@ function runList(argv) {
|
|
|
43
112
|
}
|
|
44
113
|
const db = open();
|
|
45
114
|
try {
|
|
46
|
-
const
|
|
115
|
+
const listOpts = {
|
|
47
116
|
limit,
|
|
48
117
|
...(values.origin !== undefined ? { origin: values.origin } : {}),
|
|
49
|
-
}
|
|
118
|
+
};
|
|
119
|
+
if (values.json) {
|
|
120
|
+
// Machine-readable path: pull the count-enriched rows in a single
|
|
121
|
+
// query (avoids N+1 on the list path — see listSessionsWithCounts).
|
|
122
|
+
// Always emit a JSON array (empty when no sessions), never the
|
|
123
|
+
// "No sessions recorded yet." human string. Downstream scripts can
|
|
124
|
+
// `JSON.parse` the output unconditionally.
|
|
125
|
+
const rows = listSessionsWithCounts(db, listOpts);
|
|
126
|
+
const json = rows.map((s) => ({
|
|
127
|
+
id: s.id,
|
|
128
|
+
origin: s.origin,
|
|
129
|
+
url: s.url,
|
|
130
|
+
created_at: s.createdAt,
|
|
131
|
+
updated_at: s.updatedAt,
|
|
132
|
+
event_count: s.eventCount,
|
|
133
|
+
console_count: s.consoleCount,
|
|
134
|
+
network_count: s.networkCount,
|
|
135
|
+
bytes: s.bytes,
|
|
136
|
+
status: s.status,
|
|
137
|
+
}));
|
|
138
|
+
process.stdout.write(`${JSON.stringify(json, null, 2)}\n`);
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
// Human table path: counts aren't shown (see `peek sessions show` for
|
|
142
|
+
// the drill-in view), so the cheaper `listSessions` is fine.
|
|
143
|
+
const rows = listSessions(db, listOpts);
|
|
50
144
|
if (rows.length === 0) {
|
|
51
145
|
process.stdout.write('No sessions recorded yet.\n');
|
|
52
146
|
return 0;
|
|
@@ -62,7 +156,17 @@ function runList(argv) {
|
|
|
62
156
|
}
|
|
63
157
|
}
|
|
64
158
|
function runShow(argv) {
|
|
65
|
-
const { positionals } = parseArgs({
|
|
159
|
+
const { values, positionals } = parseArgs({
|
|
160
|
+
args: argv,
|
|
161
|
+
allowPositionals: true,
|
|
162
|
+
options: {
|
|
163
|
+
help: { type: 'boolean' },
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
if (values.help) {
|
|
167
|
+
printShowHelp();
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
66
170
|
const id = positionals[0];
|
|
67
171
|
if (!id) {
|
|
68
172
|
process.stderr.write('peek sessions show: missing <session-id>\n');
|
|
@@ -91,9 +195,14 @@ function runExport(argv) {
|
|
|
91
195
|
options: {
|
|
92
196
|
format: { type: 'string' },
|
|
93
197
|
out: { type: 'string' },
|
|
198
|
+
help: { type: 'boolean' },
|
|
94
199
|
},
|
|
95
200
|
allowPositionals: true,
|
|
96
201
|
});
|
|
202
|
+
if (values.help) {
|
|
203
|
+
printExportHelp();
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
97
206
|
const id = positionals[0];
|
|
98
207
|
if (!id) {
|
|
99
208
|
process.stderr.write('peek sessions export: missing <session-id>\n');
|
|
@@ -112,10 +221,14 @@ function runExport(argv) {
|
|
|
112
221
|
process.stderr.write(`peek sessions export: no session with id '${id}'\n`);
|
|
113
222
|
return 1;
|
|
114
223
|
}
|
|
115
|
-
const result = formatSession(detail, format
|
|
224
|
+
const result = formatSession(detail, format, {
|
|
225
|
+
...(detail.session.eventsBlobPath !== null
|
|
226
|
+
? { blobPath: detail.session.eventsBlobPath }
|
|
227
|
+
: {}),
|
|
228
|
+
});
|
|
116
229
|
if (!result.ok) {
|
|
117
|
-
// html
|
|
118
|
-
//
|
|
230
|
+
// html stub: clear message, non-zero exit (never write a partial file).
|
|
231
|
+
// playwright wired through in alpha.7 (K.2); json/markdown always ok.
|
|
119
232
|
process.stderr.write(`peek sessions export: ${result.message}\n`);
|
|
120
233
|
return 2;
|
|
121
234
|
}
|
|
@@ -137,9 +250,14 @@ function runDelete(argv) {
|
|
|
137
250
|
args: argv,
|
|
138
251
|
options: {
|
|
139
252
|
'all-older-than': { type: 'string' },
|
|
253
|
+
help: { type: 'boolean' },
|
|
140
254
|
},
|
|
141
255
|
allowPositionals: true,
|
|
142
256
|
});
|
|
257
|
+
if (values.help) {
|
|
258
|
+
printDeleteHelp();
|
|
259
|
+
return 0;
|
|
260
|
+
}
|
|
143
261
|
const olderThan = values['all-older-than'];
|
|
144
262
|
const id = positionals[0];
|
|
145
263
|
if (olderThan !== undefined && id !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,gFAAgF;AAChF,uCAAuC;
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsCA,wBAAsB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BlE"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// Arg parsing uses the built-in node:util parseArgs at each command boundary
|
|
10
10
|
// (no CLI framework dependency); this top-level dispatcher just routes on the
|
|
11
11
|
// first positional so each subcommand owns its own option schema.
|
|
12
|
+
import { realpathSync } from 'node:fs';
|
|
12
13
|
import { runAudit } from './commands/audit.js';
|
|
13
14
|
import { runInit } from './commands/init.js';
|
|
14
15
|
import { runSessions } from './commands/sessions.js';
|
|
@@ -68,7 +69,16 @@ async function main() {
|
|
|
68
69
|
// Run only when invoked directly as the `peek` bin (npx / shell), not when this
|
|
69
70
|
// module is imported (tests, or another package consuming `run`). Guarded the
|
|
70
71
|
// same way as @peekdev/mcp's entry so an ESM `import` has no side effects.
|
|
71
|
-
const invokedDirectly = process.argv[1] !== undefined &&
|
|
72
|
+
const invokedDirectly = process.argv[1] !== undefined &&
|
|
73
|
+
(import.meta.url === `file://${process.argv[1]}` ||
|
|
74
|
+
(() => {
|
|
75
|
+
try {
|
|
76
|
+
return import.meta.url === `file://${realpathSync(process.argv[1])}`;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
})());
|
|
72
82
|
if (invokedDirectly) {
|
|
73
83
|
main().catch((err) => {
|
|
74
84
|
process.stderr.write(`peek: fatal — ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\n`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,8EAA8E;AAC9E,oEAAoE;AACpE,gBAAgB;AAChB,4CAA4C;AAC5C,cAAc;AACd,mBAAmB;AACnB,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,kEAAkE;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,IAAI,GAAG,QAAQ,WAAW;;;;;;;;;;;;;;;;;CAiB/B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAuB;IAC/C,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAEhC,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,SAAS,EAAE,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,SAAS,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,IAAI;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC;YACzC,OAAO,CAAC,CAAC;QACX,KAAK,SAAS,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,wEAAwE;YACxE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,OAAO,OAAO,CAAC,CAAC;YAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC;AAED,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,MAAM,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export interface SessionRow {
|
|
|
11
11
|
readonly eventCount: number;
|
|
12
12
|
readonly bytes: number;
|
|
13
13
|
readonly status: string;
|
|
14
|
+
/**
|
|
15
|
+
* Relative path to the gzipped event blob under ~/.peek/rrweb-events/.
|
|
16
|
+
* Null when the session has never flushed (active session pre-flush) or
|
|
17
|
+
* pre-dates the column. Consumed by the playwright export (K.2 alpha.7)
|
|
18
|
+
* to feed the rrweb stream to `generate_playwright_repro`.
|
|
19
|
+
*/
|
|
20
|
+
readonly eventsBlobPath: string | null;
|
|
14
21
|
}
|
|
15
22
|
/** A console message extracted for a session (mirrors `get_session_console_errors`). */
|
|
16
23
|
export interface ConsoleEventRow {
|
|
@@ -54,6 +61,31 @@ export interface ListSessionsOptions {
|
|
|
54
61
|
* (P2 PRD §C.1 `peek sessions list [--origin <url>] [--limit 20]`).
|
|
55
62
|
*/
|
|
56
63
|
export declare function listSessions(db: Database, options?: ListSessionsOptions): SessionRow[];
|
|
64
|
+
/** A list row enriched with the per-session aggregate error counts (P-18 fix). */
|
|
65
|
+
export interface SessionRowWithCounts extends SessionRow {
|
|
66
|
+
/** Console rows with level = 'error' (matches getSessionCounts.consoleErrors). */
|
|
67
|
+
readonly consoleCount: number;
|
|
68
|
+
/** Network rows with status >= 400 OR error_text IS NOT NULL (matches networkErrors). */
|
|
69
|
+
readonly networkCount: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* List sessions WITH the per-row console + network error counts in a SINGLE
|
|
73
|
+
* query (P-18 alpha.8 fix). The `peek sessions list --json` path needs the
|
|
74
|
+
* counts on each row — they're the most actionable signal for an AI consumer
|
|
75
|
+
* deciding which session to drill into. The naive approach (call
|
|
76
|
+
* `getSessionCounts` per row) is N+1: 2 child-table queries × default 20 rows
|
|
77
|
+
* = 40 queries per list. This LEFT JOIN aggregates both child tables in one
|
|
78
|
+
* statement; both have an existing `(session_id, …)` index (migration 0001:
|
|
79
|
+
* `idx_console_events_session` + `idx_network_events_session`) so the join
|
|
80
|
+
* stays sub-millisecond on thousands of sessions.
|
|
81
|
+
*
|
|
82
|
+
* Error definitions MUST match {@link getSessionCounts} exactly — otherwise
|
|
83
|
+
* `peek sessions list --json` and `peek sessions show <id>` would disagree on
|
|
84
|
+
* how many errors a session has, which would confuse downstream tooling.
|
|
85
|
+
* console error := level = 'error'
|
|
86
|
+
* network error := status >= 400 OR error_text IS NOT NULL
|
|
87
|
+
*/
|
|
88
|
+
export declare function listSessionsWithCounts(db: Database, options?: ListSessionsOptions): SessionRowWithCounts[];
|
|
57
89
|
/** Fetch one session's metadata, or `undefined` if no such id. */
|
|
58
90
|
export declare function getSession(db: Database, id: string): SessionRow | undefined;
|
|
59
91
|
/** Count error-level console rows and >=400 network rows for a session. */
|
|
@@ -76,11 +108,20 @@ export interface NetworkQueryOptions {
|
|
|
76
108
|
export declare function getNetworkEvents(db: Database, id: string, options?: NetworkQueryOptions): NetworkEventRow[];
|
|
77
109
|
/** Hydrate one session fully for `show` / `export`. Returns `undefined` if no such id. */
|
|
78
110
|
export declare function getSessionDetail(db: Database, id: string): SessionDetail | undefined;
|
|
79
|
-
/** Delete one session by id. Child rows cascade (ON DELETE CASCADE). Returns rows removed (0 or 1). */
|
|
80
|
-
export declare function deleteSession(db: Database, id: string): number;
|
|
81
111
|
/**
|
|
82
|
-
* Delete
|
|
83
|
-
*
|
|
112
|
+
* Delete one session by id. Child rows cascade (ON DELETE CASCADE). Also
|
|
113
|
+
* removes the per-session chunk directory under {@link rrwebEventsDir} — K.4
|
|
114
|
+
* fix (2026-05-28 QA walk): the DB cascade alone left gzipped blobs on disk
|
|
115
|
+
* forever. Returns rows removed (0 or 1). `rrwebBaseDir` defaults to
|
|
116
|
+
* `~/.peek/rrweb-events/`; tests override it with a tmpdir.
|
|
117
|
+
*/
|
|
118
|
+
export declare function deleteSession(db: Database, id: string, rrwebBaseDir?: string): number;
|
|
119
|
+
/**
|
|
120
|
+
* Delete every session whose `updated_at` is strictly before the ISO cutoff
|
|
121
|
+
* AND the corresponding per-session chunk directories on disk. SELECT-then-
|
|
122
|
+
* DELETE wraps in a transaction so the on-disk cleanup matches what was
|
|
123
|
+
* actually removed from the DB even if a concurrent write lands between the
|
|
124
|
+
* two statements. Returns the number of sessions removed.
|
|
84
125
|
*/
|
|
85
|
-
export declare function deleteSessionsOlderThan(db: Database, cutoffIso: string): number;
|
|
126
|
+
export declare function deleteSessionsOlderThan(db: Database, cutoffIso: string, rrwebBaseDir?: string): number;
|
|
86
127
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/lib/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db.js
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
// The returned shapes deliberately mirror the MCP tool return schema (P2 PRD
|
|
7
7
|
// §B3) so `peek sessions export --format json` and the MCP `get_session_*`
|
|
8
8
|
// tools are interchangeable for an AI consumer.
|
|
9
|
+
import { rmSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { rrwebEventsDir } from './peek-home.js';
|
|
9
12
|
function mapSession(r) {
|
|
10
13
|
return {
|
|
11
14
|
id: r.id,
|
|
@@ -18,6 +21,7 @@ function mapSession(r) {
|
|
|
18
21
|
eventCount: r.event_count,
|
|
19
22
|
bytes: r.bytes,
|
|
20
23
|
status: r.status,
|
|
24
|
+
eventsBlobPath: r.events_blob_path,
|
|
21
25
|
};
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
@@ -37,6 +41,53 @@ export function listSessions(db, options = {}) {
|
|
|
37
41
|
const rows = db.prepare(sql).all(...params);
|
|
38
42
|
return rows.map(mapSession);
|
|
39
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* List sessions WITH the per-row console + network error counts in a SINGLE
|
|
46
|
+
* query (P-18 alpha.8 fix). The `peek sessions list --json` path needs the
|
|
47
|
+
* counts on each row — they're the most actionable signal for an AI consumer
|
|
48
|
+
* deciding which session to drill into. The naive approach (call
|
|
49
|
+
* `getSessionCounts` per row) is N+1: 2 child-table queries × default 20 rows
|
|
50
|
+
* = 40 queries per list. This LEFT JOIN aggregates both child tables in one
|
|
51
|
+
* statement; both have an existing `(session_id, …)` index (migration 0001:
|
|
52
|
+
* `idx_console_events_session` + `idx_network_events_session`) so the join
|
|
53
|
+
* stays sub-millisecond on thousands of sessions.
|
|
54
|
+
*
|
|
55
|
+
* Error definitions MUST match {@link getSessionCounts} exactly — otherwise
|
|
56
|
+
* `peek sessions list --json` and `peek sessions show <id>` would disagree on
|
|
57
|
+
* how many errors a session has, which would confuse downstream tooling.
|
|
58
|
+
* console error := level = 'error'
|
|
59
|
+
* network error := status >= 400 OR error_text IS NOT NULL
|
|
60
|
+
*/
|
|
61
|
+
export function listSessionsWithCounts(db, options = {}) {
|
|
62
|
+
const limit = options.limit ?? 20;
|
|
63
|
+
const params = [];
|
|
64
|
+
// The two correlated COUNT(*) subqueries inline are simpler than two LEFT
|
|
65
|
+
// JOINs against derived tables AND let SQLite use the (session_id, ...)
|
|
66
|
+
// indexes for each row directly. With LIMIT applied to the outer query the
|
|
67
|
+
// subqueries run at most `limit` times per side — bounded the same way the
|
|
68
|
+
// naive N+1 was, but in one statement (no JS-side loop, no per-row prepare).
|
|
69
|
+
let sql = `
|
|
70
|
+
SELECT
|
|
71
|
+
s.*,
|
|
72
|
+
(SELECT COUNT(*) FROM console_events
|
|
73
|
+
WHERE session_id = s.id AND level = 'error') AS console_count,
|
|
74
|
+
(SELECT COUNT(*) FROM network_events
|
|
75
|
+
WHERE session_id = s.id AND (status >= 400 OR error_text IS NOT NULL)) AS network_count
|
|
76
|
+
FROM sessions s
|
|
77
|
+
`;
|
|
78
|
+
if (options.origin !== undefined) {
|
|
79
|
+
sql += ' WHERE s.origin = ?';
|
|
80
|
+
params.push(options.origin);
|
|
81
|
+
}
|
|
82
|
+
sql += ' ORDER BY s.updated_at DESC, s.created_at DESC LIMIT ?';
|
|
83
|
+
params.push(limit);
|
|
84
|
+
const rows = db.prepare(sql).all(...params);
|
|
85
|
+
return rows.map((r) => ({
|
|
86
|
+
...mapSession(r),
|
|
87
|
+
consoleCount: r.console_count,
|
|
88
|
+
networkCount: r.network_count,
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
40
91
|
/** Fetch one session's metadata, or `undefined` if no such id. */
|
|
41
92
|
export function getSession(db, id) {
|
|
42
93
|
const row = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id);
|
|
@@ -101,17 +152,37 @@ export function getSessionDetail(db, id) {
|
|
|
101
152
|
networkErrors: getNetworkEvents(db, id),
|
|
102
153
|
};
|
|
103
154
|
}
|
|
104
|
-
/**
|
|
105
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Delete one session by id. Child rows cascade (ON DELETE CASCADE). Also
|
|
157
|
+
* removes the per-session chunk directory under {@link rrwebEventsDir} — K.4
|
|
158
|
+
* fix (2026-05-28 QA walk): the DB cascade alone left gzipped blobs on disk
|
|
159
|
+
* forever. Returns rows removed (0 or 1). `rrwebBaseDir` defaults to
|
|
160
|
+
* `~/.peek/rrweb-events/`; tests override it with a tmpdir.
|
|
161
|
+
*/
|
|
162
|
+
export function deleteSession(db, id, rrwebBaseDir = rrwebEventsDir()) {
|
|
106
163
|
const info = db.prepare('DELETE FROM sessions WHERE id = ?').run(id);
|
|
164
|
+
if (info.changes > 0) {
|
|
165
|
+
rmSync(join(rrwebBaseDir, id), { recursive: true, force: true });
|
|
166
|
+
}
|
|
107
167
|
return info.changes;
|
|
108
168
|
}
|
|
109
169
|
/**
|
|
110
|
-
* Delete every session whose `updated_at` is strictly before the ISO cutoff
|
|
111
|
-
*
|
|
170
|
+
* Delete every session whose `updated_at` is strictly before the ISO cutoff
|
|
171
|
+
* AND the corresponding per-session chunk directories on disk. SELECT-then-
|
|
172
|
+
* DELETE wraps in a transaction so the on-disk cleanup matches what was
|
|
173
|
+
* actually removed from the DB even if a concurrent write lands between the
|
|
174
|
+
* two statements. Returns the number of sessions removed.
|
|
112
175
|
*/
|
|
113
|
-
export function deleteSessionsOlderThan(db, cutoffIso) {
|
|
114
|
-
const
|
|
115
|
-
|
|
176
|
+
export function deleteSessionsOlderThan(db, cutoffIso, rrwebBaseDir = rrwebEventsDir()) {
|
|
177
|
+
const removeIds = db.transaction((cutoff) => {
|
|
178
|
+
const rows = db.prepare('SELECT id FROM sessions WHERE updated_at < ?').all(cutoff);
|
|
179
|
+
db.prepare('DELETE FROM sessions WHERE updated_at < ?').run(cutoff);
|
|
180
|
+
return rows.map((r) => r.id);
|
|
181
|
+
});
|
|
182
|
+
const ids = removeIds(cutoffIso);
|
|
183
|
+
for (const id of ids) {
|
|
184
|
+
rmSync(join(rrwebBaseDir, id), { recursive: true, force: true });
|
|
185
|
+
}
|
|
186
|
+
return ids.length;
|
|
116
187
|
}
|
|
117
188
|
//# sourceMappingURL=db.js.map
|
package/dist/lib/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,0DAA0D;AAC1D,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,gDAAgD;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate a candidate Chrome extension ID. Returns `null` if the input is the
|
|
3
|
+
* expected 32-character `a–p` shape; otherwise a user-facing error message.
|
|
4
|
+
*
|
|
5
|
+
* Trims internal whitespace defensively — users routinely paste from
|
|
6
|
+
* `chrome://extensions/` with a trailing newline or leading space.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateChromeExtensionId(raw: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Build the `chrome-extension://<id>/` origin Chrome expects in a native-host
|
|
11
|
+
* manifest's `allowed_origins`. Mirrors `allowedOrigins()` in peek-mcp's
|
|
12
|
+
* manifest.ts but emits the bare origin string for a single id (the manifest
|
|
13
|
+
* builder de-dupes when it folds multiple IDs together).
|
|
14
|
+
*/
|
|
15
|
+
export declare function chromeExtensionOrigin(id: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* P-13 (2026-05-28 QA walk) — pull the previously-saved unpacked extension ID
|
|
18
|
+
* out of an existing native-host manifest's `allowed_origins`. Returns the
|
|
19
|
+
* first 32-char a–p ID found (origins are written in the order
|
|
20
|
+
* chromeWebStore / edgeAddons / dev, but the published-store slots ship as
|
|
21
|
+
* `PLACEHOLDER_*` strings that `allowedOrigins()` drops, so anything actually
|
|
22
|
+
* present is by definition the user's dev ID).
|
|
23
|
+
*
|
|
24
|
+
* Pure — accepts any value, returns `undefined` for non-objects, malformed
|
|
25
|
+
* arrays, missing fields, or origin strings that don't match the expected
|
|
26
|
+
* `chrome-extension://<a-p×32>/` shape. The caller's idempotency check then
|
|
27
|
+
* skips the prompt and reuses the captured ID.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractDevId(manifest: unknown): string | undefined;
|
|
30
|
+
//# sourceMappingURL=extension-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-id.d.ts","sourceRoot":"","sources":["../../src/lib/extension-id.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYpE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAWlE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Chrome extension ID validator + helpers used by `peek init` (P-10 fix,
|
|
2
|
+
// 2026-05-28 QA walk).
|
|
3
|
+
//
|
|
4
|
+
// Chrome derives the unpacked-extension ID from the SHA-256 of the absolute
|
|
5
|
+
// path of the extension folder, mapped through a 16-letter alphabet (a–p).
|
|
6
|
+
// That makes every loaded-unpacked extension ID a 32-character string of
|
|
7
|
+
// lowercase a–p — and the same shape Chrome uses for Web Store IDs. peek init
|
|
8
|
+
// captures this ID and writes it into the native-host manifest's
|
|
9
|
+
// `allowed_origins` so Chrome will let the unpacked extension connect to the
|
|
10
|
+
// native host (without an entry the manifest ships with `allowed_origins: []`
|
|
11
|
+
// and Chrome silently blocks `chrome.runtime.connectNative()`).
|
|
12
|
+
//
|
|
13
|
+
// Pure helpers — no prompt I/O lives here. The prompt loop in
|
|
14
|
+
// commands/init.ts calls `validateChromeExtensionId` from prompt.ts's
|
|
15
|
+
// `promptText({ validate })` so tests cover the input shape independently of
|
|
16
|
+
// the readline machinery.
|
|
17
|
+
/** Length + alphabet Chrome uses for both unpacked and Web Store extension IDs. */
|
|
18
|
+
const EXTENSION_ID_LENGTH = 32;
|
|
19
|
+
const EXTENSION_ID_PATTERN = /^[a-p]{32}$/;
|
|
20
|
+
/**
|
|
21
|
+
* Validate a candidate Chrome extension ID. Returns `null` if the input is the
|
|
22
|
+
* expected 32-character `a–p` shape; otherwise a user-facing error message.
|
|
23
|
+
*
|
|
24
|
+
* Trims internal whitespace defensively — users routinely paste from
|
|
25
|
+
* `chrome://extensions/` with a trailing newline or leading space.
|
|
26
|
+
*/
|
|
27
|
+
export function validateChromeExtensionId(raw) {
|
|
28
|
+
const id = raw.trim();
|
|
29
|
+
if (id.length === 0) {
|
|
30
|
+
return 'Extension ID is required (or leave empty to skip).';
|
|
31
|
+
}
|
|
32
|
+
if (id.length !== EXTENSION_ID_LENGTH) {
|
|
33
|
+
return `Expected a 32-character ID; got ${id.length}. (Copy it from chrome://extensions/.)`;
|
|
34
|
+
}
|
|
35
|
+
if (!EXTENSION_ID_PATTERN.test(id)) {
|
|
36
|
+
return 'Extension IDs are 32 lowercase letters a–p only. Re-copy from chrome://extensions/.';
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build the `chrome-extension://<id>/` origin Chrome expects in a native-host
|
|
42
|
+
* manifest's `allowed_origins`. Mirrors `allowedOrigins()` in peek-mcp's
|
|
43
|
+
* manifest.ts but emits the bare origin string for a single id (the manifest
|
|
44
|
+
* builder de-dupes when it folds multiple IDs together).
|
|
45
|
+
*/
|
|
46
|
+
export function chromeExtensionOrigin(id) {
|
|
47
|
+
return `chrome-extension://${id}/`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* P-13 (2026-05-28 QA walk) — pull the previously-saved unpacked extension ID
|
|
51
|
+
* out of an existing native-host manifest's `allowed_origins`. Returns the
|
|
52
|
+
* first 32-char a–p ID found (origins are written in the order
|
|
53
|
+
* chromeWebStore / edgeAddons / dev, but the published-store slots ship as
|
|
54
|
+
* `PLACEHOLDER_*` strings that `allowedOrigins()` drops, so anything actually
|
|
55
|
+
* present is by definition the user's dev ID).
|
|
56
|
+
*
|
|
57
|
+
* Pure — accepts any value, returns `undefined` for non-objects, malformed
|
|
58
|
+
* arrays, missing fields, or origin strings that don't match the expected
|
|
59
|
+
* `chrome-extension://<a-p×32>/` shape. The caller's idempotency check then
|
|
60
|
+
* skips the prompt and reuses the captured ID.
|
|
61
|
+
*/
|
|
62
|
+
export function extractDevId(manifest) {
|
|
63
|
+
if (manifest === null || typeof manifest !== 'object')
|
|
64
|
+
return undefined;
|
|
65
|
+
const ao = manifest.allowed_origins;
|
|
66
|
+
if (!Array.isArray(ao))
|
|
67
|
+
return undefined;
|
|
68
|
+
const pattern = /^chrome-extension:\/\/([a-p]{32})\/$/;
|
|
69
|
+
for (const origin of ao) {
|
|
70
|
+
if (typeof origin !== 'string')
|
|
71
|
+
continue;
|
|
72
|
+
const m = pattern.exec(origin);
|
|
73
|
+
if (m)
|
|
74
|
+
return m[1];
|
|
75
|
+
}
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=extension-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-id.js","sourceRoot":"","sources":["../../src/lib/extension-id.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,uBAAuB;AACvB,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,yEAAyE;AACzE,8EAA8E;AAC9E,iEAAiE;AACjE,6EAA6E;AAC7E,8EAA8E;AAC9E,gEAAgE;AAChE,EAAE;AACF,8DAA8D;AAC9D,sEAAsE;AACtE,6EAA6E;AAC7E,0BAA0B;AAE1B,mFAAmF;AACnF,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,oDAAoD,CAAC;IAC9D,CAAC;IACD,IAAI,EAAE,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACtC,OAAO,mCAAmC,EAAE,CAAC,MAAM,wCAAwC,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,OAAO,qFAAqF,CAAC;IAC/F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,OAAO,sBAAsB,EAAE,GAAG,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACxE,MAAM,EAAE,GAAI,QAA0C,CAAC,eAAe,CAAC;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,OAAO,GAAG,sCAAsC,CAAC;IACvD,KAAK,MAAM,MAAM,IAAI,EAAE,EAAE,CAAC;QACxB,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,SAAS;QACzC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|