@zuzuucodes/cli 1.4.0 → 1.5.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.
- package/bin/zuzuu.mjs +8 -1
- package/package.json +1 -1
- package/web-app/dist/zuzuu-api.js +122 -27
- package/web-app/web-dist/assets/{DiffTab-BuWonUNJ.js → DiffTab-BpGp1akx.js} +1 -1
- package/web-app/web-dist/assets/{MonacoFile-CL3DhFKG.js → MonacoFile-CqbVacUZ.js} +1 -1
- package/web-app/web-dist/assets/{cssMode-B9jnrWOz.js → cssMode-Dx3ub8Pk.js} +1 -1
- package/web-app/web-dist/assets/{dist-ChcDQ_7s.js → dist-C6R6xoyX.js} +1 -1
- package/web-app/web-dist/assets/{htmlMode-Bi8vSvwb.js → htmlMode-DM6oHc7c.js} +1 -1
- package/web-app/web-dist/assets/{index--5yy8RbA.js → index-DHpC851f.js} +25 -24
- package/web-app/web-dist/assets/index-O-t1gyMG.css +2 -0
- package/web-app/web-dist/assets/{jsonMode-C6ELX5GM.js → jsonMode-DflaUwqW.js} +1 -1
- package/web-app/web-dist/assets/{monaco-setup-CsR6EfHe.js → monaco-setup-wbBeb0oN.js} +3 -3
- package/web-app/web-dist/assets/{tsMode-a8OvovQd.js → tsMode-DRwkDcoK.js} +1 -1
- package/web-app/web-dist/index.html +2 -2
- package/zuzuu/actions/adapter.mjs +12 -20
- package/zuzuu/actions/convert.mjs +10 -9
- package/zuzuu/actions/dispatch.mjs +12 -7
- package/zuzuu/actions/inbox.mjs +5 -5
- package/zuzuu/actions/manifest.mjs +48 -30
- package/zuzuu/actions/schema.mjs +9 -3
- package/zuzuu/commands/act-author.mjs +23 -13
- package/zuzuu/commands/act.mjs +3 -5
- package/zuzuu/commands/doctor.mjs +2 -15
- package/zuzuu/commands/explain.mjs +4 -4
- package/zuzuu/commands/faculty.mjs +75 -0
- package/zuzuu/commands/generation.mjs +2 -4
- package/zuzuu/commands/hook.mjs +7 -5
- package/zuzuu/commands/init.mjs +14 -1
- package/zuzuu/commands/migrate.mjs +348 -1
- package/zuzuu/digest.mjs +18 -13
- package/zuzuu/faculty/envelope.mjs +290 -0
- package/zuzuu/faculty/generation.mjs +53 -47
- package/zuzuu/faculty/items.mjs +75 -0
- package/zuzuu/guardrails/adapter.mjs +18 -49
- package/zuzuu/guardrails.mjs +72 -24
- package/zuzuu/instructions/adapter.mjs +30 -30
- package/zuzuu/knowledge/items.mjs +56 -91
- package/zuzuu/live/install.mjs +1 -1
- package/zuzuu/memory/adapter.mjs +27 -52
- package/zuzuu/miners/actions.mjs +14 -20
- package/zuzuu/miners/guardrails.mjs +8 -11
- package/zuzuu/miners/instructions.mjs +10 -10
- package/zuzuu/scaffold.mjs +99 -38
- package/web-app/web-dist/assets/index-BVG4hgk7.css +0 -2
package/bin/zuzuu.mjs
CHANGED
|
@@ -33,6 +33,7 @@ import { web } from '../zuzuu/commands/web.mjs';
|
|
|
33
33
|
import { explain } from '../zuzuu/commands/explain.mjs';
|
|
34
34
|
import { inbox } from '../zuzuu/commands/inbox.mjs';
|
|
35
35
|
import { session } from '../zuzuu/commands/session.mjs';
|
|
36
|
+
import { faculty } from '../zuzuu/commands/faculty.mjs';
|
|
36
37
|
|
|
37
38
|
function parseArgs(argv) {
|
|
38
39
|
const a = { _: [] };
|
|
@@ -74,6 +75,10 @@ usage: zuzuu <command> [options]
|
|
|
74
75
|
recall "query" [--type t] [--attr k=v] [--related-to id] [--semantic]
|
|
75
76
|
search knowledge: lexical · graph · semantic
|
|
76
77
|
knowledge reindex|audit rebuild the search index · check registry/items health
|
|
78
|
+
faculty items <f> [--json|--jsonl]
|
|
79
|
+
list a faculty's envelope items (one doc · one line per item)
|
|
80
|
+
faculty schema <f> [--json]
|
|
81
|
+
print a faculty's payload schema (JSON-Schema subset)
|
|
77
82
|
digest [--json] [--budget N]
|
|
78
83
|
print the session-start grounding brief
|
|
79
84
|
act [list|show <slug>|new <slug>|schema <slug>]
|
|
@@ -95,7 +100,8 @@ usage: zuzuu <command> [options]
|
|
|
95
100
|
session [status|merge|continue|discard]
|
|
96
101
|
the invisible session branch (one per agent session)
|
|
97
102
|
eval [--faculty f] rank pending proposals by eval score, highest first
|
|
98
|
-
migrate [--home]
|
|
103
|
+
migrate [--home|--items] one-time migrators: proposal schema · --home moves agent/ → .zuzuu/
|
|
104
|
+
· --items rewrites legacy faculty shapes → the envelope standard
|
|
99
105
|
doctor environment + session health (reconciles lost sessions)
|
|
100
106
|
explain [topic] the 5 faculties + how graduation works
|
|
101
107
|
version print version
|
|
@@ -128,6 +134,7 @@ switch (cmd) {
|
|
|
128
134
|
case 'disable': disable(args); break;
|
|
129
135
|
case 'hook': runHook(args._[0], { host: args.host, session: args.session }); break;
|
|
130
136
|
case 'session': session(args); break;
|
|
137
|
+
case 'faculty': faculty(args); break;
|
|
131
138
|
case 'eval': evalCmd(args); break;
|
|
132
139
|
case 'migrate': migrate(args); break;
|
|
133
140
|
case 'generation': generation(args); break;
|
package/package.json
CHANGED
|
@@ -128,15 +128,104 @@ function binAvailable(binary) {
|
|
|
128
128
|
return false;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
// ── Faculty Standard envelope listing ────────────────────────────────────
|
|
132
|
+
// The CLI is the parser of record (`zuzuu faculty items <f> --json` returns
|
|
133
|
+
// the full envelopes incl. payload/body). When it's absent we degrade to a
|
|
134
|
+
// count-only frontmatter PEEK: read the items dir, lift the tiny top-level
|
|
135
|
+
// scalar lines (title:/status:/kind:) best-effort — counts still render,
|
|
136
|
+
// detail degrades. Never a re-implementation of the envelope grammar.
|
|
137
|
+
/** Flat envelope item dirs per faculty; actions are dir-shaped (ACTION.md). */
|
|
138
|
+
const ITEM_DIRS = {
|
|
139
|
+
knowledge: ["knowledge", "items"],
|
|
140
|
+
memory: ["memory", "entries"],
|
|
141
|
+
instructions: ["instructions", "items"],
|
|
142
|
+
guardrails: ["guardrails", "items"],
|
|
143
|
+
};
|
|
144
|
+
const PEEK_KEYS = new Set(["id", "faculty", "kind", "title", "status", "created_at", "updated_at"]);
|
|
145
|
+
function unquoteScalar(s) {
|
|
146
|
+
const t = s.trim();
|
|
147
|
+
if (t.startsWith('"') && t.endsWith('"') && t.length >= 2) {
|
|
148
|
+
try {
|
|
149
|
+
return JSON.parse(t);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return t.slice(1, -1);
|
|
153
|
+
}
|
|
136
154
|
}
|
|
137
|
-
|
|
138
|
-
return
|
|
155
|
+
if (t.startsWith("'") && t.endsWith("'") && t.length >= 2)
|
|
156
|
+
return t.slice(1, -1);
|
|
157
|
+
return t;
|
|
158
|
+
}
|
|
159
|
+
/** Best-effort peek at an envelope's top-level frontmatter scalars. */
|
|
160
|
+
function peekFrontmatter(text) {
|
|
161
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
162
|
+
if (!m)
|
|
163
|
+
return {};
|
|
164
|
+
const out = {};
|
|
165
|
+
for (const raw of (m[1] ?? "").split("\n")) {
|
|
166
|
+
if (/^\s/.test(raw))
|
|
167
|
+
continue; // indented = provenance/payload children
|
|
168
|
+
const kv = raw.match(/^([A-Za-z_][\w-]*):\s*(.*)$/);
|
|
169
|
+
if (kv && PEEK_KEYS.has(kv[1]))
|
|
170
|
+
out[kv[1]] = unquoteScalar(kv[2] ?? "");
|
|
139
171
|
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
/** CLI-less fallback: degraded envelope items (no payload/body) from disk. */
|
|
175
|
+
async function peekFacultyItems(agent, key) {
|
|
176
|
+
const files = [];
|
|
177
|
+
if (key === "actions") {
|
|
178
|
+
const base = path.join(agent, "actions");
|
|
179
|
+
let names = [];
|
|
180
|
+
try {
|
|
181
|
+
names = (await fsp.readdir(base)).sort();
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
for (const n of names) {
|
|
187
|
+
if (n === "inbox" || n === "proposals" || n === "_rolledback")
|
|
188
|
+
continue;
|
|
189
|
+
files.push({ id: n, file: path.join(base, n, "ACTION.md") });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const rel = ITEM_DIRS[key];
|
|
194
|
+
if (!rel)
|
|
195
|
+
return [];
|
|
196
|
+
const dir = path.join(agent, ...rel);
|
|
197
|
+
let names = [];
|
|
198
|
+
try {
|
|
199
|
+
names = (await fsp.readdir(dir)).sort();
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
for (const n of names) {
|
|
205
|
+
if (!n.endsWith(".md") || n === "README.md")
|
|
206
|
+
continue;
|
|
207
|
+
files.push({ id: n.replace(/\.md$/, ""), file: path.join(dir, n) });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const items = [];
|
|
211
|
+
for (const { id, file } of files) {
|
|
212
|
+
let fm;
|
|
213
|
+
try {
|
|
214
|
+
fm = peekFrontmatter(await fsp.readFile(file, "utf8"));
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
items.push({ kind: "?", ...fm, id: fm.id ?? id, faculty: key, title: fm.title ?? id });
|
|
220
|
+
}
|
|
221
|
+
return items;
|
|
222
|
+
}
|
|
223
|
+
/** One faculty's envelope items: CLI first (full envelopes), peek fallback. */
|
|
224
|
+
async function facultyEnvelopeItems(root, agent, key, binary) {
|
|
225
|
+
const viaCli = await runZuzuu(root, ["faculty", "items", key], { binary });
|
|
226
|
+
if (viaCli && Array.isArray(viaCli.items))
|
|
227
|
+
return { items: viaCli.items, errors: Array.isArray(viaCli.errors) ? viaCli.errors : [], degraded: false };
|
|
228
|
+
return { items: await peekFacultyItems(agent, key), errors: [], degraded: true };
|
|
140
229
|
}
|
|
141
230
|
/** Read every *.json in a dir into objects; missing dir → [], corrupt file → skipped. */
|
|
142
231
|
async function readJsonDir(dir) {
|
|
@@ -163,14 +252,6 @@ function proposalTitle(p) {
|
|
|
163
252
|
const payload = p.payload;
|
|
164
253
|
return firstLine(cand?.body ?? payload?.body ?? p.id);
|
|
165
254
|
}
|
|
166
|
-
/** The conventional item dir for a faculty, or null (heterogeneous faculties → counted as 0 for the MVP). */
|
|
167
|
-
function itemsDirOf(agent, key) {
|
|
168
|
-
if (key === "knowledge")
|
|
169
|
-
return path.join(agent, "knowledge", "items");
|
|
170
|
-
if (key === "memory")
|
|
171
|
-
return path.join(agent, "memory", "entries");
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
255
|
export function createZuzuuApi(getRoot, opts = {}) {
|
|
175
256
|
const app = new Hono();
|
|
176
257
|
let root = getRoot();
|
|
@@ -188,13 +269,13 @@ export function createZuzuuApi(getRoot, opts = {}) {
|
|
|
188
269
|
});
|
|
189
270
|
app.get("/faculties", async (c) => {
|
|
190
271
|
const agent = await agentDir();
|
|
191
|
-
const faculties =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
272
|
+
const faculties = await Promise.all(FACULTIES.map(async (key) => {
|
|
273
|
+
const [{ items }, proposals] = await Promise.all([
|
|
274
|
+
facultyEnvelopeItems(root, agent, key, opts.binary),
|
|
275
|
+
proposalsOf(agent, key),
|
|
276
|
+
]);
|
|
277
|
+
return { key, count: items.length, pending: proposals.length };
|
|
278
|
+
}));
|
|
198
279
|
return c.json({ faculties });
|
|
199
280
|
});
|
|
200
281
|
app.get("/faculty/:key", async (c) => {
|
|
@@ -202,12 +283,26 @@ export function createZuzuuApi(getRoot, opts = {}) {
|
|
|
202
283
|
if (!FACULTIES.includes(key))
|
|
203
284
|
return c.json({ error: "unknown faculty" }, 404);
|
|
204
285
|
const agent = await agentDir();
|
|
205
|
-
const
|
|
206
|
-
const items = itemsDir
|
|
207
|
-
? (await countItemFiles(itemsDir)).names.map((n) => ({ id: n.replace(/\.(json|md)$/, ""), title: n.replace(/\.(json|md)$/, "") }))
|
|
208
|
-
: [];
|
|
286
|
+
const { items, errors, degraded } = await facultyEnvelopeItems(root, agent, key, opts.binary);
|
|
209
287
|
const proposals = (await proposalsOf(agent, key)).map((p) => ({ id: String(p.id ?? "?"), faculty: key, title: proposalTitle(p) }));
|
|
210
|
-
return c.json({ key, items, proposals });
|
|
288
|
+
return c.json({ key, items, proposals, errors, ...(degraded ? { degraded: true } : {}) });
|
|
289
|
+
});
|
|
290
|
+
app.get("/faculty/:key/schema", async (c) => {
|
|
291
|
+
const key = c.req.param("key");
|
|
292
|
+
if (!FACULTIES.includes(key))
|
|
293
|
+
return c.json({ error: "unknown faculty" }, 404);
|
|
294
|
+
const viaCli = await runZuzuu(root, ["faculty", "schema", key], { binary: opts.binary });
|
|
295
|
+
if (viaCli)
|
|
296
|
+
return c.json({ key, schema: viaCli, source: "cli" });
|
|
297
|
+
// CLI absent → the seeded payload schema in the home (zuzuu init writes it)
|
|
298
|
+
const agent = await agentDir();
|
|
299
|
+
try {
|
|
300
|
+
const schema = JSON.parse(await fsp.readFile(path.join(agent, key, "schema.json"), "utf8"));
|
|
301
|
+
return c.json({ key, schema, source: "home" });
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return c.json({ key, schema: null, source: "absent" });
|
|
305
|
+
}
|
|
211
306
|
});
|
|
212
307
|
app.get("/generations", async (c) => {
|
|
213
308
|
const agent = await agentDir();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as e,f as t,u as n}from"./index
|
|
1
|
+
import{d as e,f as t,u as n}from"./index-DHpC851f.js";import{i as r,n as i,t as a}from"./monaco-setup-wbBeb0oN.js";var o=t();function s({path:t,name:s}){let{data:l,isLoading:u,error:d}=e({queryKey:[`git`,`diff`,t],queryFn:async()=>{let[e,r]=await Promise.all([n.gitDiff(t),n.readFile(t).catch(()=>``)]);return{original:e.original,working:r}}});return d?(0,o.jsx)(c,{danger:!0,children:d.message}):u||!l?(0,o.jsx)(c,{children:`loading diff…`}):(0,o.jsx)(r,{original:l.original,modified:l.working,language:i(s),theme:a(),options:{readOnly:!0,renderSideBySide:!0,fontFamily:`"JetBrains Mono Variable", ui-monospace, monospace`,fontSize:13,minimap:{enabled:!1},automaticLayout:!0}})}function c({children:e,danger:t}){return(0,o.jsx)(`div`,{className:`flex h-full items-center justify-center text-ui ${t?`text-danger`:`text-ink-500`}`,children:e})}export{s as DiffTab,s as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as e,l as t}from"./index
|
|
1
|
+
import{f as e,l as t}from"./index-DHpC851f.js";import{n,r,t as i}from"./monaco-setup-wbBeb0oN.js";var a=e();function o({path:e,name:o}){let c=t(t=>t.buffers[e]),l=t(e=>e.setValue),u=t(e=>e.save);return!c||c.loading?(0,a.jsx)(s,{children:`loading…`}):c.error?(0,a.jsx)(s,{danger:!0,children:c.error}):(0,a.jsx)(r,{path:e,language:n(o),theme:i(),value:c.value,onChange:t=>l(e,t??``),onMount:(t,n)=>{t.addCommand(n.KeyMod.CtrlCmd|n.KeyCode.KeyS,()=>{u(e)})},options:{fontFamily:`"JetBrains Mono Variable", ui-monospace, monospace`,fontSize:13,lineHeight:1.5,minimap:{enabled:!0,scale:1},scrollBeyondLastLine:!1,smoothScrolling:!0,renderWhitespace:`selection`,tabSize:2,automaticLayout:!0,padding:{top:8}}})}function s({children:e,danger:t}){return(0,a.jsx)(`div`,{className:`flex h-full items-center justify-center text-ui ${t?`text-danger`:`text-ink-500`}`,children:e})}export{o as MonacoFile,o as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{h as e}from"./editor.api2-BmGoRSl4.js";import{o as t}from"./monaco-setup-
|
|
1
|
+
import{h as e}from"./editor.api2-BmGoRSl4.js";import{o as t}from"./monaco-setup-wbBeb0oN.js";import{_ as n,a as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y}from"./lspLanguageFeatures-gTnJsses.js";var b=120*1e3,x=class{constructor(e){this._defaults=e,this._worker=null,this._client=null,this._idleCheckInterval=window.setInterval(()=>this._checkIfIdle(),30*1e3),this._lastUsedTime=0,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker())}_stopWorker(){this._worker&&=(this._worker.dispose(),null),this._client=null}dispose(){clearInterval(this._idleCheckInterval),this._configChangeListener.dispose(),this._stopWorker()}_checkIfIdle(){this._worker&&Date.now()-this._lastUsedTime>b&&this._stopWorker()}_getClient(){return this._lastUsedTime=Date.now(),this._client||=(this._worker=t({moduleId:`vs/language/css/cssWorker`,createWorker:()=>new Worker(new URL(`/assets/css.worker-CvXBzhp8.js`,``+import.meta.url),{type:`module`}),label:this._defaults.languageId,createData:{options:this._defaults.options,languageId:this._defaults.languageId}}),this._worker.getProxy()),this._client}getLanguageServiceWorker(...e){let t;return this._getClient().then(e=>{t=e}).then(t=>{if(this._worker)return this._worker.withSyncedResources(e)}).then(e=>t)}};function S(t){let n=[],s=[],c=new x(t);n.push(c);let g=(...e)=>c.getLanguageServiceWorker(...e);function y(){let{languageId:n,modeConfiguration:c}=t;w(s),c.completionItems&&s.push(e.registerCompletionItemProvider(n,new _(g,[`/`,`-`,`:`]))),c.hovers&&s.push(e.registerHoverProvider(n,new a(g))),c.documentHighlights&&s.push(e.registerDocumentHighlightProvider(n,new p(g))),c.definitions&&s.push(e.registerDefinitionProvider(n,new f(g))),c.references&&s.push(e.registerReferenceProvider(n,new o(g))),c.documentSymbols&&s.push(e.registerDocumentSymbolProvider(n,new u(g))),c.rename&&s.push(e.registerRenameProvider(n,new m(g))),c.colors&&s.push(e.registerColorProvider(n,new l(g))),c.foldingRanges&&s.push(e.registerFoldingRangeProvider(n,new v(g))),c.diagnostics&&s.push(new h(n,g,t.onDidChange)),c.selectionRanges&&s.push(e.registerSelectionRangeProvider(n,new d(g))),c.documentFormattingEdits&&s.push(e.registerDocumentFormattingEditProvider(n,new r(g))),c.documentRangeFormattingEdits&&s.push(e.registerDocumentRangeFormattingEditProvider(n,new i(g)))}return y(),n.push(C(s)),C(n)}function C(e){return{dispose:()=>w(e)}}function w(e){for(;e.length;)e.pop().dispose()}export{_ as CompletionAdapter,f as DefinitionAdapter,h as DiagnosticsAdapter,l as DocumentColorAdapter,r as DocumentFormattingEditProvider,p as DocumentHighlightAdapter,g as DocumentLinkAdapter,i as DocumentRangeFormattingEditProvider,u as DocumentSymbolAdapter,v as FoldingRangeAdapter,a as HoverAdapter,o as ReferenceAdapter,m as RenameAdapter,d as SelectionRangeAdapter,x as WorkerManager,c as fromPosition,s as fromRange,S as setupMode,n as toRange,y as toTextEdit};
|