@nodii/dev 0.6.23 → 0.6.25

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 CHANGED
@@ -298,6 +298,8 @@ style check as a submit (`CHANGE_SET_IMAGE_STYLE`).
298
298
  ```bash
299
299
  nodii-dev hook claude-figma-pre # reads Claude Code hook JSON on stdin
300
300
  nodii-dev hook claude-figma-post # reads Claude Code hook JSON on stdin
301
+ nodii-dev hook safety-pre # silent safety decision; blocks with exit 2
302
+ nodii-dev hook safety-post # silently records resources created by successful commands
301
303
  nodii-dev hook print-settings # prints managed-settings JSON; writes nothing
302
304
 
303
305
  nodii-dev lane start KEY --title TEXT --kind dev_fix|new_build|docs_change|uat_fix|prod_fix
@@ -307,7 +309,8 @@ nodii-dev lane step KEY --side backend|frontend --start|--done|--block STEP [--r
307
309
  # --block --reason records the new reason (Dev issue 125 moves it onto the step)
308
310
  nodii-dev lane evidence KEY --pr|--commit|--figma|--deploy|--dev-check REF
309
311
  nodii-dev lane heartbeat KEY [--note TEXT]
310
- nodii-dev lane review KEY
312
+ nodii-dev lane review KEY --file REVIEW.json
313
+ nodii-dev lane reviews KEY
311
314
  nodii-dev lane land KEY
312
315
  nodii-dev lane verify KEY --dev-check REF
313
316
  nodii-dev lane list [--kind KIND] [--status STATUS] [--machine UUID]
@@ -354,6 +357,28 @@ nodii-dev harness check [--json] # 0 current, 1 differs from Dev,
354
357
  nodii-dev harness update --check # the same check
355
358
  ```
356
359
 
360
+ `harness install` and `harness update` merge the two safety hooks into
361
+ `.claude/settings.json`; every installed hook invokes only `nodii-dev`. The
362
+ pre-hook blocks edits outside a lane's optional `ownedPaths`, generated UI/API
363
+ files, unsafe Git operations, stale or missing review receipts, lane identity
364
+ changes, production-secret/test-auth bypasses, cleanup of Docker resources the
365
+ run did not create, and deploy/apply commands without an exact grant. Allowed
366
+ calls produce no output.
367
+
368
+ Until Dev exposes a lane's owned paths (AGENT-HARNESS-10), an edit with no
369
+ ownership field emits a nudge instead of claiming it is safe or blocking an
370
+ unproven violation. Likewise, a deploy with no `NODII_DEV_GO_FILE` source
371
+ nudges for AGENT-HARNESS-13; when the source exists, a missing exact grant is
372
+ blocked. A Compose project whose normalized name is the lane key counts as
373
+ lane-owned, as does a project recorded by a successful `docker compose up`.
374
+
375
+ `lane review` writes its receipt to private Git metadata, pinning both `HEAD`
376
+ and `origin/main`; it never adds a repository file. Set `NODII_DEV_GO_FILE` to
377
+ the coordinator grant file so an exact `GO deploy <HEAD>` line can authorize a
378
+ deploy. A coordinator's exceptional `--no-verify` also requires
379
+ `NODII_DEV_NO_VERIFY_REASON`; the CLI records the reason in private Git
380
+ metadata. Lanes and subagents can never use `--no-verify`.
381
+
357
382
  ### DS conformance: `design roles` and `design check` (DEC-0034)
358
383
 
359
384
  Every UI role names exactly one DS component (MW6-14). Resolve your brief's
@@ -688,6 +713,14 @@ The command reaches Dev through the edge, so it needs the edge's route for
688
713
  `/devops/api/v1/lanes/:id/non-issue`; until that is on an environment, the
689
714
  command gets the edge's 404 there.
690
715
 
716
+ `lane review` reads one JSON object with the review's exact `origin/main`
717
+ commit in `base`, exact reviewed commit in `head`,
718
+ `iterationCount`, `exitReason`, `appliedPatches`, `unresolvedProposals`,
719
+ `reviewerErrors`, and `findings`. Each finding has `perspective` (`code` or
720
+ `rules`), `severity`, `summary`, `detail`, `disposition`, optional `path` and
721
+ `line`, and a required `clauseId` for rules findings. `lane reviews` reads the
722
+ append-only history, including whether each cited clause was a missed trigger.
723
+
691
724
  Heartbeat notes are optional and limited by Dev to 500 characters.
