@getnoan/wizard 0.1.4 → 0.1.5
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/package.json +1 -1
- package/src/agents.mjs +26 -5
- package/src/run.mjs +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getnoan/wizard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "One command from nothing to a grounded agent: sign in to NOAN, wire your coding assistant, install the skill, and set up the agent pack.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/agents.mjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* the pack's documented ones. Safe mode stays on: the wizard never sets DRY_RUN to 0.
|
|
7
7
|
*/
|
|
8
8
|
import { spawnSync } from "node:child_process";
|
|
9
|
-
import { existsSync } from "node:fs";
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { randomBytes } from "node:crypto";
|
|
12
12
|
import { writeEnv } from "./env-file.mjs";
|
|
@@ -128,15 +128,36 @@ export function setVariable(dest, name, value, dryRun) {
|
|
|
128
128
|
return { name, action: r.status === 0 ? "set" : "failed", error: r.status === 0 ? undefined : (r.stderr || "").trim().split("\n")[0] };
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/** Where a pack file lives in the clone, named as the pack names it (`seed-deck.mjs`).
|
|
132
|
+
*
|
|
133
|
+
* The pack groups agents/ by agent — agents/<agent>/ for one agent's files, agents/shared/
|
|
134
|
+
* for the rest — and writes agents/pack-layout.json mapping each name to its path. A pack
|
|
135
|
+
* cloned before that grouping has neither the folders nor the map, and every file sits
|
|
136
|
+
* directly in agents/. Both are live at once (a fork keeps whatever it was cloned from), so
|
|
137
|
+
* both are read.
|
|
138
|
+
*
|
|
139
|
+
* A layout file that exists but cannot be read THROWS. Falling back to the flat path would
|
|
140
|
+
* report every seed "missing" and seed nothing — the silent failure the map exists to stop. */
|
|
141
|
+
export function packFile(dest, name) {
|
|
142
|
+
const layoutPath = path.join(dest, "agents", "pack-layout.json");
|
|
143
|
+
if (existsSync(layoutPath)) {
|
|
144
|
+
let files;
|
|
145
|
+
try { files = JSON.parse(readFileSync(layoutPath, "utf8")).files; }
|
|
146
|
+
catch (e) { throw new Error(`agents/pack-layout.json in ${dest} is not readable JSON: ${e.message}`); }
|
|
147
|
+
if (files?.[name]) return path.join(dest, "agents", files[name]);
|
|
148
|
+
}
|
|
149
|
+
return path.join(dest, "agents", name);
|
|
150
|
+
}
|
|
151
|
+
|
|
131
152
|
/** Run every seed script the pack ships; collect the block slugs they print. */
|
|
132
153
|
export function runSeeds(dest, env, { dryRun = false } = {}) {
|
|
133
154
|
const seeds = ["seed-weekly-activity-report.mjs", "seed-fact-alignment.mjs", "seed-market-research-refresh.mjs", "seed-customer-support.mjs", "seed-deck.mjs"];
|
|
134
155
|
const slugs = {}; const rows = [];
|
|
135
156
|
for (const s of seeds) {
|
|
136
|
-
const p =
|
|
157
|
+
const p = packFile(dest, s);
|
|
137
158
|
if (!existsSync(p)) { rows.push({ seed: s, action: "missing" }); continue; }
|
|
138
159
|
if (dryRun) { rows.push({ seed: s, action: "would run" }); continue; }
|
|
139
|
-
const r = spawnSync(process.execPath, [p], { cwd: path.
|
|
160
|
+
const r = spawnSync(process.execPath, [p], { cwd: path.dirname(p), encoding: "utf8", env: { ...process.env, ...env } });
|
|
140
161
|
const found = parseSeedOutput((r.stdout || "") + "\n" + (r.stderr || ""));
|
|
141
162
|
Object.assign(slugs, found);
|
|
142
163
|
rows.push({ seed: s, action: r.status === 0 ? "ran" : "failed", slugs: Object.keys(found).length, error: r.status === 0 ? undefined : (r.stderr || r.stdout || "").trim().split("\n").slice(-1)[0] });
|
|
@@ -146,9 +167,9 @@ export function runSeeds(dest, env, { dryRun = false } = {}) {
|
|
|
146
167
|
|
|
147
168
|
/** The pack's grounding check: which blocks the agents read hold no fact. Runs in the clone; absent in an old pack. */
|
|
148
169
|
export function runGroundingCheck(dest, env, { dryRun = false } = {}) {
|
|
149
|
-
const p =
|
|
170
|
+
const p = packFile(dest, "grounding-check.mjs");
|
|
150
171
|
if (!existsSync(p)) return { available: false };
|
|
151
|
-
const r = spawnSync(process.execPath, [p, "--json", ...(dryRun ? ["--dry-run"] : [])], { cwd: path.
|
|
172
|
+
const r = spawnSync(process.execPath, [p, "--json", ...(dryRun ? ["--dry-run"] : [])], { cwd: path.dirname(p), encoding: "utf8", env: { ...process.env, ...env } });
|
|
152
173
|
return { available: true, ...parseGroundingOutput(r.stdout), error: r.status === 0 ? undefined : (r.stderr || "").trim().split("\n").slice(-1)[0] };
|
|
153
174
|
}
|
|
154
175
|
export function parseGroundingOutput(text) {
|
package/src/run.mjs
CHANGED
|
@@ -168,7 +168,8 @@ async function setupAgents({ args, ui, dir, key, me, report }) {
|
|
|
168
168
|
pack.writePackEnv(fork.dest, { NOAN_PERSONAL_API_KEY: key, ...(anthropic && { [mName]: anthropic }), ...(mBase && { ANTHROPIC_BASE_URL: mBase }), ...(resend && { RESEND_API_KEY: resend }) }, args.dryRun);
|
|
169
169
|
const seeds = pack.runSeeds(fork.dest, { NOAN_PERSONAL_API_KEY: key }, { dryRun: args.dryRun });
|
|
170
170
|
out.seeds = seeds.rows;
|
|
171
|
-
|
|
171
|
+
// A missing or failed seed is a warning, not a tick: its agent has no Config fact and no slug variable.
|
|
172
|
+
for (const r of seeds.rows) (/^(missing|failed)$/.test(r.action) ? ui.warn : ui.ok)(`${r.seed}: ${r.action}${r.slugs != null ? ` (${r.slugs} slug(s))` : ""}${r.error ? ` — ${r.error}` : ""}`);
|
|
172
173
|
Object.assign(vars, seeds.slugs);
|
|
173
174
|
// The blocks the agents read that hold no fact: one task each on the user's board, and a line in the report.
|
|
174
175
|
const grounding = args.dryRun ? { available: false } : pack.runGroundingCheck(fork.dest, { NOAN_PERSONAL_API_KEY: key });
|