@noir-ai/cli 1.0.0-beta.1 → 1.2.0-beta.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/dist/bin.js +154 -70
- package/dist/bin.js.map +1 -1
- package/dist/chunk-7WKKZ452.js +70 -0
- package/dist/chunk-7WKKZ452.js.map +1 -0
- package/dist/{chunk-UXT7YWQY.js → chunk-I3L3KNJM.js} +238 -86
- package/dist/chunk-I3L3KNJM.js.map +1 -0
- package/dist/create-ZK2EBXG3.js +43 -0
- package/dist/create-ZK2EBXG3.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +4 -2
- package/dist/sync-IEH2BVXU.js +46 -0
- package/dist/sync-IEH2BVXU.js.map +1 -0
- package/package.json +9 -8
- package/dist/chunk-UXT7YWQY.js.map +0 -1
- package/dist/sync-7YLRJYMR.js +0 -20
- package/dist/sync-7YLRJYMR.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -7,15 +7,20 @@ import {
|
|
|
7
7
|
handleError,
|
|
8
8
|
inferExitCode,
|
|
9
9
|
info,
|
|
10
|
-
init,
|
|
11
10
|
isInteractive,
|
|
12
11
|
log,
|
|
13
12
|
serve,
|
|
14
|
-
table
|
|
15
|
-
|
|
13
|
+
table,
|
|
14
|
+
warn
|
|
15
|
+
} from "./chunk-I3L3KNJM.js";
|
|
16
|
+
import {
|
|
17
|
+
init
|
|
18
|
+
} from "./chunk-7WKKZ452.js";
|
|
16
19
|
|
|
17
20
|
// src/bin.ts
|
|
21
|
+
import { realpathSync } from "fs";
|
|
18
22
|
import { pathToFileURL } from "url";
|
|
23
|
+
import { SUPPORTED_HOSTS } from "@noir-ai/adapters";
|
|
19
24
|
import { NOIR_VERSION as NOIR_VERSION3 } from "@noir-ai/core";
|
|
20
25
|
import { Command, Option } from "commander";
|
|
21
26
|
|
|
@@ -58,7 +63,7 @@ async function probeDaemon(opts = {}) {
|
|
|
58
63
|
return { running: false };
|
|
59
64
|
}
|
|
60
65
|
const body = await res.json().catch(() => null);
|
|
61
|
-
if (
|
|
66
|
+
if (body?.ok !== true) {
|
|
62
67
|
if (opts.verbose) process.stderr.write("noir: daemon probe: /health body not ok\n");
|
|
63
68
|
return { running: false };
|
|
64
69
|
}
|
|
@@ -95,7 +100,7 @@ async function connectClient(client, url, opts) {
|
|
|
95
100
|
async function callToolParse(client, opts, name, args) {
|
|
96
101
|
const result = await client.callTool({ name, arguments: args }).catch((err) => failDaemonDown(opts, err));
|
|
97
102
|
const block = result.content?.[0];
|
|
98
|
-
if (
|
|
103
|
+
if (block?.type !== "text" || typeof block.text !== "string") {
|
|
99
104
|
failDaemonDown(opts, new Error(`tool '${name}' returned no text content`));
|
|
100
105
|
}
|
|
101
106
|
const text = block.text;
|
|
@@ -183,10 +188,10 @@ function failTool(label, envelope, opts) {
|
|
|
183
188
|
function toHit(raw) {
|
|
184
189
|
const h = raw ?? {};
|
|
185
190
|
return {
|
|
186
|
-
path: typeof h
|
|
187
|
-
score: typeof h
|
|
188
|
-
snippet: typeof h
|
|
189
|
-
source: typeof h
|
|
191
|
+
path: typeof h.path === "string" ? h.path : "<unknown>",
|
|
192
|
+
score: typeof h.score === "number" ? h.score : 0,
|
|
193
|
+
snippet: typeof h.snippet === "string" ? h.snippet : "",
|
|
194
|
+
source: typeof h.source === "string" ? h.source : ""
|
|
190
195
|
};
|
|
191
196
|
}
|
|
192
197
|
async function contextSearch(opts) {
|
|
@@ -422,7 +427,7 @@ async function daemonStatus(opts) {
|
|
|
422
427
|
} catch {
|
|
423
428
|
health = null;
|
|
424
429
|
}
|
|
425
|
-
if (
|
|
430
|
+
if (health?.ok !== true) {
|
|
426
431
|
clearDaemonRecord();
|
|
427
432
|
fail(
|
|
428
433
|
EXIT.DAEMON_DOWN,
|
|
@@ -553,15 +558,15 @@ function toHit2(raw) {
|
|
|
553
558
|
const h = raw ?? {};
|
|
554
559
|
const arr = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
555
560
|
return {
|
|
556
|
-
id: typeof h
|
|
557
|
-
type: typeof h
|
|
558
|
-
score: typeof h
|
|
559
|
-
content: typeof h
|
|
560
|
-
concepts: arr(h
|
|
561
|
-
files: arr(h
|
|
562
|
-
ts: typeof h
|
|
563
|
-
importance: typeof h
|
|
564
|
-
source: typeof h
|
|
561
|
+
id: typeof h.id === "string" ? h.id : "",
|
|
562
|
+
type: typeof h.type === "string" ? h.type : "",
|
|
563
|
+
score: typeof h.score === "number" ? h.score : 0,
|
|
564
|
+
content: typeof h.content === "string" ? h.content : "",
|
|
565
|
+
concepts: arr(h.concepts),
|
|
566
|
+
files: arr(h.files),
|
|
567
|
+
ts: typeof h.ts === "number" ? h.ts : 0,
|
|
568
|
+
importance: typeof h.importance === "number" ? h.importance : 0,
|
|
569
|
+
source: typeof h.source === "string" ? h.source : ""
|
|
565
570
|
};
|
|
566
571
|
}
|
|
567
572
|
function failTool2(label, envelope, opts) {
|
|
@@ -612,8 +617,8 @@ async function memorySave(opts) {
|
|
|
612
617
|
const content = await resolveContent(opts);
|
|
613
618
|
const files = splitCsv(opts.files);
|
|
614
619
|
const args = { content };
|
|
615
|
-
if (typeof opts.type === "string" && opts.type.length > 0) args
|
|
616
|
-
if (files !== void 0) args
|
|
620
|
+
if (typeof opts.type === "string" && opts.type.length > 0) args.type = opts.type;
|
|
621
|
+
if (files !== void 0) args.files = files;
|
|
617
622
|
const res = await callDaemonTool(opts, "memory_save", args);
|
|
618
623
|
if (res.ok !== true) failTool2("memory save", res, opts);
|
|
619
624
|
const id = typeof res.id === "string" ? res.id : "";
|
|
@@ -654,7 +659,7 @@ function renderObservation(obs, opts) {
|
|
|
654
659
|
if (obs[key] !== void 0) rows.push({ Field: key, Value: obs[key] });
|
|
655
660
|
}
|
|
656
661
|
if (rows.length > 0) table(rows, ["Field", "Value"], opts);
|
|
657
|
-
const content = obs
|
|
662
|
+
const content = obs.content;
|
|
658
663
|
if (typeof content === "string") log(`
|
|
659
664
|
${content}`, opts);
|
|
660
665
|
}
|
|
@@ -664,9 +669,9 @@ async function memorySessions(opts) {
|
|
|
664
669
|
const sessions = Array.isArray(res.sessions) ? res.sessions.map((raw) => {
|
|
665
670
|
const s = raw ?? {};
|
|
666
671
|
return {
|
|
667
|
-
id: typeof s
|
|
668
|
-
count: typeof s
|
|
669
|
-
lastTs: typeof s
|
|
672
|
+
id: typeof s.id === "string" ? s.id : "",
|
|
673
|
+
count: typeof s.count === "number" ? s.count : 0,
|
|
674
|
+
lastTs: typeof s.lastTs === "number" ? s.lastTs : 0
|
|
670
675
|
};
|
|
671
676
|
}) : [];
|
|
672
677
|
const data = { sessions };
|
|
@@ -711,8 +716,8 @@ async function memoryConsolidate(opts) {
|
|
|
711
716
|
const types = splitCsv(opts.types);
|
|
712
717
|
const limit = parseLimit2(opts.limit, "memory consolidate", opts);
|
|
713
718
|
const args = {};
|
|
714
|
-
if (types !== void 0) args
|
|
715
|
-
if (limit !== void 0) args
|
|
719
|
+
if (types !== void 0) args.types = types;
|
|
720
|
+
if (limit !== void 0) args.limit = limit;
|
|
716
721
|
const res = await callDaemonTool(
|
|
717
722
|
opts,
|
|
718
723
|
"memory_consolidate",
|
|
@@ -735,15 +740,15 @@ async function memoryConsolidate(opts) {
|
|
|
735
740
|
const l = lessons[i];
|
|
736
741
|
if (l === void 0) continue;
|
|
737
742
|
const obs = l ?? {};
|
|
738
|
-
const id = typeof obs
|
|
739
|
-
const content = typeof obs
|
|
743
|
+
const id = typeof obs.id === "string" ? obs.id : `<lesson ${i + 1}>`;
|
|
744
|
+
const content = typeof obs.content === "string" ? obs.content : "";
|
|
740
745
|
log(`- ${id}: ${content}`, opts);
|
|
741
746
|
}
|
|
742
747
|
return;
|
|
743
748
|
}
|
|
744
749
|
const env = res;
|
|
745
|
-
const reason = (typeof env
|
|
746
|
-
const logged = env
|
|
750
|
+
const reason = (typeof env.reason === "string" ? env.reason : void 0) ?? (typeof env.error === "string" ? env.error : void 0) ?? "unknown";
|
|
751
|
+
const logged = env.logged === true || env.degraded === true;
|
|
747
752
|
const suffix = logged ? " (logged)" : "";
|
|
748
753
|
fail(EXIT.ERROR, `memory consolidate did not run: ${reason}${suffix}`, opts);
|
|
749
754
|
}
|
|
@@ -751,7 +756,10 @@ async function memoryConsolidate(opts) {
|
|
|
751
756
|
// src/commands/skills.ts
|
|
752
757
|
import { claudeAdapter } from "@noir-ai/adapters";
|
|
753
758
|
import { loadProjectInfo as loadProjectInfo4 } from "@noir-ai/core";
|
|
754
|
-
import {
|
|
759
|
+
import {
|
|
760
|
+
discoverAll,
|
|
761
|
+
emitSkillsToDir
|
|
762
|
+
} from "@noir-ai/skills";
|
|
755
763
|
var CATEGORY = {
|
|
756
764
|
"noir-brainstorm": "discovery",
|
|
757
765
|
"noir-intake": "discovery",
|
|
@@ -790,9 +798,9 @@ function categoryOf(name) {
|
|
|
790
798
|
if (mapped !== void 0) return mapped;
|
|
791
799
|
return name.replace(/^noir-/, "") || "general";
|
|
792
800
|
}
|
|
793
|
-
function toRow(s) {
|
|
801
|
+
function toRow(s, kind = "builtin") {
|
|
794
802
|
const description = typeof s.frontmatter.description === "string" ? s.frontmatter.description : "";
|
|
795
|
-
return { name: s.name, category: categoryOf(s.name), description };
|
|
803
|
+
return { name: s.name, category: categoryOf(s.name), description, kind };
|
|
796
804
|
}
|
|
797
805
|
function truncate(text, max) {
|
|
798
806
|
if (text.length <= max) return text;
|
|
@@ -803,30 +811,39 @@ function truncate(text, max) {
|
|
|
803
811
|
}
|
|
804
812
|
async function skillsList(opts) {
|
|
805
813
|
let builtins;
|
|
814
|
+
let integrations;
|
|
806
815
|
try {
|
|
807
|
-
|
|
816
|
+
const all = discoverAll();
|
|
817
|
+
builtins = all.builtins;
|
|
818
|
+
integrations = all.integrations;
|
|
808
819
|
} catch (err) {
|
|
809
820
|
fail(
|
|
810
821
|
EXIT.ERROR,
|
|
811
|
-
`skills list: could not discover
|
|
822
|
+
`skills list: could not discover skills (${err instanceof Error ? err.message : String(err)})`,
|
|
812
823
|
opts
|
|
813
824
|
);
|
|
814
825
|
}
|
|
815
|
-
const rows =
|
|
826
|
+
const rows = [
|
|
827
|
+
...builtins.map((b) => toRow(b, "builtin")),
|
|
828
|
+
...integrations.map((i) => toRow(i, "integration"))
|
|
829
|
+
];
|
|
816
830
|
const data = { count: rows.length, skills: rows };
|
|
817
831
|
if (opts.json === true) {
|
|
818
832
|
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
819
833
|
`);
|
|
820
834
|
return;
|
|
821
835
|
}
|
|
822
|
-
|
|
836
|
+
const intCount = integrations.length;
|
|
837
|
+
const banner = intCount > 0 ? `noir skills \u2014 ${rows.length} skill${rows.length === 1 ? "" : "s"} (${builtins.length} builtin, ${intCount} integration${intCount === 1 ? "" : "s"})` : `noir skills \u2014 ${rows.length} builtin skill${rows.length === 1 ? "" : "s"}`;
|
|
838
|
+
log(banner, opts);
|
|
823
839
|
table(
|
|
824
840
|
rows.map((r) => ({
|
|
825
841
|
Skill: r.name,
|
|
842
|
+
Kind: r.kind,
|
|
826
843
|
Category: r.category,
|
|
827
844
|
Description: truncate(r.description, 80)
|
|
828
845
|
})),
|
|
829
|
-
["Skill", "Category", "Description"],
|
|
846
|
+
["Skill", "Kind", "Category", "Description"],
|
|
830
847
|
opts
|
|
831
848
|
);
|
|
832
849
|
}
|
|
@@ -850,10 +867,12 @@ async function skillsSync(opts) {
|
|
|
850
867
|
}
|
|
851
868
|
const dir = claudeAdapter.skillsDir({ root });
|
|
852
869
|
const summary = await emitSkillsToDir(dir);
|
|
870
|
+
const pruned = summary.pruned ?? [];
|
|
853
871
|
const data = {
|
|
854
872
|
emitted: summary.emitted,
|
|
855
873
|
references: summary.references,
|
|
856
|
-
dir
|
|
874
|
+
dir,
|
|
875
|
+
pruned
|
|
857
876
|
};
|
|
858
877
|
if (opts.json === true) {
|
|
859
878
|
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
@@ -864,6 +883,12 @@ async function skillsSync(opts) {
|
|
|
864
883
|
`Synced ${summary.emitted.length} Noir skill${summary.emitted.length === 1 ? "" : "s"} to ${dir}.`,
|
|
865
884
|
opts
|
|
866
885
|
);
|
|
886
|
+
if (pruned.length > 0) {
|
|
887
|
+
warn(
|
|
888
|
+
`Pruned ${pruned.length} stale noir-* skill dir${pruned.length === 1 ? "" : "s"}: ${pruned.join(", ")}`,
|
|
889
|
+
opts
|
|
890
|
+
);
|
|
891
|
+
}
|
|
867
892
|
}
|
|
868
893
|
|
|
869
894
|
// src/commands/status.ts
|
|
@@ -876,7 +901,7 @@ async function tryTool(caller, name) {
|
|
|
876
901
|
}
|
|
877
902
|
}
|
|
878
903
|
function pickStore(s) {
|
|
879
|
-
if (
|
|
904
|
+
if (s?.ok !== true) return null;
|
|
880
905
|
return {
|
|
881
906
|
docCount: s.docCount,
|
|
882
907
|
vecCount: s.vecCount,
|
|
@@ -890,7 +915,7 @@ function describeEmbedder2(e) {
|
|
|
890
915
|
return `${e.kind} \xB7 ${model} (${e.dim}-dim)`;
|
|
891
916
|
}
|
|
892
917
|
function pickContext(c) {
|
|
893
|
-
if (
|
|
918
|
+
if (c?.ok !== true) return null;
|
|
894
919
|
return {
|
|
895
920
|
docCount: c.docCount,
|
|
896
921
|
vecCount: c.vecCount,
|
|
@@ -900,7 +925,7 @@ function pickContext(c) {
|
|
|
900
925
|
};
|
|
901
926
|
}
|
|
902
927
|
function pickWorkflow(w) {
|
|
903
|
-
if (
|
|
928
|
+
if (w?.ok !== true) return null;
|
|
904
929
|
return {
|
|
905
930
|
taskId: w.taskId,
|
|
906
931
|
phase: w.phase,
|
|
@@ -911,7 +936,7 @@ function pickWorkflow(w) {
|
|
|
911
936
|
};
|
|
912
937
|
}
|
|
913
938
|
function pickMemory(m) {
|
|
914
|
-
if (
|
|
939
|
+
if (m?.ok !== true || !Array.isArray(m.sessions)) return null;
|
|
915
940
|
let observations = 0;
|
|
916
941
|
for (const s of m.sessions) observations += s.count;
|
|
917
942
|
return { sessions: m.sessions.length, observations };
|
|
@@ -1186,15 +1211,20 @@ function toStatusOptions(g) {
|
|
|
1186
1211
|
input: g.input !== false
|
|
1187
1212
|
};
|
|
1188
1213
|
}
|
|
1214
|
+
function parseHost(raw) {
|
|
1215
|
+
if (raw === void 0) return void 0;
|
|
1216
|
+
return raw;
|
|
1217
|
+
}
|
|
1189
1218
|
function createProgram() {
|
|
1190
1219
|
const program2 = new Command();
|
|
1191
1220
|
program2.name("noir").description("Noir \u2014 discipline, context, and memory layer for agentic CLIs.").version(NOIR_VERSION3, "-v, --version").addOption(new Option("--json", "emit machine-readable JSON to stdout")).addOption(new Option("--no-input", "never prompt; error if input is required")).addOption(new Option("--quiet", "suppress non-essential diagnostics")).addOption(new Option("--verbose", "show additional diagnostic detail")).addOption(new Option("--cwd <path>", "run as if started in <path>")).exitOverride((err) => {
|
|
1192
1221
|
throw err;
|
|
1193
1222
|
}).configureOutput({
|
|
1194
|
-
//
|
|
1195
|
-
// errors
|
|
1196
|
-
//
|
|
1197
|
-
|
|
1223
|
+
// Stream discipline: --help/--version → stdout (conventional; users pipe
|
|
1224
|
+
// them), errors → stderr. --json data is emitted by command actions via
|
|
1225
|
+
// process.stdout directly, NOT by commander's writeOut, so routing help/
|
|
1226
|
+
// version to stdout does not conflict with --json payloads.
|
|
1227
|
+
writeOut: (str) => process.stdout.write(str),
|
|
1198
1228
|
writeErr: (str) => process.stderr.write(str)
|
|
1199
1229
|
});
|
|
1200
1230
|
program2.hook("preAction", (_thisCmd, actionCmd) => {
|
|
@@ -1211,13 +1241,66 @@ function createProgram() {
|
|
|
1211
1241
|
}
|
|
1212
1242
|
}
|
|
1213
1243
|
});
|
|
1214
|
-
program2.command("init").description("scaffold Noir in the current project (.noir/, .mcp.json, CLAUDE.md, skills)").option("--transport <transport>", "stdio | streamable-http (default: stdio)", "stdio").option("--url <url>", "streamable-http daemon URL (localhost only)").
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1244
|
+
program2.command("init").description("scaffold Noir in the current project (.noir/, .mcp.json, CLAUDE.md, skills)").option("--transport <transport>", "stdio | streamable-http (default: stdio)", "stdio").option("--url <url>", "streamable-http daemon URL (localhost only)").option(
|
|
1245
|
+
"--upgrade",
|
|
1246
|
+
"run scaffold migrations before re-emitting (re-run on an existing project)"
|
|
1247
|
+
).addOption(
|
|
1248
|
+
// S10: target host. Defaults to `'claude'` (the regression anchor). The
|
|
1249
|
+
// chosen host is forwarded to scaffold() + skills emission via
|
|
1250
|
+
// resolveAdapter. The choice list mirrors `SUPPORTED_HOSTS` so a new host
|
|
1251
|
+
// lands here automatically; commander rejects anything else as usage=2.
|
|
1252
|
+
new Option(
|
|
1253
|
+
"--host <id>",
|
|
1254
|
+
"target agentic CLI (default: claude) \u2014 drives host-side emission"
|
|
1255
|
+
).choices(SUPPORTED_HOSTS)
|
|
1256
|
+
).action(
|
|
1257
|
+
async (opts) => {
|
|
1258
|
+
const transport = opts.transport === "streamable-http" ? "streamable-http" : "stdio";
|
|
1259
|
+
const upgrade = opts.upgrade === true;
|
|
1260
|
+
const host = parseHost(opts.host);
|
|
1261
|
+
await init(process.cwd(), {
|
|
1262
|
+
transport,
|
|
1263
|
+
url: opts.url,
|
|
1264
|
+
...upgrade ? { upgrade } : {},
|
|
1265
|
+
...host !== void 0 ? { host } : {}
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
);
|
|
1269
|
+
program2.command("create [dir]").description("bootstrap the Noir AI layer in a new or empty directory").option("--transport <transport>", "stdio | streamable-http (default: stdio)", "stdio").option("--url <url>", "streamable-http daemon URL (localhost only)").addOption(
|
|
1270
|
+
new Option(
|
|
1271
|
+
"--host <id>",
|
|
1272
|
+
"target agentic CLI (default: claude) \u2014 drives host-side emission"
|
|
1273
|
+
).choices(SUPPORTED_HOSTS)
|
|
1274
|
+
).action(
|
|
1275
|
+
async (dir, opts) => {
|
|
1276
|
+
const transport = opts.transport === "streamable-http" ? "streamable-http" : "stdio";
|
|
1277
|
+
const host = parseHost(opts.host);
|
|
1278
|
+
const { create } = await import("./create-ZK2EBXG3.js");
|
|
1279
|
+
await create(dir, {
|
|
1280
|
+
transport,
|
|
1281
|
+
url: opts.url,
|
|
1282
|
+
...host !== void 0 ? { host } : {}
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
);
|
|
1286
|
+
program2.command("sync").description(
|
|
1287
|
+
"re-emit Noir managed files (.mcp.json, CLAUDE.md blocks, NOIR.md brief, ignores) + skills"
|
|
1288
|
+
).addOption(
|
|
1289
|
+
// S10: optional `--host` override. When omitted, sync reads host from
|
|
1290
|
+
// `.noir/config.yml` (whatever `noir init --host <id>` persisted). The
|
|
1291
|
+
// override is rarely needed — documented as advanced.
|
|
1292
|
+
new Option(
|
|
1293
|
+
"--host <id>",
|
|
1294
|
+
"override the configured host (advanced; default reads .noir/config.yml)"
|
|
1295
|
+
).choices(SUPPORTED_HOSTS)
|
|
1296
|
+
).action(async (opts) => {
|
|
1297
|
+
const { sync } = await import("./sync-IEH2BVXU.js");
|
|
1298
|
+
const host = parseHost(opts.host);
|
|
1299
|
+
if (host === void 0) {
|
|
1300
|
+
await sync(process.cwd());
|
|
1301
|
+
} else {
|
|
1302
|
+
await sync(process.cwd(), { host });
|
|
1303
|
+
}
|
|
1221
1304
|
});
|
|
1222
1305
|
const mcpCmd = program2.command("mcp").description("MCP server control");
|
|
1223
1306
|
mcpCmd.command("serve").description("run the Noir MCP server (stdio, or via the shared daemon)").option("--stdio", "force the stdio transport").action(async (opts) => {
|
|
@@ -1230,7 +1313,7 @@ function createProgram() {
|
|
|
1230
1313
|
daemonGrp.command("start").description("start the Noir daemon (foreground; backgrounding deferred)").option("--detach", "run in the background (not yet implemented; exits 2)").action(async (...args) => {
|
|
1231
1314
|
const cmd = trailingCmd(args);
|
|
1232
1315
|
const g = cmd.optsWithGlobals();
|
|
1233
|
-
const detach = g
|
|
1316
|
+
const detach = g.detach === true;
|
|
1234
1317
|
await daemonStart({ ...toCliOptions(g), ...detach ? { detach } : {} });
|
|
1235
1318
|
});
|
|
1236
1319
|
daemonGrp.command("stop").description("stop the Noir daemon").action(async (...args) => {
|
|
@@ -1256,7 +1339,7 @@ function createProgram() {
|
|
|
1256
1339
|
const cmd = trailingCmd(args);
|
|
1257
1340
|
const g = cmd.optsWithGlobals();
|
|
1258
1341
|
const query = typeof args[0] === "string" ? args[0] : "";
|
|
1259
|
-
const limit = typeof g
|
|
1342
|
+
const limit = typeof g.limit === "string" ? g.limit : void 0;
|
|
1260
1343
|
await contextSearch({
|
|
1261
1344
|
...toCliOptions(g),
|
|
1262
1345
|
query,
|
|
@@ -1271,8 +1354,8 @@ function createProgram() {
|
|
|
1271
1354
|
).option("--force", "ignore content-hash caching (recognized; not yet honored)").action(async (...args) => {
|
|
1272
1355
|
const cmd = trailingCmd(args);
|
|
1273
1356
|
const g = cmd.optsWithGlobals();
|
|
1274
|
-
const rawPaths = Array.isArray(g
|
|
1275
|
-
const force = g
|
|
1357
|
+
const rawPaths = Array.isArray(g.path) ? g.path.filter((p) => typeof p === "string") : [];
|
|
1358
|
+
const force = g.force === true;
|
|
1276
1359
|
await contextIndex({
|
|
1277
1360
|
...toCliOptions(g),
|
|
1278
1361
|
...rawPaths.length === 0 ? {} : { paths: rawPaths },
|
|
@@ -1290,7 +1373,7 @@ function createProgram() {
|
|
|
1290
1373
|
const cmd = trailingCmd(args);
|
|
1291
1374
|
const g = cmd.optsWithGlobals();
|
|
1292
1375
|
const query = typeof args[0] === "string" ? args[0] : "";
|
|
1293
|
-
const limit = typeof g
|
|
1376
|
+
const limit = typeof g.limit === "string" ? g.limit : void 0;
|
|
1294
1377
|
await memoryRecall({
|
|
1295
1378
|
...toCliOptions(g),
|
|
1296
1379
|
query,
|
|
@@ -1303,9 +1386,9 @@ function createProgram() {
|
|
|
1303
1386
|
).option("--files <files>", "comma-separated related file paths").action(async (...args) => {
|
|
1304
1387
|
const cmd = trailingCmd(args);
|
|
1305
1388
|
const g = cmd.optsWithGlobals();
|
|
1306
|
-
const content = typeof g
|
|
1307
|
-
const type = typeof g
|
|
1308
|
-
const files = typeof g
|
|
1389
|
+
const content = typeof g.content === "string" ? g.content : void 0;
|
|
1390
|
+
const type = typeof g.type === "string" ? g.type : void 0;
|
|
1391
|
+
const files = typeof g.files === "string" ? g.files : void 0;
|
|
1309
1392
|
await memorySave({
|
|
1310
1393
|
...toCliOptions(g),
|
|
1311
1394
|
...content === void 0 ? {} : { content },
|
|
@@ -1326,8 +1409,8 @@ function createProgram() {
|
|
|
1326
1409
|
memoryGrp.command("consolidate").description("consolidate memories into a derived lesson (provider-explicit)").option("--types <types>", "comma-separated observation types to consolidate").option("--limit <n>", "cap on candidate observations").action(async (...args) => {
|
|
1327
1410
|
const cmd = trailingCmd(args);
|
|
1328
1411
|
const g = cmd.optsWithGlobals();
|
|
1329
|
-
const types = typeof g
|
|
1330
|
-
const limit = typeof g
|
|
1412
|
+
const types = typeof g.types === "string" ? g.types : void 0;
|
|
1413
|
+
const limit = typeof g.limit === "string" ? g.limit : void 0;
|
|
1331
1414
|
await memoryConsolidate({
|
|
1332
1415
|
...toCliOptions(g),
|
|
1333
1416
|
...types === void 0 ? {} : { types },
|
|
@@ -1354,8 +1437,8 @@ function createProgram() {
|
|
|
1354
1437
|
taskGrp.command("new").description("start a new workflow task").requiredOption("--slug <slug>", "task slug").option("--mode <mode>", "full | quick").action(async (...args) => {
|
|
1355
1438
|
const cmd = trailingCmd(args);
|
|
1356
1439
|
const g = cmd.optsWithGlobals();
|
|
1357
|
-
const slug = typeof g
|
|
1358
|
-
const mode = typeof g
|
|
1440
|
+
const slug = typeof g.slug === "string" ? g.slug : "";
|
|
1441
|
+
const mode = typeof g.mode === "string" ? g.mode : void 0;
|
|
1359
1442
|
await taskNew({
|
|
1360
1443
|
...toCliOptions(g),
|
|
1361
1444
|
slug,
|
|
@@ -1375,8 +1458,8 @@ function createProgram() {
|
|
|
1375
1458
|
taskGrp.command("advance").description("advance the active task to the next phase").option("--to <phase>", "target phase").option("--force <reason>", "force the gate with a reason").action(async (...args) => {
|
|
1376
1459
|
const cmd = trailingCmd(args);
|
|
1377
1460
|
const g = cmd.optsWithGlobals();
|
|
1378
|
-
const to = typeof g
|
|
1379
|
-
const force = typeof g
|
|
1461
|
+
const to = typeof g.to === "string" ? g.to : void 0;
|
|
1462
|
+
const force = typeof g.force === "string" ? g.force : void 0;
|
|
1380
1463
|
await taskAdvance({
|
|
1381
1464
|
...toCliOptions(g),
|
|
1382
1465
|
...to === void 0 ? {} : { to },
|
|
@@ -1425,7 +1508,8 @@ async function run(argv = []) {
|
|
|
1425
1508
|
var isMainModule = (() => {
|
|
1426
1509
|
try {
|
|
1427
1510
|
const entry = process.argv[1];
|
|
1428
|
-
|
|
1511
|
+
if (typeof entry !== "string" || entry.length === 0) return false;
|
|
1512
|
+
return pathToFileURL(realpathSync(entry)).href === import.meta.url;
|
|
1429
1513
|
} catch {
|
|
1430
1514
|
return false;
|
|
1431
1515
|
}
|