@njeybe/nativ 2.0.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/CHANGELOG.md +40 -0
- package/LICENSE +21 -0
- package/README.md +334 -0
- package/bin/cli.js +31 -0
- package/dist/commands/bench.d.ts +8 -0
- package/dist/commands/bench.js +52 -0
- package/dist/commands/db.d.ts +22 -0
- package/dist/commands/db.js +415 -0
- package/dist/commands/doctor.d.ts +38 -0
- package/dist/commands/doctor.js +169 -0
- package/dist/commands/hook.d.ts +31 -0
- package/dist/commands/hook.js +105 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +144 -0
- package/dist/commands/mcp.d.ts +5 -0
- package/dist/commands/mcp.js +16 -0
- package/dist/commands/setup.d.ts +17 -0
- package/dist/commands/setup.js +51 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/task.d.ts +83 -0
- package/dist/commands/task.js +807 -0
- package/dist/commands/test-gen.d.ts +14 -0
- package/dist/commands/test-gen.js +52 -0
- package/dist/commands/triage.d.ts +70 -0
- package/dist/commands/triage.js +343 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +112 -0
- package/dist/commands/validate.d.ts +1 -0
- package/dist/commands/validate.js +89 -0
- package/dist/commands/verify.d.ts +8 -0
- package/dist/commands/verify.js +65 -0
- package/dist/commands/worktree.d.ts +47 -0
- package/dist/commands/worktree.js +396 -0
- package/dist/core/benchmark.d.ts +57 -0
- package/dist/core/benchmark.js +772 -0
- package/dist/core/enforcement.d.ts +80 -0
- package/dist/core/enforcement.js +271 -0
- package/dist/core/legacy-templates.d.ts +24 -0
- package/dist/core/legacy-templates.js +60 -0
- package/dist/core/lock-manager.d.ts +54 -0
- package/dist/core/lock-manager.js +260 -0
- package/dist/core/root-resolver.d.ts +32 -0
- package/dist/core/root-resolver.js +149 -0
- package/dist/core/setup-assets.d.ts +123 -0
- package/dist/core/setup-assets.js +438 -0
- package/dist/core/telemetry.d.ts +156 -0
- package/dist/core/telemetry.js +416 -0
- package/dist/core/test-generator-types.d.ts +227 -0
- package/dist/core/test-generator-types.js +179 -0
- package/dist/core/test-generator.d.ts +34 -0
- package/dist/core/test-generator.js +1690 -0
- package/dist/core/tier1-liaison.d.ts +139 -0
- package/dist/core/tier1-liaison.js +320 -0
- package/dist/core/verifier.d.ts +52 -0
- package/dist/core/verifier.js +249 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.js +14 -0
- package/dist/core/worktree-merge.d.ts +30 -0
- package/dist/core/worktree-merge.js +98 -0
- package/dist/db/data-engine.d.ts +46 -0
- package/dist/db/data-engine.js +802 -0
- package/dist/db/diff.d.ts +39 -0
- package/dist/db/diff.js +420 -0
- package/dist/db/env-parser.d.ts +86 -0
- package/dist/db/env-parser.js +549 -0
- package/dist/db/introspector.d.ts +21 -0
- package/dist/db/introspector.js +835 -0
- package/dist/db/types.d.ts +217 -0
- package/dist/db/types.js +9 -0
- package/dist/governor/circuit-breaker.d.ts +100 -0
- package/dist/governor/circuit-breaker.js +231 -0
- package/dist/governor/evaluator.d.ts +67 -0
- package/dist/governor/evaluator.js +851 -0
- package/dist/governor/index.d.ts +6 -0
- package/dist/governor/index.js +6 -0
- package/dist/governor/rules/api-rules.d.ts +2 -0
- package/dist/governor/rules/api-rules.js +140 -0
- package/dist/governor/rules/db-rules.d.ts +2 -0
- package/dist/governor/rules/db-rules.js +180 -0
- package/dist/governor/store.d.ts +33 -0
- package/dist/governor/store.js +84 -0
- package/dist/governor/types.d.ts +64 -0
- package/dist/governor/types.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +358 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +309 -0
- package/dist/providers/claude-api.d.ts +5 -0
- package/dist/providers/claude-api.js +75 -0
- package/dist/providers/claude-cli.d.ts +13 -0
- package/dist/providers/claude-cli.js +134 -0
- package/dist/providers/gemini.d.ts +8 -0
- package/dist/providers/gemini.js +78 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/registry.d.ts +38 -0
- package/dist/providers/registry.js +121 -0
- package/dist/providers/types.d.ts +74 -0
- package/dist/providers/types.js +25 -0
- package/dist/runner/agent-supervisor.d.ts +363 -0
- package/dist/runner/agent-supervisor.js +1672 -0
- package/dist/scanner/context-builder.d.ts +2 -0
- package/dist/scanner/context-builder.js +29 -0
- package/dist/scanner/detector.d.ts +2 -0
- package/dist/scanner/detector.js +760 -0
- package/dist/scanner/types.d.ts +80 -0
- package/dist/scanner/types.js +50 -0
- package/dist/server/studio-server.d.ts +39 -0
- package/dist/server/studio-server.js +1931 -0
- package/dist/server/studio-ui.d.ts +15 -0
- package/dist/server/studio-ui.js +5321 -0
- package/package.json +70 -0
- package/plugin/.claude-plugin/plugin.json +18 -0
- package/plugin/.mcp.json +10 -0
- package/plugin/agents/architect.md +28 -0
- package/plugin/agents/verifier.md +28 -0
- package/plugin/agents/worker.md +26 -0
- package/plugin/hooks/hooks.json +28 -0
- package/plugin/skills/nativ/SKILL.md +75 -0
- package/templates/.claudeignore +45 -0
- package/templates/AGENTS.md +67 -0
- package/templates/CLAUDE.md +32 -0
- package/templates/GEMINI.md +66 -0
- package/templates/claude-agents/architect.md +28 -0
- package/templates/claude-agents/verifier.md +28 -0
- package/templates/claude-agents/worker.md +26 -0
- package/templates/dot-ai/api_contracts.json +66 -0
- package/templates/dot-ai/context.md +38 -0
- package/templates/dot-ai/db_schema.json +39 -0
- package/templates/dot-ai/master_plan.json +28 -0
- package/templates/dot-ai/subagents/backend.md +11 -0
- package/templates/dot-ai/subagents/database.md +10 -0
- package/templates/dot-ai/subagents/db-migration.md +11 -0
- package/templates/dot-ai/subagents/devops-agent.md +11 -0
- package/templates/dot-ai/subagents/flutter-developer.md +11 -0
- package/templates/dot-ai/subagents/frontend.md +126 -0
- package/templates/dot-ai/subagents/qa-tester.md +13 -0
- package/templates/dot-ai/subagents/security-auditor.md +11 -0
- package/templates/dot-ai/ui_specs.md +78 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
nativ is now role-based and Claude-first. The roles (architect, project manager, worker, verifier) are fixed; the model behind each one is configurable, and Claude Code is the default host for all of them. Antigravity and Gemini still work as an optional architect.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Provider chain for Tier 1 triage.** Claude Code under your own login first (no API key needed), then the Anthropic API, then Gemini, then the offline rules engine. A provider that hits a usage limit is remembered and skipped until it resets, so a limit no longer stalls triage.
|
|
10
|
+
- **Role enforcement.** `nativ hook check` runs before every file write from Claude Code. It flags or blocks writes outside the active task's `targetFiles`, writes under `.ai/` from anyone but the architect, and writes to secret files. Modes are `warn` (default), `block` and `off`, set in `.nativ/config.json`. `nativ task unlock <id>` lifts scope for one task and is deliberately not available to agents. `nativ hook status` shows what applies.
|
|
11
|
+
- **`nativ setup` and `nativ doctor`.** Setup writes and merges `.mcp.json`, `.claude/settings.json`, `.claude/agents/`, `AGENTS.md` and `.nativ/config.json` without overwriting your own settings. Doctor checks the integration, asks Claude Code whether the MCP server connects, and `nativ doctor --fix` repairs drift. `nativ init` now runs setup.
|
|
12
|
+
- **Claude Code plugin and marketplace** (`njeybe/nativ`), generated from the same sources as setup.
|
|
13
|
+
- **Agent defaults for a Claude subscription.** Architect on Opus, worker on Sonnet, verifier on Haiku, with turn caps; triage on Haiku.
|
|
14
|
+
- **`nativ_doctor`** MCP tool (read-only).
|
|
15
|
+
- **`AGENTS.md`** as the one canonical directive. `CLAUDE.md` and `GEMINI.md` point at it.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **The npm package is now `@njeybe/nativ`** (it was `nativ-cli`). The command is still `nativ`. `nativ-cli` stays on npm and is deprecated in favour of the new name.
|
|
20
|
+
- **`nativ update` no longer overwrites files you edited.** It refreshes only files nativ wrote and you have not touched, keeps the rest and reports them, and `--force` replaces them. It also restores `AGENTS.md`, the agents and the hooks. It never touches your contracts.
|
|
21
|
+
- **Dispatched agents no longer run with `--dangerously-skip-permissions`.** The runner and Studio use `acceptEdits` plus a per-task allowlist, so the deny and ask rules and the enforcement hook apply. A task that needs another command is denied instead of run; widen the list with `NATIV_RUNNER_ALLOW`.
|
|
22
|
+
- Claude is the default architect and triage provider. Wording across the CLI, templates and docs names roles instead of one vendor.
|
|
23
|
+
- `nativ --version` and the MCP server report the version from `package.json`.
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- **The `agentj_*` MCP tools and the `agentj://` resources.** Only `nativ_*` and `nativ://` remain. The `.agentj/*.local.json` secret patterns and the `AGENTJ_DEV_DATABASE_URL` / `AGENTJ_PROD_DATABASE_URL` variables are still recognised.
|
|
28
|
+
|
|
29
|
+
### Migrating from 1.x
|
|
30
|
+
|
|
31
|
+
1. Switch to the new package: `npm uninstall -g nativ-cli`, then `npm install -g @njeybe/nativ`. If your own MCP configs or `nativ setup --command` use `npx -y nativ-cli`, change that to `npx -y @njeybe/nativ`.
|
|
32
|
+
2. Rename any `agentj_*` tool or `agentj://` resource in your own configs to `nativ_*` and `nativ://`.
|
|
33
|
+
3. In each project run `nativ update`, then `nativ doctor` (add `--fix` if it reports drift).
|
|
34
|
+
4. Open Claude Code in the project once and accept the trust dialog; until then it ignores the project's permission rules.
|
|
35
|
+
5. If `nativ doctor` warns that a `nativ` MCP server in your user or local scope shadows the project's, remove it: `claude mcp remove nativ -s local`.
|
|
36
|
+
6. Optional: `nativ setup --enforcement block` once you trust the scope rules.
|
|
37
|
+
|
|
38
|
+
## 1.0.0
|
|
39
|
+
|
|
40
|
+
Initial release.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JB Natividad
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# nativ
|
|
2
|
+
|
|
3
|
+
A role-based multi-agent workflow for AI coding agents. **Claude Code is the default**; other agents plug in. `nativ` keeps the design contracts, the task plan and the guardrails in your repository, so the same rules hold whichever tool or model does the work.
|
|
4
|
+
|
|
5
|
+
> **Package:** `@njeybe/nativ` | **Command:** `nativ`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The idea
|
|
10
|
+
|
|
11
|
+
Four roles, fixed. The model or vendor behind each role is configurable.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Architect designs contracts (database, API, UI); the human approves each step
|
|
15
|
+
|
|
|
16
|
+
v .ai/ contracts + master_plan.json
|
|
17
|
+
Project Manager runs the task loop, delegates, reports (the main Claude Code session)
|
|
18
|
+
|
|
|
19
|
+
v one task, one role guide, its own worktree if you like
|
|
20
|
+
Workers backend, frontend, database, QA, Flutter, DevOps, security, migration
|
|
21
|
+
|
|
|
22
|
+
v
|
|
23
|
+
Verifier independent checks; cannot edit files
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Why it works:
|
|
27
|
+
|
|
28
|
+
- **Contracts, not chat.** `.ai/db_schema.json`, `.ai/api_contracts.json` and `.ai/ui_specs.md` are the source of truth. Workers implement against them and escalate gaps instead of improvising.
|
|
29
|
+
- **Boundaries enforced by code.** A Claude Code hook checks every file write against the active task, the protected contracts and your secret files. It does not rely on the model remembering a rule.
|
|
30
|
+
- **Independent verification.** Each task has a `verificationCommand` that a gatekeeper re-runs before the task can complete, and a separate verifier agent reviews the result.
|
|
31
|
+
- **Zero-credential air-gap.** Agents see database structure, never passwords, connection strings or rows.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
### 1. Install
|
|
38
|
+
|
|
39
|
+
You need Node.js 20 or newer and Git. You do **not** need a clone of this repository.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# From npm
|
|
43
|
+
npm install -g @njeybe/nativ
|
|
44
|
+
|
|
45
|
+
# Or straight from GitHub (builds on install, about a minute)
|
|
46
|
+
npm install -g github:njeybe/nativ
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Check it with `nativ --version`. Developing nativ itself? See [docs/installation.md](docs/installation.md) for the clone and `npm link` route.
|
|
50
|
+
|
|
51
|
+
### 2. Set up a project
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd your-project
|
|
55
|
+
nativ init
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`nativ init` scaffolds the `.ai/` workflow and then runs `nativ setup`, which writes the Claude Code configuration:
|
|
59
|
+
|
|
60
|
+
| File | What it does |
|
|
61
|
+
| :--- | :--- |
|
|
62
|
+
| `.mcp.json` | Registers the `nativ` MCP server |
|
|
63
|
+
| `.claude/settings.json` | Permission rules, the enforcement hook, the session-start orientation hook |
|
|
64
|
+
| `.claude/agents/` | The `architect`, `worker` and `verifier` agents |
|
|
65
|
+
| `AGENTS.md` | The one directive every agent follows. `CLAUDE.md` and `GEMINI.md` point at it |
|
|
66
|
+
| `.nativ/config.json` | Enforcement mode and provider choices |
|
|
67
|
+
|
|
68
|
+
Setup **merges**: it never overwrites your own settings, hooks, MCP servers or edited files. It is safe to run any number of times, and `nativ setup --dry-run` shows what it would change.
|
|
69
|
+
|
|
70
|
+
Open Claude Code in the folder once and accept the workspace trust dialog. Until you do, Claude Code ignores the project's `permissions.allow` entries.
|
|
71
|
+
|
|
72
|
+
### 3. Or install it as a Claude Code plugin
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
/plugin marketplace add njeybe/nativ
|
|
76
|
+
/plugin install nativ@nativ
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The plugin brings the agents, the enforcement hooks, the MCP server and a skill that teaches the task loop. It calls the `nativ` command, so install the CLI first. **A plugin cannot ship permission rules**, so also run `nativ setup` in the project to add the rules that deny `nativ task unlock` and `nativ db sync`, block reading `.env*` files, and make Claude Code ask before any write under `.ai/`.
|
|
80
|
+
|
|
81
|
+
### 4. Work
|
|
82
|
+
|
|
83
|
+
1. Ask Claude to use the **architect** agent to design your contracts. It stops for your approval after the database schema, then the API, then the UI. Claude Code asks you to confirm every write under `.ai/`.
|
|
84
|
+
2. Ask Claude to run `nativ task next` and delegate each task to a **worker** agent. It works only inside the task's `targetFiles`, verifies, and completes.
|
|
85
|
+
3. Ask for a **verifier** pass before you call a milestone done.
|
|
86
|
+
|
|
87
|
+
### 5. Keep it healthy
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
nativ doctor # checks the MCP server, hooks, permissions, agents, providers
|
|
91
|
+
nativ doctor --fix # repairs what it can, idempotently
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run it after updating Claude Code or nativ. It also asks Claude Code itself whether the `nativ` server connects, and warns when a `nativ` server registered in your user or local scope is shadowing the project's.
|
|
95
|
+
|
|
96
|
+
### 6. Update
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm install -g @njeybe/nativ@latest # or: npm install -g github:njeybe/nativ
|
|
100
|
+
nativ update # in each project
|
|
101
|
+
nativ doctor
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`nativ update` refreshes the directives, role guides, agents and hooks that nativ wrote and you have not edited. Anything you edited is kept and reported; `nativ update --force` replaces it. It never touches your contracts (`.ai/db_schema.json`, `.ai/api_contracts.json`, `.ai/ui_specs.md`, `.ai/master_plan.json`, `.ai/context.md`). See [CHANGELOG.md](CHANGELOG.md) before upgrading across a major version.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Role enforcement
|
|
109
|
+
|
|
110
|
+
`nativ hook check` runs before every `Write`, `Edit`, `MultiEdit` and `NotebookEdit`. It looks at three things:
|
|
111
|
+
|
|
112
|
+
| Rule | Applies to | Meaning |
|
|
113
|
+
| :--- | :--- | :--- |
|
|
114
|
+
| `out_of_scope` | Workers and the project manager | The file is not in the active task's `targetFiles` (exact files, directories with a trailing `/`, and `*`/`**` globs) |
|
|
115
|
+
| `protected_path` | Everyone but the architect | Anything under `.ai/` |
|
|
116
|
+
| `secret_path` | Everyone, architect included | `.env`, `.env.*` (not `.env.example`), `.nativ/*.local.json`, `*.pem`, `*.key` |
|
|
117
|
+
|
|
118
|
+
Who is the architect? Inside a subagent, Claude Code reports the agent's name, so the `architect` agent (or the plugin's `nativ:architect`) is recognised. For a whole session, start it with `NATIV_ROLE=architect`.
|
|
119
|
+
|
|
120
|
+
**Modes** (`"enforcement"` in `.nativ/config.json`, or `nativ setup --enforcement <mode>`):
|
|
121
|
+
|
|
122
|
+
| Mode | Behaviour |
|
|
123
|
+
| :--- | :--- |
|
|
124
|
+
| `warn` (default) | The write goes through, the agent is told why it is out of scope, and the violation is logged to `.ai/telemetry.json` |
|
|
125
|
+
| `block` | The write is denied with the reason |
|
|
126
|
+
| `off` | No checks |
|
|
127
|
+
|
|
128
|
+
Start in `warn`, look at the log, then switch to `block`. If a task genuinely needs to leave its scope, `nativ task unlock <taskId>` lifts the scope rule for that task (contracts and secrets stay protected) and `--revoke` restores it. Unlock is a CLI command on purpose: it is not an MCP tool, so an agent cannot remove its own guardrail.
|
|
129
|
+
|
|
130
|
+
`nativ hook status` shows the mode, the role and the active task's scope. Two limits to know: the hook watches the file-editing tools, not shell commands (`sed -i` or a redirect can still write a file), and it fails open, so a broken payload never stops your work. The permission rules that `nativ setup` writes add a second layer.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Providers
|
|
135
|
+
|
|
136
|
+
nativ's own model calls (currently triage of escalations) go through one adapter, so no single vendor is on the critical path.
|
|
137
|
+
|
|
138
|
+
Default order: `claude-cli`, `claude-api`, `gemini`, then a deterministic rules engine.
|
|
139
|
+
|
|
140
|
+
| Provider | Needs | Notes |
|
|
141
|
+
| :--- | :--- | :--- |
|
|
142
|
+
| `claude-cli` | Claude Code signed in | Runs `claude -p` with your subscription login. No API key. Uses Haiku by default, with all tools disabled, from an empty working directory |
|
|
143
|
+
| `claude-api` | `ANTHROPIC_API_KEY` | Anthropic SDK |
|
|
144
|
+
| `gemini` | `GEMINI_API_KEY` or `GOOGLE_API_KEY` | The key is sent in a header, never the URL |
|
|
145
|
+
|
|
146
|
+
If a provider reports a rate or usage limit, nativ remembers it in `.nativ/provider-state.json` and skips that provider until the limit resets, so a limit costs seconds, not a long wait. If nothing is available, triage still answers from the offline rules engine. Prompts pass through secret redaction before leaving the machine.
|
|
147
|
+
|
|
148
|
+
Choose providers and models per role in `.nativ/config.json`:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"enforcement": "warn",
|
|
153
|
+
"providers": { "triage": ["claude-cli", "gemini"] },
|
|
154
|
+
"models": { "claude-cli": "haiku", "gemini": "gemini-3.8-flash" }
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Roles are `architect`, `pm`, `worker`, `verifier` and `triage`. Adding a vendor means adding one file under `src/providers/`.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## CLI reference
|
|
163
|
+
|
|
164
|
+
### Setup and health
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
nativ init # scaffold .ai/ and run setup
|
|
168
|
+
nativ setup [--dry-run] [--enforcement warn|block|off] [--command "npx -y @njeybe/nativ"] [--force]
|
|
169
|
+
nativ doctor [--fix] [--no-deep] [--json]
|
|
170
|
+
nativ hook status [--json] # enforcement mode, role, active task scope
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Task management and JIT context slicing
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
nativ task next # next executable task and its contract slice
|
|
177
|
+
nativ task list --available
|
|
178
|
+
nativ task list --milestone m1 --status pending
|
|
179
|
+
nativ task add "Implement OAuth2 callback" -a backend -v "npm test" -f "src/auth.ts"
|
|
180
|
+
nativ task start task-01
|
|
181
|
+
nativ task complete task-01 # runs the verification command
|
|
182
|
+
nativ task complete task-01 --timeout 600000 # for slow suites
|
|
183
|
+
nativ task block task-01 --reason "Missing Stripe API key"
|
|
184
|
+
nativ task escalate task-01 --type schema_flaw --details "Missing foreign key on orders table"
|
|
185
|
+
nativ task propose-patch task-01 --target db_schema --op ADD --path users.columns.bio --reason "..."
|
|
186
|
+
nativ task unlock task-01 --reason "refactor touches a shared file" # emergency; --revoke to re-lock
|
|
187
|
+
nativ triage # evaluate pending escalations; decision cards for the human
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Verification
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
nativ verify task-01
|
|
194
|
+
nativ verify --all
|
|
195
|
+
nativ verify --milestone m1 --timeout 60000 --json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Status and telemetry
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
nativ status
|
|
202
|
+
nativ status --telemetry # durations, token estimates, cost estimates, pass rates, role violations
|
|
203
|
+
nativ status --json
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Benchmarks
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
nativ bench
|
|
210
|
+
nativ bench --scenario concurrency --concurrency 8
|
|
211
|
+
nativ bench --json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Database studio and schema telemetry (masked, structure only)
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
nativ db status
|
|
218
|
+
nativ db inspect --env dev
|
|
219
|
+
nativ db diff --target contract --exit-code
|
|
220
|
+
nativ studio # local dashboard at http://localhost:4983
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Git worktree sandboxing
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
nativ worktree create task-01
|
|
227
|
+
nativ worktree list
|
|
228
|
+
nativ worktree merge task-01 # Safe Merge Gatekeeper enforced
|
|
229
|
+
nativ worktree remove task-01
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Contract Governor
|
|
235
|
+
|
|
236
|
+
A deterministic firewall between agents and the contracts (`.ai/db_schema.json`, `.ai/api_contracts.json`):
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
An agent proposes a contract change
|
|
240
|
+
|
|
|
241
|
+
v
|
|
242
|
+
[ Contract Governor ]
|
|
243
|
+
|
|
|
244
|
+
+-----------------+------------------+
|
|
245
|
+
v v
|
|
246
|
+
LOW_ADDITIVE HIGH_DESTRUCTIVE
|
|
247
|
+
new nullable columns, new tables, dropping tables or columns,
|
|
248
|
+
optional params, new response fields changing column types, dropping
|
|
249
|
+
routes, new required params
|
|
250
|
+
| |
|
|
251
|
+
v v
|
|
252
|
+
auto-approved and patched rejected with a structured
|
|
253
|
+
atomically violation; three strikes trip the
|
|
254
|
+
circuit breaker and log an escalation
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Concurrency
|
|
260
|
+
|
|
261
|
+
`.ai/master_plan.json` and `.ai/telemetry.json` are protected by OS-level advisory file locks (`proper-lockfile`) with atomic read-modify-write and retry backoff for Windows `EBUSY`/`EPERM`. Several agents in separate terminals can start, complete and add tasks without lost updates. Long verification commands run outside the lock.
|
|
262
|
+
|
|
263
|
+
Parallel agents share your Claude usage limit. Two or three at a time is a sensible default on a subscription.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Telemetry
|
|
268
|
+
|
|
269
|
+
Task transitions and role violations are recorded in `.ai/telemetry.json`: durations, token estimates priced with the model table in `src/core/telemetry.ts`, verification pass rates, circuit-breaker trips, and (capped at the latest 200) enforcement violations with the rule, mode, tool, project-relative path and task. File contents are never logged.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## MCP server
|
|
274
|
+
|
|
275
|
+
`nativ mcp` speaks the Model Context Protocol over stdio. `nativ setup` registers it for Claude Code; the same server works with Cursor, Claude Desktop and Antigravity.
|
|
276
|
+
|
|
277
|
+
| Tool / resource | Description |
|
|
278
|
+
| :--- | :--- |
|
|
279
|
+
| `nativ_task_next`, `nativ_task_list`, `nativ_task_add` | Find and add work |
|
|
280
|
+
| `nativ_task_start`, `nativ_task_complete`, `nativ_task_block` | Move a task through its lifecycle (complete runs the gatekeeper) |
|
|
281
|
+
| `nativ_task_escalate`, `nativ_task_propose_patch` | Escalate a contract gap, or propose a governed patch |
|
|
282
|
+
| `nativ_verify`, `nativ_bench`, `nativ_status` | Verification, benchmarks, progress |
|
|
283
|
+
| `nativ_worktree_*` | Create, list, merge and remove task worktrees |
|
|
284
|
+
| `nativ_db_status`, `nativ_db_inspect`, `nativ_db_diff` | Masked, structure-only database telemetry |
|
|
285
|
+
| `nativ_doctor` | Read-only health report. Repairs are `nativ doctor --fix` in a terminal |
|
|
286
|
+
| `nativ://context`, `nativ://master-plan`, `nativ://db-schema`, `nativ://api-contracts`, `nativ://escalation`, `nativ://telemetry` | Read-only resources |
|
|
287
|
+
|
|
288
|
+
There is deliberately no MCP tool to unlock a task, write a contract, sync a database schema or run setup.
|
|
289
|
+
|
|
290
|
+
Manual registration, if you prefer:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
claude mcp add nativ -- nativ mcp
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"mcpServers": {
|
|
299
|
+
"nativ": { "command": "npx", "args": ["-y", "@njeybe/nativ", "mcp", "/absolute/path/to/project"] }
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Repository structure
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
nativ/
|
|
310
|
+
bin/cli.js entry point (a fast path serves the hook commands without loading the whole CLI)
|
|
311
|
+
src/
|
|
312
|
+
index.ts command registry
|
|
313
|
+
commands/ init, setup, doctor, hook, task, verify, worktree, db, triage, ...
|
|
314
|
+
core/ enforcement, setup-assets, tier1-liaison, telemetry, lock-manager, verifier, ...
|
|
315
|
+
providers/ claude-cli, claude-api, gemini, registry (fallback chain and cooldown)
|
|
316
|
+
governor/ contract evaluator, circuit breaker, rules
|
|
317
|
+
mcp/server.ts MCP server
|
|
318
|
+
db/ masked env parser, introspection, schema diff
|
|
319
|
+
server/ Studio web dashboard
|
|
320
|
+
runner/ agent supervisor
|
|
321
|
+
templates/ AGENTS.md, CLAUDE.md, GEMINI.md, claude-agents/, dot-ai/
|
|
322
|
+
plugin/ Claude Code plugin (generated by `npm run sync-plugin`)
|
|
323
|
+
.claude-plugin/ marketplace entry for the plugin
|
|
324
|
+
scripts/sync-plugin.mjs renders plugin/ from the same sources as `nativ setup`
|
|
325
|
+
tests/ regression suites (`npm test`)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Changed a template or the setup generator? Run `npm run sync-plugin`; a test fails if `plugin/` is out of date.
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## License
|
|
333
|
+
|
|
334
|
+
MIT (c) JB Natividad. See [LICENSE](LICENSE).
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Claude Code runs `nativ hook check` before every file write, so those two commands skip loading the whole CLI
|
|
4
|
+
// (every command and database driver, roughly half a second) and import only what they need. Everything else
|
|
5
|
+
// goes through the full program exactly as before.
|
|
6
|
+
const [, , group, subcommand, ...rest] = process.argv;
|
|
7
|
+
|
|
8
|
+
if (group === 'hook' && (subcommand === 'check' || subcommand === 'context')) {
|
|
9
|
+
// The optional targetDir is the first argument that is not a flag.
|
|
10
|
+
const targetDir = rest.find((arg) => !arg.startsWith('-'));
|
|
11
|
+
try {
|
|
12
|
+
if (subcommand === 'check') {
|
|
13
|
+
const { runHookCheck } = await import('../dist/commands/hook.js');
|
|
14
|
+
await runHookCheck(targetDir);
|
|
15
|
+
} else {
|
|
16
|
+
const { runSessionContext } = await import('../dist/core/setup-assets.js');
|
|
17
|
+
runSessionContext(targetDir);
|
|
18
|
+
}
|
|
19
|
+
} catch (err) {
|
|
20
|
+
// A hook must never fail the tool call it guards.
|
|
21
|
+
process.stderr.write(`nativ hook ${subcommand}: ${err instanceof Error ? err.message : String(err)}; allowing.\n`);
|
|
22
|
+
}
|
|
23
|
+
// No process.exit(): on Windows a pipe write is asynchronous and exiting here could cut the decision short.
|
|
24
|
+
process.exitCode = 0;
|
|
25
|
+
} else {
|
|
26
|
+
const { run } = await import('../dist/index.js');
|
|
27
|
+
run().catch((err) => {
|
|
28
|
+
console.error(err);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BenchmarkOptions, BenchmarkReport } from '../core/benchmark.js';
|
|
2
|
+
export interface BenchCommandOptions extends BenchmarkOptions {
|
|
3
|
+
output?: string;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
scenario?: string;
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function runBench(targetDirArg?: string, options?: BenchCommandOptions): Promise<BenchmarkReport | undefined>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import pc from 'picocolors';
|
|
4
|
+
import { runBenchmarks, formatBenchmarkReport } from '../core/benchmark.js';
|
|
5
|
+
export async function runBench(targetDirArg, options = {}) {
|
|
6
|
+
const targetDir = path.resolve(targetDirArg || process.cwd());
|
|
7
|
+
try {
|
|
8
|
+
if (!options.json) {
|
|
9
|
+
console.log(pc.bold(pc.cyan('\nš Initiating Nativ Synthetic Benchmark Matrix...')));
|
|
10
|
+
if (options.scenario) {
|
|
11
|
+
console.log(pc.dim(` Target Scenario: `) + pc.yellow(options.scenario));
|
|
12
|
+
}
|
|
13
|
+
if (options.concurrency) {
|
|
14
|
+
console.log(pc.dim(` Simulated Workers: `) + pc.yellow(String(options.concurrency)));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const report = await runBenchmarks(options);
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(JSON.stringify(report, null, 2));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(formatBenchmarkReport(report));
|
|
23
|
+
}
|
|
24
|
+
// Write to output file if requested or if inside an existing .ai project
|
|
25
|
+
let outputPath = options.output;
|
|
26
|
+
if (!outputPath) {
|
|
27
|
+
const aiDir = path.join(targetDir, '.ai');
|
|
28
|
+
if (fs.existsSync(aiDir)) {
|
|
29
|
+
outputPath = path.join(aiDir, 'benchmark_report.json');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (outputPath) {
|
|
33
|
+
const resolvedOutput = path.resolve(outputPath);
|
|
34
|
+
const outDir = path.dirname(resolvedOutput);
|
|
35
|
+
if (!fs.existsSync(outDir)) {
|
|
36
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
fs.writeFileSync(resolvedOutput, JSON.stringify(report, null, 2) + '\n', 'utf8');
|
|
39
|
+
if (!options.json) {
|
|
40
|
+
console.log(pc.dim(`š Benchmark report saved to: `) + pc.white(resolvedOutput) + '\n');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (report.summary.failedScenarios > 0) {
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
return report;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error(pc.red(`\nā Benchmark suite failed: ${err.message}`));
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare function runDbStatus(targetDirArg?: string, options?: {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
}): Promise<void>;
|
|
4
|
+
export declare function runDbInspect(targetDirArg?: string, options?: {
|
|
5
|
+
env?: string;
|
|
6
|
+
table?: string;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function runDbDiff(targetDirArg?: string, options?: {
|
|
10
|
+
target?: string;
|
|
11
|
+
json?: boolean;
|
|
12
|
+
exitCode?: boolean;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
/** Exports a live schema into .ai/db_schema.json. Previews unless --yes is passed. */
|
|
15
|
+
export declare function runDbSync(targetDirArg?: string, options?: {
|
|
16
|
+
source?: string;
|
|
17
|
+
yes?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
export declare function runDbUi(targetDirArg?: string, options?: {
|
|
20
|
+
port?: string;
|
|
21
|
+
open?: boolean;
|
|
22
|
+
}): Promise<void>;
|