692
725
  Prioritize and deprioritize require a 1–500 character reason, which the CLI
693
726
  sends to Dev. `lane review` records the review gate.
package/dist/cli.js CHANGED
@@ -23,6 +23,7 @@ import {
23
23
  import { heartbeatCurrentLane, postHook, postHookFailure, preHook, settingsSnippet, workflowSuggestion } from "./hooks.js";
24
24
  import { setupCommand } from "./setup.js";
25
25
  import { harnessCommand } from "./harness.js";
26
+ import { safetyPostHook, safetyPreHook } from "./safety.js";
26
27
  import { doctorCommand } from "./doctor.js";
27
28
  import {
28
29
  figmaChangeSetShow,
@@ -119,7 +120,7 @@ Usage: nodii-dev <command> [options] [--json]
119
120
  figma changeset show CHANGE_SET # items, variants, round, decision and comment (with the previous round's)
120
121
  figma file add FILE_KEY --name TEXT --kind design-system|surfaces|prototype [--module M]
121
122
  # register a Figma file in Dev so it can be locked
122
- hook claude-figma-pre|claude-figma-post|print-settings
123
+ hook claude-figma-pre|claude-figma-post|safety-pre|safety-post|print-settings
123
124
  setup [--yes|--check] # dry-run by default
124
125
  harness install|update [--include-drafts[=false]] [--adopt PATH,...] [--dry-run]
125
126
  harness check # 0 current, 1 differs from Dev, 2 not installed
@@ -138,7 +139,9 @@ Usage: nodii-dev <command> [options] [--json]
138
139
  lane step <key> --side SIDE --start|--done|--block <step> [--reason TEXT]
139
140
  # --block --reason on a blocked step records its new reason
140
141
  lane evidence <key> --pr|--commit|--figma|--deploy|--dev-check REF
141
- lane heartbeat|review|land|verify|prioritize|deprioritize|stop <key>
142
+ lane heartbeat|land|verify|prioritize|deprioritize|stop <key>
143
+ lane review <key> --file REVIEW.json # base/head, outcome and clause-cited findings
144
+ lane reviews <key> # stored review history for the lane
142
145
  lane non-issue <key> --reason TEXT --evidence TEXT --reroute KEY[,KEY]|none
143
146
  --branch carried:KEY|dropped[:REASON] [--commits SHA[,SHA]]
144
147
  # DEC-0011: terminal non_issue; issue -> wont_do; slot frees
@@ -771,6 +774,31 @@ export async function main(argv = process.argv.slice(2)) {
771
774
  );
772
775
  }
773
776
  }
777
+ if (action === "safety-pre") {
778
+ // A malformed or unavailable safety check must not turn into permission.
779
+ try {
780
+ const result = await safetyPreHook(JSON.parse(await stdinText()));
781
+ for (const nudge of result.nudges ?? []) console.log(nudge);
782
+ return;
783
+ } catch (error) {
784
+ throw new CliError(
785
+ error?.code ?? "SAFETY_HOOK_FAILED",
786
+ error?.message ?? String(error),
787
+ 2,
788
+ error?.details,
789
+ );
790
+ }
791
+ }
792
+ if (action === "safety-post") {
793
+ try {
794
+ await safetyPostHook(JSON.parse(await stdinText()));
795
+ } catch (error) {
796
+ // A post-hook cannot undo a completed command; report state-tracking
797
+ // failure without making Claude treat the completed command as failed.
798
+ console.error(`nodii-dev safety post hook: ${error?.code ?? "ERROR"}: ${error?.message ?? String(error)}`);
799
+ }
800
+ return;
801
+ }
774
802
  if (action === "lane-heartbeat") {
775
803
  const result = await heartbeatCurrentLane();
776
804
  return emit(result, json, result.heartbeated ? `Heartbeat recorded for ${result.key}.` : "No current-branch lane; no heartbeat sent.");
package/dist/core.js CHANGED
@@ -4,7 +4,7 @@ import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { homedir, platform } from "node:os";
5
5
  import { dirname, join } from "node:path";
6
6
 
7
- export const VERSION = "0.6.23";
7
+ export const VERSION = "0.6.25";
8
8
  export const configPath = () =>
9
9
  process.env.NODII_DEV_CONFIG_PATH ??
10
10
  join(homedir(), ".config/nodii-dev/config.json");