vaan-ai 0.1.0

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.
Files changed (106) hide show
  1. package/LICENSE +216 -0
  2. package/README.md +390 -0
  3. package/dist/src/agent.js +151 -0
  4. package/dist/src/agent.js.map +1 -0
  5. package/dist/src/cli/args.js +38 -0
  6. package/dist/src/cli/args.js.map +1 -0
  7. package/dist/src/cli/doctor.js +98 -0
  8. package/dist/src/cli/doctor.js.map +1 -0
  9. package/dist/src/cli/dotenv.js +58 -0
  10. package/dist/src/cli/dotenv.js.map +1 -0
  11. package/dist/src/cli/main.js +138 -0
  12. package/dist/src/cli/main.js.map +1 -0
  13. package/dist/src/cli/memory-cmd.js +31 -0
  14. package/dist/src/cli/memory-cmd.js.map +1 -0
  15. package/dist/src/cli/repl.js +275 -0
  16. package/dist/src/cli/repl.js.map +1 -0
  17. package/dist/src/cli/schedule.js +184 -0
  18. package/dist/src/cli/schedule.js.map +1 -0
  19. package/dist/src/cli/suggested.js +26 -0
  20. package/dist/src/cli/suggested.js.map +1 -0
  21. package/dist/src/cli/trace-cmd.js +69 -0
  22. package/dist/src/cli/trace-cmd.js.map +1 -0
  23. package/dist/src/cli/wizard.js +346 -0
  24. package/dist/src/cli/wizard.js.map +1 -0
  25. package/dist/src/config.js +130 -0
  26. package/dist/src/config.js.map +1 -0
  27. package/dist/src/eval/graders.js +145 -0
  28. package/dist/src/eval/graders.js.map +1 -0
  29. package/dist/src/eval/report.js +20 -0
  30. package/dist/src/eval/report.js.map +1 -0
  31. package/dist/src/eval/runner.js +67 -0
  32. package/dist/src/eval/runner.js.map +1 -0
  33. package/dist/src/eval/suites.js +164 -0
  34. package/dist/src/eval/suites.js.map +1 -0
  35. package/dist/src/http.js +134 -0
  36. package/dist/src/http.js.map +1 -0
  37. package/dist/src/inbox.js +51 -0
  38. package/dist/src/inbox.js.map +1 -0
  39. package/dist/src/index.js +180 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/memory/context.js +63 -0
  42. package/dist/src/memory/context.js.map +1 -0
  43. package/dist/src/memory/index.js +28 -0
  44. package/dist/src/memory/index.js.map +1 -0
  45. package/dist/src/memory/search.js +32 -0
  46. package/dist/src/memory/search.js.map +1 -0
  47. package/dist/src/memory/store.js +171 -0
  48. package/dist/src/memory/store.js.map +1 -0
  49. package/dist/src/observability/events.js +109 -0
  50. package/dist/src/observability/events.js.map +1 -0
  51. package/dist/src/observability/request.js +20 -0
  52. package/dist/src/observability/request.js.map +1 -0
  53. package/dist/src/observability/trace.js +149 -0
  54. package/dist/src/observability/trace.js.map +1 -0
  55. package/dist/src/paths.js +24 -0
  56. package/dist/src/paths.js.map +1 -0
  57. package/dist/src/permissions/approval.js +80 -0
  58. package/dist/src/permissions/approval.js.map +1 -0
  59. package/dist/src/permissions/policy.js +75 -0
  60. package/dist/src/permissions/policy.js.map +1 -0
  61. package/dist/src/permissions/rules.js +200 -0
  62. package/dist/src/permissions/rules.js.map +1 -0
  63. package/dist/src/prompt.js +114 -0
  64. package/dist/src/prompt.js.map +1 -0
  65. package/dist/src/providers/anthropic.js +233 -0
  66. package/dist/src/providers/anthropic.js.map +1 -0
  67. package/dist/src/providers/custom.js +46 -0
  68. package/dist/src/providers/custom.js.map +1 -0
  69. package/dist/src/providers/google.js +197 -0
  70. package/dist/src/providers/google.js.map +1 -0
  71. package/dist/src/providers/index.js +122 -0
  72. package/dist/src/providers/index.js.map +1 -0
  73. package/dist/src/providers/ollama.js +44 -0
  74. package/dist/src/providers/ollama.js.map +1 -0
  75. package/dist/src/providers/openai.js +193 -0
  76. package/dist/src/providers/openai.js.map +1 -0
  77. package/dist/src/providers/shared.js +32 -0
  78. package/dist/src/providers/shared.js.map +1 -0
  79. package/dist/src/sandbox/filesystem.js +193 -0
  80. package/dist/src/sandbox/filesystem.js.map +1 -0
  81. package/dist/src/sandbox/network.js +119 -0
  82. package/dist/src/sandbox/network.js.map +1 -0
  83. package/dist/src/sandbox/process.js +198 -0
  84. package/dist/src/sandbox/process.js.map +1 -0
  85. package/dist/src/skills.js +80 -0
  86. package/dist/src/skills.js.map +1 -0
  87. package/dist/src/tools/basics.js +41 -0
  88. package/dist/src/tools/basics.js.map +1 -0
  89. package/dist/src/tools/code.js +114 -0
  90. package/dist/src/tools/code.js.map +1 -0
  91. package/dist/src/tools/files.js +162 -0
  92. package/dist/src/tools/files.js.map +1 -0
  93. package/dist/src/tools/git.js +91 -0
  94. package/dist/src/tools/git.js.map +1 -0
  95. package/dist/src/tools/grep.js +92 -0
  96. package/dist/src/tools/grep.js.map +1 -0
  97. package/dist/src/tools/index.js +66 -0
  98. package/dist/src/tools/index.js.map +1 -0
  99. package/dist/src/tools/shared.js +11 -0
  100. package/dist/src/tools/shared.js.map +1 -0
  101. package/dist/src/tools/web.js +217 -0
  102. package/dist/src/tools/web.js.map +1 -0
  103. package/dist/src/types.js +14 -0
  104. package/dist/src/types.js.map +1 -0
  105. package/package.json +59 -0
  106. package/scripts/postinstall.js +47 -0
