@noir-ai/cli 1.9.3-beta.1 → 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/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
- intake: "noir-intake",
782
- clarify: "noir-clarify",
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-plan",
785
- execute: "noir-execute",
786
- verify: "noir-verify",
787
- document: "noir-document"
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-brainstorm": "discovery",
1915
- "noir-intake": "discovery",
1916
- "noir-clarify": "discovery",
1917
- "noir-explore": "discovery",
1918
+ "noir-brainstorming": "discovery",
1919
+ "noir-sync": "discovery",
1920
+ "noir-checkpoint": "discovery",
1921
+ "noir-exploring": "discovery",
1918
1922
  "noir-spec": "spec",
1919
- "noir-plan": "plan",
1920
- "noir-execute": "execute",
1921
- "noir-tdd": "execute",
1922
- "noir-debug": "execute",
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-verify": "verify",
1926
- "noir-review": "verify",
1930
+ "noir-verifying": "verify",
1927
1931
  "noir-security": "verify",
1928
- "noir-test": "verify",
1929
- "noir-document": "document",
1932
+ "noir-wrap": "document",
1930
1933
  "noir-readme": "document",
1931
- "noir-commit": "git",
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-skill-author": "meta",
1943
- "noir-sync": "meta",
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
- return { name: s.name, category: categoryOf(s.name), description, kind };
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) => {