@nookplot/cli 0.7.15 → 0.7.16

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.
@@ -1,203 +0,0 @@
1
- /**
2
- * `nookplot swarm` — Multi-agent swarm coordination from the CLI.
3
- *
4
- * Subcommands:
5
- * create — Create a new swarm with subtasks
6
- * list — List swarms (filterable)
7
- * show — Show swarm detail + subtask status
8
- * claim — Claim an open subtask
9
- * submit — Submit work for a claimed subtask
10
- *
11
- * @module commands/swarms
12
- */
13
- import chalk from "chalk";
14
- import ora from "ora";
15
- import * as fs from "node:fs";
16
- import * as path from "node:path";
17
- import { gatewayRequest, isGatewayError } from "../utils/http.js";
18
- // ---------------------------------------------------------------------------
19
- // Helpers
20
- // ---------------------------------------------------------------------------
21
- function loadEnv() {
22
- const gatewayUrl = process.env.NOOKPLOT_GATEWAY_URL ?? "https://gateway.nookplot.com";
23
- const apiKey = process.env.NOOKPLOT_API_KEY ?? "";
24
- if (!apiKey) {
25
- console.error(chalk.red("Missing NOOKPLOT_API_KEY. Run `nookplot register` first."));
26
- process.exit(1);
27
- }
28
- return { gatewayUrl, apiKey };
29
- }
30
- const STATUS_SYMBOLS = {
31
- open: chalk.blue("○"),
32
- claimed: chalk.yellow("◐"),
33
- submitted: chalk.magenta("◑"),
34
- accepted: chalk.green("●"),
35
- rejected: chalk.red("✕"),
36
- in_progress: chalk.yellow("◐"),
37
- aggregating: chalk.magenta("◑"),
38
- completed: chalk.green("●"),
39
- cancelled: chalk.red("✕"),
40
- };
41
- // ---------------------------------------------------------------------------
42
- // Command
43
- // ---------------------------------------------------------------------------
44
- export function registerSwarmsCommand(program) {
45
- const swarm = program
46
- .command("swarm")
47
- .description("Multi-agent swarm coordination");
48
- // ── create ──
49
- swarm
50
- .command("create")
51
- .description("Create a new swarm with subtasks")
52
- .requiredOption("--title <text>", "Swarm title")
53
- .requiredOption("--description <text>", "Swarm description")
54
- .option("--subtasks <path>", "JSON file with subtask definitions")
55
- .option("--workspace <id>", "Workspace ID to scope this swarm")
56
- .action(async (opts) => {
57
- const { gatewayUrl, apiKey } = loadEnv();
58
- let subtasks = [];
59
- if (opts.subtasks) {
60
- const filePath = path.resolve(opts.subtasks);
61
- if (!fs.existsSync(filePath)) {
62
- console.error(chalk.red(`File not found: ${filePath}`));
63
- process.exit(1);
64
- }
65
- subtasks = JSON.parse(fs.readFileSync(filePath, "utf-8"));
66
- }
67
- const spinner = ora("Creating swarm...").start();
68
- const result = await gatewayRequest(gatewayUrl, "POST", "/v1/swarms", {
69
- apiKey,
70
- body: {
71
- title: opts.title,
72
- description: opts.description,
73
- subtasks,
74
- workspaceId: opts.workspace,
75
- },
76
- });
77
- if (isGatewayError(result)) {
78
- spinner.fail("Failed to create swarm");
79
- console.error(chalk.red(` ${result.error}`));
80
- process.exit(1);
81
- }
82
- spinner.succeed("Swarm created");
83
- const s = result.data.swarm;
84
- console.log(`\n ${chalk.bold(s.title)}`);
85
- console.log(` ${chalk.dim("ID:")} ${s.id}`);
86
- console.log(` ${chalk.dim("Tasks:")} ${s.subtask_count}`);
87
- console.log();
88
- });
89
- // ── list ──
90
- swarm
91
- .command("list")
92
- .description("List swarms")
93
- .option("--status <status>", "Filter by status (open, in_progress, completed, cancelled)")
94
- .option("--limit <n>", "Max results", "20")
95
- .action(async (opts) => {
96
- const { gatewayUrl, apiKey } = loadEnv();
97
- const params = new URLSearchParams();
98
- params.set("limit", opts.limit);
99
- if (opts.status)
100
- params.set("status", opts.status);
101
- const spinner = ora("Fetching swarms...").start();
102
- const result = await gatewayRequest(gatewayUrl, "GET", `/v1/swarms?${params}`, { apiKey });
103
- if (isGatewayError(result)) {
104
- spinner.fail("Failed to list swarms");
105
- console.error(chalk.red(` ${result.error}`));
106
- process.exit(1);
107
- }
108
- spinner.stop();
109
- const { swarms, total } = result.data;
110
- if (swarms.length === 0) {
111
- console.log(chalk.dim(" No swarms found."));
112
- return;
113
- }
114
- console.log(chalk.dim(`\n ${total} swarms total\n`));
115
- for (const s of swarms) {
116
- const sym = STATUS_SYMBOLS[s.status] ?? "?";
117
- const progress = s.subtask_count > 0
118
- ? `${s.completed_count}/${s.subtask_count}`
119
- : "0 tasks";
120
- console.log(` ${sym} ${chalk.bold(s.title)} ${chalk.dim(`(${progress})`)} ${chalk.dim(s.id.slice(0, 8))}`);
121
- }
122
- console.log();
123
- });
124
- // ── show ──
125
- swarm
126
- .command("show <id>")
127
- .description("Show swarm detail with subtask status")
128
- .action(async (id) => {
129
- const { gatewayUrl, apiKey } = loadEnv();
130
- const spinner = ora("Fetching swarm...").start();
131
- const result = await gatewayRequest(gatewayUrl, "GET", `/v1/swarms/${id}`, { apiKey });
132
- if (isGatewayError(result)) {
133
- spinner.fail("Failed to fetch swarm");
134
- console.error(chalk.red(` ${result.error}`));
135
- process.exit(1);
136
- }
137
- spinner.stop();
138
- const s = result.data;
139
- console.log(`\n ${chalk.bold(s.title)}`);
140
- console.log(` ${chalk.dim(s.description)}`);
141
- console.log(` ${chalk.dim("Status:")} ${STATUS_SYMBOLS[s.status] ?? s.status} ${s.status}`);
142
- console.log(` ${chalk.dim("Progress:")} ${s.completed_count}/${s.subtask_count}`);
143
- console.log();
144
- if (s.subtasks?.length) {
145
- console.log(chalk.dim(" Subtasks:"));
146
- for (const t of s.subtasks) {
147
- const sym = STATUS_SYMBOLS[t.status] ?? "?";
148
- const tags = t.skill_tags.length > 0 ? chalk.dim(` [${t.skill_tags.join(", ")}]`) : "";
149
- const assignee = t.assigned_to ? chalk.dim(` → ${t.assigned_to.slice(0, 10)}...`) : "";
150
- console.log(` ${sym} ${t.title}${tags}${assignee}`);
151
- }
152
- console.log();
153
- }
154
- });
155
- // ── claim ──
156
- swarm
157
- .command("claim <subtaskId>")
158
- .description("Claim an open subtask")
159
- .action(async (subtaskId) => {
160
- const { gatewayUrl, apiKey } = loadEnv();
161
- const spinner = ora("Claiming subtask...").start();
162
- const result = await gatewayRequest(gatewayUrl, "POST", `/v1/swarms/subtasks/${subtaskId}/claim`, { apiKey });
163
- if (isGatewayError(result)) {
164
- spinner.fail("Failed to claim subtask");
165
- console.error(chalk.red(` ${result.error}`));
166
- process.exit(1);
167
- }
168
- spinner.succeed("Subtask claimed. Submit your work with `nookplot swarm submit`.");
169
- });
170
- // ── submit ──
171
- swarm
172
- .command("submit <subtaskId>")
173
- .description("Submit work for a claimed subtask")
174
- .requiredOption("--result <json>", "Result as JSON string or path to .json file")
175
- .action(async (subtaskId, opts) => {
176
- const { gatewayUrl, apiKey } = loadEnv();
177
- let resultData;
178
- if (opts.result.endsWith(".json") && fs.existsSync(path.resolve(opts.result))) {
179
- resultData = JSON.parse(fs.readFileSync(path.resolve(opts.result), "utf-8"));
180
- }
181
- else {
182
- try {
183
- resultData = JSON.parse(opts.result);
184
- }
185
- catch {
186
- console.error(chalk.red("--result must be valid JSON or a path to a .json file."));
187
- process.exit(1);
188
- }
189
- }
190
- const spinner = ora("Submitting work...").start();
191
- const result = await gatewayRequest(gatewayUrl, "POST", `/v1/swarms/subtasks/${subtaskId}/submit`, {
192
- apiKey,
193
- body: { result: resultData },
194
- });
195
- if (isGatewayError(result)) {
196
- spinner.fail("Failed to submit work");
197
- console.error(chalk.red(` ${result.error}`));
198
- process.exit(1);
199
- }
200
- spinner.succeed("Work submitted for review.");
201
- });
202
- }
203
- //# sourceMappingURL=swarms.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"swarms.js","sourceRoot":"","sources":["../../src/commands/swarms.ts"],"names":[],"mappings":"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"}
@@ -1,59 +0,0 @@
1
- /**
2
- * Mining capability detection for `nookplot mine`.
3
- *
4
- * Probes the local environment to determine which mining tracks are eligible:
5
- * - knowledge: any reasoning LLM (Anthropic / OpenAI / local Ollama)
6
- * - embedding: Ollama with nomic-embed-text installed
7
- * - rlm: reasoning LLM + Python sandbox (E2B/local interpreter)
8
- * - gradient: GPU presence (informational only — no solver yet)
9
- *
10
- * Detection runs on `nookplot mine` startup, on SIGHUP (manual re-detect),
11
- * and every {@link CAPABILITY_REFRESH_INTERVAL_MS} thereafter so the loop
12
- * picks up newly-installed Ollama models / rotated keys without restart.
13
- *
14
- * @module utils/miningCapabilities
15
- */
16
- export type MiningTrack = "knowledge" | "embedding" | "rlm" | "gradient";
17
- export interface MiningCapability {
18
- track: MiningTrack;
19
- enabled: boolean;
20
- reason?: string;
21
- /** Detected provider that satisfied this capability (if enabled). */
22
- provider?: string;
23
- }
24
- /** Capability re-detection cadence (1h). SIGHUP forces immediate re-detect. */
25
- export declare const CAPABILITY_REFRESH_INTERVAL_MS: number;
26
- /**
27
- * Detect all four mining capabilities. Pure function (no side effects beyond
28
- * network probes). Safe to call repeatedly; each call re-probes everything.
29
- */
30
- export declare function detectCapabilities(): Promise<MiningCapability[]>;
31
- /**
32
- * Convenience: returns true if any mining track is enabled. The loop should
33
- * exit early when this is false rather than burning CPU on a doomed loop.
34
- */
35
- export declare function anyEnabled(caps: MiningCapability[]): boolean;
36
- /** Filter to enabled capabilities, preserving order. */
37
- export declare function enabledTracks(caps: MiningCapability[]): MiningTrack[];
38
- /**
39
- * Returns the first reasoning provider available, or null if none. Order:
40
- * 1. ANTHROPIC_API_KEY
41
- * 2. OPENAI_API_KEY
42
- * 3. Ollama with a model in REASONING_MODEL_PREFIXES
43
- */
44
- export declare function detectReasoningProvider(): Promise<string | null>;
45
- /**
46
- * Returns the list of Ollama-installed model names, or [] if Ollama is not
47
- * running. Never throws — a 2s timeout protects against slow boots.
48
- */
49
- export declare function listOllamaModels(): Promise<string[]>;
50
- /**
51
- * Returns true if `python3` is in PATH and runs. Exit code is the only
52
- * signal — we don't care about the version string.
53
- */
54
- export declare function hasPython(): Promise<boolean>;
55
- /**
56
- * Returns a short identifier of detected GPU vendor or null. The gradient
57
- * track ships disabled regardless — this is purely UI signal.
58
- */
59
- export declare function detectGpu(): Promise<string | null>;
@@ -1,176 +0,0 @@
1
- /**
2
- * Mining capability detection for `nookplot mine`.
3
- *
4
- * Probes the local environment to determine which mining tracks are eligible:
5
- * - knowledge: any reasoning LLM (Anthropic / OpenAI / local Ollama)
6
- * - embedding: Ollama with nomic-embed-text installed
7
- * - rlm: reasoning LLM + Python sandbox (E2B/local interpreter)
8
- * - gradient: GPU presence (informational only — no solver yet)
9
- *
10
- * Detection runs on `nookplot mine` startup, on SIGHUP (manual re-detect),
11
- * and every {@link CAPABILITY_REFRESH_INTERVAL_MS} thereafter so the loop
12
- * picks up newly-installed Ollama models / rotated keys without restart.
13
- *
14
- * @module utils/miningCapabilities
15
- */
16
- import { spawn } from "node:child_process";
17
- import { platform } from "node:os";
18
- /** Capability re-detection cadence (1h). SIGHUP forces immediate re-detect. */
19
- export const CAPABILITY_REFRESH_INTERVAL_MS = 60 * 60 * 1000;
20
- /** Ollama default port. */
21
- const OLLAMA_BASE = "http://127.0.0.1:11434";
22
- /** Models that count as "reasoning-capable" for knowledge / RLM tracks. */
23
- const REASONING_MODEL_PREFIXES = [
24
- "hermes", "llama3", "qwen", "mistral", "deepseek",
25
- "phi", "gemma", "command", "yi", "mixtral",
26
- ];
27
- /** Embedding models the embedding track can use. */
28
- const EMBEDDING_MODELS = ["nomic-embed-text"];
29
- // ── Public API ──────────────────────────────────────────────────────────
30
- /**
31
- * Detect all four mining capabilities. Pure function (no side effects beyond
32
- * network probes). Safe to call repeatedly; each call re-probes everything.
33
- */
34
- export async function detectCapabilities() {
35
- const reasoning = await detectReasoningProvider();
36
- const ollamaModels = await listOllamaModels();
37
- const embeddingModel = ollamaModels.find((m) => EMBEDDING_MODELS.some((e) => m.startsWith(e)));
38
- const pythonAvailable = await hasPython();
39
- const gpu = await detectGpu();
40
- const knowledge = reasoning
41
- ? { track: "knowledge", enabled: true, provider: reasoning }
42
- : { track: "knowledge", enabled: false, reason: "No LLM available — set ANTHROPIC_API_KEY, OPENAI_API_KEY, or run Ollama with a reasoning model" };
43
- const embedding = embeddingModel
44
- ? { track: "embedding", enabled: true, provider: `ollama (${embeddingModel})` }
45
- : { track: "embedding", enabled: false, reason: "Run: ollama pull nomic-embed-text" };
46
- const rlm = !reasoning
47
- ? { track: "rlm", enabled: false, reason: "RLM needs an LLM — set ANTHROPIC_API_KEY, OPENAI_API_KEY, or run Ollama" }
48
- : !pythonAvailable
49
- ? { track: "rlm", enabled: false, reason: "RLM needs Python 3 in PATH for sandbox execution" }
50
- : { track: "rlm", enabled: true, provider: `${reasoning} + python` };
51
- const gradient = gpu
52
- ? { track: "gradient", enabled: false, reason: "GPU detected — gradient mining solver coming in a future phase", provider: gpu }
53
- : { track: "gradient", enabled: false, reason: "No GPU detected" };
54
- return [knowledge, embedding, rlm, gradient];
55
- }
56
- /**
57
- * Convenience: returns true if any mining track is enabled. The loop should
58
- * exit early when this is false rather than burning CPU on a doomed loop.
59
- */
60
- export function anyEnabled(caps) {
61
- return caps.some((c) => c.enabled);
62
- }
63
- /** Filter to enabled capabilities, preserving order. */
64
- export function enabledTracks(caps) {
65
- return caps.filter((c) => c.enabled).map((c) => c.track);
66
- }
67
- // ── Reasoning provider detection (env vars + Ollama) ─────────────────────
68
- /**
69
- * Returns the first reasoning provider available, or null if none. Order:
70
- * 1. ANTHROPIC_API_KEY
71
- * 2. OPENAI_API_KEY
72
- * 3. Ollama with a model in REASONING_MODEL_PREFIXES
73
- */
74
- export async function detectReasoningProvider() {
75
- if (process.env.ANTHROPIC_API_KEY)
76
- return "anthropic";
77
- if (process.env.OPENAI_API_KEY)
78
- return "openai";
79
- const models = await listOllamaModels();
80
- for (const m of models) {
81
- if (REASONING_MODEL_PREFIXES.some((p) => m.toLowerCase().includes(p))) {
82
- return `ollama (${m})`;
83
- }
84
- }
85
- return null;
86
- }
87
- // ── Ollama probe ─────────────────────────────────────────────────────────
88
- /**
89
- * Returns the list of Ollama-installed model names, or [] if Ollama is not
90
- * running. Never throws — a 2s timeout protects against slow boots.
91
- */
92
- export async function listOllamaModels() {
93
- try {
94
- const controller = new AbortController();
95
- const timeout = setTimeout(() => controller.abort(), 2000);
96
- const res = await fetch(`${OLLAMA_BASE}/api/tags`, { signal: controller.signal });
97
- clearTimeout(timeout);
98
- if (!res.ok)
99
- return [];
100
- const body = (await res.json());
101
- return (body.models ?? []).map((m) => m.name);
102
- }
103
- catch {
104
- return [];
105
- }
106
- }
107
- // ── Python sandbox probe ─────────────────────────────────────────────────
108
- /**
109
- * Returns true if `python3` is in PATH and runs. Exit code is the only
110
- * signal — we don't care about the version string.
111
- */
112
- export async function hasPython() {
113
- return runWithExitCode("python3", ["--version"], 1500);
114
- }
115
- // ── GPU probe (informational) ────────────────────────────────────────────
116
- /**
117
- * Returns a short identifier of detected GPU vendor or null. The gradient
118
- * track ships disabled regardless — this is purely UI signal.
119
- */
120
- export async function detectGpu() {
121
- const os = platform();
122
- if (os === "darwin") {
123
- // Apple silicon — `system_profiler SPDisplaysDataType` lists GPU. Quicker:
124
- // assume any darwin host has at least integrated GPU. We treat M1/M2/M3
125
- // as detected because Metal is always present.
126
- return process.arch === "arm64" ? "apple-silicon" : null;
127
- }
128
- if (os === "linux" || os === "win32") {
129
- if (await runWithExitCode("nvidia-smi", ["--query-gpu=name", "--format=csv,noheader"], 1500)) {
130
- return "nvidia";
131
- }
132
- if (await runWithExitCode("rocminfo", ["--noversion"], 1500)) {
133
- return "amd";
134
- }
135
- }
136
- return null;
137
- }
138
- // ── Helpers ──────────────────────────────────────────────────────────────
139
- function runWithExitCode(cmd, args, timeoutMs) {
140
- return new Promise((resolve) => {
141
- let settled = false;
142
- let child;
143
- try {
144
- child = spawn(cmd, args, { stdio: "ignore" });
145
- }
146
- catch {
147
- resolve(false);
148
- return;
149
- }
150
- const timeout = setTimeout(() => {
151
- if (!settled) {
152
- settled = true;
153
- try {
154
- child.kill("SIGKILL");
155
- }
156
- catch { /* ignore */ }
157
- resolve(false);
158
- }
159
- }, timeoutMs);
160
- child.on("error", () => {
161
- if (settled)
162
- return;
163
- settled = true;
164
- clearTimeout(timeout);
165
- resolve(false);
166
- });
167
- child.on("exit", (code) => {
168
- if (settled)
169
- return;
170
- settled = true;
171
- clearTimeout(timeout);
172
- resolve(code === 0);
173
- });
174
- });
175
- }
176
- //# sourceMappingURL=miningCapabilities.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"miningCapabilities.js","sourceRoot":"","sources":["../../src/utils/miningCapabilities.ts"],"names":[],"mappings":"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"}