@djolex999/vir-cli 0.23.3 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/claude/updater.js +24 -4
- package/dist/claude/updater.js.map +1 -1
- package/dist/cli/audit.js +136 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/compose.js +101 -0
- package/dist/cli/compose.js.map +1 -0
- package/dist/cli/costLabel.js +14 -0
- package/dist/cli/costLabel.js.map +1 -0
- package/dist/cli/dedupe.js +92 -0
- package/dist/cli/dedupe.js.map +1 -0
- package/dist/cli/embed.js +183 -0
- package/dist/cli/embed.js.map +1 -0
- package/dist/cli/guards.js +40 -0
- package/dist/cli/guards.js.map +1 -0
- package/dist/cli/init.js +361 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/lint.js +160 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/reconcile.js +110 -62
- package/dist/cli/reconcile.js.map +1 -1
- package/dist/cli/review.js +26 -5
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/summarize.js +148 -0
- package/dist/cli/summarize.js.map +1 -0
- package/dist/cli.js +36 -1100
- package/dist/cli.js.map +1 -1
- package/dist/config.js +12 -6
- package/dist/config.js.map +1 -1
- package/dist/cost/report.js +5 -2
- package/dist/cost/report.js.map +1 -1
- package/dist/diagnostics/doctor.js +23 -0
- package/dist/diagnostics/doctor.js.map +1 -1
- package/dist/mcp/server.js +40 -28
- package/dist/mcp/server.js.map +1 -1
- package/dist/pipeline/claudeCli.js +41 -5
- package/dist/pipeline/claudeCli.js.map +1 -1
- package/dist/pipeline/composer.js +1 -0
- package/dist/pipeline/composer.js.map +1 -1
- package/dist/pipeline/distillSession.js +96 -0
- package/dist/pipeline/distillSession.js.map +1 -0
- package/dist/pipeline/distiller.js +12 -5
- package/dist/pipeline/distiller.js.map +1 -1
- package/dist/pipeline/embeddingSweep.js +9 -5
- package/dist/pipeline/embeddingSweep.js.map +1 -1
- package/dist/pipeline/run.js +53 -73
- package/dist/pipeline/run.js.map +1 -1
- package/dist/pipeline/scrubber.js +4 -4
- package/dist/pipeline/scrubber.js.map +1 -1
- package/dist/pipeline/writer.js +83 -10
- package/dist/pipeline/writer.js.map +1 -1
- package/dist/state/db.js +8 -8
- package/dist/state/db.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import confirm from "@inquirer/confirm";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { loadConfig } from "../config.js";
|
|
4
|
+
import { normalizeModelName, resolveModelShorthand, } from "../pipeline/distiller.js";
|
|
5
|
+
import { countByCategory, summarizeAll, summarizeProject, } from "../pipeline/summarizer.js";
|
|
6
|
+
import { buildPeriodPrompt, estimatePeriodCostTokens, periodLabel, periodRange, selectNotesInPeriod, summarizePeriod, } from "../pipeline/periodSummary.js";
|
|
7
|
+
import { StateDb } from "../state/db.js";
|
|
8
|
+
import * as ui from "../ui/display.js";
|
|
9
|
+
import { estCostLabel } from "./costLabel.js";
|
|
10
|
+
import { withPipelineLock } from "./guards.js";
|
|
11
|
+
export async function summarizeCommand(project, opts) {
|
|
12
|
+
// Writes notes and the DB: hold the lock (a dry run only reads).
|
|
13
|
+
const run = async () => {
|
|
14
|
+
const cfg = loadConfig();
|
|
15
|
+
const wantWeek = opts.week !== undefined;
|
|
16
|
+
const wantMonth = opts.month !== undefined;
|
|
17
|
+
if (wantWeek && wantMonth) {
|
|
18
|
+
console.error(chalk.red("use --week or --month, not both"));
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// ── period summary path (--week / --month) ──────────────────────────
|
|
23
|
+
if (wantWeek || wantMonth) {
|
|
24
|
+
if (project || opts.all) {
|
|
25
|
+
console.error(chalk.red("--week/--month cannot be combined with a project or --all"));
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (opts.model && !["haiku", "sonnet"].includes(opts.model)) {
|
|
30
|
+
console.error(chalk.red(`--model must be 'haiku' or 'sonnet', got '${opts.model}'`));
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const kind = wantWeek ? "week" : "month";
|
|
35
|
+
const raw = wantWeek ? opts.week : opts.month;
|
|
36
|
+
// commander yields `true` for a bare flag, or the string value for `--week 2`
|
|
37
|
+
const offset = typeof raw === "string" ? Number.parseInt(raw, 10) : 0;
|
|
38
|
+
if (!Number.isInteger(offset) || offset < 0) {
|
|
39
|
+
console.error(chalk.red(`--${kind} offset must be a non-negative integer`));
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const period = { kind, offset };
|
|
44
|
+
const now = new Date();
|
|
45
|
+
const db = new StateDb();
|
|
46
|
+
try {
|
|
47
|
+
ui.header("summarize");
|
|
48
|
+
ui.divider();
|
|
49
|
+
const range = periodRange(period, now);
|
|
50
|
+
const label = periodLabel(period, range);
|
|
51
|
+
console.log(ui.text(label));
|
|
52
|
+
ui.divider();
|
|
53
|
+
ui.blank();
|
|
54
|
+
const notes = selectNotesInPeriod(db.listDistilled(), period, now);
|
|
55
|
+
if (notes.length === 0) {
|
|
56
|
+
ui.row(ui.warn(ui.WARN_GLYPH), ui.text(`no notes distilled in ${label} — nothing to summarize`));
|
|
57
|
+
ui.line(ui.dim(" run `vir run` to distill more sessions first"));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const model = normalizeModelName(resolveModelShorthand(opts.model ?? cfg.models.distill), cfg.provider);
|
|
61
|
+
const counts = countByCategory(notes);
|
|
62
|
+
const prompt = buildPeriodPrompt(label, notes, counts);
|
|
63
|
+
const { inputTokens, outputTokens } = estimatePeriodCostTokens(prompt);
|
|
64
|
+
const estCost = estCostLabel(cfg, model, inputTokens, outputTokens);
|
|
65
|
+
ui.summary({
|
|
66
|
+
notes: { value: notes.length, color: ui.info },
|
|
67
|
+
model: { value: model, color: ui.accent },
|
|
68
|
+
"est. cost": { value: estCost, color: ui.warn },
|
|
69
|
+
});
|
|
70
|
+
ui.divider();
|
|
71
|
+
if (opts.dryRun === true) {
|
|
72
|
+
ui.line(ui.dim(" dry run — no synthesis performed; actuals may vary ±30%"));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (opts.yes !== true) {
|
|
76
|
+
const proceed = await confirm({
|
|
77
|
+
message: `synthesize with ${model} (~${estCost})?`,
|
|
78
|
+
default: true,
|
|
79
|
+
});
|
|
80
|
+
if (!proceed) {
|
|
81
|
+
ui.line(ui.dim("aborted"));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const sp = ui.spinner("synthesizing period summary").start();
|
|
86
|
+
let result;
|
|
87
|
+
try {
|
|
88
|
+
result = await summarizePeriod(cfg, db, period, {
|
|
89
|
+
now,
|
|
90
|
+
model: opts.model,
|
|
91
|
+
});
|
|
92
|
+
sp.stop();
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
sp.fail(ui.errorColor(err.message));
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!result) {
|
|
100
|
+
ui.row(ui.warn(ui.WARN_GLYPH), ui.text("nothing to summarize"));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
ui.row(ui.success(ui.CHECK), ui.text(`wrote ${result.relPath} (${result.noteCount} notes)`));
|
|
104
|
+
ui.blank();
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
db.close();
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// ── project / --all path (unchanged) ────────────────────────────────
|
|
112
|
+
const db = new StateDb();
|
|
113
|
+
try {
|
|
114
|
+
if (opts.all) {
|
|
115
|
+
const results = await summarizeAll(cfg, db);
|
|
116
|
+
if (results.length === 0) {
|
|
117
|
+
console.log(chalk.yellow("no projects with notes"));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
for (const r of results) {
|
|
121
|
+
console.log(chalk.green(`summarized project/${r.slug}`) +
|
|
122
|
+
` (${r.counts.total} sessions)`);
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!project) {
|
|
127
|
+
console.error(chalk.red("usage: vir summarize <project> | --all | --week [n] | --month [n]"));
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const res = await summarizeProject(cfg, project, db);
|
|
132
|
+
if (!res) {
|
|
133
|
+
console.log(chalk.yellow(`no distilled notes for project '${project}'`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
console.log(chalk.green(`summarized project/${res.slug}`) +
|
|
137
|
+
` (${res.counts.total} sessions) → ${res.path}`);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
db.close();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
if (opts.dryRun)
|
|
144
|
+
await run();
|
|
145
|
+
else
|
|
146
|
+
await withPipelineLock(run);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=summarize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../src/cli/summarize.ts"],"names":[],"mappings":"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"}
|