@getnoan/wizard 0.1.0 → 0.1.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/package.json +2 -2
- package/src/agents.mjs +15 -0
- package/src/run.mjs +12 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getnoan/wizard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/getnoan/wizard.git"
|
|
24
|
+
"url": "git+https://github.com/getnoan/wizard.git"
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://getnoan.com/mcp",
|
|
27
27
|
"keywords": [
|
package/src/agents.mjs
CHANGED
|
@@ -86,6 +86,21 @@ export function runSeeds(dest, env, { dryRun = false } = {}) {
|
|
|
86
86
|
return { slugs, rows };
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/** The pack's grounding check: which blocks the agents read hold no fact. Runs in the clone; absent in an old pack. */
|
|
90
|
+
export function runGroundingCheck(dest, env, { dryRun = false } = {}) {
|
|
91
|
+
const p = path.join(dest, "agents", "grounding-check.mjs");
|
|
92
|
+
if (!existsSync(p)) return { available: false };
|
|
93
|
+
const r = spawnSync(process.execPath, [p, "--json", ...(dryRun ? ["--dry-run"] : [])], { cwd: path.join(dest, "agents"), encoding: "utf8", env: { ...process.env, ...env } });
|
|
94
|
+
return { available: true, ...parseGroundingOutput(r.stdout), error: r.status === 0 ? undefined : (r.stderr || "").trim().split("\n").slice(-1)[0] };
|
|
95
|
+
}
|
|
96
|
+
export function parseGroundingOutput(text) {
|
|
97
|
+
for (const line of String(text || "").split("\n").reverse()) {
|
|
98
|
+
if (!line.trim().startsWith("{")) continue;
|
|
99
|
+
try { const j = JSON.parse(line); return { gaps: j.gaps || [], filed: j.filed || [] }; } catch {}
|
|
100
|
+
}
|
|
101
|
+
return { gaps: [], filed: [] };
|
|
102
|
+
}
|
|
103
|
+
|
|
89
104
|
export function dispatchDryRun(dest, workflow, dryRun) {
|
|
90
105
|
if (dryRun) return { workflow, action: "would dispatch" };
|
|
91
106
|
const r = gh(["workflow", "run", workflow, "-f", "dry_run=1"], { cwd: dest });
|
package/src/run.mjs
CHANGED
|
@@ -86,7 +86,7 @@ export async function run(args) {
|
|
|
86
86
|
ui.step(5, "The agent pack");
|
|
87
87
|
let wantAgents = args.agents;
|
|
88
88
|
if (wantAgents == null) wantAgents = ui.interactive ? await ui.confirm("Set up the six open-source agents on your GitHub account too?", false) : false;
|
|
89
|
-
if (wantAgents) report.steps.agents = await setupAgents({ args, ui, dir, key, me });
|
|
89
|
+
if (wantAgents) report.steps.agents = await setupAgents({ args, ui, dir, key, me, report });
|
|
90
90
|
else { ui.info("skipped" + (args.yes && args.agents == null ? " (pass --agents to include it)" : "")); report.steps.agents = { skipped: true }; }
|
|
91
91
|
|
|
92
92
|
/* 6. report */
|
|
@@ -96,7 +96,7 @@ export async function run(args) {
|
|
|
96
96
|
|
|
97
97
|
async function ask(ui, q, o) { return ui.ask(q, o); }
|
|
98
98
|
|
|
99
|
-
async function setupAgents({ args, ui, dir, key, me }) {
|
|
99
|
+
async function setupAgents({ args, ui, dir, key, me, report }) {
|
|
100
100
|
const ready = pack.ghReady();
|
|
101
101
|
if (!ready.ok) { ui.warn(ready.reason); return { ok: false, reason: ready.reason }; }
|
|
102
102
|
const fork = pack.forkAndClone(dir, { dryRun: args.dryRun });
|
|
@@ -131,6 +131,16 @@ async function setupAgents({ args, ui, dir, key, me }) {
|
|
|
131
131
|
out.seeds = seeds.rows;
|
|
132
132
|
for (const r of seeds.rows) ui.ok(`${r.seed}: ${r.action}${r.slugs != null ? ` (${r.slugs} slug(s))` : ""}${r.error ? ` — ${r.error}` : ""}`);
|
|
133
133
|
Object.assign(vars, seeds.slugs);
|
|
134
|
+
// The blocks the agents read that hold no fact: one task each on the user's board, and a line in the report.
|
|
135
|
+
const grounding = args.dryRun ? { available: false } : pack.runGroundingCheck(fork.dest, { NOAN_PERSONAL_API_KEY: key });
|
|
136
|
+
out.grounding = grounding;
|
|
137
|
+
if (grounding.available) {
|
|
138
|
+
if (grounding.gaps.length) {
|
|
139
|
+
ui.warn(`${grounding.gaps.length} block(s) the agents read hold no fact — ${grounding.filed.filter(f => f.action === "filed").length} task(s) filed on your NOAN board`);
|
|
140
|
+
for (const g of grounding.gaps) ui.info(` ${g.title}: needed by ${g.agents.join(", ")}`);
|
|
141
|
+
report.next.push({ id: "grounding", say: `Fill the ${grounding.gaps.length} block(s) the agents read (tasks are on your NOAN board): ${grounding.gaps.map(g => g.title).join(", ")}.`, why: "an agent grounded in an empty block fails quietly" });
|
|
142
|
+
} else ui.ok("every block the agents read holds a fact");
|
|
143
|
+
}
|
|
134
144
|
for (const [n, v] of Object.entries(vars)) { if (!v) continue; const r = pack.setVariable(fork.dest, n, v, args.dryRun); out.variables.push(r); }
|
|
135
145
|
ui.ok(`${out.variables.length} repository variable(s) ${args.dryRun ? "to set" : "set"} (DRY_RUN=1: every agent stays in safe mode)`);
|
|
136
146
|
// No point dispatching a run that will only fail for a missing key: say what is missing instead.
|