@vextlabs/theron-cli 0.1.1 → 0.2.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.
@@ -0,0 +1,194 @@
1
+ // slash_commands — custom user-defined slash commands.
2
+ //
3
+ // Theron's analogue to Claude Code's project/personal slash commands.
4
+ // Each `foo.md` in a commands directory becomes `/foo`: typing it (with
5
+ // optional arguments) sends the file's body as that turn's prompt, with
6
+ // $ARGUMENTS / $1 / $2 / … substituted.
7
+ //
8
+ // Resolution (mirrors cap_config.ts's two-tier overlay):
9
+ // 1. Global — ~/.theron/commands/*.md (your cross-project commands)
10
+ // 2. Project — <cwd>/.theron/commands/*.md (this repo's commands)
11
+ //
12
+ // Project wins on a name collision so a repo can override a global
13
+ // command. The command name is the FILE basename (minus `.md`),
14
+ // lowercased. Names that collide with a built-in slash command are
15
+ // rejected at load time so a custom `clear.md` can never shadow the
16
+ // real /clear — the built-in checks run first in the REPL dispatch and
17
+ // the guard here keeps the help listing honest too.
18
+ //
19
+ // Pure client-side, never-throws: a malformed commands dir degrades to
20
+ // "no custom commands" rather than breaking the REPL.
21
+ import fs from "node:fs";
22
+ import path from "node:path";
23
+ import process from "node:process";
24
+ /** Max bytes of a command body we keep. A runaway command file
25
+ * shouldn't blow the request body; mirrors project_memory's cap. */
26
+ const MAX_COMMAND_BYTES = 32 * 1024;
27
+ /** Built-in slash command names a custom command MUST NOT shadow. These
28
+ * are the leading tokens (without the `/`) of every built-in handled in
29
+ * repl.ts BEFORE the custom-command branch. Keeping this list in sync
30
+ * with the REPL is the one coupling point — a custom command named any
31
+ * of these is rejected at load so the built-in always wins. */
32
+ export const RESERVED_SLASH_NAMES = new Set([
33
+ "quit", "exit", "help", "status", "memory", "mode", "clear", "yolo",
34
+ "cwd", "cd", "cap", "tools", "suggest", "pin", "unpin", "login",
35
+ "logout", "connections", "integrations", "model", "readiness",
36
+ "innovate", "design", "deck", "draft", "research", "proposal", "bug",
37
+ // Built-ins added by the parity features:
38
+ "plan", "render", "commands", "resume", "continue", "sessions",
39
+ ]);
40
+ /** Read a UTF-8 file, returning null on any error. Never throws. */
41
+ function readSafe(filePath) {
42
+ try {
43
+ const st = fs.statSync(filePath);
44
+ if (!st.isFile())
45
+ return null;
46
+ return fs.readFileSync(filePath, "utf8");
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /** List `*.md` files in a directory, returning [] on any error. */
53
+ function listMarkdown(dir) {
54
+ try {
55
+ return fs
56
+ .readdirSync(dir)
57
+ .filter((f) => f.toLowerCase().endsWith(".md"))
58
+ .map((f) => path.join(dir, f));
59
+ }
60
+ catch {
61
+ return [];
62
+ }
63
+ }
64
+ /**
65
+ * Strip an optional leading frontmatter block and pull out a
66
+ * `description:` line if present. Supports the conventional
67
+ *
68
+ * ---
69
+ * description: One-line summary
70
+ * ---
71
+ * <body…>
72
+ *
73
+ * fenced form. If the file does not start with `---`, the whole file is
74
+ * the body and there is no description. Never throws.
75
+ */
76
+ function parseFrontmatter(raw) {
77
+ const text = raw.replace(/^/, ""); // strip BOM
78
+ // Normalize to \n for the fence match; keep original line breaks in body.
79
+ const lines = text.split(/\r?\n/);
80
+ if (lines[0]?.trim() !== "---") {
81
+ return { body: text.trim() };
82
+ }
83
+ // Find the closing fence.
84
+ let close = -1;
85
+ for (let i = 1; i < lines.length; i++) {
86
+ if (lines[i].trim() === "---") {
87
+ close = i;
88
+ break;
89
+ }
90
+ }
91
+ if (close === -1) {
92
+ // Unterminated frontmatter — treat the whole file as body so the
93
+ // user still gets their prompt rather than silent loss.
94
+ return { body: text.trim() };
95
+ }
96
+ let description;
97
+ for (let i = 1; i < close; i++) {
98
+ const m = /^\s*description\s*:\s*(.+?)\s*$/i.exec(lines[i]);
99
+ if (m) {
100
+ description = m[1].replace(/^["']|["']$/g, "").trim() || undefined;
101
+ break;
102
+ }
103
+ }
104
+ const body = lines.slice(close + 1).join("\n").trim();
105
+ return { body, description };
106
+ }
107
+ /** Clamp a body to MAX_COMMAND_BYTES on a UTF-8 boundary. */
108
+ function clampBytes(text) {
109
+ const buf = Buffer.from(text, "utf8");
110
+ if (buf.length <= MAX_COMMAND_BYTES)
111
+ return text;
112
+ return buf.subarray(0, MAX_COMMAND_BYTES).toString("utf8");
113
+ }
114
+ /** Resolve the global commands dir, or null when HOME is unset. */
115
+ function globalCommandsDir() {
116
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
117
+ return home ? path.join(home, ".theron", "commands") : null;
118
+ }
119
+ /**
120
+ * Load custom slash commands for a working directory. Global first, then
121
+ * the project overlay (project wins on name collision). Commands whose
122
+ * name collides with a built-in slash command are skipped so they can
123
+ * never shadow a built-in.
124
+ *
125
+ * Always returns a value; on any failure the map is simply smaller.
126
+ */
127
+ export function loadCustomCommands(cwd = process.cwd()) {
128
+ const map = new Map();
129
+ const dirs = [];
130
+ const ingest = (dir, source) => {
131
+ const files = listMarkdown(dir);
132
+ if (files.length === 0) {
133
+ // Only record the dir if it actually exists (so /commands shows
134
+ // real scanned locations).
135
+ try {
136
+ if (fs.statSync(dir).isDirectory())
137
+ dirs.push(dir);
138
+ }
139
+ catch { /* skip */ }
140
+ return;
141
+ }
142
+ dirs.push(dir);
143
+ for (const file of files) {
144
+ const raw = readSafe(file);
145
+ if (raw === null)
146
+ continue;
147
+ const name = path.basename(file).replace(/\.md$/i, "").toLowerCase().trim();
148
+ if (!name)
149
+ continue;
150
+ // Reject names that would shadow a built-in. Project commands
151
+ // still can't shadow built-ins — that protects /clear etc.
152
+ if (RESERVED_SLASH_NAMES.has(name))
153
+ continue;
154
+ // Only allow safe command names so `/<name>` parsing stays simple
155
+ // and a filename can't smuggle whitespace/slashes.
156
+ if (!/^[a-z0-9][a-z0-9_-]*$/.test(name))
157
+ continue;
158
+ const { body, description } = parseFrontmatter(raw);
159
+ if (!body)
160
+ continue;
161
+ map.set(name, { name, body: clampBytes(body), description, source, file });
162
+ }
163
+ };
164
+ const gdir = globalCommandsDir();
165
+ if (gdir)
166
+ ingest(gdir, "global");
167
+ const pdir = path.join(path.resolve(cwd), ".theron", "commands");
168
+ // Don't double-scan if the project dir IS the global dir.
169
+ if (pdir !== gdir)
170
+ ingest(pdir, "project");
171
+ return { map, dirs };
172
+ }
173
+ /**
174
+ * Substitute argument placeholders in a command body.
175
+ *
176
+ * $ARGUMENTS → the full argument string (everything after the command)
177
+ * $1, $2, … → positional args (whitespace-split of the argument string)
178
+ *
179
+ * A placeholder with no corresponding argument expands to the empty
180
+ * string. A literal `$` not followed by ARGUMENTS or a digit is left
181
+ * untouched. The substituted text is sent to the model as a prompt — it
182
+ * is NEVER passed to a shell, so no shell-escaping concerns apply here.
183
+ */
184
+ export function substituteArgs(body, argString) {
185
+ const args = argString.trim().length > 0 ? argString.trim().split(/\s+/) : [];
186
+ // Replace $ARGUMENTS first (longest token), then positional $N.
187
+ let out = body.replace(/\$ARGUMENTS\b/g, () => argString.trim());
188
+ out = out.replace(/\$(\d+)/g, (_m, d) => {
189
+ const idx = Number(d) - 1;
190
+ return idx >= 0 && idx < args.length ? args[idx] : "";
191
+ });
192
+ return out;
193
+ }
194
+ //# sourceMappingURL=slash_commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slash_commands.js","sourceRoot":"","sources":["../src/slash_commands.ts"],"names":[],"mappings":"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"}
@@ -29,3 +29,12 @@ export interface ToolContext {
29
29
  }
30
30
  export declare const TOOL_REGISTRY: Record<string, ToolExecutor>;
31
31
  export declare const TOOL_SCHEMAS: ToolDef[];
32
+ /** Tool names that can MUTATE the user's machine or hit a real SaaS.
33
+ * Plan mode hard-denies these at the executor (see repl.ts) so no write
34
+ * can run even with --yes. Stoa is included because its caps cause real
35
+ * side effects; Bash because a shell can write/delete. */
36
+ export declare const MUTATING_TOOLS: ReadonlySet<string>;
37
+ /** The read-only subset of TOOL_SCHEMAS sent to the model in plan mode.
38
+ * Filtering the schema makes the model LESS likely to even attempt a
39
+ * write; the executor-side deny in repl.ts is the actual guarantee. */
40
+ export declare const READONLY_TOOL_SCHEMAS: ToolDef[];
@@ -177,4 +177,15 @@ export const TOOL_SCHEMAS = [
177
177
  },
178
178
  STOA_TOOL_SCHEMA,
179
179
  ];
180
+ /** Tool names that can MUTATE the user's machine or hit a real SaaS.
181
+ * Plan mode hard-denies these at the executor (see repl.ts) so no write
182
+ * can run even with --yes. Stoa is included because its caps cause real
183
+ * side effects; Bash because a shell can write/delete. */
184
+ export const MUTATING_TOOLS = new Set([
185
+ "Write", "Edit", "Bash", "Stoa",
186
+ ]);
187
+ /** The read-only subset of TOOL_SCHEMAS sent to the model in plan mode.
188
+ * Filtering the schema makes the model LESS likely to even attempt a
189
+ * write; the executor-side deny in repl.ts is the actual guarantee. */
190
+ export const READONLY_TOOL_SCHEMAS = TOOL_SCHEMAS.filter((t) => !MUTATING_TOOLS.has(t.function.name));
180
191
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Print an update notice (from cache — instant) and refresh the cache in the
2
+ * background. Safe to call unconditionally: self-gates on TTY + opt-out env,
3
+ * never throws, never blocks the hot path. */
4
+ export declare function maybeNotifyUpdate(currentVersion: string): void;
@@ -0,0 +1,104 @@
1
+ // update_check.ts — a non-blocking "an update is available" notice.
2
+ //
3
+ // Pattern (mirrors the npm `update-notifier` package): print from a CACHED
4
+ // latest-version value so startup is INSTANT (no network on the hot path),
5
+ // and refresh that cache in the BACKGROUND for the next launch. Fail-open
6
+ // and silent on any error — an update check must never block, slow, or
7
+ // crash the CLI. Prints to STDERR so it never pollutes stdout / -p json.
8
+ //
9
+ // Opt out with THERON_NO_UPDATE_CHECK=1 (also skipped under CI and when
10
+ // stderr is not a TTY, e.g. piped / headless).
11
+ import fs from "node:fs";
12
+ import os from "node:os";
13
+ import path from "node:path";
14
+ const PKG = "@vextlabs/theron-cli";
15
+ const REGISTRY = `https://registry.npmjs.org/${encodeURIComponent(PKG)}/latest`;
16
+ const CACHE_DIR = path.join(os.homedir(), ".theron");
17
+ const CACHE_FILE = path.join(CACHE_DIR, "update-check.json");
18
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // refresh the cache at most once/day
19
+ const FETCH_TIMEOUT_MS = 1500;
20
+ function readCache() {
21
+ try {
22
+ const c = JSON.parse(fs.readFileSync(CACHE_FILE, "utf8"));
23
+ return {
24
+ lastCheck: typeof c.lastCheck === "number" ? c.lastCheck : 0,
25
+ latest: typeof c.latest === "string" ? c.latest : null,
26
+ };
27
+ }
28
+ catch {
29
+ return { lastCheck: 0, latest: null };
30
+ }
31
+ }
32
+ function writeCache(c) {
33
+ try {
34
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
35
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(c), "utf8");
36
+ }
37
+ catch {
38
+ /* fail-open — caching is best-effort */
39
+ }
40
+ }
41
+ /** Split "a.b.c" into numbers; a non-numeric part becomes -1 so a malformed
42
+ * string never beats a real version. Ignores pre-release tags. */
43
+ function parts(v) {
44
+ return v
45
+ .split("-")[0]
46
+ .split(".")
47
+ .map((x) => {
48
+ const n = parseInt(x, 10);
49
+ return Number.isFinite(n) ? n : -1;
50
+ });
51
+ }
52
+ /** True if `latest` is strictly greater than `current` (numeric, semver-ish). */
53
+ function isNewer(latest, current) {
54
+ const a = parts(latest);
55
+ const b = parts(current);
56
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
57
+ const x = a[i] ?? 0;
58
+ const y = b[i] ?? 0;
59
+ if (x > y)
60
+ return true;
61
+ if (x < y)
62
+ return false;
63
+ }
64
+ return false;
65
+ }
66
+ async function fetchLatest() {
67
+ try {
68
+ const ctrl = new AbortController();
69
+ const t = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
70
+ const r = await fetch(REGISTRY, { signal: ctrl.signal, headers: { accept: "application/json" } });
71
+ clearTimeout(t);
72
+ if (!r.ok)
73
+ return null;
74
+ const j = (await r.json());
75
+ return typeof j.version === "string" ? j.version : null;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ /** Print an update notice (from cache — instant) and refresh the cache in the
82
+ * background. Safe to call unconditionally: self-gates on TTY + opt-out env,
83
+ * never throws, never blocks the hot path. */
84
+ export function maybeNotifyUpdate(currentVersion) {
85
+ if (process.env.CI || process.env.THERON_NO_UPDATE_CHECK || !process.stderr.isTTY)
86
+ return;
87
+ const cache = readCache();
88
+ // Notify from the cached latest — no network on the launch path, so the
89
+ // notice appears starting the launch AFTER a new version is published.
90
+ if (cache.latest && isNewer(cache.latest, currentVersion)) {
91
+ process.stderr.write(`\n Update available ${currentVersion} → ${cache.latest}\n` +
92
+ ` Run npm i -g ${PKG}@latest\n\n`);
93
+ }
94
+ // Refresh the cache for next launch, at most once/day. Fire-and-forget:
95
+ // we never await it, so it cannot delay startup.
96
+ if (Date.now() - cache.lastCheck > CHECK_INTERVAL_MS) {
97
+ void fetchLatest()
98
+ .then((latest) => writeCache({ lastCheck: Date.now(), latest: latest ?? cache.latest }))
99
+ .catch(() => {
100
+ /* fail-open */
101
+ });
102
+ }
103
+ }
104
+ //# sourceMappingURL=update_check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update_check.js","sourceRoot":"","sources":["../src/update_check.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vextlabs/theron-cli",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Theron CLI — an agentic coding assistant that verifies its own output. Runs an agentic tool loop in your terminal, then runs post-turn checks (types, tests, lint, arithmetic, citations) over the files it touched; blocking failures feed the next turn so it self-corrects. Across a 33-profile domain council. From Vext Labs.",
5
5
  "author": "Vext Labs Inc.",
6
6
  "license": "Apache-2.0",
@@ -31,7 +31,10 @@
31
31
  "start": "node ./bin/theron.js",
32
32
  "test": "npm run build && node test/sweep.mjs",
33
33
  "test:integration": "npm run build && THERON_RUN_INTEGRATION=1 node test/integration.mjs",
34
- "prepublishOnly": "npm run build"
34
+ "prepublishOnly": "npm run build",
35
+ "release": "npm version patch && npm publish",
36
+ "release:minor": "npm version minor && npm publish",
37
+ "release:major": "npm version major && npm publish"
35
38
  },
36
39
  "dependencies": {
37
40
  "@types/node": "^20.0.0",
@@ -56,6 +59,9 @@
56
59
  "council",
57
60
  "specialist",
58
61
  "stoa",
59
- "terminal"
62
+ "terminal",
63
+ "slash-commands",
64
+ "plan-mode",
65
+ "headless"
60
66
  ]
61
67
  }