novahiz 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +30 -26
  2. package/package.json +1 -1
  3. package/src/cli.ts +103 -43
package/README.md CHANGED
@@ -48,14 +48,19 @@ The package exposes no programmatic import surface. It ships a CLI and an MCP se
48
48
 
49
49
  ## Install
50
50
 
51
- Clone into the Novahiz home and run the installer:
51
+ ```
52
+ npm install -g novahiz
53
+ novahiz init
54
+ ```
55
+
56
+ Or from source:
52
57
 
53
58
  ```
54
59
  git clone https://github.com/novahiz/novahiz ~/.config/novahiz
55
60
  node ~/.config/novahiz/install/install.mjs
56
61
  ```
57
62
 
58
- The installer copies the bundled skills, drops the opencode plugin, writes `novahiz.config.json` if missing, and builds the catalog. It never deletes your files. Restart opencode afterward. The plugin registers the MCP server on its own.
63
+ Restart opencode afterward. The plugin registers the MCP server on its own.
59
64
 
60
65
  Full options and the uninstall steps are in [docs/INSTALL.md](docs/INSTALL.md).
61
66
 
@@ -72,35 +77,34 @@ Machine-specific settings live in `novahiz.config.json`, which is gitignored: th
72
77
  ## CLI
73
78
 
74
79
  ```
75
- node src/cli.ts sync
76
- node src/cli.ts check
77
- node src/cli.ts classify "ajoute une migration supabase avec une policy rls"
78
- node src/cli.ts gate --file src/hero.css --tool edit
79
- node src/cli.ts gate --file src/hero.css --tool edit --loaded humanizer,impeccable
80
- node src/cli.ts skills --category design-ui
81
- node src/cli.ts catalog "design frontend landing" --limit 5
82
- node src/cli.ts roadmap --category code
83
- node src/cli.ts step --session my-session --done plan
84
- node src/cli.ts report --format markdown
85
- node src/cli.ts task new --title "Add the CSV export"
86
- node src/cli.ts task plan --task <id> --json '[{"label":"read the parser","kind":"read"},{"label":"write the exporter","kind":"edit","acceptance":"csv round-trips","owner":"src/export.ts"}]'
87
- node src/cli.ts task start --id <todo>
88
- node src/cli.ts task done --id <todo> --proof "node --test tests/export.test.ts -> 4 pass"
89
- node src/cli.ts task status --session <id>
90
- node src/cli.ts dispatch --task <id>
91
- node src/cli.ts tokens --calibrate --format text
92
- node src/cli.ts clean --days 30 --dry-run
93
- node src/cli.ts clean --days 30 --apply --vacuum
94
- node src/cli.ts doctor
80
+ novahiz init # one-shot setup (config, skills, catalog)
81
+ novahiz doctor # health check
82
+ novahiz status # classification and gate state
83
+ novahiz task new "Add CSV" # start a tracked task
84
+ novahiz task status # show task progress
85
+ novahiz task done <id> # mark a todo complete
86
+ novahiz report # session report
87
+ novahiz clean # remove old logs and sessions
88
+ novahiz upgrade # pull latest and rebuild catalog
89
+ novahiz version # show version
95
90
  ```
96
91
 
97
- `gate` prints a JSON verdict and exits `0` when the edit is allowed, `2` when it is blocked. Adapters rely on that exit code.
92
+ Advanced (for power users and adapters):
98
93
 
99
- Output follows the terminal by default, and `--pretty` or `--json` forces a mode. `clean` prunes old enforcement logs, roadmap progress, sessions, and closed tasks; without `--apply` it shows the plan and, on an interactive terminal, asks for confirmation. `doctor` runs the preflight checks and exits non-zero on a blocking finding.
94
+ ```
95
+ novahiz classify "ajoute une migration supabase"
96
+ novahiz gate --file src/hero.css --tool edit
97
+ novahiz skills --category design-ui
98
+ novahiz catalog "design frontend landing" --limit 5
99
+ novahiz roadmap --category code
100
+ novahiz dispatch --task <id>
101
+ novahiz tokens --calibrate
102
+ novahiz clean --days 30 --apply --vacuum
103
+ ```
100
104
 
