@nodii/dev 0.4.0 → 0.5.0

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
@@ -12,42 +12,45 @@ Linux only (the launcher is a POSIX shell script).
12
12
  nodii-dev login # opens the approval page in your browser
13
13
  nodii-dev login --no-browser # prints the link and code instead
14
14
  nodii-dev login --scope devops.issues.read,devops.issues.write # narrower grant
15
- nodii-dev agent register --name my-agent --service nodii-planning-hub
16
-
17
- # Temporary compatibility path:
18
- printf '%s' "$PLANNING_HUB_HMAC_SECRET" | nodii-dev login --person PERSON_ID --secret-stdin
19
- nodii-dev login --hmac --person PERSON_ID --from-aws
15
+ nodii-dev agent register --name my-agent
20
16
  ```
21
17
 
22
- OAuth is the default: the CLI signs in as the platform tenant's nodii-dev app
23
- (`NODII_DEV_OAUTH_CLIENT_ID` or `--client-id` overrides the built-in public
24
- client id). With no `--scope`, auth grants the app's full ceiling: every live
25
- `devops.*` key except `devops.releases.promote`, which is never granted. Pass
26
- `--hmac` to keep the interim path. Login uses RFC 8628 and
27
- opens the verification page on an interactive terminal unless `--no-browser`
28
- is passed. Refresh tokens are stored only in macOS Keychain or Linux Secret
29
- Service (`secret-tool`); the CLI refuses plaintext fallback. Access tokens stay
30
- in memory. OAuth API calls use the platform edge `/devops` route and send the
31
- registered `x-agent-id`. `logout` revokes the refresh chain before erasing local
18
+ `nodii-dev` talks only to Dev, through the platform edge
19
+ (`https://platform.nucleus-cloud.in/devops/*`), signed in as the platform
20
+ tenant's nodii-dev OAuth app (D1368). There is no other host and no other way
21
+ to sign in. `NODII_DEV_OAUTH_CLIENT_ID` or `--client-id` overrides the built-in
22
+ public client id. With no `--scope`, auth grants the app's full ceiling: every
23
+ live `devops.*` key except `devops.releases.promote`, which is never granted.
24
+ Login uses the RFC 8628 device flow and opens the verification page on an
25
+ interactive terminal unless `--no-browser` is passed. Refresh tokens are
26
+ stored only in macOS Keychain or Linux Secret Service (`secret-tool`); the CLI
27
+ refuses plaintext fallback. Access tokens stay in memory. Every API call goes
28
+ to the edge's `/devops` prefix with the OAuth bearer and the registered
29
+ `x-agent-id`. `logout` revokes the refresh chain before erasing local
32
30
  credentials. `--auth-url`, `--edge-url`, and `--tenant-hint` select another real
33
31
  deployment.
34
32
 
33
+ Upgrading from 0.4.x: the shared-secret login (`login --hmac`, `--person`,
34
+ `--secret-stdin`, `--from-aws`, `--hub-url`) was removed in 0.5.0, and `login`
35
+ refuses those flags. The first command you run after upgrading deletes the old
36
+ config and its stored secret (Keychain item or file) without printing it, then
37
+ asks you to run `nodii-dev login`.
38
+
35
39
  Every command accepts `--json`; without it, output is formatted for humans.
36
- Hub failures print the hub error code to stderr and exit non-zero.
40
+ Dev failures print Dev's error code to stderr and exit non-zero.
37
41
 
38
42
  ## Commands
39
43
 
