@h1veframework/cli 0.5.1 → 0.5.2
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 +48 -62
- package/dist/index.js +32 -2
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -1,93 +1,79 @@
|
|
|
1
|
-
# @h1veframework/cli
|
|
1
|
+
# @h1veframework/cli · `nf`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
(status, start, move, spec, done, blocker, health, connect), autenticado por um token pessoal.
|
|
3
|
+
**The command-line companion for [H1VE](https://h1ve.org) — the governance & memory layer for teams building with AI.**
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Your team ships with AI (Claude Code, Cursor, Copilot). As the codebase grows, the AI and your teammates start
|
|
6
|
+
**losing context and drifting from decisions you already made**. H1VE keeps every feature aligned — a shared,
|
|
7
|
+
**eternal project memory** plus an **anti-drift engine** that checks each change against what's been decided.
|
|
8
|
+
`nf` drives that workflow straight from your terminal.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Part of the H1VE toolchain, alongside the **[MCP server](https://www.npmjs.com/package/@h1veframework/mcp)** for
|
|
11
|
+
Claude Code / Cursor.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- Uma conta no H1VE Flow. **Não precisa criar/colar token** — o `nf login` cuida disso.
|
|
13
|
+
→ **[h1ve.org](https://h1ve.org)** · **[app.h1ve.org](https://app.h1ve.org)**
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Quickstart (zero paste)
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
18
|
npm i -g @h1veframework/cli
|
|
18
|
-
nf
|
|
19
|
+
nf login # opens your browser → you click Authorize → done
|
|
20
|
+
nf status # state of the current branch's feature
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
`nf login` stores the credential locally (`~/.config/h1ve/credentials.json`, `600`) — the MCP server reads the
|
|
24
|
+
same one, so **one login sets up both**. The project **auto-resolves from your git remote**, so there's nothing
|
|
25
|
+
to paste and no `H1VE_PROJECT_ID` to set. `nf logout` removes it.
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
nf login # abre o navegador → você autoriza → pronto
|
|
25
|
-
nf health # já funciona
|
|
26
|
-
```
|
|
27
|
+
> `nf health` saying "no snapshots yet" is **success** (you're connected; the project just has no metrics yet).
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
a credencial sozinho** em `~/.config/h1ve/credentials.json` (permissão 600). O **[MCP](https://www.npmjs.com/package/@h1veframework/mcp)**
|
|
30
|
-
lê a mesma credencial — um `nf login` configura os dois. `nf logout` remove. **100% automático** (SPEC-078):
|
|
31
|
-
o projeto também é resolvido sozinho pelo repo (SPEC-077), então nada de `H1VE_PROJECT_ID`.
|
|
29
|
+
## Commands
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
| Command | What it does |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `nf login` / `nf logout` | Authorize in the browser and store the credential locally / remove it |
|
|
34
|
+
| `nf status` | State of the current branch's feature (stage, days active, blockers, sign-offs) |
|
|
35
|
+
| `nf start [<#\|id>] [--slug <s>]` | Start an assigned feature: create the `feat/{you}/{slug}` branch and record the slug |
|
|
36
|
+
| `nf spec` | Print the feature's spec (markdown) |
|
|
37
|
+
| `nf move <stage> [--note]` | Move the feature to another stage |
|
|
38
|
+
| `nf done [--from <file>] [--no-move]` | Submit the AI declaration (JSON) and move `dev → pr` |
|
|
39
|
+
| `nf blocker "<desc>"` | Open a blocker on the feature (you become its owner) |
|
|
40
|
+
| `nf health` | Latest technical-health snapshots for the project |
|
|
41
|
+
| `nf connect --kind <k> --label <l> --env KEY=VAL` | Write a credential to your **local** `.env.local` and register the inventory (never sent to the server) |
|
|
42
|
+
| `nf serve [--port 7391]` | Run the local agent (`127.0.0.1`) so the dashboard can apply credentials from the browser |
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
Flags: `--json` (raw output for scripts) · `--project <name\|id>` (if you belong to more than one project) · `-h`.
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
## Example
|
|
38
47
|
|
|
39
48
|
```bash
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
nf start # start your assigned feature (creates the branch)
|
|
50
|
+
# ... work: git, code, commits ...
|
|
51
|
+
nf status # check state anytime
|
|
52
|
+
nf blocker "waiting on the Neon credential" # blocked? open a blocker
|
|
53
|
+
nf done --from ai-declaration.json # submit the AI declaration + move dev → pr
|
|
43
54
|
```
|
|
44
55
|
|
|
45
|
-
|
|
46
|
-
> CLI **resolve o projeto sozinho** pelo `git remote` — zero config, mesmo com 2+ projetos. Use só pra
|
|
47
|
-
> **forçar** um projeto (override).
|
|
56
|
+
## CI / headless (env vars)
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
| Comando | O que faz |
|
|
52
|
-
|---|---|
|
|
53
|
-
| `nf login` | Autoriza no navegador e salva a credencial local (sem colar nada) |
|
|
54
|
-
| `nf logout` | Remove a credencial local |
|
|
55
|
-
| `nf health` | Últimos snapshots de saúde técnica do projeto |
|
|
56
|
-
| `nf status` | Estado da feature da branch atual (stage, dias ativo, blockers, sign-offs) |
|
|
57
|
-
| `nf start [<nº\|id>] [--slug <s>]` | Inicia uma feature atribuída: cria a branch `feat/{você}/{slug}` e grava o slug |
|
|
58
|
-
| `nf spec` | Imprime a spec (markdown) da feature da branch |
|
|
59
|
-
| `nf move <stage> [--note]` | Move a feature para outro stage |
|
|
60
|
-
| `nf done [--from <arq>] [--no-move]` | Envia a AI declaration (JSON) e move `dev → pr` |
|
|
61
|
-
| `nf blocker "<desc>"` | Abre um blocker na feature (você vira o dono) |
|
|
62
|
-
| `nf connect --kind <k> --label <l> --env KEY=VAL` | Aplica uma credencial no `.env.local` **local** (nunca ao servidor) e registra o inventário (Jeito B) |
|
|
63
|
-
| `nf serve [--port 7391]` | Sobe o agente local (`127.0.0.1`) p/ o menu visual do painel aplicar credenciais pelo navegador |
|
|
64
|
-
|
|
65
|
-
Flags: `--json` (saída crua p/ scripts) · `--project <nome\|id>` (se você é membro de +1 projeto) · `-h` (ajuda completa).
|
|
66
|
-
|
|
67
|
-
## Exemplo de uso
|
|
58
|
+
No browser? Configure by env (takes **precedence** over `nf login`):
|
|
68
59
|
|
|
69
60
|
```bash
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
nf blocker "aguardando credencial do Neon" # trava? abre blocker
|
|
74
|
-
nf done --from ai-declaration.json # envia a AI declaration + move dev → pr
|
|
61
|
+
export H1VE_API_URL="https://app.h1ve.org" # optional (this is the default)
|
|
62
|
+
export H1VE_API_KEY="nf_pat_..." # a PAT from app.h1ve.org/api-tokens
|
|
63
|
+
# export H1VE_PROJECT_ID="..." # OPTIONAL — the CLI resolves the project from the repo
|
|
75
64
|
```
|
|
76
65
|
|
|
77
66
|
## Troubleshooting
|
|
78
67
|
|
|
79
|
-
|
|
|
68
|
+
| Symptom | Fix |
|
|
80
69
|
|---|---|
|
|
81
|
-
| `nf: command not found` | Node
|
|
82
|
-
| `404`
|
|
83
|
-
| `NO_PROJECT` |
|
|
84
|
-
| `401` / `403` |
|
|
85
|
-
|
|
86
|
-
## Compatibilidade de nomes
|
|
70
|
+
| `nf: command not found` | Node missing or wrong terminal. Check `node --version`. On Windows, reopen the shell or use the VS Code terminal. |
|
|
71
|
+
| `404` on install | npm propagation right after a publish — wait a few minutes. |
|
|
72
|
+
| `NO_PROJECT` | You belong to more than one project — pass `--project <name\|id>`. |
|
|
73
|
+
| `401` / `403` | Wrong/missing token. Make sure `H1VE_API_KEY` is a PAT (`nf_pat_…`). `403 SERVICE_CANNOT_WRITE` = a read-only service key used on a write → use a PAT. |
|
|
87
74
|
|
|
88
|
-
|
|
89
|
-
**ainda são aceitos** por compatibilidade — se você já configurou com eles, não precisa mudar nada.
|
|
75
|
+
Requires **Node.js 18.18+**. Legacy env names `NEXUS_FLOW_API_URL` / `NEXUS_FLOW_API_KEY` are still accepted.
|
|
90
76
|
|
|
91
77
|
---
|
|
92
78
|
|
|
93
|
-
MIT · [H1VE
|
|
79
|
+
MIT · built with H1VE, by [H1VE](https://h1ve.org) 🐝
|
package/dist/index.js
CHANGED
|
@@ -128,16 +128,17 @@ function createClient(config) {
|
|
|
128
128
|
// do id e ignora o header onde não escopa — então mandar sempre é simples e seguro.
|
|
129
129
|
...config.projectId ? { "x-project-id": config.projectId } : {}
|
|
130
130
|
};
|
|
131
|
-
async function
|
|
131
|
+
async function writeAction(method, featureId, action, body) {
|
|
132
132
|
const url = `${rootUrl(config.baseUrl)}/api/features/${encodeURIComponent(featureId)}/${action}`;
|
|
133
133
|
const res = await doFetch(url, {
|
|
134
|
-
method
|
|
134
|
+
method,
|
|
135
135
|
headers: { ...authHeaders, "content-type": "application/json" },
|
|
136
136
|
body: JSON.stringify(body)
|
|
137
137
|
});
|
|
138
138
|
if (!res.ok) throw mapWriteError(res.status, await readErrorCode(res));
|
|
139
139
|
return await res.json();
|
|
140
140
|
}
|
|
141
|
+
const postAction = (featureId, action, body) => writeAction("POST", featureId, action, body);
|
|
141
142
|
return {
|
|
142
143
|
async getContext(branch) {
|
|
143
144
|
const url = `${rootUrl(config.baseUrl)}/api/context?branch=${encodeURIComponent(branch)}`;
|
|
@@ -157,9 +158,38 @@ function createClient(config) {
|
|
|
157
158
|
if (!res.ok) throw errorForStatus(res.status, await readErrorCode(res));
|
|
158
159
|
return await res.json();
|
|
159
160
|
},
|
|
161
|
+
async recallMemory(query) {
|
|
162
|
+
const params = new URLSearchParams();
|
|
163
|
+
if (query.entities?.length) params.set("entities", query.entities.join(","));
|
|
164
|
+
if (query.text) params.set("q", query.text);
|
|
165
|
+
if (query.limit) params.set("limit", String(query.limit));
|
|
166
|
+
const url = `${rootUrl(config.baseUrl)}/api/memory/recall?${params.toString()}`;
|
|
167
|
+
const res = await doFetch(url, { headers: authHeaders });
|
|
168
|
+
if (!res.ok) throw errorForStatus(res.status, await readErrorCode(res));
|
|
169
|
+
return await res.json();
|
|
170
|
+
},
|
|
160
171
|
startFeature(featureId, slug) {
|
|
161
172
|
return postAction(featureId, "start", slug ? { slug } : {});
|
|
162
173
|
},
|
|
174
|
+
setSpec(featureId, specContent) {
|
|
175
|
+
return writeAction("PATCH", featureId, "spec", { spec_content: specContent });
|
|
176
|
+
},
|
|
177
|
+
// SPEC-100 (B2): best-effort — o juiz de drift é ADVISORY; qualquer falha → {checked:false}
|
|
178
|
+
// (nunca lança, pra não estragar o fluxo de gravar a SPEC no `set_spec` do MCP).
|
|
179
|
+
async checkSpecAlignment(featureId) {
|
|
180
|
+
try {
|
|
181
|
+
const url = `${rootUrl(config.baseUrl)}/api/features/${encodeURIComponent(featureId)}/spec/alignment`;
|
|
182
|
+
const res = await doFetch(url, {
|
|
183
|
+
method: "POST",
|
|
184
|
+
headers: { ...authHeaders, "content-type": "application/json" },
|
|
185
|
+
body: "{}"
|
|
186
|
+
});
|
|
187
|
+
if (!res.ok) return { checked: false };
|
|
188
|
+
return await res.json();
|
|
189
|
+
} catch {
|
|
190
|
+
return { checked: false };
|
|
191
|
+
}
|
|
192
|
+
},
|
|
163
193
|
moveStage(featureId, toStage, note) {
|
|
164
194
|
return postAction(featureId, "move", { to_stage: toStage, note });
|
|
165
195
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h1veframework/cli",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "CLI
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"description": "The CLI for H1VE — the governance & memory layer for teams building with AI. Drive your feature flow (start, status, move, spec, done) from the terminal. Works with Claude Code, Cursor and Copilot.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -19,17 +19,27 @@
|
|
|
19
19
|
"url": "git+https://github.com/GusHartz/nexus-flow.git",
|
|
20
20
|
"directory": "packages/cli"
|
|
21
21
|
},
|
|
22
|
-
"homepage": "https://
|
|
22
|
+
"homepage": "https://h1ve.org",
|
|
23
23
|
"bugs": {
|
|
24
24
|
"url": "https://github.com/GusHartz/nexus-flow/issues"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"h1ve",
|
|
28
|
-
"h1ve-flow",
|
|
29
28
|
"cli",
|
|
30
29
|
"nf",
|
|
30
|
+
"ai",
|
|
31
|
+
"claude-code",
|
|
32
|
+
"cursor",
|
|
33
|
+
"copilot",
|
|
34
|
+
"ai-coding",
|
|
35
|
+
"ai-agents",
|
|
36
|
+
"memory",
|
|
37
|
+
"anti-drift",
|
|
38
|
+
"context",
|
|
39
|
+
"governance",
|
|
40
|
+
"developer-tools",
|
|
31
41
|
"dev-workflow",
|
|
32
|
-
"
|
|
42
|
+
"mcp"
|
|
33
43
|
],
|
|
34
44
|
"publishConfig": {
|
|
35
45
|
"access": "public"
|