101
- Run `node src/cli.ts` with no arguments for the full command list, including `categories`, `rules`, `session-load`, `session-state`, `hook`, `providers`, `deps`, and every `task` subcommand.
105
+ `gate` prints a JSON verdict and exits `0` when the edit is allowed, `2` when it is blocked. Adapters rely on that exit code.
102
106
 
103
- The adapter also trims tool output and deduplicates stale reads to keep long sessions cheap.
107
+ Run `novahiz` with no arguments for the full command list.
104
108
 
105
109
  ## opencode adapter
106
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "novahiz",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Deterministic agentic layer for coding harnesses: skill catalog, prompt classifier, and a pre-edit enforcement gate.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/cli.ts CHANGED
@@ -1,4 +1,7 @@
1
- import { resolve } from "node:path";
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { join, dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { spawnSync } from "node:child_process";
2
5
  import { parse, print } from "./commands/context.ts";
3
6
  import { expandHome } from "./spec.ts";
4
7
 
@@ -10,42 +13,88 @@ import { commandClean } from "./commands/clean.ts";
10
13
  import { commandDoctor } from "./commands/doctor.ts";
11
14
  import { commandTokens } from "./commands/tokens.ts";
12
15
 
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const HOME = process.env.NOVAHIZ_HOME || join(process.env.HOME || process.env.USERPROFILE || "", ".config", "novahiz");
18
+
19
+ function runSync(): void {
20
+ const cli = join(HOME, "src", "cli.ts");
21
+ if (existsSync(cli)) {
22
+ spawnSync(process.execPath, [cli, "sync"], {
23
+ encoding: "utf8",
24
+ stdio: "inherit",
25
+ env: { ...process.env, NOVAHIZ_HOME: HOME }
26
+ });
27
+ }
28
+ }
29
+
13
30
  function usage(): void {
14
31
  print({
15
32
  name: "novahiz",
16
33
  commands: [
17
- "check",
18
- "sync",
19
- "classify <text> [--min-score N] [--max-categories N]",
20
- "gate --tool <tool> (--file <path> | --args-stdin) [--categories a,b] [--loaded a,b] [--session id]",
21
- "skills [--category id]",
22
- "categories",
23
- "rules",
24
- "session-load --session id --skill name",
25
- "session-state --session id",
26
- "report [--format markdown]",
27
- "catalog <query> [--limit N]",
28
- "roadmap --category id | <query>",
29
- "step --session id --done <step>",
30
- "providers [--category id] [--mcp-json] [--install]",
31
- "deps [--install]",
32
- "task new --title <title> [--id id] [--session id]",
33
- "task plan [--task id] [--session id] (JSON array on stdin or --json '<...>')",
34
- "task todo --label <label> [--task id] [--kind read|edit|verify|delegate] [--owner a,b] [--acceptance ...] [--max-iterations N]",
35
- "task start|done|block --id <todo> [--proof ...|--reason ...]",
36
- "task review [--task id] [--reason ...] [--json '<additions|amendments|removals|order>'] (or JSON on stdin)",
37
- "task amend --id <todo> [--label ...] [--kind ...] [--acceptance ...] [--owner a,b] [--max-iterations N]",
38
- "task insert --label <label> [--task id] [--kind ...] [--owner a,b] [--acceptance ...] [--position start|end|N]",
39
- "task drop --id <todo> [--reason ...]",
40
- "task reorder [--task id] --order <id,id,...>",
41
- "task signals [--task id]",
42
- "task status|resume|current [--session id]",
43
- "dispatch [--task id] [--session id]",
44
- "clean [--target logs|roadmap|sessions|tasks|all] [--days N] [--dry-run|--apply] [--vacuum] [--json]",
45
- "doctor [--json]",
46
- "tokens [--json] [--calibrate]"
34
+ "init Set up Novahiz (config, skills, catalog)",
35
+ "doctor Check that everything works",
36
+ "status Show current classification and gate state",
37
+ "task new <title> Start a new tracked task",
38
+ "task status Show task progress",
39
+ "task done <id> Mark a todo as complete",
40
+ "report Session report",
41
+ "clean Remove old logs and sessions",
42
+ "upgrade Pull latest and rebuild catalog",
43
+ "version Show version",
44
+ "",
45
+ "Advanced (for power users and adapters):",
46
+ " classify <text> Classify a prompt",
47
+ " gate --tool <t> --file <f> Check if an edit is allowed",
48
+ " skills [--category c] List loaded skills",
49
+ " catalog <query> Search the skill catalog",
50
+ " roadmap --category c Show execution roadmap",
51
+ " dispatch [--task id] Generate work packets",
52
+ " tokens Token diagnostics",
47
53
  ]
48
- });}
54
+ });
55
+ }
56
+
57
+ function printVersion(): void {
58
+ try {
59
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf8"));
60
+ process.stdout.write(`novahiz ${pkg.version}\n`);
61
+ } catch {
62
+ process.stdout.write("novahiz (unknown version)\n");
63
+ }
64
+ }
65
+
66
+ function runInit(): void {
67
+ const installScript = join(HOME, "install", "install.mjs");
68
+ if (existsSync(installScript)) {
69
+ process.stdout.write("Installing Novahiz...\n");
70
+ const result = spawnSync(process.execPath, [installScript, "--yes"], {
71
+ encoding: "utf8",
72
+ stdio: "inherit",
73
+ env: { ...process.env, NOVAHIZ_HOME: HOME }
74
+ });
75
+ if (result.status !== 0) {
76
+ process.stderr.write("Installation failed. Run `novahiz doctor` for details.\n");
77
+ process.exitCode = 1;
78
+ return;
79
+ }
80
+ }
81
+ process.stdout.write("\nBuilding skill catalog...\n");
82
+ runSync();
83
+ process.stdout.write("\nDone! Restart opencode to activate Novahiz.\n");
84
+ }
85
+
86
+ function runUpgrade(): void {
87
+ if (!existsSync(join(HOME, ".git"))) {
88
+ process.stderr.write("Not a git repository. Install from source first.\n");
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ process.stdout.write("Pulling latest changes...\n");
93
+ spawnSync("git", ["pull"], { cwd: HOME, stdio: "inherit" });
94
+ process.stdout.write("\nRebuilding skill catalog...\n");
95
+ runSync();
96
+ process.stdout.write("\nUpgraded! Restart opencode to apply changes.\n");
97
+ }
49
98
 
50
99
  function main(argv: string[]): void {
51
100
  const parsed = parse(argv);
@@ -58,8 +107,27 @@ function main(argv: string[]): void {
58
107
  return;
59
108
  }
60
109
  switch (command) {
110
+ case "init":
111
+ case "setup":
112
+ return runInit();
113
+ case "doctor":
114
+ return commandDoctor(parsed);
115
+ case "status":
61
116
  case "check":
62
117
  return commandCheck();
118
+ case "report":
119
+ return commandReport(parsed);
120
+ case "clean":
121
+ return commandClean(parsed);
122
+ case "upgrade":
123
+ case "update":
124
+ return runUpgrade();
125
+ case "version":
126
+ case "-v":
127
+ case "--version":
128
+ return printVersion();
129
+ case "task":
130
+ return commandTask(parsed);
63
131
  case "sync":
64
132
  return commandSync();
65
133
  case "classify":
@@ -76,14 +144,6 @@ function main(argv: string[]): void {
76
144
  return commandSessionLoad(parsed);
77
145
  case "session-state":
78
146
  return commandSessionState(parsed);
79
- case "report":
80
- return commandReport(parsed);
81
- case "clean":
82
- return commandClean(parsed);
83
- case "doctor":
84
- return commandDoctor(parsed);
85
- case "tokens":
86
- return commandTokens(parsed);
87
147
  case "catalog":
88
148
  return commandCatalog(parsed);
89
149
  case "roadmap":
@@ -94,12 +154,12 @@ function main(argv: string[]): void {
94
154
  return commandProviders(parsed);
95
155
  case "deps":
96
156
  return commandDeps(parsed);
97
- case "task":
98
- return commandTask(parsed);
99
157
  case "dispatch":
100
158
  return commandDispatch(parsed);
159
+ case "tokens":
160
+ return commandTokens(parsed);
101
161
  default:
102
- process.stderr.write(`novahiz: unknown command ${command}\n`);
162
+ process.stderr.write(`novahiz: unknown command "${command}"\n\n`);
103
163
  usage();
104
164
  process.exitCode = 1;
105
165
  return;