40
44
  ```text
41
- nodii-dev login [--no-browser]
42
- nodii-dev login --hmac --person ID (--secret-stdin | --from-aws)
45
+ nodii-dev login [--no-browser] [--scope KEYS]
43
46
  nodii-dev logout
44
- nodii-dev whoami
47
+ nodii-dev whoami # OAuth identity plus the registered agent
45
48
  nodii-dev config show
46
49
 
47
50
  nodii-dev api list [--tag TAG] [--json]
48
51
  nodii-dev api OPERATION_ID [--param name=value ...] [--body @file|-|JSON]
49
52
 
50
- nodii-dev agent register --name NAME [--service SERVICE] [--session ID]
53
+ nodii-dev agent register --name NAME [--session ID] # staff bind the agent to a service on the Dev Agents page
51
54
  nodii-dev agent heartbeat
52
55
  nodii-dev agents spawn SERVICE [--repo-root DIR]
53
56
  nodii-dev agents cowork-tick [--json]
@@ -140,11 +143,11 @@ nodii-dev setup --check # exit non-zero when it has drifted
140
143
 
141
144
  `lane start` creates and starts a lane. It infers the repository, branch and
142
145
  worktree from git unless overridden, and resolves `--issue` keys to the UUIDs
143
- required by the hub. Lane keys are passed directly to every lane and Built
146
+ required by Dev. Lane keys are passed directly to every lane and Built
144
147
  acknowledgement route. `next` reads the lane's generated
145
148
  API steps and prints the exact next `lane step` command. Server refusals,
146
149
  including operator-only actions, workflow blocks, lane limits and Built items
147
- that are not on dev, retain the hub error code/message and exit non-zero.
150
+ that are not on dev, retain Dev's error code/message and exit non-zero.
148
151
 
149
152
  `setup` installs the Claude Code workflow harness in the current repository.
150
153
  It writes `.claude/skills/nodii-build-workflow/SKILL.md`, merges SessionStart,
@@ -152,15 +155,16 @@ Stop and Bash PostToolUse hooks into `.claude/settings.json`, and maintains one
152
155
  marked section in an existing `CLAUDE.md` or `AGENTS.md` (creating `CLAUDE.md`
153
156
  when neither exists). Existing settings and hooks are preserved. The default
154
157
  is a read-only preview; `--yes` applies, and `--check` is suitable for drift
155
- checks. Setup also checks `whoami` and prints `nodii-dev login` guidance without
156
- exposing credential details.
158
+ checks. Setup also checks the OAuth login (a token refresh, then the registered
159
+ agent) and prints `nodii-dev login` guidance without exposing credential
160
+ details.
157
161
 
158
- Heartbeat notes are optional and limited by the hub to 500 characters.
162
+ Heartbeat notes are optional and limited by Dev to 500 characters.
159
163
  Prioritize and deprioritize require a 1–500 character reason, which the CLI
160
- sends to the hub. `lane review` records the review gate.
164
+ sends to Dev. `lane review` records the review gate.
161
165
 
162
166
  The CLI does not duplicate authorization policy. It sends requests and prints
163
- the hub's refusal unchanged. Stop, Built acknowledgement, and machine
167
+ Dev's refusal unchanged. Stop, Built acknowledgement, and machine
164
168
  create/update/coordinator changes require a staff person login. Machine agent
165
169
  assignment is for coordinators; lane-limit and repository-grant changes are for
166
170
  the target agent's coordinator or staff. Agent registration does not accept
@@ -177,10 +181,12 @@ nodii-dev requests resolve UUID --commit-sha abc1234 --resolution-md "shipped"
177
181
  nodii-dev open-questions answer UUID --decision-id D1420
178
182
  ```
179
183
 
180
- The first-class resource families cover every live OpenAPI tag: services,
184
+ The CLI bundles Dev's OpenAPI document as the edge routes it (the edge does not
185
+ serve Dev's own document), so `api list` works offline and lists only
186
+ operations the edge exposes. The first-class resource families cover every tag: services,
181
187
  feature docs, contracts (gRPC, REST, outbox, sagas, tables), libraries,
182
188
  workers, projects, slices, SQL lookups, issues, backlogs, builds, changes,
183
- deploy reports, runtime, people, agents, inbox/gates, design, runbooks,
189
+ runtime, people, agents, inbox/gates, design, runbooks,
184
190
  doctrine and exceptions, changelog, health verdicts, approval kinds,
185
191
  notification registry, skills, questions, decisions, drift, requests,
186
192
  pipelines, runners, routing, usage, audit, reconciliation, cron, composite
@@ -189,7 +195,7 @@ surfaces, service edges, lanes, swaps, ideas, and terminology. `api list` is the
189
195
 
190
196
  `figma check` exits `0` when allowed and `3` when denied. The pre-hook permits
191
197
  non-Figma tools and allowlisted Figma reads, but defaults to denying every
192
- Figma write if the file key is absent, the hub cannot be reached, or the lock
198
+ Figma write if the file key is absent, Dev cannot be reached, or the lock
193
199
  is denied. It exits `2`, which makes Claude Code block the call. The post-hook