@@ -0,0 +1,151 @@
1
+ // The loop. Read this first.
2
+ //
3
+ // A language model can't do anything. It only produces text. When it "reads a
4
+ // file" it emits a request saying *please run read_file on agent.ts*. This
5
+ // function runs the read, hands the result back, and asks again.
6
+ //
7
+ // Five things it guards, marked GUARD below. Each one is a bug you only find in
8
+ // production: reasoning must round-trip, tool calls arrive in parallel, tool
9
+ // errors are data, not every stop is a stop, and a refused permission is an
10
+ // answer rather than a crash.
11
+ //
12
+ // What the loop does *not* do is decide anything about safety. It doesn't know
13
+ // what a workspace is, whether a path is allowed, or who approves a command.
14
+ // Tools ask the gate; the gate asks a human. Keeping that out of here is why
15
+ // this file stays readable.
16
+ import { PermissionDenied } from "./permissions/approval.js";
17
+ const DEFAULT_MAX_STEPS = 12;
18
+ const DEFAULT_MAX_TOKENS = 4096;
19
+ /** Answer one prompt. */
20
+ export function runAgent(prompt, opts) {
21
+ const first = { role: "user", parts: [{ type: "text", text: prompt }] };
22
+ return continueAgent([first], opts);
23
+ }
24
+ /** The same loop, resuming a transcript. The REPL uses this from turn two on. */
25
+ export async function continueAgent(messages, opts) {
26
+ const { model, system, tools, ctx, signal, trace } = opts;
27
+ const usedTools = [];
28
+ const maxSteps = opts.maxSteps ?? DEFAULT_MAX_STEPS;
29
+ let maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
30
+ let raisedCap = false;
31
+ let usage;
32
+ let steps = 0;
33
+ for (let step = 0; step < maxSteps; step++) {
34
+ steps = step + 1;
35
+ const request = { model, system, tools, messages, maxTokens, ...(signal ? { signal } : {}) };
36
+ const reply = opts.stream
37
+ ? await consume(opts.provider.stream(request), opts.onEvent)
38
+ : await opts.provider.generate(request);
39
+ if (reply.usage) {
40
+ usage = {
41
+ input: (usage?.input ?? 0) + reply.usage.input,
42
+ output: (usage?.output ?? 0) + reply.usage.output,
43
+ };
44
+ }
45
+ trace?.record({
46
+ kind: "model_call",
47
+ provider: opts.provider.name,
48
+ model,
49
+ ...(reply.usage ? { tokensIn: reply.usage.input, tokensOut: reply.usage.output } : {}),
50
+ });
51
+ // GUARD 4a. Truncated mid-turn. Whatever we got is half-written — a tool
52
+ // call with an unparseable input, a sentence that stops dead — so throw it
53
+ // away rather than append it, raise the cap, and ask again unchanged.
54
+ if (reply.stop === "max_tokens" && !raisedCap) {
55
+ raisedCap = true;
56
+ maxTokens *= 2;
57
+ continue;
58
+ }
59
+ // GUARD 1. Push the provider's own message object, never one we rebuilt
60
+ // from `parts`. `raw` rides along inside it, so signed reasoning blocks go
61
+ // back byte-for-byte on the next request instead of being dropped.
62
+ messages.push(reply.message);
63
+ // GUARD 4b. `pause_turn` is neither an answer nor an error. The provider
64
+ // is asking for the same history back so it can pick up where it stopped.
65
+ if (reply.stop === "pause")
66
+ continue;
67
+ const text = textOf(reply.message);
68
+ if (text && !opts.stream)
69
+ opts.onEvent?.({ type: "text", text });
70
+ const calls = reply.message.parts.filter(isToolCall);
71
+ if (calls.length === 0)
72
+ return { text, messages, usedTools, steps, ...(usage ? { usage } : {}) };
73
+ // GUARD 2. One turn can carry several calls. Run them together, then put
74
+ // every result in the *single* next message, each keyed by its call id.
75
+ // Split them across two messages and the provider rejects the turn.
76
+ const results = await Promise.all(calls.map(async (call) => {
77
+ // Recorded before it runs: the trajectory grader asks what the model
78
+ // reached for, and a tool that failed was still a tool it reached for.
79
+ usedTools.push(call.name);
80
+ opts.onEvent?.({ type: "tool_call", name: call.name, input: call.input });
81
+ trace?.record({ kind: "tool_call", tool: call.name, input: call.input });
82
+ const part = await runTool(call, tools, ctx);
83
+ const { output, isError } = part;
84
+ opts.onEvent?.({ type: "tool_result", name: call.name, output, isError });
85
+ trace?.record({
86
+ kind: "tool_result",
87
+ tool: call.name,
88
+ ok: !isError,
89
+ summary: output.split("\n")[0] ?? "",
90
+ });
91
+ return part;
92
+ }));
93
+ messages.push({ role: "user", parts: results });
94
+ }
95
+ const text = `Stopped after ${maxSteps} steps without reaching an answer.`;
96
+ trace?.record({ kind: "error", where: "agent", message: text });
97
+ return { text, messages, usedTools, steps, ...(usage ? { usage } : {}) };
98
+ }
99
+ /** Drain a streamed turn, forwarding deltas, and hand back the assembled reply. */
100
+ async function consume(events, onEvent) {
101
+ let reply;
102
+ for await (const event of events) {
103
+ if (event.type === "text")
104
+ onEvent?.({ type: "delta", text: event.text });
105
+ else if (event.type === "done")
106
+ reply = event.reply;
107
+ }
108
+ if (!reply)
109
+ throw new Error("The provider's stream ended without finishing the turn.");
110
+ return reply;
111
+ }
112
+ /**
113
+ * GUARD 3. A tool that throws is information, not a crash. The failure goes
114
+ * back to the model flagged as an error so it can recover — a missing file
115
+ * usually means it should try a different path, not that the run is over.
116
+ *
117
+ * GUARD 5. A refused permission is the same kind of information, and the
118
+ * wording matters: the model has to understand that the answer was no and that
119
+ * asking again the same way will get the same no. It is not a transient error
120
+ * to retry, and it is not a reason to look for another route to the same place.
121
+ */
122
+ async function runTool(call, tools, ctx) {
123
+ const tool = tools.find((candidate) => candidate.name === call.name);
124
+ if (!tool)
125
+ return toolResult(call.id, `No tool named "${call.name}".`, true);
126
+ try {
127
+ return toolResult(call.id, await tool.run(asRecord(call.input), ctx), false);
128
+ }
129
+ catch (err) {
130
+ if (err instanceof PermissionDenied) {
131
+ return toolResult(call.id, `${err.message}. The user was asked and the answer was no — don't retry this or ` +
132
+ `look for another way to do it. Tell them what you needed and why.`, true);
133
+ }
134
+ return toolResult(call.id, `${call.name} failed: ${describe(err)}`, true);
135
+ }
136
+ }
137
+ const toolResult = (id, output, isError) => ({
138
+ type: "tool_result",
139
+ id,
140
+ output,
141
+ isError,
142
+ });
143
+ const isToolCall = (part) => part.type === "tool_call";
144
+ const textOf = (message) => message.parts
145
+ .filter((part) => part.type === "text")
146
+ .map((part) => part.text)
147
+ .join("")
148
+ .trim();
149
+ const asRecord = (input) => input !== null && typeof input === "object" ? input : {};
150
+ const describe = (err) => (err instanceof Error ? err.message : String(err));
151
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ // Argument parsing, extracted so it can be tested.
2
+ //
3
+ // It lived inline in main.ts and had a bug that every unit test missed: with
4
+ // no `--model` flag, `indexOf` returns -1, so `argv[index + 1]` read argv[0]
5
+ // and swallowed the command. `vaan memory` silently became `vaan`. Hence this
6
+ // file, and test/cli.test.ts.
7
+ /** Flags that take a value, so the value is never mistaken for the command. */
8
+ const VALUED = ["--model", "--workspace"];
9
+ export function parseArgs(argv) {
10
+ const flags = new Set(argv.filter((arg) => arg.startsWith("-")));
11
+ // Track each valued flag's *position*, not just its value: -1 means the flag
12
+ // is absent, and index 0 is a perfectly good place for a command to be.
13
+ const consumed = new Set();
14
+ const values = {};
15
+ for (const flag of VALUED) {
16
+ const at = argv.indexOf(flag);
17
+ if (at === -1)
18
+ continue;
19
+ consumed.add(at + 1);
20
+ values[flag] = argv[at + 1];
21
+ }
22
+ const positionals = argv.filter((arg, index) => !arg.startsWith("-") && !consumed.has(index));
23
+ const [command = "repl", ...rest] = positionals;
24
+ const model = values["--model"];
25
+ const workspace = values["--workspace"];
26
+ return {
27
+ command,
28
+ rest,
29
+ ...(model ? { model } : {}),
30
+ ...(workspace ? { workspace } : {}),
31
+ yes: flags.has("--yes") || flags.has("-y"),
32
+ memory: !flags.has("--no-memory"),
33
+ trace: !flags.has("--no-trace"),
34
+ help: flags.has("--help") || flags.has("-h") || command === "help",
35
+ version: flags.has("--version") || flags.has("-v"),
36
+ };
37
+ }
38
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/cli/args.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,8BAA8B;AAE9B,+EAA+E;AAC/E,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,aAAa,CAAU,CAAC;AAgBnD,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEjE,6EAA6E;IAC7E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAAuC,EAAE,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAC7D,CAAC;IACF,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC;IAEhD,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IAExC,OAAO;QACL,OAAO;QACP,IAAI;QACJ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;QACjC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,MAAM;QAClE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;KACnD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,98 @@
1
+ // `vaan doctor` — is this install actually going to work.
2
+ //
3
+ // Every check answers a question a user would otherwise discover three turns
4
+ // into a conversation: is FTS5 there, is a key set, does the config parse, are
5
+ // the two groups that ship empty actually empty. It never calls a model: a
6
+ // diagnostic that costs money and needs the network is one people won't run.
7
+ import { existsSync } from "node:fs";
8
+ import { defaultConfig, describeConfig, loadConfig } from "../config.js";
9
+ import { probeFts5 } from "../memory/store.js";
10
+ import { describeRules } from "../permissions/policy.js";
11
+ import { defaultRules } from "../permissions/rules.js";
12
+ import { configFile, databaseFile, home, skillsDir } from "../paths.js";
13
+ import { statuses } from "../providers/index.js";
14
+ import { loadSkills } from "../skills.js";
15
+ import { GROUPS } from "../tools/index.js";
16
+ import { listTraces } from "../observability/trace.js";
17
+ /** Returns the exit code: non-zero when something is actually broken. */
18
+ export function runDoctor(out, opts) {
19
+ const problems = [];
20
+ const line = (ok, text) => {
21
+ out.write(` ${ok === undefined ? " " : ok ? "✓" : "✗"} ${text}\n`);
22
+ };
23
+ out.write("\n environment\n\n");
24
+ line(true, `node ${process.version} on ${process.platform}`);
25
+ line(true, `workspace ${opts.workspace}`);
26
+ out.write("\n memory\n\n");
27
+ const fts = probeFts5();
28
+ if (fts) {
29
+ problems.push("SQLite has no FTS5");
30
+ line(false, `SQLite is missing FTS5 — ${fts}`);
31
+ line(undefined, "fix: npm install better-sqlite3 --build-from-source");
32
+ }
33
+ else {
34
+ line(true, "SQLite with FTS5");
35
+ }
36
+ line(existsSync(databaseFile(opts.workspace)) || undefined, existsSync(databaseFile(opts.workspace))
37
+ ? `database at ${databaseFile(opts.workspace)}`
38
+ : "no database yet — it's created on the first turn");
39
+ out.write("\n providers\n\n");
40
+ const ready = statuses(opts.env);
41
+ for (const spec of ready) {
42
+ const key = spec.envKey ? `${spec.envKey} ${spec.ready ? "set" : "missing"}` : "no key needed";
43
+ line(spec.ready, `${spec.name.padEnd(12)} ${key}`);
44
+ }
45
+ if (!ready.some((spec) => spec.ready)) {
46
+ problems.push("no provider is usable");
47
+ }
48
+ out.write("\n configuration\n\n");
49
+ const config = loadConfig(opts.workspace);
50
+ if (!config) {
51
+ line(false, `no config at ${configFile(opts.workspace)} — run \`vaan init\``);
52
+ problems.push("not configured");
53
+ }
54
+ else {
55
+ line(true, "config parses");
56
+ for (const entry of describeConfig(config))
57
+ line(undefined, entry);
58
+ }
59
+ out.write("\n permissions\n\n");
60
+ for (const entry of describeRules(config ? defaultRules(config.approvals) : defaultRules())) {
61
+ line(undefined, entry);
62
+ }
63
+ line(undefined, "credentials and system changes are denied by fixed policy, always");
64
+ out.write("\n tools\n\n");
65
+ // With no config yet, report what would actually run rather than "off":
66
+ // an unconfigured install still has defaults, and saying otherwise sends
67
+ // people looking for a problem that isn't there.
68
+ const enabled = new Set(config?.tools ?? defaultConfig(opts.workspace).tools);
69
+ for (const group of GROUPS) {
70
+ const state = !group.available
71
+ ? "not configured in this build"
72
+ : enabled.has(group.group)
73
+ ? "on"
74
+ : "off";
75
+ line(group.available && enabled.has(group.group), `${group.label.padEnd(22)} ${state}`);
76
+ }
77
+ const { skills, warnings } = loadSkills(opts.workspace);
78
+ out.write("\n skills\n\n");
79
+ if (skills.length === 0) {
80
+ line(undefined, `none — drop a SKILL.md in ${skillsDir(opts.workspace)}`);
81
+ }
82
+ else {
83
+ for (const skill of skills)
84
+ line(true, `${skill.name.padEnd(22)} ${skill.path}`);
85
+ }
86
+ for (const warning of warnings)
87
+ line(false, warning);
88
+ out.write("\n traces\n\n");
89
+ const traces = listTraces(home(opts.workspace), 1);
90
+ line(undefined, traces.length === 0
91
+ ? "none yet — written to .vaan/traces after each request"
92
+ : `most recent ${traces[0]?.at ?? ""}`);
93
+ out.write(problems.length === 0
94
+ ? "\n all clear\n\n"
95
+ : `\n ${problems.length} problem${problems.length === 1 ? "" : "s"}: ${problems.join(", ")}\n\n`);
96
+ return problems.length === 0 ? 0 : 1;
97
+ }
98
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ // A very small .env reader. Node has --env-file, but that only helps if the
2
+ // user remembers to pass it, and `npx vaan` gives them nowhere to put it.
3
+ //
4
+ // Values already in the real environment win, so an exported key always beats
5
+ // a stale one in the file.
6
+ import { readFileSync, writeFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ export function loadEnv(cwd, env = process.env) {
9
+ for (const [key, value] of Object.entries(parseEnv(read(join(cwd, ".env"))))) {
10
+ if (env[key] === undefined)
11
+ env[key] = value;
12
+ }
13
+ }
14
+ export function parseEnv(text) {
15
+ const out = {};
16
+ for (const raw of text.split("\n")) {
17
+ const line = raw.trim();
18
+ if (!line || line.startsWith("#"))
19
+ continue;
20
+ const eq = line.indexOf("=");
21
+ if (eq <= 0)
22
+ continue;
23
+ const key = line.slice(0, eq).trim();
24
+ const value = line.slice(eq + 1).trim();
25
+ out[key] = /^(".*"|'.*')$/s.test(value) ? value.slice(1, -1) : value;
26
+ }
27
+ return out;
28
+ }
29
+ /** Add or replace keys in .env, leaving comments and unrelated keys alone. */
30
+ export function updateEnvFile(cwd, updates) {
31
+ const path = join(cwd, ".env");
32
+ const lines = read(path).split("\n");
33
+ const remaining = { ...updates };
34
+ const merged = lines.map((line) => {
35
+ const eq = line.indexOf("=");
36
+ if (line.trim().startsWith("#") || eq <= 0)
37
+ return line;
38
+ const key = line.slice(0, eq).trim();
39
+ if (!(key in remaining))
40
+ return line;
41
+ const value = remaining[key];
42
+ delete remaining[key];
43
+ return `${key}=${value}`;
44
+ });
45
+ const added = Object.entries(remaining).map(([key, value]) => `${key}=${value}`);
46
+ const body = [...merged, ...added].join("\n").replace(/\n{3,}/g, "\n\n").trimEnd();
47
+ writeFileSync(path, `${body}\n`, "utf8");
48
+ return path;
49
+ }
50
+ function read(path) {
51
+ try {
52
+ return readFileSync(path, "utf8");
53
+ }
54
+ catch {
55
+ return "";
56
+ }
57
+ }
58
+ //# sourceMappingURL=dotenv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotenv.js","sourceRoot":"","sources":["../../../src/cli/dotenv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ // Entry point. Seven commands, and the bare one is the REPL.
3
+ import { resolve } from "node:path";
4
+ import { defaultConfig, loadConfig } from "../config.js";
5
+ import { printReport } from "../eval/report.js";
6
+ import { runEvals } from "../eval/runner.js";
7
+ import { openMemory } from "../memory/store.js";
8
+ import { parseArgs } from "./args.js";
9
+ import { runDoctor } from "./doctor.js";
10
+ import { loadEnv } from "./dotenv.js";
11
+ import { printMemory } from "./memory-cmd.js";
12
+ import { runRepl } from "./repl.js";
13
+ import { addSchedule, printSchedules, removeSchedule, runSchedule } from "./schedule.js";
14
+ import { printTrace, printTraceList } from "./trace-cmd.js";
15
+ import { runWizard, VERSION } from "./wizard.js";
16
+ const HELP = `
17
+ Vaan ${VERSION}
18
+
19
+ vaan start the REPL
20
+ vaan init run setup again
21
+ vaan memory print facts and recent turns
22
+ vaan trace [id] list requests, or show one in full
23
+ vaan doctor check this install
24
+ vaan eval run the suites, exit non-zero if they fail
25
+ vaan schedule list, add, remove or run a scheduled task
26
+
27
+ options
28
+
29
+ --model <spec> provider/model for this run, e.g. anthropic/claude-opus-5
30
+ --workspace <path> work somewhere other than the current directory
31
+ --no-memory don't read or write memory this session
32
+ --no-trace don't write a trace file this session
33
+ --yes grant every permission without asking
34
+ --help, --version
35
+
36
+ In the REPL: /model /new /memory /forget /inbox /status /trace /settings /exit
37
+ `;
38
+ async function main(argv) {
39
+ const out = process.stdout;
40
+ const args = parseArgs(argv);
41
+ const workspace = resolve(args.workspace ?? process.cwd());
42
+ loadEnv(workspace);
43
+ if (args.help) {
44
+ out.write(HELP);
45
+ return 0;
46
+ }
47
+ if (args.version) {
48
+ out.write(`${VERSION}\n`);
49
+ return 0;
50
+ }
51
+ const stored = loadConfig(workspace);
52
+ // Precedence: the flag, then the environment, then what setup decided.
53
+ const model = args.model ?? process.env.VAAN_MODEL ?? stored?.model;
54
+ switch (args.command) {
55
+ case "memory": {
56
+ const store = openMemory({ dir: workspace, turnLimit: 10 });
57
+ printMemory(out, await store.recall(workspace, ""));
58
+ store.close?.();
59
+ return 0;
60
+ }
61
+ case "trace":
62
+ return args.rest[0]
63
+ ? printTrace(out, workspace, args.rest[0])
64
+ : printTraceList(out, workspace);
65
+ case "doctor":
66
+ return runDoctor(out, {
67
+ workspace,
68
+ env: process.env,
69
+ ...(model ? { model } : {}),
70
+ });
71
+ case "eval": {
72
+ if (!model)
73
+ return unconfigured(out);
74
+ const report = await runEvals({ workspace, model, env: process.env });
75
+ printReport(out, report);
76
+ return report.passed ? 0 : 1;
77
+ }
78
+ case "schedule": {
79
+ const [sub, id] = args.rest;
80
+ if (!sub)
81
+ return printSchedules(out, workspace);
82
+ if (sub === "add")
83
+ return addSchedule(out, workspace);
84
+ if (sub === "remove" && id)
85
+ return removeSchedule(out, workspace, id);
86
+ if (sub === "run" && id) {
87
+ if (!model)
88
+ return unconfigured(out);
89
+ return runSchedule(out, id, { workspace, env: process.env, model, yes: args.yes });
90
+ }
91
+ out.write("\n vaan schedule [add | run <id> | remove <id>]\n\n");
92
+ return 1;
93
+ }
94
+ case "repl":
95
+ case "init":
96
+ break;
97
+ default:
98
+ out.write(`\n Unknown command "${args.command}".\n${HELP}`);
99
+ return 1;
100
+ }
101
+ // Setup needs a person at the keyboard. Say so and leave, rather than
102
+ // blocking forever on a prompt that nothing is going to answer.
103
+ const needsSetup = args.command === "init" || !model;
104
+ if (!process.stdin.isTTY && (needsSetup ? !args.yes : true)) {
105
+ out.write(needsSetup
106
+ ? "\n Vaan needs a terminal to set up. Run it interactively, or pass --yes with\n" +
107
+ " VAAN_MODEL and an API key already in the environment.\n\n"
108
+ : "\n Vaan is a REPL and needs a terminal. It doesn't read piped input.\n\n");
109
+ return 1;
110
+ }
111
+ let config = stored ?? defaultConfig(workspace, model ?? "");
112
+ if (needsSetup) {
113
+ const result = await runWizard({ cwd: workspace, yes: args.yes, env: process.env });
114
+ if (!result)
115
+ return 1;
116
+ config = result.config;
117
+ if (args.command === "init")
118
+ return 0;
119
+ }
120
+ return runRepl({
121
+ workspace: config.workspace,
122
+ model: args.model ?? config.model,
123
+ config,
124
+ memory: args.memory && config.memory,
125
+ yes: args.yes,
126
+ trace: args.trace,
127
+ env: process.env,
128
+ });
129
+ }
130
+ function unconfigured(out) {
131
+ out.write("\n No model configured. Run `vaan init` first.\n\n");
132
+ return 1;
133
+ }
134
+ main(process.argv.slice(2)).then((code) => process.exit(code), (err) => {
135
+ process.stderr.write(`\n ${err instanceof Error ? err.message : String(err)}\n\n`);
136
+ process.exit(1);
137
+ });
138
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ // `vaan memory`, and the /memory slash command. Both print the same thing:
2
+ // what's injected on every turn, then what's sitting in the searchable tier.
3
+ export function printMemory(out, recall) {
4
+ out.write("\n facts — sent with every message\n\n");
5
+ if (recall.facts.length === 0) {
6
+ out.write(" (none yet)\n");
7
+ }
8
+ else {
9
+ for (const fact of recall.facts) {
10
+ out.write(` ${String(fact.id).padStart(3)} ${fact.text}\n`);
11
+ }
12
+ }
13
+ out.write("\n recent turns — searched, not injected\n\n");
14
+ if (recall.turns.length === 0) {
15
+ out.write(" (none yet)\n");
16
+ }
17
+ else {
18
+ for (const turn of recall.turns) {
19
+ const tools = turn.tools.length > 0 ? ` [${turn.tools.join(", ")}]` : "";
20
+ out.write(` ${turn.ts.slice(0, 16).replace("T", " ")}${tools}\n`);
21
+ out.write(` ${clip(turn.userText)}\n`);
22
+ out.write(` ${clip(turn.replyText)}\n\n`);
23
+ }
24
+ }
25
+ out.write("\n");
26
+ }
27
+ const clip = (text) => {
28
+ const line = text.replace(/\s+/g, " ").trim();
29
+ return line.length <= 96 ? line : `${line.slice(0, 96)}…`;
30
+ };
31
+ //# sourceMappingURL=memory-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-cmd.js","sourceRoot":"","sources":["../../../src/cli/memory-cmd.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAI7E,MAAM,UAAU,WAAW,CAAC,GAAuB,EAAE,MAAc;IACjE,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,GAAG,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;YACrE,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;AAC5D,CAAC,CAAC"}