friction-log 0.0.0-stage → 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 +54 -0
- package/LICENSE +21 -0
- package/README.md +98 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/bilanz.d.ts +23 -0
- package/dist/commands/bilanz.js +106 -0
- package/dist/commands/bilanz.js.map +1 -0
- package/dist/commands/digest.d.ts +36 -0
- package/dist/commands/digest.js +288 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/export.d.ts +36 -0
- package/dist/commands/export.js +118 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/file.d.ts +18 -0
- package/dist/commands/file.js +51 -0
- package/dist/commands/file.js.map +1 -0
- package/dist/commands/import.d.ts +31 -0
- package/dist/commands/import.js +283 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +44 -0
- package/dist/commands/init.js +256 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +16 -0
- package/dist/commands/list.js +57 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/log.d.ts +18 -0
- package/dist/commands/log.js +52 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/rm.d.ts +9 -0
- package/dist/commands/rm.js +22 -0
- package/dist/commands/rm.js.map +1 -0
- package/dist/commands/scan.d.ts +25 -0
- package/dist/commands/scan.js +73 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/search.d.ts +15 -0
- package/dist/commands/search.js +37 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/sync-export.d.ts +46 -0
- package/dist/commands/sync-export.js +80 -0
- package/dist/commands/sync-export.js.map +1 -0
- package/dist/commands/update.d.ts +12 -0
- package/dist/commands/update.js +24 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.js +145 -0
- package/dist/config.js.map +1 -0
- package/dist/db.d.ts +81 -0
- package/dist/db.js +548 -0
- package/dist/db.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +503 -0
- package/dist/main.js.map +1 -0
- package/dist/node-guard.d.ts +14 -0
- package/dist/node-guard.js +36 -0
- package/dist/node-guard.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/scanners/claude-code.d.ts +6 -0
- package/dist/scanners/claude-code.js +202 -0
- package/dist/scanners/claude-code.js.map +1 -0
- package/dist/scanners/index.d.ts +4 -0
- package/dist/scanners/index.js +12 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/sinks/agent-tasks.d.ts +36 -0
- package/dist/sinks/agent-tasks.js +153 -0
- package/dist/sinks/agent-tasks.js.map +1 -0
- package/dist/sinks/github-issues.d.ts +20 -0
- package/dist/sinks/github-issues.js +98 -0
- package/dist/sinks/github-issues.js.map +1 -0
- package/dist/sinks/index.d.ts +11 -0
- package/dist/sinks/index.js +48 -0
- package/dist/sinks/index.js.map +1 -0
- package/dist/sinks/linear.d.ts +25 -0
- package/dist/sinks/linear.js +157 -0
- package/dist/sinks/linear.js.map +1 -0
- package/dist/sinks/markdown-file.d.ts +7 -0
- package/dist/sinks/markdown-file.js +54 -0
- package/dist/sinks/markdown-file.js.map +1 -0
- package/dist/sinks/stdout-json.d.ts +15 -0
- package/dist/sinks/stdout-json.js +49 -0
- package/dist/sinks/stdout-json.js.map +1 -0
- package/dist/templates/auth-expiry.yml +30 -0
- package/dist/templates/doc-gap.yml +30 -0
- package/dist/templates/output-overflow.yml +25 -0
- package/dist/templates/schema-drift.yml +26 -0
- package/dist/templates/tool-error.yml +34 -0
- package/dist/templates/tool-missing-capability.yml +26 -0
- package/dist/templates/workflow-friction.yml +26 -0
- package/dist/templates.d.ts +5 -0
- package/dist/templates.js +88 -0
- package/dist/templates.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/commands.md +74 -0
- package/docs/design.md +25 -0
- package/docs/sinks.md +79 -0
- package/docs/storage.md +20 -0
- package/docs/sync-export.md +23 -0
- package/package.json +64 -4
- package/templates/auth-expiry.yml +30 -0
- package/templates/doc-gap.yml +30 -0
- package/templates/output-overflow.yml +25 -0
- package/templates/schema-drift.yml +26 -0
- package/templates/tool-error.yml +34 -0
- package/templates/tool-missing-capability.yml +26 -0
- package/templates/workflow-friction.yml +26 -0
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
|
package/dist/main.js.map
ADDED
|
@@ -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/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function defaultDbPath(): string;
|
|
2
|
+
export declare function defaultConfigPath(): string;
|
|
3
|
+
export declare function defaultMarkdownSinkDir(): string;
|
|
4
|
+
/**
|
|
5
|
+
* sync_export has no XDG-style fallback location (it is opt-in only), so
|
|
6
|
+
* unlike the `default*Path` helpers above these return `undefined` when the
|
|
7
|
+
* env var is unset rather than falling back to a computed default. Callers
|
|
8
|
+
* (config.ts) treat `undefined` as "no override" and fall through to the
|
|
9
|
+
* config-file value, if any.
|
|
10
|
+
*/
|
|
11
|
+
export declare function syncExportPathOverride(): string | undefined;
|
|
12
|
+
export declare function syncExportOriginOverride(): string | undefined;
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
function xdgDataHome() {
|
|
4
|
+
return process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share");
|
|
5
|
+
}
|
|
6
|
+
function xdgConfigHome() {
|
|
7
|
+
return process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
|
|
8
|
+
}
|
|
9
|
+
export function defaultDbPath() {
|
|
10
|
+
return (process.env.FRICTION_LOG_DB ??
|
|
11
|
+
join(xdgDataHome(), "friction-log", "db.sqlite"));
|
|
12
|
+
}
|
|
13
|
+
export function defaultConfigPath() {
|
|
14
|
+
return (process.env.FRICTION_LOG_CONFIG ??
|
|
15
|
+
join(xdgConfigHome(), "friction-log", "config.yml"));
|
|
16
|
+
}
|
|
17
|
+
export function defaultMarkdownSinkDir() {
|
|
18
|
+
return (process.env.FRICTION_LOG_MARKDOWN_DIR ??
|
|
19
|
+
join(xdgDataHome(), "friction-log", "frictions"));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* sync_export has no XDG-style fallback location (it is opt-in only), so
|
|
23
|
+
* unlike the `default*Path` helpers above these return `undefined` when the
|
|
24
|
+
* env var is unset rather than falling back to a computed default. Callers
|
|
25
|
+
* (config.ts) treat `undefined` as "no override" and fall through to the
|
|
26
|
+
* config-file value, if any.
|
|
27
|
+
*/
|
|
28
|
+
export function syncExportPathOverride() {
|
|
29
|
+
return process.env.FRICTION_LOG_SYNC_EXPORT_PATH || undefined;
|
|
30
|
+
}
|
|
31
|
+
export function syncExportOriginOverride() {
|
|
32
|
+
return process.env.FRICTION_LOG_SYNC_EXPORT_ORIGIN || undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,WAAW,CAAC,CACjD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC/B,IAAI,CAAC,aAAa,EAAE,EAAE,cAAc,EAAE,YAAY,CAAC,CACpD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACrC,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,WAAW,CAAC,CACjD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,SAAS,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,SAAS,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Scanner, ScannerInput, ScannerOutput } from "../types.js";
|
|
2
|
+
export declare class ClaudeCodeAdapter implements Scanner {
|
|
3
|
+
readonly name = "claude-code";
|
|
4
|
+
scan(input: ScannerInput): Promise<ScannerOutput>;
|
|
5
|
+
}
|
|
6
|
+
export declare function fileExistsCheck(p: string): boolean;
|