friction-log 0.6.0 → 0.6.1

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/CHANGELOG.md CHANGED
@@ -7,10 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.1] - 2026-10-10
11
+
12
+ First release cut for the tag-driven `publish-npm.yml` workflow (npm Trusted Publishing), which publishes with `--provenance`.
13
+
14
+ ### Fixed
15
+
16
+ - The CLI now refuses to start on a Node version below the `engines.node` range (currently `>=22`), exiting 1 with a stderr message that names the required and the running version. Previously npm only warned, and the first database command crashed with a SIGSEGV. The check runs in a small entry module (`dist/cli.js`) before the real CLI, and thus `better-sqlite3`, is loaded; `--help` and `--version` are refused as well. (11dc376f)
17
+
10
18
  ## [0.6.0] - 2026-10-10
11
19
 
12
20
  First release published to npm (`npm i -g friction-log`). Earlier versions ran from a local build of this repository. The entries below cover everything since the 0.5.0 milestone tag.
13
21
 
22
+ 0.6.0 was published by hand from a build of commit `48926fca`, because npm accepts a Trusted Publisher entry only for a package that already exists; it therefore has no provenance attestation. There is deliberately no `friction-log/v0.6.0` git tag: pushing it would trigger `publish-npm.yml`, which refuses a registry version without an attestation and would fail red.
23
+
14
24
  ### Added
15
25
 
16
26
  - Opt-in `sync_export` config block and a `sync-export` command: a deterministic, atomic, no-op-skipping export of the local database, written through after each of the six mutating commands (`log`, `update`, `rm`, `file`, `import`, `scan`). Without the config block everything is an exact no-op. See [sync export](docs/sync-export.md).
