@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,183 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { stdin, stdout } from "node:process";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { loadConfig } from "../config.js";
|
|
5
|
+
import { embedNoteWithProvider, resolveEmbeddingProvider, } from "../search/provider.js";
|
|
6
|
+
import { runEmbedSetup } from "./embedSetup.js";
|
|
7
|
+
import { StateDb } from "../state/db.js";
|
|
8
|
+
import * as ui from "../ui/display.js";
|
|
9
|
+
import { VaultWriter } from "../pipeline/writer.js";
|
|
10
|
+
export async function embedCommand(opts) {
|
|
11
|
+
if (opts.setup) {
|
|
12
|
+
await runEmbedSetup(opts.yes === true);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const cfg = loadConfig();
|
|
16
|
+
ui.header("embed");
|
|
17
|
+
ui.blank();
|
|
18
|
+
const provider = await resolveEmbeddingProvider(cfg.embeddingProvider);
|
|
19
|
+
if (!provider) {
|
|
20
|
+
ui.row(ui.errorColor(ui.CROSS), ui.text("no embedding provider available"));
|
|
21
|
+
ui.line(ui.dim(" vir embed --setup # local provider, no Ollama needed (~233 MB)"));
|
|
22
|
+
ui.line(ui.dim(" or: brew install ollama && ollama pull nomic-embed-text && ollama serve"));
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const provenance = provider.provenance();
|
|
27
|
+
const db = new StateDb();
|
|
28
|
+
try {
|
|
29
|
+
// Same text the writer embeds (note file minus generated sections),
|
|
30
|
+
// falling back to stored content when a file is gone.
|
|
31
|
+
const text = new VaultWriter(cfg, db).embeddingText;
|
|
32
|
+
const rows = db.listDistilled();
|
|
33
|
+
const root = join(cfg.vaultPath, cfg.outputDir);
|
|
34
|
+
const embeddedRows = [
|
|
35
|
+
...db.getEmbeddings(root),
|
|
36
|
+
...db.getArticleEmbeddings(),
|
|
37
|
+
...db.getTopicEmbeddings(root, cfg.topicsDir),
|
|
38
|
+
...db.getPdfEmbeddings(),
|
|
39
|
+
];
|
|
40
|
+
// Crossing a model boundary is an index invalidation, not a gap fill —
|
|
41
|
+
// it needs --force AND explicit consent, with the cost stated first.
|
|
42
|
+
// Without --force, mismatched rows stay excluded from vector search
|
|
43
|
+
// (counted, reported) and only NULL-embedding gaps are filled.
|
|
44
|
+
const mismatched = embeddedRows.filter((r) => r.embeddingModel !== provider.modelName).length;
|
|
45
|
+
if (mismatched > 0 && !opts.force) {
|
|
46
|
+
ui.row(ui.warn(ui.WARN_GLYPH), ui.text(`${mismatched} note(s) are embedded under a different model than the active one (${provider.modelName})`));
|
|
47
|
+
ui.line(ui.dim("they are excluded from vector search until re-embedded"));
|
|
48
|
+
ui.line(ui.dim("run `vir embed --force` to re-embed the whole index"));
|
|
49
|
+
}
|
|
50
|
+
if (mismatched > 0 && opts.force) {
|
|
51
|
+
const estSecs = Math.max(1, Math.round(rows.length * 0.15));
|
|
52
|
+
ui.row(ui.warn(ui.WARN_GLYPH), ui.text(`model boundary: re-embedding ${rows.length} note(s) under ${provider.modelName} (~${estSecs}s), replacing vectors from other models`));
|
|
53
|
+
if (!opts.yes) {
|
|
54
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
55
|
+
const answer = (await rl.question("Proceed? [y/N] ")).trim().toLowerCase();
|
|
56
|
+
rl.close();
|
|
57
|
+
if (answer !== "y" && answer !== "yes") {
|
|
58
|
+
ui.line(ui.dim("aborted — index unchanged"));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const existing = new Set(db
|
|
64
|
+
.getEmbeddings(root)
|
|
65
|
+
.filter((r) => r.embeddingModel === provider.modelName)
|
|
66
|
+
.map((r) => r.sessionId));
|
|
67
|
+
const target = opts.force
|
|
68
|
+
? rows
|
|
69
|
+
: rows.filter((r) => !existing.has(r.sessionId));
|
|
70
|
+
// Topics live in their own table, so backfill them here too — a compose
|
|
71
|
+
// while Ollama was down heals on a manual `vir embed`, not only the next
|
|
72
|
+
// `vir run` sweep. --force re-embeds all topics; otherwise just NULL ones.
|
|
73
|
+
const topicTargets = opts.force
|
|
74
|
+
? db.listTopics().map((t) => ({ id: t.id, content: t.content }))
|
|
75
|
+
: db.listTopicEmbeddingTargets();
|
|
76
|
+
// Articles live in their own table too — back-fill them here so a clip
|
|
77
|
+
// distilled while Ollama was down heals on a manual `vir embed`, not only
|
|
78
|
+
// the next `vir run` sweep. --force re-embeds all embeddable articles
|
|
79
|
+
// (keyed by source path); otherwise just the NULL-embedding ones.
|
|
80
|
+
const articleTargets = opts.force
|
|
81
|
+
? db.listArticles().map((a) => ({
|
|
82
|
+
path: a.path,
|
|
83
|
+
notePath: a.notePath,
|
|
84
|
+
content: a.content,
|
|
85
|
+
}))
|
|
86
|
+
: db.listArticleEmbeddingTargets();
|
|
87
|
+
// PDFs live in their own table too — same back-fill rationale as articles.
|
|
88
|
+
const pdfTargets = opts.force
|
|
89
|
+
? db.listPdfs().map((p) => ({
|
|
90
|
+
path: p.path,
|
|
91
|
+
notePath: p.notePath,
|
|
92
|
+
content: p.content,
|
|
93
|
+
}))
|
|
94
|
+
: db.listPdfEmbeddingTargets();
|
|
95
|
+
const total = target.length +
|
|
96
|
+
topicTargets.length +
|
|
97
|
+
articleTargets.length +
|
|
98
|
+
pdfTargets.length;
|
|
99
|
+
if (total === 0) {
|
|
100
|
+
ui.row(ui.success(ui.CHECK), ui.text("all notes already embedded"));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const sp = ui.spinner(`embedding notes (0/${total})`).start();
|
|
104
|
+
let embedded = 0;
|
|
105
|
+
let skipped = 0;
|
|
106
|
+
let errors = 0;
|
|
107
|
+
for (let i = 0; i < target.length; i += 1) {
|
|
108
|
+
const r = target[i];
|
|
109
|
+
if (!r)
|
|
110
|
+
continue;
|
|
111
|
+
if (r.content.trim().length === 0) {
|
|
112
|
+
skipped += 1;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const vec = await embedNoteWithProvider(provider, text.session(r.sessionId) ?? r.content);
|
|
116
|
+
if (!vec) {
|
|
117
|
+
errors += 1;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
db.storeEmbedding(r.sessionId, vec, provenance);
|
|
121
|
+
embedded += 1;
|
|
122
|
+
sp.text = ui.dim(`embedding notes (${embedded}/${total})`);
|
|
123
|
+
}
|
|
124
|
+
for (const t of topicTargets) {
|
|
125
|
+
if (!t.content || t.content.trim().length === 0) {
|
|
126
|
+
skipped += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const vec = await embedNoteWithProvider(provider, text.topic(t.id) ?? t.content);
|
|
130
|
+
if (!vec) {
|
|
131
|
+
errors += 1;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
db.storeTopicEmbedding(t.id, vec, provenance);
|
|
135
|
+
embedded += 1;
|
|
136
|
+
sp.text = ui.dim(`embedding notes (${embedded}/${total})`);
|
|
137
|
+
}
|
|
138
|
+
for (const a of articleTargets) {
|
|
139
|
+
if (!a.content || a.content.trim().length === 0) {
|
|
140
|
+
skipped += 1;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const vec = await embedNoteWithProvider(provider, (a.notePath ? text.file(a.notePath) : null) ?? a.content);
|
|
144
|
+
if (!vec) {
|
|
145
|
+
errors += 1;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
db.storeArticleEmbedding(a.path, vec, provenance);
|
|
149
|
+
embedded += 1;
|
|
150
|
+
sp.text = ui.dim(`embedding notes (${embedded}/${total})`);
|
|
151
|
+
}
|
|
152
|
+
for (const p of pdfTargets) {
|
|
153
|
+
if (!p.content || p.content.trim().length === 0) {
|
|
154
|
+
skipped += 1;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const vec = await embedNoteWithProvider(provider, (p.notePath ? text.file(p.notePath) : null) ?? p.content);
|
|
158
|
+
if (!vec) {
|
|
159
|
+
errors += 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
db.storePdfEmbedding(p.path, vec, provenance);
|
|
163
|
+
embedded += 1;
|
|
164
|
+
sp.text = ui.dim(`embedding notes (${embedded}/${total})`);
|
|
165
|
+
}
|
|
166
|
+
sp.succeed(ui.text(`embedded ${embedded} notes`));
|
|
167
|
+
ui.blank();
|
|
168
|
+
ui.divider();
|
|
169
|
+
ui.summary({
|
|
170
|
+
embedded: { value: embedded, color: ui.success },
|
|
171
|
+
skipped: { value: skipped, color: ui.muted },
|
|
172
|
+
errors: {
|
|
173
|
+
value: errors,
|
|
174
|
+
color: errors > 0 ? ui.errorColor : ui.dim,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
ui.divider();
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
db.close();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.js","sourceRoot":"","sources":["../../src/cli/embed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import confirm from "@inquirer/confirm";
|
|
2
|
+
import { acquireLock, LOCK_PATH, LockHeldError, releaseLock, } from "../pipeline/lock.js";
|
|
3
|
+
import * as ui from "../ui/display.js";
|
|
4
|
+
// Runs a command that writes notes or the DB while holding the pipeline lock,
|
|
5
|
+
// so it cannot race a daemon `vir run`. A held lock is reported and exits 1,
|
|
6
|
+
// the same as `vir run` and `vir reconcile`.
|
|
7
|
+
export async function withPipelineLock(fn, lockPath = LOCK_PATH) {
|
|
8
|
+
try {
|
|
9
|
+
acquireLock(lockPath);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
if (err instanceof LockHeldError) {
|
|
13
|
+
ui.row(ui.warn(ui.WARN_GLYPH), ui.text(err.message));
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
await fn();
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
releaseLock(lockPath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Gate for a paid LLM step. --yes proceeds; a terminal asks; with no terminal
|
|
27
|
+
// (cron, scripts) the step is skipped with a note rather than hanging on a
|
|
28
|
+
// prompt or spending without consent.
|
|
29
|
+
export async function confirmPaidStep(message, opts = {}) {
|
|
30
|
+
if (opts.yes === true)
|
|
31
|
+
return true;
|
|
32
|
+
const interactive = opts.interactive ?? process.stdin.isTTY === true;
|
|
33
|
+
if (!interactive) {
|
|
34
|
+
ui.line(ui.dim(` skipped: ${message} (pass --yes to run without a prompt)`));
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const ask = opts.ask ?? ((m) => confirm({ message: m, default: true }));
|
|
38
|
+
return ask(message);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/cli/guards.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAC;AACxC,OAAO,EACL,WAAW,EACX,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC,8EAA8E;AAC9E,6EAA6E;AAC7E,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAuB,EACvB,WAAmB,SAAS;IAE5B,IAAI,CAAC;QACH,WAAW,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,CAAC;IACb,CAAC;YAAS,CAAC;QACT,WAAW,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,2EAA2E;AAC3E,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,OAII,EAAE;IAEN,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;IACrE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,OAAO,uCAAuC,CAAC,CAAC,CAAC;QAC9E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GACP,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import confirm from "@inquirer/confirm";
|
|
2
|
+
import input from "@inquirer/input";
|
|
3
|
+
import select from "@inquirer/select";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { CONFIG_PATH, maskSecret, ConfigSchema, configExists, ensureVirDir, expandHome, loadConfig, saveConfig, } from "../config.js";
|
|
9
|
+
import { setupNotifications } from "./notificationsSetup.js";
|
|
10
|
+
import { categorizeTranscriptHead, classifyTranscript, estimateSessionCost, groupByProject, readTranscriptHead, } from "../pipeline/projects.js";
|
|
11
|
+
import { promptProjectDecisions } from "./projectSelect.js";
|
|
12
|
+
import { scanSessions } from "../pipeline/scanner.js";
|
|
13
|
+
import { normalizeModelName } from "../pipeline/distiller.js";
|
|
14
|
+
import { buildInitConfig } from "./initConfig.js";
|
|
15
|
+
import { installToClaudeCode } from "../mcp/install.js";
|
|
16
|
+
import * as ui from "../ui/display.js";
|
|
17
|
+
export async function cmdInit() {
|
|
18
|
+
ensureVirDir();
|
|
19
|
+
const existing = configExists() ? safeLoad() : null;
|
|
20
|
+
ui.header("init");
|
|
21
|
+
ui.blank();
|
|
22
|
+
// ── vault path ──────────────────────────────────────────────────────────
|
|
23
|
+
let vaultPath = "";
|
|
24
|
+
for (;;) {
|
|
25
|
+
vaultPath = await input({
|
|
26
|
+
message: "Obsidian vault path",
|
|
27
|
+
default: existing?.vaultPath ??
|
|
28
|
+
join(homedir(), "Documents", "Obsidian", "MyVault"),
|
|
29
|
+
});
|
|
30
|
+
const expanded = expandHome(vaultPath);
|
|
31
|
+
if (existsSync(expanded))
|
|
32
|
+
break;
|
|
33
|
+
const create = await confirm({
|
|
34
|
+
message: `Vault path does not exist (${expanded}). Create it?`,
|
|
35
|
+
default: true,
|
|
36
|
+
});
|
|
37
|
+
if (create) {
|
|
38
|
+
try {
|
|
39
|
+
mkdirSync(expanded, { recursive: true });
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(chalk.red(`failed to create: ${err.message}`));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const outputDir = await input({
|
|
48
|
+
message: "Output subdir inside vault",
|
|
49
|
+
default: existing?.outputDir ?? "vir",
|
|
50
|
+
});
|
|
51
|
+
// ── claude projects dir ─────────────────────────────────────────────────
|
|
52
|
+
let claudeProjectsDir = "";
|
|
53
|
+
for (;;) {
|
|
54
|
+
claudeProjectsDir = await input({
|
|
55
|
+
message: "Claude Code projects dir",
|
|
56
|
+
default: existing?.claudeProjectsDir ?? join(homedir(), ".claude", "projects"),
|
|
57
|
+
});
|
|
58
|
+
const expanded = expandHome(claudeProjectsDir);
|
|
59
|
+
if (existsSync(expanded))
|
|
60
|
+
break;
|
|
61
|
+
console.warn(chalk.yellow("directory not found — Claude Code sessions may not exist yet"));
|
|
62
|
+
const cont = await confirm({
|
|
63
|
+
message: "continue anyway?",
|
|
64
|
+
default: false,
|
|
65
|
+
});
|
|
66
|
+
if (cont)
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
// ── web articles (optional second input source) ─────────────────────────
|
|
70
|
+
let articlesDir = existing?.articlesDir;
|
|
71
|
+
const wantsArticles = await confirm({
|
|
72
|
+
message: "Do you save web articles to a folder (e.g. Obsidian Web Clipper)?",
|
|
73
|
+
default: existing?.articlesDir !== undefined,
|
|
74
|
+
});
|
|
75
|
+
if (wantsArticles) {
|
|
76
|
+
for (;;) {
|
|
77
|
+
articlesDir = await input({
|
|
78
|
+
message: "Articles (raw/) directory",
|
|
79
|
+
default: existing?.articlesDir ??
|
|
80
|
+
join(homedir(), "Documents", "Obsidian", "raw"),
|
|
81
|
+
});
|
|
82
|
+
const expanded = expandHome(articlesDir);
|
|
83
|
+
if (existsSync(expanded))
|
|
84
|
+
break;
|
|
85
|
+
const create = await confirm({
|
|
86
|
+
message: `Path does not exist (${expanded}). Create it?`,
|
|
87
|
+
default: true,
|
|
88
|
+
});
|
|
89
|
+
if (create) {
|
|
90
|
+
try {
|
|
91
|
+
mkdirSync(expanded, { recursive: true });
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
console.error(chalk.red(`failed to create: ${err.message}`));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
articlesDir = undefined;
|
|
105
|
+
}
|
|
106
|
+
// ── PDFs / papers (optional third input source) ──────────────────────────
|
|
107
|
+
let pdfsDir = existing?.pdfsDir;
|
|
108
|
+
const wantsPdfs = await confirm({
|
|
109
|
+
message: "Do you keep PDFs / papers in a folder to ingest?",
|
|
110
|
+
default: existing?.pdfsDir !== undefined,
|
|
111
|
+
});
|
|
112
|
+
if (wantsPdfs) {
|
|
113
|
+
for (;;) {
|
|
114
|
+
pdfsDir = await input({
|
|
115
|
+
message: "PDFs directory",
|
|
116
|
+
default: existing?.pdfsDir ?? join(homedir(), "Documents", "papers"),
|
|
117
|
+
});
|
|
118
|
+
const expanded = expandHome(pdfsDir);
|
|
119
|
+
if (existsSync(expanded))
|
|
120
|
+
break;
|
|
121
|
+
const create = await confirm({
|
|
122
|
+
message: `Path does not exist (${expanded}). Create it?`,
|
|
123
|
+
default: true,
|
|
124
|
+
});
|
|
125
|
+
if (create) {
|
|
126
|
+
try {
|
|
127
|
+
mkdirSync(expanded, { recursive: true });
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error(chalk.red(`failed to create: ${err.message}`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
pdfsDir = undefined;
|
|
141
|
+
}
|
|
142
|
+
const cadenceHours = Number(await input({
|
|
143
|
+
message: "Cadence (hours)",
|
|
144
|
+
default: String(existing?.cadenceHours ?? 3),
|
|
145
|
+
validate: (v) => {
|
|
146
|
+
const n = Number(v);
|
|
147
|
+
return Number.isFinite(n) && n > 0 ? true : "must be a positive number";
|
|
148
|
+
},
|
|
149
|
+
}));
|
|
150
|
+
// ── provider picker ─────────────────────────────────────────────────────
|
|
151
|
+
const provider = (await select({
|
|
152
|
+
message: "Provider",
|
|
153
|
+
default: existing?.provider ?? "anthropic",
|
|
154
|
+
choices: [
|
|
155
|
+
{
|
|
156
|
+
name: "Anthropic (API key — predictable per-session cost, no effect on your Claude Code limits)",
|
|
157
|
+
value: "anthropic",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: "Claude Code (subscription — free and keyless; distills consume your Claude Code usage limits)",
|
|
161
|
+
value: "claude-cli",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "Kie.ai (~72% cheaper API, third-party proxy — you trade reliability for cost)",
|
|
165
|
+
value: "kie",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
}));
|
|
169
|
+
// Secret prompt discipline: mask while typing, echo only a masked
|
|
170
|
+
// confirmation (maskSecret), and NEVER render the existing key as the
|
|
171
|
+
// visible inquirer default — that prints the full secret to the terminal
|
|
172
|
+
// before a single keystroke. Empty input keeps the existing/env key.
|
|
173
|
+
const promptSecret = async (message, keep, validate) => {
|
|
174
|
+
const value = await input({
|
|
175
|
+
message: keep
|
|
176
|
+
? `${message} (Enter keeps ${maskSecret(keep)})`
|
|
177
|
+
: message,
|
|
178
|
+
transformer: (v, { isFinal }) => isFinal ? maskSecret(v || keep || "") : "•".repeat(v.length),
|
|
179
|
+
validate: (v) => (v === "" && keep ? true : validate(v)),
|
|
180
|
+
});
|
|
181
|
+
return value === "" && keep ? keep : value;
|
|
182
|
+
};
|
|
183
|
+
let anthropicApiKey;
|
|
184
|
+
let kieApiKey;
|
|
185
|
+
if (provider === "anthropic") {
|
|
186
|
+
anthropicApiKey = await promptSecret("Anthropic API key", existing?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY ?? undefined, (v) => (v.startsWith("sk-ant-") ? true : "key should start with sk-ant-"));
|
|
187
|
+
}
|
|
188
|
+
else if (provider === "kie") {
|
|
189
|
+
kieApiKey = await promptSecret("Kie.ai API key", existing?.kieApiKey ?? process.env.KIE_API_KEY ?? undefined, (v) => (v.length > 10 ? true : "enter a valid Kie.ai API key"));
|
|
190
|
+
}
|
|
191
|
+
// claude-cli: no credential of any kind — it uses the `claude` login.
|
|
192
|
+
// ── model pickers (provider-aware) ──────────────────────────────────────
|
|
193
|
+
// claude-cli accepts the same full Anthropic model ids (and pins them per
|
|
194
|
+
// invocation via --model), so it shares the anthropic id set.
|
|
195
|
+
const classifyChoices = provider !== "kie"
|
|
196
|
+
? [
|
|
197
|
+
{
|
|
198
|
+
name: "claude-haiku-4-5-20251001 (recommended)",
|
|
199
|
+
value: "claude-haiku-4-5-20251001",
|
|
200
|
+
},
|
|
201
|
+
{ name: "claude-sonnet-4-6", value: "claude-sonnet-4-6" },
|
|
202
|
+
]
|
|
203
|
+
: [
|
|
204
|
+
{
|
|
205
|
+
name: "claude-haiku-4-5 (recommended)",
|
|
206
|
+
value: "claude-haiku-4-5",
|
|
207
|
+
},
|
|
208
|
+
{ name: "claude-sonnet-4-6", value: "claude-sonnet-4-6" },
|
|
209
|
+
];
|
|
210
|
+
const classifyModel = await select({
|
|
211
|
+
message: "Classify model (fast pass)",
|
|
212
|
+
choices: classifyChoices,
|
|
213
|
+
});
|
|
214
|
+
const distillChoices = provider !== "kie"
|
|
215
|
+
? [
|
|
216
|
+
{
|
|
217
|
+
name: "claude-sonnet-5 (recommended)",
|
|
218
|
+
value: "claude-sonnet-5",
|
|
219
|
+
},
|
|
220
|
+
{ name: "claude-sonnet-4-6", value: "claude-sonnet-4-6" },
|
|
221
|
+
{
|
|
222
|
+
name: "claude-haiku-4-5-20251001 (faster, cheaper)",
|
|
223
|
+
value: "claude-haiku-4-5-20251001",
|
|
224
|
+
},
|
|
225
|
+
]
|
|
226
|
+
: [
|
|
227
|
+
{
|
|
228
|
+
name: "claude-sonnet-4-6 (recommended)",
|
|
229
|
+
value: "claude-sonnet-4-6",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "claude-haiku-4-5 (faster, cheaper)",
|
|
233
|
+
value: "claude-haiku-4-5",
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
const distillModel = await select({
|
|
237
|
+
message: "Distill model (deep extraction)",
|
|
238
|
+
choices: distillChoices,
|
|
239
|
+
});
|
|
240
|
+
const filterThreshold = Number(await input({
|
|
241
|
+
message: "Filter threshold (0..1)",
|
|
242
|
+
default: String(existing?.filterThreshold ?? 0.4),
|
|
243
|
+
validate: (v) => {
|
|
244
|
+
const n = Number(v);
|
|
245
|
+
return Number.isFinite(n) && n >= 0 && n <= 1
|
|
246
|
+
? true
|
|
247
|
+
: "must be between 0 and 1";
|
|
248
|
+
},
|
|
249
|
+
}));
|
|
250
|
+
// ── project triage (the primary decision point) ─────────────────────────
|
|
251
|
+
// Every project found under the Claude projects dir is shown once with its
|
|
252
|
+
// session count and rough cost; selected = include, unselected = exclude.
|
|
253
|
+
// Projects that appear later start undecided and trigger the run prompt.
|
|
254
|
+
let projectDecisions = {};
|
|
255
|
+
let agentTranscriptsAnswer;
|
|
256
|
+
try {
|
|
257
|
+
const projectsDirX = expandHome(claudeProjectsDir);
|
|
258
|
+
const allFound = scanSessions(projectsDirX);
|
|
259
|
+
// Triage counts + the agent-transcript question. Only top-level
|
|
260
|
+
// transcripts count (nested workflow/sidechain have their own filter),
|
|
261
|
+
// and agent transcripts are excluded from the per-project multi-select
|
|
262
|
+
// numbers so the costs shown reflect what would actually distill.
|
|
263
|
+
const topLevel = allFound.filter((s) => classifyTranscript(s.path, projectsDirX) === "session");
|
|
264
|
+
const counts = { interactive: 0, agent: 0, stub: 0 };
|
|
265
|
+
const agentPaths = new Set();
|
|
266
|
+
for (const s of topLevel) {
|
|
267
|
+
const cat = categorizeTranscriptHead(readTranscriptHead(s.path), s.size);
|
|
268
|
+
counts[cat] += 1;
|
|
269
|
+
if (cat === "agent")
|
|
270
|
+
agentPaths.add(s.path);
|
|
271
|
+
}
|
|
272
|
+
if (counts.agent > 0) {
|
|
273
|
+
ui.blank();
|
|
274
|
+
ui.line(ui.dim(` ${counts.interactive} interactive · ${counts.agent} SDK-launched · ${counts.stub} stubs`));
|
|
275
|
+
agentTranscriptsAnswer = (await select({
|
|
276
|
+
message: "SDK-launched agent transcripts (review/verify harness output) — distill them?",
|
|
277
|
+
default: existing?.agentTranscripts ?? "exclude",
|
|
278
|
+
choices: [
|
|
279
|
+
{
|
|
280
|
+
name: "Exclude (recommended — agent-internal execution, not your decisions)",
|
|
281
|
+
value: "exclude",
|
|
282
|
+
},
|
|
283
|
+
{ name: "Include (distill them like any session)", value: "include" },
|
|
284
|
+
],
|
|
285
|
+
}));
|
|
286
|
+
}
|
|
287
|
+
const found = agentTranscriptsAnswer !== "include"
|
|
288
|
+
? topLevel.filter((s) => !agentPaths.has(s.path))
|
|
289
|
+
: topLevel;
|
|
290
|
+
const groups = [...groupByProject(found, projectsDirX).values()];
|
|
291
|
+
if (groups.length > 0) {
|
|
292
|
+
const classifyId = normalizeModelName(classifyModel, provider);
|
|
293
|
+
const distillId = normalizeModelName(distillModel, provider);
|
|
294
|
+
const infos = groups
|
|
295
|
+
.map((g) => ({
|
|
296
|
+
name: g.name,
|
|
297
|
+
sessionCount: g.sessions.length,
|
|
298
|
+
totalBytes: g.totalBytes,
|
|
299
|
+
estCost: g.sessions.reduce((sum, s) => sum +
|
|
300
|
+
estimateSessionCost(provider, classifyId, distillId, s.size), 0),
|
|
301
|
+
}))
|
|
302
|
+
.sort((a, b) => b.estCost - a.estCost);
|
|
303
|
+
ui.blank();
|
|
304
|
+
ui.line(ui.dim(" Which projects should vir distill? Costs are rough upper bounds."));
|
|
305
|
+
projectDecisions = await promptProjectDecisions(infos, existing?.projects ?? {}, "Projects to track");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
console.warn(chalk.yellow(`project scan failed (${err.message}) — you can decide later with vir projects`));
|
|
310
|
+
}
|
|
311
|
+
const parsed = ConfigSchema.safeParse(buildInitConfig(existing, {
|
|
312
|
+
vaultPath,
|
|
313
|
+
outputDir,
|
|
314
|
+
claudeProjectsDir,
|
|
315
|
+
cadenceHours,
|
|
316
|
+
provider,
|
|
317
|
+
anthropicApiKey,
|
|
318
|
+
kieApiKey,
|
|
319
|
+
filterThreshold,
|
|
320
|
+
articlesDir,
|
|
321
|
+
pdfsDir,
|
|
322
|
+
classifyModel,
|
|
323
|
+
distillModel,
|
|
324
|
+
projects: projectDecisions,
|
|
325
|
+
agentTranscripts: agentTranscriptsAnswer,
|
|
326
|
+
}));
|
|
327
|
+
if (!parsed.success) {
|
|
328
|
+
console.error(chalk.red("invalid config:"));
|
|
329
|
+
for (const issue of parsed.error.issues) {
|
|
330
|
+
console.error(` - ${issue.path.join(".")}: ${issue.message}`);
|
|
331
|
+
}
|
|
332
|
+
process.exitCode = 1;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
saveConfig(parsed.data);
|
|
336
|
+
ui.blank();
|
|
337
|
+
ui.row(ui.success(ui.CHECK), ui.text(`saved ${CONFIG_PATH}`));
|
|
338
|
+
ui.blank();
|
|
339
|
+
const wantsMcp = await confirm({
|
|
340
|
+
message: "Register Vir with Claude Code now? (recommended)",
|
|
341
|
+
default: true,
|
|
342
|
+
});
|
|
343
|
+
if (wantsMcp) {
|
|
344
|
+
await installToClaudeCode("user");
|
|
345
|
+
}
|
|
346
|
+
if (process.platform === "darwin" && parsed.data.notifications) {
|
|
347
|
+
ui.blank();
|
|
348
|
+
setupNotifications({ test: false });
|
|
349
|
+
}
|
|
350
|
+
ui.blank();
|
|
351
|
+
ui.line(ui.dim("next: `vir run` to test once, then `vir schedule install`"));
|
|
352
|
+
}
|
|
353
|
+
function safeLoad() {
|
|
354
|
+
try {
|
|
355
|
+
return loadConfig();
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|