194
200
  best-effort logs the write and never blocks. Per D1433, Codex remains read-only
195
201
  for Figma; this package does not write to Figma itself.
package/dist/api.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { stdin } from "node:process";
3
- import { CliError, encode, hubRawRequest, readConfig } from "./core.js";
3
+ import { CliError, devRawRequest, encode } from "./core.js";
4
4
 
5
5
  const methods = new Set(["get", "post", "put", "patch", "delete", "head", "options"]);
6
- export async function loadOpenApi(fetcher = fetch) {
7
- const { hubUrl } = await readConfig();
8
- const response = await fetcher(`${hubUrl.replace(/\/$/, "")}/openapi.json`, { headers: { accept: "application/json" } });
9
- if (!response.ok) throw new CliError("OPENAPI_UNAVAILABLE", `Cannot load OpenAPI: HTTP ${response.status}`);
10
- return response.json();
6
+ // The Dev API as the platform edge routes it, bundled with the package (the
7
+ // edge does not serve Dev's own document). Refresh: `npm run openapi:snapshot`.
8
+ let bundled;
9
+ export async function loadOpenApi() {
10
+ bundled ??= JSON.parse(await readFile(new URL("./devops-openapi.json", import.meta.url), "utf8"));
11
+ return bundled;
11
12
  }
12
13
 
13
14
  export function operationsFrom(spec) {
@@ -86,13 +87,13 @@ export function flagsToOperation(entry, positional, flags) {
86
87
 
87
88
  export async function callOperation(entry, params, body) {
88
89
  const request = buildOperationRequest(entry, params, body);
89
- return hubRawRequest(request.method, request.path, body === undefined ? undefined : JSON.stringify(body));
90
+ return devRawRequest(request.method, request.path, body === undefined ? undefined : JSON.stringify(body));
90
91
  }
91
92
 
92
93
  export const GROUPS = {
93
94
  services: "Services", "feature-docs": "FeatureDocs", contracts: ["GrpcInterfaces", "RestInterfaces", "Outbox", "OutboxTopics", "Sagas", "Tables"],
94
95
  sagas: "Sagas", "outbox-topics": ["Outbox", "OutboxTopics"], tables: "Tables", libraries: "Libraries", workers: "Workers",
95
- projects: "Projects", issues: "Issues", backlog: "Backlogs", backlogs: "Backlogs", builds: "Delivery", changes: "Delivery", "deploy-reports": "Runtime",
96
+ projects: "Projects", issues: "Issues", backlog: "Backlogs", backlogs: "Backlogs", builds: "Delivery", changes: "Delivery",
96
97
  runtime: "Runtime", people: "People", agents: "Agents", inbox: "Inbox", gate: "Inbox", design: "Design", runbooks: "Runbooks",
97
98
  doctrine: ["Doctrine", "DoctrineExceptions"], rulebook: "Doctrine", changelog: "Changelog", "health-verdicts": "HealthVerdicts",
98
99
  "approval-kinds": "ApprovalKinds", "notification-registry": "Notification registry", skills: "Skills", "open-questions": "OpenQuestions",
@@ -123,7 +124,7 @@ export const ALIASES = {
123
124
  "projects:list": "listServiceProjects", "projects:show": "getProject", "projects:create": "createProject", "projects:update": "updateProject",
124
125
  "builds:list": "listBuilds", "builds:show": "getBuild", "builds:report": "reportBuild",
125
126
  "changes:list": "listChanges", "changes:show": "getChange", "changes:mark": "markChange",
126
- "deploy-reports:report": "reportDeployment", "runtime:list": "listRuntimeInventory", "runtime:show": "getServiceRuntime",
127
+ "runtime:list": "listRuntimeInventory", "runtime:show": "getServiceRuntime",
127
128
  "people:list": "listPeople", "people:show": "getPerson", "agents:list": "listAgents", "agents:show": "getAgent",
128
129
  "gate:fleet": "getFleetGate", "gate:service": "getServiceGate", "gate:dry-run": "getGateDryRun",
129
130
  "runbooks:list": "listRunbooks", "runbooks:show": "getRunbook", "runbooks:create": "registerRunbook", "runbooks:update": "updateRunbook",