@noir-ai/cli 1.9.3 → 1.9.4-beta.1
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/README.md +1 -1
- package/dist/bin.js +107 -29
- package/dist/bin.js.map +1 -1
- package/dist/tui/index.js +107 -29
- package/dist/tui/index.js.map +1 -1
- package/package.json +11 -11
package/dist/tui/index.js
CHANGED
|
@@ -778,13 +778,15 @@ async function status(opts) {
|
|
|
778
778
|
// src/commands/task.ts
|
|
779
779
|
import { PHASES } from "@noir-ai/workflow";
|
|
780
780
|
var PHASE_SKILL = {
|
|
781
|
-
|
|
782
|
-
|
|
781
|
+
// C3 curation (2026-08-10): intake+clarify merged into brainstorming;
|
|
782
|
+
// execute → executing-plans; verify → verifying; document → wrap.
|
|
783
|
+
intake: "noir-brainstorming",
|
|
784
|
+
clarify: "noir-brainstorming",
|
|
783
785
|
spec: "noir-spec",
|
|
784
|
-
plan: "noir-
|
|
785
|
-
execute: "noir-
|
|
786
|
-
verify: "noir-
|
|
787
|
-
document: "noir-
|
|
786
|
+
plan: "noir-planning",
|
|
787
|
+
execute: "noir-executing-plans",
|
|
788
|
+
verify: "noir-verifying",
|
|
789
|
+
document: "noir-wrap"
|
|
788
790
|
};
|
|
789
791
|
function skillFor(phase) {
|
|
790
792
|
if (typeof phase !== "string") return null;
|
|
@@ -1907,41 +1909,38 @@ async function memoryConsolidate(opts) {
|
|
|
1907
1909
|
import { claudeAdapter } from "@noir-ai/adapters";
|
|
1908
1910
|
import { loadProjectInfo as loadProjectInfo6 } from "@noir-ai/core";
|
|
1909
1911
|
import {
|
|
1912
|
+
buildRegistry,
|
|
1910
1913
|
discoverAll,
|
|
1911
|
-
emitSkillsToDir
|
|
1914
|
+
emitSkillsToDir,
|
|
1915
|
+
lintSkill
|
|
1912
1916
|
} from "@noir-ai/skills";
|
|
1913
1917
|
var CATEGORY = {
|
|
1914
|
-
"noir-
|
|
1915
|
-
"noir-
|
|
1916
|
-
"noir-
|
|
1917
|
-
"noir-
|
|
1918
|
+
"noir-brainstorming": "discovery",
|
|
1919
|
+
"noir-sync": "discovery",
|
|
1920
|
+
"noir-checkpoint": "discovery",
|
|
1921
|
+
"noir-exploring": "discovery",
|
|
1918
1922
|
"noir-spec": "spec",
|
|
1919
|
-
"noir-
|
|
1920
|
-
"noir-
|
|
1921
|
-
"noir-
|
|
1922
|
-
"noir-
|
|
1923
|
+
"noir-planning": "plan",
|
|
1924
|
+
"noir-prd": "plan",
|
|
1925
|
+
"noir-executing-plans": "execute",
|
|
1926
|
+
"noir-test-driven-development": "execute",
|
|
1927
|
+
"noir-systematic-debugging": "execute",
|
|
1923
1928
|
"noir-subagent": "execute",
|
|
1924
1929
|
"noir-parallel": "execute",
|
|
1925
|
-
"noir-
|
|
1926
|
-
"noir-review": "verify",
|
|
1930
|
+
"noir-verifying": "verify",
|
|
1927
1931
|
"noir-security": "verify",
|
|
1928
|
-
"noir-
|
|
1929
|
-
"noir-document": "document",
|
|
1932
|
+
"noir-wrap": "document",
|
|
1930
1933
|
"noir-readme": "document",
|
|
1931
|
-
"noir-
|
|
1932
|
-
"noir-branch": "git",
|
|
1933
|
-
"noir-pr": "git",
|
|
1934
|
+
"noir-shipping": "git",
|
|
1934
1935
|
"noir-worktree": "git",
|
|
1935
1936
|
"noir-recall": "memory",
|
|
1936
1937
|
"noir-remember": "memory",
|
|
1937
|
-
"noir-checkpoint": "memory",
|
|
1938
1938
|
"noir-context": "context",
|
|
1939
1939
|
"noir-frontend": "domain",
|
|
1940
1940
|
"noir-backend": "domain",
|
|
1941
1941
|
"noir-doctor": "meta",
|
|
1942
|
-
"noir-
|
|
1943
|
-
"noir-
|
|
1944
|
-
"noir-wrap": "meta"
|
|
1942
|
+
"noir-writing-skills": "meta",
|
|
1943
|
+
"noir-rules": "meta"
|
|
1945
1944
|
};
|
|
1946
1945
|
function categoryOf(name) {
|
|
1947
1946
|
const mapped = CATEGORY[name];
|
|
@@ -1950,7 +1949,9 @@ function categoryOf(name) {
|
|
|
1950
1949
|
}
|
|
1951
1950
|
function toRow(s, kind = "builtin") {
|
|
1952
1951
|
const description = typeof s.frontmatter.description === "string" ? s.frontmatter.description : "";
|
|
1953
|
-
|
|
1952
|
+
const status2 = s.skillMd.includes("> **Stub:**") ? "stub" : "full";
|
|
1953
|
+
const category = s.frontmatter.metadata?.category?.trim() || categoryOf(s.name);
|
|
1954
|
+
return { name: s.name, category, description, kind, status: status2 };
|
|
1954
1955
|
}
|
|
1955
1956
|
function truncate(text, max) {
|
|
1956
1957
|
if (text.length <= max) return text;
|
|
@@ -1991,9 +1992,10 @@ async function skillsList(opts) {
|
|
|
1991
1992
|
Skill: r.name,
|
|
1992
1993
|
Kind: r.kind,
|
|
1993
1994
|
Category: r.category,
|
|
1995
|
+
Status: r.status,
|
|
1994
1996
|
Description: truncate(r.description, 80)
|
|
1995
1997
|
})),
|
|
1996
|
-
["Skill", "Kind", "Category", "Description"],
|
|
1998
|
+
["Skill", "Kind", "Category", "Status", "Description"],
|
|
1997
1999
|
opts
|
|
1998
2000
|
);
|
|
1999
2001
|
}
|
|
@@ -2040,6 +2042,76 @@ async function skillsSync(opts) {
|
|
|
2040
2042
|
);
|
|
2041
2043
|
}
|
|
2042
2044
|
}
|
|
2045
|
+
async function skillsLint(opts) {
|
|
2046
|
+
let skills;
|
|
2047
|
+
try {
|
|
2048
|
+
const all = discoverAll();
|
|
2049
|
+
skills = [...all.builtins, ...all.integrations].map(lintSkill);
|
|
2050
|
+
} catch (err) {
|
|
2051
|
+
fail(
|
|
2052
|
+
EXIT.ERROR,
|
|
2053
|
+
`skills lint: could not lint skills (${err instanceof Error ? err.message : String(err)})`,
|
|
2054
|
+
opts
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
const errored = skills.filter((s) => s.errors.length > 0);
|
|
2058
|
+
const warned = skills.filter((s) => s.warnings.length > 0 && s.errors.length === 0);
|
|
2059
|
+
const data = { count: skills.length, errored: errored.length, skills };
|
|
2060
|
+
if (opts.json === true) {
|
|
2061
|
+
process.stdout.write(`${JSON.stringify({ ok: errored.length === 0, data })}
|
|
2062
|
+
`);
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
if (errored.length === 0) {
|
|
2066
|
+
log(`noir skills lint \u2014 ${skills.length} skills, all validate clean.`, opts);
|
|
2067
|
+
} else {
|
|
2068
|
+
warn(
|
|
2069
|
+
`noir skills lint \u2014 ${errored.length} skill${errored.length === 1 ? "" : "s"} FAIL validation:`,
|
|
2070
|
+
opts
|
|
2071
|
+
);
|
|
2072
|
+
}
|
|
2073
|
+
for (const s of errored) {
|
|
2074
|
+
for (const e of s.errors) warn(` ${s.name}: ${e}`, opts);
|
|
2075
|
+
}
|
|
2076
|
+
if (warned.length > 0) {
|
|
2077
|
+
info(` ${warned.length} skill${warned.length === 1 ? "" : "s"} carry lint warnings:`, opts);
|
|
2078
|
+
for (const s of warned) {
|
|
2079
|
+
for (const w of s.warnings) info(` ${s.name}: ${w}`, opts);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
async function skillsRegistry(opts) {
|
|
2084
|
+
let reg;
|
|
2085
|
+
try {
|
|
2086
|
+
reg = buildRegistry();
|
|
2087
|
+
} catch (err) {
|
|
2088
|
+
fail(
|
|
2089
|
+
EXIT.ERROR,
|
|
2090
|
+
`skills registry: could not build registry (${err instanceof Error ? err.message : String(err)})`,
|
|
2091
|
+
opts
|
|
2092
|
+
);
|
|
2093
|
+
}
|
|
2094
|
+
const data = { count: reg.length, skills: reg };
|
|
2095
|
+
if (opts.json === true) {
|
|
2096
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
2097
|
+
`);
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
log(`noir skills registry \u2014 ${reg.length} skills.`, opts);
|
|
2101
|
+
table(
|
|
2102
|
+
reg.map((r) => ({
|
|
2103
|
+
Skill: r.name,
|
|
2104
|
+
Kind: r.kind,
|
|
2105
|
+
Category: r.category,
|
|
2106
|
+
Version: r.version,
|
|
2107
|
+
Status: r.status,
|
|
2108
|
+
Refs: String(r.referenceCount),
|
|
2109
|
+
Lines: String(r.lines)
|
|
2110
|
+
})),
|
|
2111
|
+
["Skill", "Kind", "Category", "Version", "Status", "Refs", "Lines"],
|
|
2112
|
+
opts
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2043
2115
|
|
|
2044
2116
|
// src/serve.ts
|
|
2045
2117
|
import { loadProjectInfo as loadProjectInfo7 } from "@noir-ai/core";
|
|
@@ -2413,8 +2485,14 @@ function createProgram() {
|
|
|
2413
2485
|
skillsGrp.command("sync").description("re-emit skills to the host skills dir").action(async (...args) => {
|
|
2414
2486
|
await skillsSync(toCliOptions(actionGlobals(args)));
|
|
2415
2487
|
});
|
|
2488
|
+
skillsGrp.command("lint").description("structural quality gate over the shipped pack (C3)").action(async (...args) => {
|
|
2489
|
+
await skillsLint(toCliOptions(actionGlobals(args)));
|
|
2490
|
+
});
|
|
2491
|
+
skillsGrp.command("registry").description("emit the runtime-derived skill registry (C3)").action(async (...args) => {
|
|
2492
|
+
await skillsRegistry(toCliOptions(actionGlobals(args)));
|
|
2493
|
+
});
|
|
2416
2494
|
skillsGrp.action(() => {
|
|
2417
|
-
throw new NoirCliError(EXIT.USAGE, "Usage: noir skills list|sync");
|
|
2495
|
+
throw new NoirCliError(EXIT.USAGE, "Usage: noir skills list|sync|lint|registry");
|
|
2418
2496
|
});
|
|
2419
2497
|
const taskGrp = program2.command("task").description("workflow task control");
|
|
2420
2498
|
taskGrp.command("new").description("start a new workflow task").requiredOption("--slug <slug>", "task slug").option("--mode <mode>", "full | quick").action(async (...args) => {
|