package/dist/cli.js CHANGED
@@ -1,504 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { Command, Option } from "commander";
3
- import { readFileSync } from "node:fs";
4
- import { dirname, join } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
- import { runBilanz } from "./commands/bilanz.js";
7
- import { formatDigest, runDigest } from "./commands/digest.js";
8
- import { runExport } from "./commands/export.js";
9
- import { runFile } from "./commands/file.js";
10
- import { runImport } from "./commands/import.js";
11
- import { runInit } from "./commands/init.js";
12
- import { formatTable, runList } from "./commands/list.js";
13
- import { runLog } from "./commands/log.js";
14
- import { runRm } from "./commands/rm.js";
15
- import { payloadToScanInput, runScan, summarize, } from "./commands/scan.js";
16
- import { runSearch } from "./commands/search.js";
17
- import { runSyncExport } from "./commands/sync-export.js";
18
- import { runUpdate } from "./commands/update.js";
19
- import { parseSinkOpts } from "./config.js";
20
- import { availableSinks } from "./sinks/index.js";
21
- function readPackageVersion() {
22
- try {
23
- const here = dirname(fileURLToPath(import.meta.url));
24
- const pkgPath = join(here, "..", "package.json");
25
- const raw = readFileSync(pkgPath, "utf8");
26
- const parsed = JSON.parse(raw);
27
- return typeof parsed.version === "string" ? parsed.version : "0.0.0";
28
- }
29
- catch {
30
- return "0.0.0";
31
- }
32
- }
33
- const SEVERITY_CHOICES = ["low", "medium", "high", "critical"];
34
- const STATUS_CHOICES = ["open", "filed", "resolved", "wontfix"];
35
- const SOURCE_CHOICES = ["scan", "manual", "import"];
36
- const SCANNER_CHOICES = ["claude-code"];
37
- const DIGEST_GROUP_CHOICES = [
38
- "tool",
39
- "category",
40
- "severity",
41
- "source",
42
- ];
43
- const EXPORT_FORMAT_CHOICES = ["json", "csv", "md"];
44
- const IMPORT_FORMAT_CHOICES = ["markdown-frontmatter"];
45
- const program = new Command();
46
- program
47
- .name("friction-log")
48
- .description("Capture, query, and infer agent-workflow frictions.")
49
- .version(readPackageVersion());
50
- program
51
- .command("log")
52
- .description("Manually record a friction.")
53
- .requiredOption("--title <title>", "Short title describing the friction")
54
- .option("--description <text>", "Longer description / reproduction notes")
55
- .option("--tool <surface>", "Tool surface that caused the friction (e.g. mcp:agent-tasks/tasks_list)")
56
- .option("--category <name>", "Category (e.g. output-overflow, tool-error)")
57
- .addOption(new Option("--severity <level>", "Severity level").choices([
58
- ...SEVERITY_CHOICES,
59
- ]))
60
- .option("--session <id>", "Session id to associate with this friction")
61
- .option("--recurrence-of <id>", "Mark this friction as a recurrence of an existing one", (v) => Number(v))
62
- .option("--db <path>", "Override database path (default: XDG)")
63
- .action((opts) => {
64
- const recurrenceOfRaw = opts.recurrenceOf;
65
- let recurrenceOfId;
66
- if (recurrenceOfRaw !== undefined) {
67
- if (typeof recurrenceOfRaw !== "number" ||
68
- !Number.isInteger(recurrenceOfRaw) ||
69
- recurrenceOfRaw <= 0) {
70
- process.stderr.write(`friction-log: --recurrence-of must be a positive integer, got "${String(recurrenceOfRaw)}"\n`);
71
- process.exit(2);
72
- }
73
- recurrenceOfId = recurrenceOfRaw;
74
- }
75
- const out = runLog({
76
- title: opts.title,
77
- description: opts.description,
78
- tool: opts.tool,
79
- category: opts.category,
80
- severity: opts.severity,
81
- sessionId: opts.session,
82
- recurrenceOfId,
83
- dbPath: opts.db,
84
- });
85
- const recurrenceTag = out.recurrenceOfId != null ? ` recurrence_of=${out.recurrenceOfId}` : "";
86
- process.stdout.write(`friction id=${out.id} captured_at=${out.capturedAt}${recurrenceTag}\n`);
87
- });
88
- program
89
- .command("list")
90
- .description("List frictions with optional filters.")
91
- .addOption(new Option("--status <status>", "Filter by status").choices([
92
- ...STATUS_CHOICES,
93
- ]))
94
- .option("--tool <surface>", "Filter by tool surface")
95
- .option("--category <name>", "Filter by category")
96
- .addOption(new Option("--source <source>", "Filter by source").choices([
97
- ...SOURCE_CHOICES,
98
- ]))
99
- .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
100
- .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
101
- .option("--json", "Emit JSON instead of a table")
102
- .option("--db <path>", "Override database path")
103
- .action((opts) => {
104
- const out = runList({
105
- status: opts.status,
106
- tool: opts.tool,
107
- category: opts.category,
108
- source: opts.source,
109
- age: opts.age,
110
- limit: typeof opts.limit === "number" ? opts.limit : undefined,
111
- dbPath: opts.db,
112
- });
113
- if (opts.json) {
114
- process.stdout.write(JSON.stringify(out.frictions, null, 2) + "\n");
115
- }
116
- else {
117
- process.stdout.write(formatTable(out.frictions) + "\n");
118
- }
119
- });
120
- program
121
- .command("file <frictionId>")
122
- .description("Push a friction to a configured sink. Default sink: markdown-file.")
123
- .addOption(new Option("--sink <name>", "Sink to use")
124
- .choices([...availableSinks])
125
- .default("markdown-file"))
126
- .option("--template <name>", "Template override (defaults to friction.category match)")
127
- .option("--sink-target <value>", "Sink-specific target (markdown-file: directory path)")
128
- .option("--sink-opt <key=value>", "Per-sink option override, repeatable (e.g. --sink-opt repo=owner/name)", (value, previous = []) => [...previous, value], [])
129
- .option("--config <path>", "Override config file path (default: $XDG_CONFIG_HOME/friction-log/config.yml)")
130
- .option("--db <path>", "Override database path")
131
- .action(async (frictionId, opts) => {
132
- const id = Number(frictionId);
133
- if (!Number.isInteger(id) || id <= 0) {
134
- process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
135
- process.exit(2);
136
- }
137
- try {
138
- const sinkOptPairs = Array.isArray(opts.sinkOpt)
139
- ? opts.sinkOpt
140
- : [];
141
- const sinkOpts = sinkOptPairs.length
142
- ? parseSinkOpts(sinkOptPairs)
143
- : undefined;
144
- const out = await runFile({
145
- frictionId: id,
146
- sink: opts.sink,
147
- template: opts.template,
148
- sinkTarget: opts.sinkTarget,
149
- sinkOpts,
150
- configPath: opts.config,
151
- dbPath: opts.db,
152
- });
153
- process.stdout.write(`filed friction id=${id} via sink=${out.sinkName} target=${out.sinkTarget}\n${out.message}\n`);
154
- }
155
- catch (err) {
156
- process.stderr.write(`${err.message}\n`);
157
- process.exit(1);
158
- }
159
- });
160
- program
161
- .command("scan")
162
- .description("Scan a transcript for candidate frictions and store them.")
163
- .option("--session <id>", "Session id (defaults to derivation from --transcript filename)")
164
- .option("--transcript <path>", "Path to the transcript file (e.g. ~/.claude/projects/.../<id>.jsonl)")
165
- .addOption(new Option("--adapter <name>", "Scanner adapter").choices([
166
- ...SCANNER_CHOICES,
167
- ]))
168
- .option("--silent", "Never throw, exit 0 always (Stop-hook mode)")
169
- .option("--stdin-payload", "Read a JSON Stop-hook payload from stdin to derive session+transcript")
170
- .option("--db <path>", "Override database path")
171
- .action(async (opts) => {
172
- try {
173
- let baseInput = {
174
- sessionId: opts.session,
175
- transcriptPath: opts.transcript,
176
- adapter: opts.adapter,
177
- dbPath: opts.db,
178
- };
179
- if (opts.stdinPayload) {
180
- const payload = await readStdinPayload();
181
- const derived = payloadToScanInput(payload, baseInput.adapter);
182
- baseInput = {
183
- sessionId: derived.sessionId ?? baseInput.sessionId,
184
- transcriptPath: derived.transcriptPath ?? baseInput.transcriptPath,
185
- adapter: derived.adapter ?? baseInput.adapter,
186
- dbPath: baseInput.dbPath,
187
- };
188
- }
189
- const out = await runScan(baseInput);
190
- if (!opts.silent) {
191
- process.stdout.write(summarize(out, out.sessionId) + "\n");
192
- }
193
- }
194
- catch (err) {
195
- if (opts.silent) {
196
- process.stderr.write(`friction-log scan (silent): ${err.message}\n`);
197
- process.exit(0);
198
- }
199
- process.stderr.write(`${err.message}\n`);
200
- process.exit(1);
201
- }
202
- });
203
- program
204
- .command("bilanz")
205
- .description("Format a session-boundary bilanz: tools, frictions, tasks.")
206
- .option("--session <id>", "Session id (defaults to most-recent in db)")
207
- .option("--db <path>", "Override database path")
208
- .action(async (opts) => {
209
- try {
210
- const out = await runBilanz({ sessionId: opts.session, dbPath: opts.db });
211
- process.stdout.write(out.formatted);
212
- }
213
- catch (err) {
214
- process.stderr.write(`${err.message}\n`);
215
- process.exit(1);
216
- }
217
- });
218
- program
219
- .command("rm <frictionId>")
220
- .description("Delete a friction (and any task rows pointing at it) from the local store.")
221
- .option("--db <path>", "Override database path")
222
- .action((frictionId, opts) => {
223
- const id = Number(frictionId);
224
- if (!Number.isInteger(id) || id <= 0) {
225
- process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
226
- process.exit(2);
227
- }
228
- try {
229
- const out = runRm({ frictionId: id, dbPath: opts.db });
230
- process.stdout.write(`removed friction id=${id} (${out.removed ? "ok" : "no-op"})\n`);
231
- }
232
- catch (err) {
233
- process.stderr.write(`${err.message}\n`);
234
- process.exit(1);
235
- }
236
- });
237
- program
238
- .command("update <frictionId>")
239
- .description("Update a friction (status only in M2; more fields in later milestones).")
240
- .addOption(new Option("--status <status>", "New status")
241
- .choices([...STATUS_CHOICES])
242
- .makeOptionMandatory(true))
243
- .option("--db <path>", "Override database path")
244
- .action((frictionId, opts) => {
245
- const id = Number(frictionId);
246
- if (!Number.isInteger(id) || id <= 0) {
247
- process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
248
- process.exit(2);
249
- }
250
- try {
251
- const out = runUpdate({
252
- frictionId: id,
253
- status: opts.status,
254
- dbPath: opts.db,
255
- });
256
- process.stdout.write(`updated friction id=${out.id} status=${out.status}\n`);
257
- }
258
- catch (err) {
259
- process.stderr.write(`${err.message}\n`);
260
- process.exit(1);
261
- }
262
- });
263
- program
264
- .command("search <query>")
265
- .description("Full-text search over title + description (FTS5).")
266
- .addOption(new Option("--status <status>", "Filter by status").choices([
267
- ...STATUS_CHOICES,
268
- ]))
269
- .option("--tool <surface>", "Filter by tool surface")
270
- .option("--category <name>", "Filter by category")
271
- .addOption(new Option("--source <source>", "Filter by source").choices([
272
- ...SOURCE_CHOICES,
273
- ]))
274
- .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
275
- .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
276
- .option("--json", "Emit JSON instead of a table")
277
- .option("--db <path>", "Override database path")
278
- .action((query, opts) => {
279
- try {
280
- const out = runSearch({
281
- query,
282
- status: opts.status,
283
- tool: opts.tool,
284
- category: opts.category,
285
- source: opts.source,
286
- age: opts.age,
287
- limit: typeof opts.limit === "number" ? opts.limit : undefined,
288
- dbPath: opts.db,
289
- });
290
- if (opts.json) {
291
- process.stdout.write(JSON.stringify(out.frictions, null, 2) + "\n");
292
- }
293
- else {
294
- process.stdout.write(formatTable(out.frictions) + "\n");
295
- }
296
- }
297
- catch (err) {
298
- process.stderr.write(`${err.message}\n`);
299
- process.exit(1);
300
- }
301
- });
302
- program
303
- .command("digest")
304
- .description("Aggregations over frictions: counts, open-vs-filed, recurrences, avg hours to triage.")
305
- .addOption(new Option("--group-by <field>", "Group by field")
306
- .choices([...DIGEST_GROUP_CHOICES])
307
- .makeOptionMandatory(true))
308
- .option("--last <span>", "Restrict to frictions newer than e.g. 30d, 4w, 12h")
309
- .option("--include-peers", "Also render read-only digest sections for each configured sync_export.peer_paths file")
310
- .option("--json", "Emit JSON instead of a table")
311
- .option("--config <path>", "Override config file path (only used by --include-peers)")
312
- .option("--db <path>", "Override database path")
313
- .action((opts) => {
314
- try {
315
- const out = runDigest({
316
- groupBy: opts.groupBy,
317
- last: opts.last,
318
- dbPath: opts.db,
319
- configPath: opts.config,
320
- includePeers: Boolean(opts.includePeers),
321
- });
322
- if (opts.json) {
323
- process.stdout.write(JSON.stringify(out, null, 2) + "\n");
324
- }
325
- else {
326
- process.stdout.write(formatDigest(out) + "\n");
327
- }
328
- if (out.peers) {
329
- for (const peer of out.peers) {
330
- if (peer.error) {
331
- process.stderr.write(`friction-log: warning: peer digest source ${peer.sourcePath} (origin=${peer.origin}) skipped: ${peer.error}\n`);
332
- }
333
- else if (peer.skipped > 0) {
334
- process.stderr.write(`friction-log: warning: peer digest source ${peer.sourcePath} (origin=${peer.origin}) skipped ${peer.skipped} malformed record(s)\n`);
335
- }
336
- }
337
- }
338
- }
339
- catch (err) {
340
- process.stderr.write(`${err.message}\n`);
341
- process.exit(1);
342
- }
343
- });
344
- program
345
- .command("export")
346
- .description("Export frictions as JSON, CSV, or Markdown.")
347
- .addOption(new Option("--format <fmt>", "Output format")
348
- .choices([...EXPORT_FORMAT_CHOICES])
349
- .default("json"))
350
- .option("--out <path>", "Write to a file instead of stdout")
351
- .option("--query <text>", "Only export frictions matching an FTS5 query")
352
- .addOption(new Option("--status <status>", "Filter by status").choices([
353
- ...STATUS_CHOICES,
354
- ]))
355
- .option("--tool <surface>", "Filter by tool surface")
356
- .option("--category <name>", "Filter by category")
357
- .addOption(new Option("--source <source>", "Filter by source").choices([
358
- ...SOURCE_CHOICES,
359
- ]))
360
- .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
361
- .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
362
- .option("--db <path>", "Override database path")
363
- .action((opts) => {
364
- try {
365
- const out = runExport({
366
- format: opts.format,
367
- out: opts.out,
368
- query: opts.query,
369
- status: opts.status,
370
- tool: opts.tool,
371
- category: opts.category,
372
- source: opts.source,
373
- age: opts.age,
374
- limit: typeof opts.limit === "number" ? opts.limit : undefined,
375
- dbPath: opts.db,
376
- });
377
- if (out.out) {
378
- process.stderr.write(`exported ${out.count} records (${out.format}) to ${out.out}\n`);
379
- }
380
- else {
381
- process.stdout.write(out.rendered);
382
- }
383
- }
384
- catch (err) {
385
- process.stderr.write(`${err.message}\n`);
386
- process.exit(1);
387
- }
388
- });
389
- program
390
- .command("sync-export")
391
- .description("Write every friction as deterministic, origin-tagged JSON to the configured sync_export.path. " +
392
- 'No-op error unless "sync_export" (path + origin) is set in config.yml or via FRICTION_LOG_SYNC_EXPORT_PATH/_ORIGIN.')
393
- .option("--config <path>", "Override config file path")
394
- .option("--db <path>", "Override database path")
395
- .action((opts) => {
396
- try {
397
- const out = runSyncExport({
398
- configPath: opts.config,
399
- dbPath: opts.db,
400
- });
401
- process.stderr.write(`sync-export: wrote ${out.count} frictions (origin=${out.origin}) to ${out.path}\n`);
402
- }
403
- catch (err) {
404
- process.stderr.write(`${err.message}\n`);
405
- process.exit(1);
406
- }
407
- });
408
- program
409
- .command("init")
410
- .description("Interactive setup: write config.yml, optionally install Stop-hook.")
411
- .addOption(new Option("--sink <name>", "Default sink (skips the interactive prompt)").choices([...availableSinks]))
412
- .option("-y, --yes", "Non-interactive; use --sink (or markdown-file fallback) and skip Stop-hook offer")
413
- .option("--install-stop-hook", "Force-install the Claude Code Stop-hook (skip the interactive y/N)")
414
- .option("--config <path>", "Override config file path")
415
- .option("--sync-export-path <path>", "Opt in to sync-export: write this config's sync_export.path")
416
- .option("--sync-export-origin <name>", "Opt in to sync-export: this machine's sync_export.origin label")
417
- .option("--sync-export-peer <path>", "Peer sync-export file to read for `digest --include-peers`, repeatable", (value, previous = []) => [...previous, value], [])
418
- .action(async (opts) => {
419
- try {
420
- const syncExportPath = opts.syncExportPath;
421
- const syncExportOrigin = opts.syncExportOrigin;
422
- if (Boolean(syncExportPath) !== Boolean(syncExportOrigin)) {
423
- process.stderr.write("friction-log: --sync-export-path and --sync-export-origin must be given together\n");
424
- process.exit(2);
425
- }
426
- const syncExportPeers = Array.isArray(opts.syncExportPeer)
427
- ? opts.syncExportPeer
428
- : [];
429
- const out = await runInit({
430
- configPath: opts.config,
431
- sink: opts.sink,
432
- yes: Boolean(opts.yes),
433
- installStopHook: opts.installStopHook === true ? true : undefined,
434
- syncExport: syncExportPath && syncExportOrigin
435
- ? {
436
- path: syncExportPath,
437
- origin: syncExportOrigin,
438
- peerPaths: syncExportPeers,
439
- }
440
- : undefined,
441
- });
442
- process.stdout.write(`init: ${out.configWritten ? "wrote" : "no change to"} ${out.configPath}\n` +
443
- (out.stopHookWrittenTo
444
- ? `init: Stop-hook installed at ${out.stopHookWrittenTo}\n`
445
- : "") +
446
- "\nNext steps:\n" +
447
- out.nextSteps.map((s) => ` ${s}`).join("\n") +
448
- "\n");
449
- }
450
- catch (err) {
451
- process.stderr.write(`${err.message}\n`);
452
- process.exit(1);
453
- }
454
- });
455
- program
456
- .command("import <path>")
457
- .description("Bulk-ingest frictions from a directory of markdown files.")
458
- .addOption(new Option("--format <fmt>", "Source format")
459
- .choices([...IMPORT_FORMAT_CHOICES])
460
- .default("markdown-frontmatter"))
461
- .option("--db <path>", "Override database path")
462
- .action((path, opts) => {
463
- try {
464
- const out = runImport({
465
- format: opts.format,
466
- path,
467
- dbPath: opts.db,
468
- });
469
- process.stdout.write(`import: scanned=${out.scanned} imported=${out.imported} skipped=${out.skipped}\n`);
470
- if (out.errors.length) {
471
- process.stderr.write(`import: ${out.errors.length} errors:\n`);
472
- for (const e of out.errors.slice(0, 10)) {
473
- process.stderr.write(` ${e.file}: ${e.reason}\n`);
474
- }
475
- if (out.errors.length > 10) {
476
- process.stderr.write(` ... and ${out.errors.length - 10} more\n`);
477
- }
478
- }
479
- }
480
- catch (err) {
481
- process.stderr.write(`${err.message}\n`);
482
- process.exit(1);
483
- }
484
- });
485
- async function readStdinPayload() {
486
- const chunks = [];
487
- for await (const chunk of process.stdin) {
488
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
489
- }
490
- const text = Buffer.concat(chunks).toString("utf8").trim();
491
- if (!text)
492
- return {};
493
- try {
494
- return JSON.parse(text);
495
- }
496
- catch {
497
- return {};
498
- }
499
- }
500
- program.parseAsync(process.argv).catch((err) => {
501
- process.stderr.write(`friction-log: ${err.message}\n`);
2
+ // Entry point. Static imports are evaluated before any code in the importing
3
+ // module, and the real CLI reaches better-sqlite3 through them. So this file
4
+ // imports only the dependency-free guard and loads the CLI dynamically after
5
+ // the Node version check has passed.
6
+ import { nodeGuardMessage, readEnginesNode } from "./node-guard.js";
7
+ const message = nodeGuardMessage(process.versions.node, readEnginesNode());
8
+ if (message) {
9
+ process.stderr.write(`${message}\n`);
502
10
  process.exit(1);
503
- });
11
+ }
12
+ await import("./main.js");
504
13
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAqB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAqB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,OAAO,EACP,SAAS,GAEV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,SAAS,kBAAkB;IACzB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,OAAO,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AACxE,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAU,CAAC;AACzE,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAC7D,MAAM,eAAe,GAAG,CAAC,aAAa,CAAU,CAAC;AACjD,MAAM,oBAAoB,GAAG;IAC3B,MAAM;IACN,UAAU;IACV,UAAU;IACV,QAAQ;CACA,CAAC;AACX,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAU,CAAC;AAC7D,MAAM,qBAAqB,GAAG,CAAC,sBAAsB,CAAU,CAAC;AAEhE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,6BAA6B,CAAC;KAC1C,cAAc,CAAC,iBAAiB,EAAE,qCAAqC,CAAC;KACxE,MAAM,CAAC,sBAAsB,EAAE,yCAAyC,CAAC;KACzE,MAAM,CACL,kBAAkB,EAClB,yEAAyE,CAC1E;KACA,MAAM,CAAC,mBAAmB,EAAE,6CAA6C,CAAC;KAC1E,SAAS,CACR,IAAI,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC,OAAO,CAAC;IACzD,GAAG,gBAAgB;CACpB,CAAC,CACH;KACA,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;KACtE,MAAM,CACL,sBAAsB,EACtB,uDAAuD,EACvD,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CACjB;KACA,MAAM,CAAC,aAAa,EAAE,uCAAuC,CAAC;KAC9D,MAAM,CAAC,CAAC,IAA6B,EAAE,EAAE;IACxC,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC;IAC1C,IAAI,cAAkC,CAAC;IACvC,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,IACE,OAAO,eAAe,KAAK,QAAQ;YACnC,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC;YAClC,eAAe,IAAI,CAAC,EACpB,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kEAAkE,MAAM,CAAC,eAAe,CAAC,KAAK,CAC/F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,cAAc,GAAG,eAAe,CAAC;IACnC,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC;QACjB,KAAK,EAAE,IAAI,CAAC,KAAe;QAC3B,WAAW,EAAE,IAAI,CAAC,WAAiC;QACnD,IAAI,EAAE,IAAI,CAAC,IAA0B;QACrC,QAAQ,EAAE,IAAI,CAAC,QAA8B;QAC7C,QAAQ,EAAE,IAAI,CAAC,QAAgC;QAC/C,SAAS,EAAE,IAAI,CAAC,OAA6B;QAC7C,cAAc;QACd,MAAM,EAAE,IAAI,CAAC,EAAwB;KACtC,CAAC,CAAC;IACH,MAAM,aAAa,GACjB,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,GAAG,CAAC,EAAE,gBAAgB,GAAG,CAAC,UAAU,GAAG,aAAa,IAAI,CACxE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uCAAuC,CAAC;KACpD,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;KACpD,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACjD,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,cAAc,EAAE,6CAA6C,CAAC;KACrE,MAAM,CAAC,aAAa,EAAE,wBAAwB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KACjE,MAAM,CAAC,QAAQ,EAAE,8BAA8B,CAAC;KAChD,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,IAA6B,EAAE,EAAE;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC;QAClB,MAAM,EAAE,IAAI,CAAC,MAAoC;QACjD,IAAI,EAAE,IAAI,CAAC,IAA0B;QACrC,QAAQ,EAAE,IAAI,CAAC,QAA8B;QAC7C,MAAM,EAAE,IAAI,CAAC,MAAoC;QACjD,GAAG,EAAE,IAAI,CAAC,GAAyB;QACnC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC9D,MAAM,EAAE,IAAI,CAAC,EAAwB;KACtC,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CACV,oEAAoE,CACrE;KACA,SAAS,CACR,IAAI,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC;KACvC,OAAO,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;KAC5B,OAAO,CAAC,eAAe,CAAC,CAC5B;KACA,MAAM,CACL,mBAAmB,EACnB,yDAAyD,CAC1D;KACA,MAAM,CACL,uBAAuB,EACvB,sDAAsD,CACvD;KACA,MAAM,CACL,wBAAwB,EACxB,wEAAwE,EACxE,CAAC,KAAa,EAAE,WAAqB,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,EAChE,EAAc,CACf;KACA,MAAM,CACL,iBAAiB,EACjB,+EAA+E,CAChF;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,IAA6B,EAAE,EAAE;IAClE,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+DAA+D,UAAU,KAAK,CAC/E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9C,CAAC,CAAE,IAAI,CAAC,OAAoB;YAC5B,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM;YAClC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC;YAC7B,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;YACxB,UAAU,EAAE,EAAE;YACd,IAAI,EAAE,IAAI,CAAC,IAAc;YACzB,QAAQ,EAAE,IAAI,CAAC,QAA8B;YAC7C,UAAU,EAAE,IAAI,CAAC,UAAgC;YACjD,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,MAA4B;YAC7C,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qBAAqB,EAAE,aAAa,GAAG,CAAC,QAAQ,WAAW,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC,OAAO,IAAI,CAC9F,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2DAA2D,CAAC;KACxE,MAAM,CACL,gBAAgB,EAChB,gEAAgE,CACjE;KACA,MAAM,CACL,qBAAqB,EACrB,sEAAsE,CACvE;KACA,SAAS,CACR,IAAI,MAAM,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,OAAO,CAAC;IACxD,GAAG,eAAe;CACnB,CAAC,CACH;KACA,MAAM,CAAC,UAAU,EAAE,6CAA6C,CAAC;KACjE,MAAM,CACL,iBAAiB,EACjB,uEAAuE,CACxE;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,KAAK,EAAE,IAA6B,EAAE,EAAE;IAC9C,IAAI,CAAC;QACH,IAAI,SAAS,GAAG;YACd,SAAS,EAAE,IAAI,CAAC,OAA6B;YAC7C,cAAc,EAAE,IAAI,CAAC,UAAgC;YACrD,OAAO,EAAE,IAAI,CAAC,OAA6B;YAC3C,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC;QACF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;YAC/D,SAAS,GAAG;gBACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;gBACnD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC,cAAc;gBAClE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;gBAC7C,MAAM,EAAE,SAAS,CAAC,MAAM;aACzB,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+BAAgC,GAAa,CAAC,OAAO,IAAI,CAC1D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;KACtE,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,KAAK,EAAE,IAA4B,EAAE,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CACV,4EAA4E,CAC7E;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,UAAkB,EAAE,IAA4B,EAAE,EAAE;IAC3D,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+DAA+D,UAAU,KAAK,CAC/E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uBAAuB,EAAE,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,CAChE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CACV,yEAAyE,CAC1E;KACA,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,YAAY,CAAC;KAC1C,OAAO,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;KAC5B,mBAAmB,CAAC,IAAI,CAAC,CAC7B;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,UAAkB,EAAE,IAA4B,EAAE,EAAE;IAC3D,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+DAA+D,UAAU,KAAK,CAC/E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC;YACpB,UAAU,EAAE,EAAE;YACd,MAAM,EAAE,IAAI,CAAC,MAAwB;YACrC,MAAM,EAAE,IAAI,CAAC,EAAE;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uBAAuB,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,IAAI,CACvD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,mDAAmD,CAAC;KAChE,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;KACpD,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACjD,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,cAAc,EAAE,6CAA6C,CAAC;KACrE,MAAM,CAAC,aAAa,EAAE,wBAAwB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KACjE,MAAM,CAAC,QAAQ,EAAE,8BAA8B,CAAC;KAChD,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,KAAa,EAAE,IAA6B,EAAE,EAAE;IACvD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC;YACpB,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,MAAoC;YACjD,IAAI,EAAE,IAAI,CAAC,IAA0B;YACrC,QAAQ,EAAE,IAAI,CAAC,QAA8B;YAC7C,MAAM,EAAE,IAAI,CAAC,MAAoC;YACjD,GAAG,EAAE,IAAI,CAAC,GAAyB;YACnC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YAC9D,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CACV,uFAAuF,CACxF;KACA,SAAS,CACR,IAAI,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC;KAC/C,OAAO,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC;KAClC,mBAAmB,CAAC,IAAI,CAAC,CAC7B;KACA,MAAM,CAAC,eAAe,EAAE,oDAAoD,CAAC;KAC7E,MAAM,CACL,iBAAiB,EACjB,uFAAuF,CACxF;KACA,MAAM,CAAC,QAAQ,EAAE,8BAA8B,CAAC;KAChD,MAAM,CACL,iBAAiB,EACjB,0DAA0D,CAC3D;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,IAA6B,EAAE,EAAE;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC;YACpB,OAAO,EAAE,IAAI,CAAC,OAAwB;YACtC,IAAI,EAAE,IAAI,CAAC,IAA0B;YACrC,MAAM,EAAE,IAAI,CAAC,EAAwB;YACrC,UAAU,EAAE,IAAI,CAAC,MAA4B;YAC7C,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC;SACzC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC7B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CAA6C,IAAI,CAAC,UAAU,YAAY,IAAI,CAAC,MAAM,cAAc,IAAI,CAAC,KAAK,IAAI,CAChH,CAAC;gBACJ,CAAC;qBAAM,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;oBAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CAA6C,IAAI,CAAC,UAAU,YAAY,IAAI,CAAC,MAAM,aAAa,IAAI,CAAC,OAAO,wBAAwB,CACrI,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,SAAS,CACR,IAAI,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC;KAC1C,OAAO,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC;KACnC,OAAO,CAAC,MAAM,CAAC,CACnB;KACA,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC;KAC3D,MAAM,CAAC,gBAAgB,EAAE,8CAA8C,CAAC;KACxE,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;KACpD,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACjD,SAAS,CACR,IAAI,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC;IAC1D,GAAG,cAAc;CAClB,CAAC,CACH;KACA,MAAM,CAAC,cAAc,EAAE,6CAA6C,CAAC;KACrE,MAAM,CAAC,aAAa,EAAE,wBAAwB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KACjE,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,IAA6B,EAAE,EAAE;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC;YACpB,MAAM,EAAE,IAAI,CAAC,MAAsB;YACnC,GAAG,EAAE,IAAI,CAAC,GAAyB;YACnC,KAAK,EAAE,IAAI,CAAC,KAA2B;YACvC,MAAM,EAAE,IAAI,CAAC,MAAoC;YACjD,IAAI,EAAE,IAAI,CAAC,IAA0B;YACrC,QAAQ,EAAE,IAAI,CAAC,QAA8B;YAC7C,MAAM,EAAE,IAAI,CAAC,MAAoC;YACjD,GAAG,EAAE,IAAI,CAAC,GAAyB;YACnC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YAC9D,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,YAAY,GAAG,CAAC,KAAK,aAAa,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAChE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CACV,gGAAgG;IAC9F,qHAAqH,CACxH;KACA,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;KACtD,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,IAA6B,EAAE,EAAE;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,CAAC;YACxB,UAAU,EAAE,IAAI,CAAC,MAA4B;YAC7C,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sBAAsB,GAAG,CAAC,KAAK,sBAAsB,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,CACpF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CACV,oEAAoE,CACrE;KACA,SAAS,CACR,IAAI,MAAM,CACR,eAAe,EACf,6CAA6C,CAC9C,CAAC,OAAO,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAC/B;KACA,MAAM,CACL,WAAW,EACX,kFAAkF,CACnF;KACA,MAAM,CACL,qBAAqB,EACrB,oEAAoE,CACrE;KACA,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;KACtD,MAAM,CACL,2BAA2B,EAC3B,6DAA6D,CAC9D;KACA,MAAM,CACL,6BAA6B,EAC7B,gEAAgE,CACjE;KACA,MAAM,CACL,2BAA2B,EAC3B,wEAAwE,EACxE,CAAC,KAAa,EAAE,WAAqB,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,EAChE,EAAc,CACf;KACA,MAAM,CAAC,KAAK,EAAE,IAA6B,EAAE,EAAE;IAC9C,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,CAAC,cAAoC,CAAC;QACjE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAsC,CAAC;QACrE,IAAI,OAAO,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oFAAoF,CACrF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC;YACxD,CAAC,CAAE,IAAI,CAAC,cAA2B;YACnC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;YACxB,UAAU,EAAE,IAAI,CAAC,MAA4B;YAC7C,IAAI,EAAE,IAAI,CAAC,IAA0D;YACrE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YACtB,eAAe,EAAE,IAAI,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACjE,UAAU,EACR,cAAc,IAAI,gBAAgB;gBAChC,CAAC,CAAC;oBACE,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,gBAAgB;oBACxB,SAAS,EAAE,eAAe;iBAC3B;gBACH,CAAC,CAAC,SAAS;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,SAAS,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,UAAU,IAAI;YACzE,CAAC,GAAG,CAAC,iBAAiB;gBACpB,CAAC,CAAC,gCAAgC,GAAG,CAAC,iBAAiB,IAAI;gBAC3D,CAAC,CAAC,EAAE,CAAC;YACP,iBAAiB;YACjB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7C,IAAI,CACP,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,2DAA2D,CAAC;KACxE,SAAS,CACR,IAAI,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC;KAC1C,OAAO,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC;KACnC,OAAO,CAAC,sBAAsB,CAAC,CACnC;KACA,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,CAAC,IAAY,EAAE,IAA6B,EAAE,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC;YACpB,MAAM,EAAE,IAAI,CAAC,MAAsB;YACnC,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,EAAwB;SACtC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,GAAG,CAAC,OAAO,aAAa,GAAG,CAAC,QAAQ,YAAY,GAAG,CAAC,OAAO,IAAI,CACnF,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC;YAC/D,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,SAAS,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,KAAK,UAAU,gBAAgB;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoB,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,qCAAqC;AACrC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;AAC3E,IAAI,OAAO,EAAE,CAAC;IACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AACD,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,503 @@
1
+ import { Command, Option } from "commander";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { runBilanz } from "./commands/bilanz.js";
6
+ import { formatDigest, runDigest } from "./commands/digest.js";
7
+ import { runExport } from "./commands/export.js";
8
+ import { runFile } from "./commands/file.js";
9
+ import { runImport } from "./commands/import.js";
10
+ import { runInit } from "./commands/init.js";
11
+ import { formatTable, runList } from "./commands/list.js";
12
+ import { runLog } from "./commands/log.js";
13
+ import { runRm } from "./commands/rm.js";
14
+ import { payloadToScanInput, runScan, summarize, } from "./commands/scan.js";
15
+ import { runSearch } from "./commands/search.js";
16
+ import { runSyncExport } from "./commands/sync-export.js";
17
+ import { runUpdate } from "./commands/update.js";
18
+ import { parseSinkOpts } from "./config.js";
19
+ import { availableSinks } from "./sinks/index.js";
20
+ function readPackageVersion() {
21
+ try {
22
+ const here = dirname(fileURLToPath(import.meta.url));
23
+ const pkgPath = join(here, "..", "package.json");
24
+ const raw = readFileSync(pkgPath, "utf8");
25
+ const parsed = JSON.parse(raw);
26
+ return typeof parsed.version === "string" ? parsed.version : "0.0.0";
27
+ }
28
+ catch {
29
+ return "0.0.0";
30
+ }
31
+ }
32
+ const SEVERITY_CHOICES = ["low", "medium", "high", "critical"];
33
+ const STATUS_CHOICES = ["open", "filed", "resolved", "wontfix"];
34
+ const SOURCE_CHOICES = ["scan", "manual", "import"];
35
+ const SCANNER_CHOICES = ["claude-code"];
36
+ const DIGEST_GROUP_CHOICES = [
37
+ "tool",
38
+ "category",
39
+ "severity",
40
+ "source",
41
+ ];
42
+ const EXPORT_FORMAT_CHOICES = ["json", "csv", "md"];
43
+ const IMPORT_FORMAT_CHOICES = ["markdown-frontmatter"];
44
+ const program = new Command();
45
+ program
46
+ .name("friction-log")
47
+ .description("Capture, query, and infer agent-workflow frictions.")
48
+ .version(readPackageVersion());
49
+ program
50
+ .command("log")
51
+ .description("Manually record a friction.")
52
+ .requiredOption("--title <title>", "Short title describing the friction")
53
+ .option("--description <text>", "Longer description / reproduction notes")
54
+ .option("--tool <surface>", "Tool surface that caused the friction (e.g. mcp:agent-tasks/tasks_list)")
55
+ .option("--category <name>", "Category (e.g. output-overflow, tool-error)")
56
+ .addOption(new Option("--severity <level>", "Severity level").choices([
57
+ ...SEVERITY_CHOICES,
58
+ ]))
59
+ .option("--session <id>", "Session id to associate with this friction")
60
+ .option("--recurrence-of <id>", "Mark this friction as a recurrence of an existing one", (v) => Number(v))
61
+ .option("--db <path>", "Override database path (default: XDG)")
62
+ .action((opts) => {
63
+ const recurrenceOfRaw = opts.recurrenceOf;
64
+ let recurrenceOfId;
65
+ if (recurrenceOfRaw !== undefined) {
66
+ if (typeof recurrenceOfRaw !== "number" ||
67
+ !Number.isInteger(recurrenceOfRaw) ||
68
+ recurrenceOfRaw <= 0) {
69
+ process.stderr.write(`friction-log: --recurrence-of must be a positive integer, got "${String(recurrenceOfRaw)}"\n`);
70
+ process.exit(2);
71
+ }
72
+ recurrenceOfId = recurrenceOfRaw;
73
+ }
74
+ const out = runLog({
75
+ title: opts.title,
76
+ description: opts.description,
77
+ tool: opts.tool,
78
+ category: opts.category,
79
+ severity: opts.severity,
80
+ sessionId: opts.session,
81
+ recurrenceOfId,
82
+ dbPath: opts.db,
83
+ });
84
+ const recurrenceTag = out.recurrenceOfId != null ? ` recurrence_of=${out.recurrenceOfId}` : "";
85
+ process.stdout.write(`friction id=${out.id} captured_at=${out.capturedAt}${recurrenceTag}\n`);
86
+ });
87
+ program
88
+ .command("list")
89
+ .description("List frictions with optional filters.")
90
+ .addOption(new Option("--status <status>", "Filter by status").choices([
91
+ ...STATUS_CHOICES,
92
+ ]))
93
+ .option("--tool <surface>", "Filter by tool surface")
94
+ .option("--category <name>", "Filter by category")
95
+ .addOption(new Option("--source <source>", "Filter by source").choices([
96
+ ...SOURCE_CHOICES,
97
+ ]))
98
+ .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
99
+ .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
100
+ .option("--json", "Emit JSON instead of a table")
101
+ .option("--db <path>", "Override database path")
102
+ .action((opts) => {
103
+ const out = runList({
104
+ status: opts.status,
105
+ tool: opts.tool,
106
+ category: opts.category,
107
+ source: opts.source,
108
+ age: opts.age,
109
+ limit: typeof opts.limit === "number" ? opts.limit : undefined,
110
+ dbPath: opts.db,
111
+ });
112
+ if (opts.json) {
113
+ process.stdout.write(JSON.stringify(out.frictions, null, 2) + "\n");
114
+ }
115
+ else {
116
+ process.stdout.write(formatTable(out.frictions) + "\n");
117
+ }
118
+ });
119
+ program
120
+ .command("file <frictionId>")
121
+ .description("Push a friction to a configured sink. Default sink: markdown-file.")
122
+ .addOption(new Option("--sink <name>", "Sink to use")
123
+ .choices([...availableSinks])
124
+ .default("markdown-file"))
125
+ .option("--template <name>", "Template override (defaults to friction.category match)")
126
+ .option("--sink-target <value>", "Sink-specific target (markdown-file: directory path)")
127
+ .option("--sink-opt <key=value>", "Per-sink option override, repeatable (e.g. --sink-opt repo=owner/name)", (value, previous = []) => [...previous, value], [])
128
+ .option("--config <path>", "Override config file path (default: $XDG_CONFIG_HOME/friction-log/config.yml)")
129
+ .option("--db <path>", "Override database path")
130
+ .action(async (frictionId, opts) => {
131
+ const id = Number(frictionId);
132
+ if (!Number.isInteger(id) || id <= 0) {
133
+ process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
134
+ process.exit(2);
135
+ }
136
+ try {
137
+ const sinkOptPairs = Array.isArray(opts.sinkOpt)
138
+ ? opts.sinkOpt
139
+ : [];
140
+ const sinkOpts = sinkOptPairs.length
141
+ ? parseSinkOpts(sinkOptPairs)
142
+ : undefined;
143
+ const out = await runFile({
144
+ frictionId: id,
145
+ sink: opts.sink,
146
+ template: opts.template,
147
+ sinkTarget: opts.sinkTarget,
148
+ sinkOpts,
149
+ configPath: opts.config,
150
+ dbPath: opts.db,
151
+ });
152
+ process.stdout.write(`filed friction id=${id} via sink=${out.sinkName} target=${out.sinkTarget}\n${out.message}\n`);
153
+ }
154
+ catch (err) {
155
+ process.stderr.write(`${err.message}\n`);
156
+ process.exit(1);
157
+ }
158
+ });
159
+ program
160
+ .command("scan")
161
+ .description("Scan a transcript for candidate frictions and store them.")
162
+ .option("--session <id>", "Session id (defaults to derivation from --transcript filename)")
163
+ .option("--transcript <path>", "Path to the transcript file (e.g. ~/.claude/projects/.../<id>.jsonl)")
164
+ .addOption(new Option("--adapter <name>", "Scanner adapter").choices([
165
+ ...SCANNER_CHOICES,
166
+ ]))
167
+ .option("--silent", "Never throw, exit 0 always (Stop-hook mode)")
168
+ .option("--stdin-payload", "Read a JSON Stop-hook payload from stdin to derive session+transcript")
169
+ .option("--db <path>", "Override database path")
170
+ .action(async (opts) => {
171
+ try {
172
+ let baseInput = {
173
+ sessionId: opts.session,
174
+ transcriptPath: opts.transcript,
175
+ adapter: opts.adapter,
176
+ dbPath: opts.db,
177
+ };
178
+ if (opts.stdinPayload) {
179
+ const payload = await readStdinPayload();
180
+ const derived = payloadToScanInput(payload, baseInput.adapter);
181
+ baseInput = {
182
+ sessionId: derived.sessionId ?? baseInput.sessionId,
183
+ transcriptPath: derived.transcriptPath ?? baseInput.transcriptPath,
184
+ adapter: derived.adapter ?? baseInput.adapter,
185
+ dbPath: baseInput.dbPath,
186
+ };
187
+ }
188
+ const out = await runScan(baseInput);
189
+ if (!opts.silent) {
190
+ process.stdout.write(summarize(out, out.sessionId) + "\n");
191
+ }
192
+ }
193
+ catch (err) {
194
+ if (opts.silent) {
195
+ process.stderr.write(`friction-log scan (silent): ${err.message}\n`);
196
+ process.exit(0);
197
+ }
198
+ process.stderr.write(`${err.message}\n`);
199
+ process.exit(1);
200
+ }
201
+ });
202
+ program
203
+ .command("bilanz")
204
+ .description("Format a session-boundary bilanz: tools, frictions, tasks.")
205
+ .option("--session <id>", "Session id (defaults to most-recent in db)")
206
+ .option("--db <path>", "Override database path")
207
+ .action(async (opts) => {
208
+ try {
209
+ const out = await runBilanz({ sessionId: opts.session, dbPath: opts.db });
210
+ process.stdout.write(out.formatted);
211
+ }
212
+ catch (err) {
213
+ process.stderr.write(`${err.message}\n`);
214
+ process.exit(1);
215
+ }
216
+ });
217
+ program
218
+ .command("rm <frictionId>")
219
+ .description("Delete a friction (and any task rows pointing at it) from the local store.")
220
+ .option("--db <path>", "Override database path")
221
+ .action((frictionId, opts) => {
222
+ const id = Number(frictionId);
223
+ if (!Number.isInteger(id) || id <= 0) {
224
+ process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
225
+ process.exit(2);
226
+ }
227
+ try {
228
+ const out = runRm({ frictionId: id, dbPath: opts.db });
229
+ process.stdout.write(`removed friction id=${id} (${out.removed ? "ok" : "no-op"})\n`);
230
+ }
231
+ catch (err) {
232
+ process.stderr.write(`${err.message}\n`);
233
+ process.exit(1);
234
+ }
235
+ });
236
+ program
237
+ .command("update <frictionId>")
238
+ .description("Update a friction (status only in M2; more fields in later milestones).")
239
+ .addOption(new Option("--status <status>", "New status")
240
+ .choices([...STATUS_CHOICES])
241
+ .makeOptionMandatory(true))
242
+ .option("--db <path>", "Override database path")
243
+ .action((frictionId, opts) => {
244
+ const id = Number(frictionId);
245
+ if (!Number.isInteger(id) || id <= 0) {
246
+ process.stderr.write(`friction-log: <frictionId> must be a positive integer, got "${frictionId}"\n`);
247
+ process.exit(2);
248
+ }
249
+ try {
250
+ const out = runUpdate({
251
+ frictionId: id,
252
+ status: opts.status,
253
+ dbPath: opts.db,
254
+ });
255
+ process.stdout.write(`updated friction id=${out.id} status=${out.status}\n`);
256
+ }
257
+ catch (err) {
258
+ process.stderr.write(`${err.message}\n`);
259
+ process.exit(1);
260
+ }
261
+ });
262
+ program
263
+ .command("search <query>")
264
+ .description("Full-text search over title + description (FTS5).")
265
+ .addOption(new Option("--status <status>", "Filter by status").choices([
266
+ ...STATUS_CHOICES,
267
+ ]))
268
+ .option("--tool <surface>", "Filter by tool surface")
269
+ .option("--category <name>", "Filter by category")
270
+ .addOption(new Option("--source <source>", "Filter by source").choices([
271
+ ...SOURCE_CHOICES,
272
+ ]))
273
+ .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
274
+ .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
275
+ .option("--json", "Emit JSON instead of a table")
276
+ .option("--db <path>", "Override database path")
277
+ .action((query, opts) => {
278
+ try {
279
+ const out = runSearch({
280
+ query,
281
+ status: opts.status,
282
+ tool: opts.tool,
283
+ category: opts.category,
284
+ source: opts.source,
285
+ age: opts.age,
286
+ limit: typeof opts.limit === "number" ? opts.limit : undefined,
287
+ dbPath: opts.db,
288
+ });
289
+ if (opts.json) {
290
+ process.stdout.write(JSON.stringify(out.frictions, null, 2) + "\n");
291
+ }
292
+ else {
293
+ process.stdout.write(formatTable(out.frictions) + "\n");
294
+ }
295
+ }
296
+ catch (err) {
297
+ process.stderr.write(`${err.message}\n`);
298
+ process.exit(1);
299
+ }
300
+ });
301
+ program
302
+ .command("digest")
303
+ .description("Aggregations over frictions: counts, open-vs-filed, recurrences, avg hours to triage.")
304
+ .addOption(new Option("--group-by <field>", "Group by field")
305
+ .choices([...DIGEST_GROUP_CHOICES])
306
+ .makeOptionMandatory(true))
307
+ .option("--last <span>", "Restrict to frictions newer than e.g. 30d, 4w, 12h")
308
+ .option("--include-peers", "Also render read-only digest sections for each configured sync_export.peer_paths file")
309
+ .option("--json", "Emit JSON instead of a table")
310
+ .option("--config <path>", "Override config file path (only used by --include-peers)")
311
+ .option("--db <path>", "Override database path")
312
+ .action((opts) => {
313
+ try {
314
+ const out = runDigest({
315
+ groupBy: opts.groupBy,
316
+ last: opts.last,
317
+ dbPath: opts.db,
318
+ configPath: opts.config,
319
+ includePeers: Boolean(opts.includePeers),
320
+ });
321
+ if (opts.json) {
322
+ process.stdout.write(JSON.stringify(out, null, 2) + "\n");
323
+ }
324
+ else {
325
+ process.stdout.write(formatDigest(out) + "\n");
326
+ }
327
+ if (out.peers) {
328
+ for (const peer of out.peers) {
329
+ if (peer.error) {
330
+ process.stderr.write(`friction-log: warning: peer digest source ${peer.sourcePath} (origin=${peer.origin}) skipped: ${peer.error}\n`);
331
+ }
332
+ else if (peer.skipped > 0) {
333
+ process.stderr.write(`friction-log: warning: peer digest source ${peer.sourcePath} (origin=${peer.origin}) skipped ${peer.skipped} malformed record(s)\n`);
334
+ }
335
+ }
336
+ }
337
+ }
338
+ catch (err) {
339
+ process.stderr.write(`${err.message}\n`);
340
+ process.exit(1);
341
+ }
342
+ });
343
+ program
344
+ .command("export")
345
+ .description("Export frictions as JSON, CSV, or Markdown.")
346
+ .addOption(new Option("--format <fmt>", "Output format")
347
+ .choices([...EXPORT_FORMAT_CHOICES])
348
+ .default("json"))
349
+ .option("--out <path>", "Write to a file instead of stdout")
350
+ .option("--query <text>", "Only export frictions matching an FTS5 query")
351
+ .addOption(new Option("--status <status>", "Filter by status").choices([
352
+ ...STATUS_CHOICES,
353
+ ]))
354
+ .option("--tool <surface>", "Filter by tool surface")
355
+ .option("--category <name>", "Filter by category")
356
+ .addOption(new Option("--source <source>", "Filter by source").choices([
357
+ ...SOURCE_CHOICES,
358
+ ]))
359
+ .option("--age <span>", "Only frictions newer than e.g. 14d, 4w, 12h")
360
+ .option("--limit <n>", "Max rows (default 100)", (v) => Number(v))
361
+ .option("--db <path>", "Override database path")
362
+ .action((opts) => {
363
+ try {
364
+ const out = runExport({
365
+ format: opts.format,
366
+ out: opts.out,
367
+ query: opts.query,
368
+ status: opts.status,
369
+ tool: opts.tool,
370
+ category: opts.category,
371
+ source: opts.source,
372
+ age: opts.age,
373
+ limit: typeof opts.limit === "number" ? opts.limit : undefined,
374
+ dbPath: opts.db,
375
+ });
376
+ if (out.out) {
377
+ process.stderr.write(`exported ${out.count} records (${out.format}) to ${out.out}\n`);
378
+ }
379
+ else {
380
+ process.stdout.write(out.rendered);
381
+ }
382
+ }
383
+ catch (err) {
384
+ process.stderr.write(`${err.message}\n`);
385
+ process.exit(1);
386
+ }
387
+ });
388
+ program
389
+ .command("sync-export")
390
+ .description("Write every friction as deterministic, origin-tagged JSON to the configured sync_export.path. " +
391
+ 'No-op error unless "sync_export" (path + origin) is set in config.yml or via FRICTION_LOG_SYNC_EXPORT_PATH/_ORIGIN.')
392
+ .option("--config <path>", "Override config file path")
393
+ .option("--db <path>", "Override database path")
394
+ .action((opts) => {
395
+ try {
396
+ const out = runSyncExport({
397
+ configPath: opts.config,
398
+ dbPath: opts.db,
399
+ });
400
+ process.stderr.write(`sync-export: wrote ${out.count} frictions (origin=${out.origin}) to ${out.path}\n`);
401
+ }
402
+ catch (err) {
403
+ process.stderr.write(`${err.message}\n`);
404
+ process.exit(1);
405
+ }
406
+ });
407
+ program
408
+ .command("init")
409
+ .description("Interactive setup: write config.yml, optionally install Stop-hook.")
410
+ .addOption(new Option("--sink <name>", "Default sink (skips the interactive prompt)").choices([...availableSinks]))
411
+ .option("-y, --yes", "Non-interactive; use --sink (or markdown-file fallback) and skip Stop-hook offer")
412
+ .option("--install-stop-hook", "Force-install the Claude Code Stop-hook (skip the interactive y/N)")
413
+ .option("--config <path>", "Override config file path")
414
+ .option("--sync-export-path <path>", "Opt in to sync-export: write this config's sync_export.path")
415
+ .option("--sync-export-origin <name>", "Opt in to sync-export: this machine's sync_export.origin label")
416
+ .option("--sync-export-peer <path>", "Peer sync-export file to read for `digest --include-peers`, repeatable", (value, previous = []) => [...previous, value], [])
417
+ .action(async (opts) => {
418
+ try {
419
+ const syncExportPath = opts.syncExportPath;
420
+ const syncExportOrigin = opts.syncExportOrigin;
421
+ if (Boolean(syncExportPath) !== Boolean(syncExportOrigin)) {
422
+ process.stderr.write("friction-log: --sync-export-path and --sync-export-origin must be given together\n");
423
+ process.exit(2);
424
+ }
425
+ const syncExportPeers = Array.isArray(opts.syncExportPeer)
426
+ ? opts.syncExportPeer
427
+ : [];
428
+ const out = await runInit({
429
+ configPath: opts.config,
430
+ sink: opts.sink,
431
+ yes: Boolean(opts.yes),
432
+ installStopHook: opts.installStopHook === true ? true : undefined,
433
+ syncExport: syncExportPath && syncExportOrigin
434
+ ? {
435
+ path: syncExportPath,
436
+ origin: syncExportOrigin,
437
+ peerPaths: syncExportPeers,
438
+ }
439
+ : undefined,
440
+ });
441
+ process.stdout.write(`init: ${out.configWritten ? "wrote" : "no change to"} ${out.configPath}\n` +
442
+ (out.stopHookWrittenTo
443
+ ? `init: Stop-hook installed at ${out.stopHookWrittenTo}\n`
444
+ : "") +
445
+ "\nNext steps:\n" +
446
+ out.nextSteps.map((s) => ` ${s}`).join("\n") +
447
+ "\n");
448
+ }
449
+ catch (err) {
450
+ process.stderr.write(`${err.message}\n`);
451
+ process.exit(1);
452
+ }
453
+ });
454
+ program
455
+ .command("import <path>")
456
+ .description("Bulk-ingest frictions from a directory of markdown files.")
457
+ .addOption(new Option("--format <fmt>", "Source format")
458
+ .choices([...IMPORT_FORMAT_CHOICES])
459
+ .default("markdown-frontmatter"))
460
+ .option("--db <path>", "Override database path")
461
+ .action((path, opts) => {
462
+ try {
463
+ const out = runImport({
464
+ format: opts.format,
465
+ path,
466
+ dbPath: opts.db,
467
+ });
468
+ process.stdout.write(`import: scanned=${out.scanned} imported=${out.imported} skipped=${out.skipped}\n`);
469
+ if (out.errors.length) {
470
+ process.stderr.write(`import: ${out.errors.length} errors:\n`);
471
+ for (const e of out.errors.slice(0, 10)) {
472
+ process.stderr.write(` ${e.file}: ${e.reason}\n`);
473
+ }
474
+ if (out.errors.length > 10) {
475
+ process.stderr.write(` ... and ${out.errors.length - 10} more\n`);
476
+ }
477
+ }
478
+ }
479
+ catch (err) {
480
+ process.stderr.write(`${err.message}\n`);
481
+ process.exit(1);
482
+ }
483
+ });
484
+ async function readStdinPayload() {
485
+ const chunks = [];
486
+ for await (const chunk of process.stdin) {
487
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
488
+ }
489
+ const text = Buffer.concat(chunks).toString("utf8").trim();
490
+ if (!text)
491
+ return {};
492
+ try {
493
+ return JSON.parse(text);
494
+ }
495
+ catch {
496
+ return {};
497
+ }
498
+ }
499
+ program.parseAsync(process.argv).catch((err) => {
500
+ process.stderr.write(`friction-log: ${err.message}\n`);
501
+ process.exit(1);
502
+ });
503
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Extract the minimum major version from an engines range such as ">=22".
3
+ * Returns null when the range is not of the simple ">=N[.x.y]" form.
4
+ */
5
+ export declare function parseMinMajor(range: string): number | null;
6
+ /** True when the running Node version satisfies the minimum major. */
7
+ export declare function isSupportedNode(running: string, minMajor: number): boolean;
8
+ /**
9
+ * Returns an error message when `running` is below the major required by
10
+ * `enginesRange`, or null when it is supported (or the range is not parseable).
11
+ */
12
+ export declare function nodeGuardMessage(running: string, enginesRange: string): string | null;
13
+ /** Reads the `engines.node` range from the package's own package.json. */
14
+ export declare function readEnginesNode(): string;
@@ -0,0 +1,36 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * Extract the minimum major version from an engines range such as ">=22".
6
+ * Returns null when the range is not of the simple ">=N[.x.y]" form.
7
+ */
8
+ export function parseMinMajor(range) {
9
+ const m = /^\s*>=\s*v?(\d+)(?:\.\d+){0,2}\s*$/.exec(range);
10
+ return m ? Number(m[1]) : null;
11
+ }
12
+ /** True when the running Node version satisfies the minimum major. */
13
+ export function isSupportedNode(running, minMajor) {
14
+ const major = Number(running.replace(/^v/, "").split(".")[0]);
15
+ return Number.isInteger(major) && major >= minMajor;
16
+ }
17
+ /**
18
+ * Returns an error message when `running` is below the major required by
19
+ * `enginesRange`, or null when it is supported (or the range is not parseable).
20
+ */
21
+ export function nodeGuardMessage(running, enginesRange) {
22
+ const minMajor = parseMinMajor(enginesRange);
23
+ if (minMajor === null || isSupportedNode(running, minMajor))
24
+ return null;
25
+ return (`friction-log requires Node ${enginesRange} but is running on Node ${running}. ` +
26
+ `Its SQLite binding does not work on this version; upgrade Node and retry.`);
27
+ }
28
+ /** Reads the `engines.node` range from the package's own package.json. */
29
+ export function readEnginesNode() {
30
+ const here = dirname(fileURLToPath(import.meta.url));
31
+ const raw = readFileSync(join(here, "..", "package.json"), "utf8");
32
+ const parsed = JSON.parse(raw);
33
+ const node = parsed.engines?.node;
34
+ return typeof node === "string" ? node : "";
35
+ }
36
+ //# sourceMappingURL=node-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-guard.js","sourceRoot":"","sources":["../src/node-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,CAAC,GAAG,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3D,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,QAAgB;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,YAAoB;IAEpB,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,IAAI,IAAI,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,OAAO,CACL,8BAA8B,YAAY,2BAA2B,OAAO,IAAI;QAChF,2EAA2E,CAC5E,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqC,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;IAClC,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "friction-log",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Capture, query, and infer agent-workflow frictions. SQLite-backed, sink-pluggable, zero-config default.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",