nubos-pilot 0.3.0 → 0.4.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/agents/np-code-fixer.md +22 -4
- package/agents/np-code-reviewer.md +6 -5
- package/agents/np-codebase-documenter.md +176 -0
- package/agents/np-executor.md +54 -7
- package/agents/np-planner.md +1 -0
- package/agents/np-researcher.md +7 -0
- package/bin/np-tools/discuss-project.cjs +377 -0
- package/bin/np-tools/discuss-project.test.cjs +238 -0
- package/bin/np-tools/doctor.cjs +103 -0
- package/bin/np-tools/doctor.test.cjs +112 -0
- package/bin/np-tools/new-project.cjs +6 -0
- package/bin/np-tools/scan-codebase.cjs +204 -0
- package/bin/np-tools/scan-codebase.test.cjs +165 -0
- package/bin/np-tools/update-docs.cjs +216 -0
- package/bin/np-tools/update-docs.test.cjs +130 -0
- package/docs/adr/0007-codebase-docs-layer.md +273 -0
- package/docs/adr/README.md +2 -0
- package/lib/codebase-docs.cjs +450 -0
- package/lib/codebase-docs.test.cjs +266 -0
- package/lib/codebase-manifest.cjs +171 -0
- package/lib/codebase-manifest.test.cjs +156 -0
- package/lib/git.cjs +38 -0
- package/lib/workspace-scan.cjs +290 -0
- package/lib/workspace-scan.test.cjs +212 -0
- package/np-tools.cjs +3 -0
- package/package.json +1 -1
- package/templates/PROJECT.md +26 -4
- package/workflows/discuss-project.md +177 -0
- package/workflows/new-project.md +141 -94
- package/workflows/scan-codebase.md +155 -0
- package/workflows/update-docs.md +132 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
command: np:discuss-project
|
|
3
|
+
description: Project-level discovery — adaptive interview that fills (bootstrap) or refreshes (refresh) PROJECT.md sections (Domain, Target Users, Non-Goals, Success Criteria, Strategic Decisions) and proposes REQ candidates.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# np:discuss-project
|
|
7
|
+
|
|
8
|
+
Deep, adaptive interview on project identity. Called automatically from
|
|
9
|
+
`np:new-project` (bootstrap mode — obligatory before roadmap/plan work),
|
|
10
|
+
and on demand later (refresh mode) when positioning or scope shifts.
|
|
11
|
+
|
|
12
|
+
The interview is informed by a codebase scan (so when the project already
|
|
13
|
+
contains code, the discussion builds on what exists rather than asking in
|
|
14
|
+
a vacuum).
|
|
15
|
+
|
|
16
|
+
## Philosophy
|
|
17
|
+
|
|
18
|
+
<philosophy>
|
|
19
|
+
Five boilerplate questions do not a project understand. PROJECT.md is the
|
|
20
|
+
one artifact every downstream agent reads before asking what to build, and
|
|
21
|
+
its quality caps the quality of every plan that follows. This workflow
|
|
22
|
+
treats the project discussion as a first-class moment — adaptive, grounded
|
|
23
|
+
in the scanned workspace, and ends with a filled PROJECT.md plus a
|
|
24
|
+
user-reviewable list of proposed requirements.
|
|
25
|
+
</philosophy>
|
|
26
|
+
|
|
27
|
+
## Scope Guardrail
|
|
28
|
+
|
|
29
|
+
<scope_guardrail>
|
|
30
|
+
Writes only:
|
|
31
|
+
- `.nubos-pilot/PROJECT.md` (section bodies only — structure preserved)
|
|
32
|
+
- `.nubos-pilot/REQUIREMENTS.md` (append-only "Proposed" block)
|
|
33
|
+
|
|
34
|
+
Never:
|
|
35
|
+
- rewrites application source
|
|
36
|
+
- touches `.nubos-pilot/codebase/` (that is `np:scan-codebase`'s job)
|
|
37
|
+
- writes requirements into the Active list (user promotes manually)
|
|
38
|
+
</scope_guardrail>
|
|
39
|
+
|
|
40
|
+
## Downstream Awareness
|
|
41
|
+
|
|
42
|
+
<downstream_awareness>
|
|
43
|
+
- `np:discuss-phase` reads PROJECT.md's Constraints and Domain.
|
|
44
|
+
- `np:planner` reads Non-Goals to avoid scope creep.
|
|
45
|
+
- `np:researcher` reads Strategic Decisions before proposing libraries.
|
|
46
|
+
- REQ-IDs appended by this workflow are consumed by `np:plan-phase` after
|
|
47
|
+
the user promotes them.
|
|
48
|
+
</downstream_awareness>
|
|
49
|
+
|
|
50
|
+
## Single-Call Init
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
INIT=$(node np-tools.cjs init discuss-project ${BOOTSTRAP:+--bootstrap})
|
|
54
|
+
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Parse: `mode`, `sub_mode` (`bootstrap` or `refresh`), `project_md_exists`,
|
|
58
|
+
`scan_context`, `questions[]`, `required_fields[]`.
|
|
59
|
+
|
|
60
|
+
## Process
|
|
61
|
+
|
|
62
|
+
### Step 1: Ground the user in the scan
|
|
63
|
+
|
|
64
|
+
Show the scan context before questions:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Before we discuss — here is what I found in the workspace:
|
|
68
|
+
|
|
69
|
+
- Files: <scan_context.file_count>
|
|
70
|
+
- Languages: <top 3 from language_distribution>
|
|
71
|
+
- Manifests: <manifest_paths>
|
|
72
|
+
- README head:
|
|
73
|
+
<first 10 lines or "none">
|
|
74
|
+
- Git: <commits[0..2] subjects or "no git repo">
|
|
75
|
+
|
|
76
|
+
Does this match what you expect, or am I missing something?
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Let the user correct (e.g. "the README is stale, ignore it"). Record
|
|
80
|
+
corrections — they shape follow-up questions.
|
|
81
|
+
|
|
82
|
+
### Step 2: Adaptive interview across the six required fields
|
|
83
|
+
|
|
84
|
+
The six required fields come from `required_fields[]`:
|
|
85
|
+
|
|
86
|
+
1. `project_description` — What This Is (2–3 sentences)
|
|
87
|
+
2. `domain_text` — Domain / lore / background
|
|
88
|
+
3. `target_users_text` — Target users
|
|
89
|
+
4. `non_goals_text` — Explicit Non-Goals
|
|
90
|
+
5. `success_criteria_text` — Observable success criteria
|
|
91
|
+
6. `strategic_decisions_text` — Strategic tech/business decisions
|
|
92
|
+
|
|
93
|
+
For each field: ask the seed question from `questions[]`, then follow up
|
|
94
|
+
with 1–3 deepening questions based on the answer. Use `np-tools.cjs
|
|
95
|
+
askuser` for every prompt (SC-5 enforcement — never bypass the gateway).
|
|
96
|
+
|
|
97
|
+
Tailor follow-ups to the scan:
|
|
98
|
+
|
|
99
|
+
- If the workspace has code, ask "I see `src/auth/` and `services/api/` —
|
|
100
|
+
does the Non-Goals list carve out what these will not do?"
|
|
101
|
+
- If no code, ask "For Strategic Decisions, what language/runtime are you
|
|
102
|
+
committing to?"
|
|
103
|
+
|
|
104
|
+
When the user's answer references an existing doc (e.g. "see README
|
|
105
|
+
section X"), fetch it and ground your summary in that.
|
|
106
|
+
|
|
107
|
+
### Step 3: Propose requirements
|
|
108
|
+
|
|
109
|
+
Based on the Success Criteria + Domain + Non-Goals, propose 3–7 candidate
|
|
110
|
+
REQ entries. Present them for user confirmation:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
I see these requirements emerging from your answers. Want me to add them to
|
|
114
|
+
REQUIREMENTS.md under "Proposed"?
|
|
115
|
+
|
|
116
|
+
REQ-02 — must operate offline (no network calls)
|
|
117
|
+
REQ-03 — persists all state as plain Markdown files
|
|
118
|
+
REQ-04 — supports Node 22+ and Python 3.12+
|
|
119
|
+
|
|
120
|
+
(confirm all / pick subset / none)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Write the confirmed list to a JSON file:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
REQ_FILE=$(mktemp -t np-proposed-reqs-XXXXXX.json)
|
|
127
|
+
# [{"id":"REQ-02","text":"..."}, ...]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Step 4: Apply answers
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
ANSWERS=$(mktemp -t np-discuss-project-answers.XXXXXX.json)
|
|
134
|
+
# Write the six answer fields as JSON
|
|
135
|
+
|
|
136
|
+
node np-tools.cjs init discuss-project --apply "$ANSWERS" \
|
|
137
|
+
${BOOTSTRAP:+--bootstrap} \
|
|
138
|
+
${REQ_FILE:+--proposed-requirements "$REQ_FILE"}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The subcommand replaces PROJECT.md section bodies (structure preserved)
|
|
142
|
+
and appends a "Proposed" block to REQUIREMENTS.md. Both writes are atomic.
|
|
143
|
+
|
|
144
|
+
### Step 5: Commit respecting config.commit_docs
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
COMMIT_DOCS=$(node np-tools.cjs config-get workflow.commit_docs 2>/dev/null || echo "true")
|
|
148
|
+
if [[ "$COMMIT_DOCS" == "true" ]]; then
|
|
149
|
+
git add .nubos-pilot/PROJECT.md .nubos-pilot/REQUIREMENTS.md 2>/dev/null || true
|
|
150
|
+
git commit -m "docs: np:discuss-project ${BOOTSTRAP:+bootstrap}${BOOTSTRAP:-refresh}" 2>/dev/null || true
|
|
151
|
+
fi
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Output
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
np:discuss-project complete (<sub_mode>).
|
|
158
|
+
|
|
159
|
+
Updated:
|
|
160
|
+
.nubos-pilot/PROJECT.md
|
|
161
|
+
.nubos-pilot/REQUIREMENTS.md (if requirements were proposed)
|
|
162
|
+
|
|
163
|
+
Next:
|
|
164
|
+
- Promote proposed REQs to Active in REQUIREMENTS.md
|
|
165
|
+
- Run `np:scan-codebase` if you have not yet (recommended)
|
|
166
|
+
- Run `np:discuss-phase 1` when ready to scope the first phase
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Errors
|
|
170
|
+
|
|
171
|
+
| Code | Trigger | User action |
|
|
172
|
+
|------|---------|-------------|
|
|
173
|
+
| `discuss-project-not-initialized` | `.nubos-pilot/` missing | Run `np:new-project` |
|
|
174
|
+
| `discuss-project-missing-field` | answer JSON lacks one of six fields | Complete the interview |
|
|
175
|
+
| `discuss-project-cannot-refresh` | refresh mode but PROJECT.md missing | Run bootstrap mode first |
|
|
176
|
+
| `discuss-project-bootstrap-requires-project` | bootstrap but no scaffold | Run `np:new-project` |
|
|
177
|
+
| `discuss-project-answers-parse-error` | answers file not valid JSON | Retry |
|
package/workflows/new-project.md
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
command: np:new-project
|
|
3
|
-
description: Greenfield project scaffold — runs
|
|
3
|
+
description: Greenfield project scaffold — scans existing workspace, runs bootstrap interview (5 questions), scaffolds the baseline artifacts, then chains into obligatory project discovery and initial codebase scan.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# np:new-project
|
|
7
7
|
|
|
8
|
-
Initialize a new project
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
Initialize a new nubos-pilot project in three phases:
|
|
9
|
+
|
|
10
|
+
1. **Phase 0 — Workspace Scan** (context capture)
|
|
11
|
+
2. **Phase 1 — Bootstrap Interview** (5 structural questions → scaffold)
|
|
12
|
+
3. **Phase 2 — Project Discovery** (obligatory, chains into `np:discuss-project --bootstrap`)
|
|
13
|
+
|
|
14
|
+
Optionally runs an initial codebase scan at the end when the workspace
|
|
15
|
+
contains existing source (`np:scan-codebase`). Everything lands under
|
|
16
|
+
`.nubos-pilot/`; no source files are ever modified.
|
|
13
17
|
|
|
14
18
|
## Philosophy
|
|
15
19
|
|
|
16
20
|
<philosophy>
|
|
17
|
-
The most leveraged moment in any project is the first interview
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
specific
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
The most leveraged moment in any project is the first interview, and the
|
|
22
|
+
first interview must be grounded in what actually exists. A bare interview
|
|
23
|
+
produces generic PROJECT.md stubs; a grounded one captures the specific
|
|
24
|
+
project under specific constraints. This workflow therefore scans *first*,
|
|
25
|
+
uses the scan to enrich the interview, and then makes the deeper
|
|
26
|
+
discovery step obligatory — no more jumping into phases with a skeleton
|
|
27
|
+
PROJECT.md.
|
|
28
|
+
|
|
29
|
+
Runtime-agnostic throughout: scanner is deterministic Node code; interview
|
|
30
|
+
uses the askuser gateway; discovery is delegated to `np:discuss-project`
|
|
31
|
+
which dispatches the documenter agent through whatever host is active.
|
|
24
32
|
</philosophy>
|
|
25
33
|
|
|
26
34
|
## Scope Guardrail
|
|
@@ -29,86 +37,92 @@ well-formed scaffold, not to pretend to understand the project.
|
|
|
29
37
|
This workflow ONLY touches `.nubos-pilot/` and creates its first phase
|
|
30
38
|
directory. It NEVER:
|
|
31
39
|
|
|
32
|
-
-
|
|
33
|
-
- writes when `.nubos-pilot/PROJECT.md` already exists (
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
`project-already-initialized` and this workflow offers two paths: abort
|
|
39
|
-
or destructively reset (user must confirm destructively).
|
|
40
|
+
- modifies files outside `.nubos-pilot/`
|
|
41
|
+
- writes when `.nubos-pilot/PROJECT.md` already exists (refuses with
|
|
42
|
+
`project-already-initialized`)
|
|
43
|
+
- mutates application source code
|
|
44
|
+
- spawns long-running tasks without user consent (batched codebase scan
|
|
45
|
+
offers pause between batches)
|
|
40
46
|
</scope_guardrail>
|
|
41
47
|
|
|
42
48
|
## Downstream Awareness
|
|
43
49
|
|
|
44
50
|
<downstream_awareness>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
- `np:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
is expected to edit it before running `np:plan-phase 1`.
|
|
51
|
+
This workflow writes:
|
|
52
|
+
- `.nubos-pilot/PROJECT.md` (section bodies later filled by discovery)
|
|
53
|
+
- `.nubos-pilot/REQUIREMENTS.md` (REQ-01 placeholder)
|
|
54
|
+
- `.nubos-pilot/roadmap.yaml` + `ROADMAP.md`
|
|
55
|
+
- `.nubos-pilot/STATE.md`
|
|
56
|
+
- `.nubos-pilot/phases/01-<slug>/01-CONTEXT.md`
|
|
57
|
+
- (optional) `.nubos-pilot/codebase/` via chained `np:scan-codebase`
|
|
58
|
+
|
|
59
|
+
`np:discuss-project` (Phase 2) chains automatically — not skippable.
|
|
60
|
+
`np:scan-codebase` chains when the workspace contains >= 1 source file.
|
|
56
61
|
</downstream_awareness>
|
|
57
62
|
|
|
58
|
-
##
|
|
63
|
+
## Phase 0: Workspace Scan
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
single `np-tools.cjs init new-project` call.
|
|
65
|
+
Probe the workspace for context before asking anything:
|
|
62
66
|
|
|
63
67
|
```bash
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
SCAN=$(node -e '
|
|
69
|
+
const { scan } = require("./lib/workspace-scan.cjs");
|
|
70
|
+
const r = scan({ cwd: process.cwd(), batchSize: 1000 });
|
|
71
|
+
process.stdout.write(JSON.stringify({
|
|
72
|
+
file_count: r.stats.file_count,
|
|
73
|
+
langs: r.language_distribution,
|
|
74
|
+
manifests: Object.keys(r.manifests),
|
|
75
|
+
docs: Object.keys(r.docs),
|
|
76
|
+
readme_head: r.docs["README.md"]
|
|
77
|
+
? r.docs["README.md"].content.split("\\n").slice(0, 20).join("\\n")
|
|
78
|
+
: null,
|
|
79
|
+
git: r.git,
|
|
80
|
+
}));
|
|
81
|
+
')
|
|
66
82
|
```
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"mode": "interview",
|
|
73
|
-
"questions": [
|
|
74
|
-
{ "key": "project_name", "type": "input", "question": "Project name?" },
|
|
75
|
-
{ "key": "core_value", "type": "input", "question": "Core value — one sentence…" },
|
|
76
|
-
{ "key": "primary_constraints", "type": "input", "question": "Primary constraints…" },
|
|
77
|
-
{ "key": "first_milestone_name", "type": "input", "question": "First milestone name…" },
|
|
78
|
-
{ "key": "first_phase_name", "type": "input", "question": "First phase name…" }
|
|
79
|
-
]
|
|
80
|
-
}
|
|
84
|
+
Show findings to the user and offer pre-filled suggestions:
|
|
85
|
+
|
|
81
86
|
```
|
|
87
|
+
Workspace inventory:
|
|
88
|
+
- Files: <file_count>
|
|
89
|
+
- Top languages: <top 3>
|
|
90
|
+
- Manifests found: <list>
|
|
91
|
+
- README detected: <yes/no>
|
|
92
|
+
- Git repo: <yes/no, N commits>
|
|
93
|
+
|
|
94
|
+
I can suggest defaults from this scan. Review and adjust.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Use the scan to propose:
|
|
98
|
+
- `project_name` — from directory basename; edit if off
|
|
99
|
+
- `primary_constraints` — derived from manifests (e.g. "Node 22" from
|
|
100
|
+
`package.json.engines.node`)
|
|
101
|
+
- `core_value` — best-effort extraction from README first paragraph
|
|
82
102
|
|
|
83
|
-
## Interview
|
|
103
|
+
## Phase 1: Bootstrap Interview
|
|
84
104
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
105
|
+
The 5 structural questions. All prompts go through the askuser gateway.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
INIT=$(node np-tools.cjs init new-project)
|
|
109
|
+
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
110
|
+
```
|
|
88
111
|
|
|
89
112
|
```bash
|
|
90
113
|
ANS_PROJECT_NAME=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"Project name?"}')
|
|
91
|
-
ANS_CORE_VALUE=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"Core value
|
|
114
|
+
ANS_CORE_VALUE=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"Core value — one sentence that must stay true if everything else fails?"}')
|
|
92
115
|
ANS_CONSTRAINTS=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"Primary constraints (comma-separated)?"}')
|
|
93
116
|
ANS_FIRST_MS=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"First milestone name?"}')
|
|
94
117
|
ANS_FIRST_PHASE=$(node np-tools.cjs askuser --json '{"type":"input","prompt":"First phase name?"}')
|
|
95
118
|
```
|
|
96
119
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
and throws `invalid-slug` if either produces an empty string after
|
|
100
|
-
stripping non-`[a-z0-9-]` characters. The user sees this error immediately
|
|
101
|
-
and can re-run the workflow with a different answer.
|
|
120
|
+
When Phase 0 produced a suggestion, include it as the prompt default in
|
|
121
|
+
the askuser call (e.g. `"prompt":"Project name? (suggested: T-AI)"`).
|
|
102
122
|
|
|
103
|
-
|
|
104
|
-
inside the rendered templates — the subcommand's `render()` helper treats
|
|
105
|
-
them as plain strings, so shell metacharacters, Markdown syntax, and YAML
|
|
106
|
-
control chars are all inert. Task 2's NP-5 test asserts this.
|
|
107
|
-
</answer_validation>
|
|
123
|
+
## Apply scaffold
|
|
108
124
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Write the five answers to a tmp JSON file and feed it to the subcommand.
|
|
125
|
+
Write the five answers to a tmp JSON file and call the subcommand:
|
|
112
126
|
|
|
113
127
|
```bash
|
|
114
128
|
ANSWERS=$(mktemp -t np-new-project-answers.XXXXXX)
|
|
@@ -116,30 +130,28 @@ trap 'rm -f "$ANSWERS"' EXIT
|
|
|
116
130
|
|
|
117
131
|
node -e '
|
|
118
132
|
const fs = require("fs");
|
|
119
|
-
|
|
133
|
+
fs.writeFileSync(process.env.ANSWERS, JSON.stringify({
|
|
120
134
|
project_name: process.env.ANS_PROJECT_NAME,
|
|
121
135
|
core_value: process.env.ANS_CORE_VALUE,
|
|
122
136
|
primary_constraints: process.env.ANS_CONSTRAINTS,
|
|
123
137
|
first_milestone_name: process.env.ANS_FIRST_MS,
|
|
124
138
|
first_phase_name: process.env.ANS_FIRST_PHASE,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
|
|
139
|
+
}));
|
|
140
|
+
' ANSWERS="$ANSWERS" \
|
|
141
|
+
ANS_PROJECT_NAME="$ANS_PROJECT_NAME" ANS_CORE_VALUE="$ANS_CORE_VALUE" \
|
|
142
|
+
ANS_CONSTRAINTS="$ANS_CONSTRAINTS" ANS_FIRST_MS="$ANS_FIRST_MS" \
|
|
143
|
+
ANS_FIRST_PHASE="$ANS_FIRST_PHASE"
|
|
128
144
|
|
|
129
145
|
node np-tools.cjs init new-project --apply "$ANSWERS"
|
|
130
146
|
```
|
|
131
147
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
`
|
|
135
|
-
|
|
148
|
+
The six discovery-related PROJECT.md fields (`project_description`,
|
|
149
|
+
`domain_text`, `target_users_text`, `non_goals_text`,
|
|
150
|
+
`success_criteria_text`, `strategic_decisions_text`) are written as
|
|
151
|
+
`_TBD — filled by /np:discuss-project._` placeholders. Phase 2 fills them.
|
|
136
152
|
|
|
137
153
|
## Re-Init Guard
|
|
138
154
|
|
|
139
|
-
When `PROJECT.md` already exists, the subcommand throws
|
|
140
|
-
`project-already-initialized`. The workflow catches it and offers a
|
|
141
|
-
decision:
|
|
142
|
-
|
|
143
155
|
```bash
|
|
144
156
|
set +e
|
|
145
157
|
node np-tools.cjs init new-project --apply "$ANSWERS"
|
|
@@ -167,38 +179,75 @@ if [ "$APPLY_STATUS" -ne 0 ]; then
|
|
|
167
179
|
fi
|
|
168
180
|
```
|
|
169
181
|
|
|
170
|
-
|
|
171
|
-
without an explicit `select` answer containing `Delete`.
|
|
182
|
+
## Phase 2: Project Discovery (obligatory)
|
|
172
183
|
|
|
173
|
-
|
|
184
|
+
Do not let the user skip this. Chain into `np:discuss-project --bootstrap`:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
BOOTSTRAP=1 /np:discuss-project
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The user answers the six adaptive discovery questions (Target Users,
|
|
191
|
+
Domain, What-This-Is, Non-Goals, Success Criteria, Strategic Decisions),
|
|
192
|
+
reviews proposed requirements, and ends with a fully populated PROJECT.md.
|
|
193
|
+
|
|
194
|
+
If the user tries to exit mid-discovery, warn:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
PROJECT.md still has _TBD placeholders. Downstream phases will treat
|
|
198
|
+
the project as under-specified. Continue discovery? (yes / no, I will
|
|
199
|
+
finish later)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Record the skip in STATE.md so the next `np:next` reminds the user.
|
|
174
203
|
|
|
175
|
-
|
|
176
|
-
|
|
204
|
+
## Phase 3 (conditional): Initial Codebase Scan
|
|
205
|
+
|
|
206
|
+
If Phase 0 reported `file_count > 0` with code files (not only manifests
|
|
207
|
+
and docs), offer to run the initial scan now:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
RUN_SCAN=$(node np-tools.cjs askuser --json '{
|
|
211
|
+
"type": "confirm",
|
|
212
|
+
"prompt": "Run initial codebase scan now (np:scan-codebase)?",
|
|
213
|
+
"default": true
|
|
214
|
+
}')
|
|
215
|
+
|
|
216
|
+
if [[ "$RUN_SCAN" == "true" ]]; then
|
|
217
|
+
/np:scan-codebase
|
|
218
|
+
fi
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Empty workspaces skip this cleanly.
|
|
222
|
+
|
|
223
|
+
## Optional Commit
|
|
177
224
|
|
|
178
225
|
```bash
|
|
179
226
|
if [ "$(node np-tools.cjs config-get workflow.commit_docs 2>/dev/null)" = "true" ]; then
|
|
180
227
|
git add .nubos-pilot/
|
|
181
|
-
git commit -m "chore: np:new-project scaffold"
|
|
228
|
+
git commit -m "chore: np:new-project scaffold + discovery"
|
|
182
229
|
fi
|
|
183
230
|
```
|
|
184
231
|
|
|
185
232
|
## Output
|
|
186
233
|
|
|
187
|
-
On success, print a summary block and point the user at `np:next`:
|
|
188
|
-
|
|
189
234
|
```
|
|
190
235
|
np:new-project complete.
|
|
191
236
|
|
|
192
237
|
Created:
|
|
193
|
-
.nubos-pilot/PROJECT.md
|
|
238
|
+
.nubos-pilot/PROJECT.md (populated by discovery)
|
|
194
239
|
.nubos-pilot/REQUIREMENTS.md
|
|
195
240
|
.nubos-pilot/roadmap.yaml
|
|
196
241
|
.nubos-pilot/ROADMAP.md
|
|
197
242
|
.nubos-pilot/STATE.md
|
|
198
243
|
.nubos-pilot/phases/01-<slug>/01-CONTEXT.md
|
|
244
|
+
.nubos-pilot/codebase/ (if initial scan ran)
|
|
199
245
|
|
|
200
|
-
|
|
201
|
-
|
|
246
|
+
Milestone: <milestoneId> · Phase 1: <firstPhaseSlug>
|
|
247
|
+
|
|
248
|
+
Next:
|
|
249
|
+
- /np:discuss-phase 1 to scope the first phase
|
|
250
|
+
- /np:update-docs after any code change (agents will do this automatically)
|
|
202
251
|
```
|
|
203
252
|
|
|
204
253
|
## Errors
|
|
@@ -208,6 +257,4 @@ the first phase with `np:discuss-phase 1`.
|
|
|
208
257
|
| `project-already-initialized` | `PROJECT.md` exists | Abort or re-run with destructive option |
|
|
209
258
|
| `invalid-slug` | milestone/phase name has no `[a-z0-9]` content | Re-run with a different name |
|
|
210
259
|
| `answers-missing-field` | empty answer | Re-run and fill all 5 fields |
|
|
211
|
-
|
|
212
|
-
All errors propagate from the subcommand as `NubosPilotError` with a
|
|
213
|
-
stable `code` — workflow consumers can script against them.
|
|
260
|
+
| `discuss-project-bootstrap-requires-project` | Discovery invoked before scaffold | Restart workflow |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
command: np:scan-codebase
|
|
3
|
+
description: Initial deep codebase scan — inventories files, groups them into coherent modules, writes skill-style docs under .nubos-pilot/codebase/ that dev-agents must read before touching code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# np:scan-codebase
|
|
7
|
+
|
|
8
|
+
Perform the initial codebase scan for a project. Produces a full set of
|
|
9
|
+
module docs under `.nubos-pilot/codebase/modules/`, an `INDEX.md` pointer
|
|
10
|
+
file, a `.hashes.json` manifest for staleness tracking, and a
|
|
11
|
+
`.doc-index.json` mapping of doc → source paths.
|
|
12
|
+
|
|
13
|
+
Dev-agents (executor, code-fixer, planner, researcher, documenter, custom)
|
|
14
|
+
MUST read `INDEX.md` + any relevant module docs before modifying code, and
|
|
15
|
+
MUST call `np:update-docs` after changes.
|
|
16
|
+
|
|
17
|
+
## Philosophy
|
|
18
|
+
|
|
19
|
+
<philosophy>
|
|
20
|
+
The codebase doc layer is the shared memory of every agent working in the
|
|
21
|
+
project. If it is empty or stale, each agent re-derives context from raw
|
|
22
|
+
source, burns tokens, and can drift. This workflow pays the one-time cost
|
|
23
|
+
of a deep inventory, hybrid-parser-plus-documenter-agent pass so that every
|
|
24
|
+
subsequent agent starts informed.
|
|
25
|
+
|
|
26
|
+
Nothing in this workflow is Claude-specific. The subcommand returns
|
|
27
|
+
module-facts JSON, the documenter agent is a prompt that any orchestrator
|
|
28
|
+
(Claude Code, OpenAI, Codex) can dispatch. Stay runtime-agnostic.
|
|
29
|
+
</philosophy>
|
|
30
|
+
|
|
31
|
+
## Scope Guardrail
|
|
32
|
+
|
|
33
|
+
<scope_guardrail>
|
|
34
|
+
This workflow ONLY writes inside `.nubos-pilot/codebase/`. It NEVER:
|
|
35
|
+
|
|
36
|
+
- modifies application source code
|
|
37
|
+
- touches PROJECT.md, REQUIREMENTS.md, or roadmap.yaml
|
|
38
|
+
- runs git commands beyond read-only `git log` via the scanner
|
|
39
|
+
- spawns network calls outside the documenter agent's own tool surface
|
|
40
|
+
|
|
41
|
+
Refuse and report if any of these boundaries would be crossed.
|
|
42
|
+
</scope_guardrail>
|
|
43
|
+
|
|
44
|
+
## Downstream Awareness
|
|
45
|
+
|
|
46
|
+
<downstream_awareness>
|
|
47
|
+
- `np:update-docs` reads `.doc-index.json` + `.hashes.json` to diff.
|
|
48
|
+
- Every `np:execute-*` workflow's post-step calls `np:update-docs`.
|
|
49
|
+
- Every np-agent is instructed to read `.nubos-pilot/codebase/INDEX.md` and
|
|
50
|
+
relevant module docs before editing source.
|
|
51
|
+
|
|
52
|
+
If this workflow produces malformed INDEX.md or unreadable frontmatter,
|
|
53
|
+
every downstream agent degrades silently. Validate the written files at the
|
|
54
|
+
end.
|
|
55
|
+
</downstream_awareness>
|
|
56
|
+
|
|
57
|
+
## Single-Call Init
|
|
58
|
+
|
|
59
|
+
Scan, group, write manifest + stubs, emit module-facts in one call:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
PLAN=$(node np-tools.cjs scan-codebase --project-name "$PROJECT_NAME")
|
|
63
|
+
if [[ "$PLAN" == @file:* ]]; then PLAN=$(cat "${PLAN#@file:}"); fi
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`--project-name` is optional; when provided it goes into `INDEX.md`. Other
|
|
67
|
+
flags: `--batch-size N` (default 500), `--max-files N`.
|
|
68
|
+
|
|
69
|
+
Parse: `mode`, `stats`, `modules[]` (each with `id`, `directory`,
|
|
70
|
+
`primary_language`, `file_count`, `facts`), `index_path`, `manifest_path`.
|
|
71
|
+
|
|
72
|
+
## Process
|
|
73
|
+
|
|
74
|
+
### Step 1: Confirm scan scope with the user
|
|
75
|
+
|
|
76
|
+
Show a summary before iterating modules:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Scan complete.
|
|
80
|
+
- Files walked: <stats.file_count>
|
|
81
|
+
- Hashed: <stats.hashed_count>
|
|
82
|
+
- Languages: <top 3 by count>
|
|
83
|
+
- Modules discovered: <modules.length>
|
|
84
|
+
- Manifests captured: <manifests.length> (package.json, …)
|
|
85
|
+
|
|
86
|
+
Generate doc prose for all <N> modules? (yes / pick subset)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Large codebases may warrant a subset pass. Honor the user's choice — do
|
|
90
|
+
not blast through 500 agent calls without consent.
|
|
91
|
+
|
|
92
|
+
### Step 2: For each selected module, dispatch the documenter
|
|
93
|
+
|
|
94
|
+
Per module, build the prompt from `facts` and dispatch the documenter
|
|
95
|
+
subagent. The subagent is defined in `agents/np-codebase-documenter.md` and
|
|
96
|
+
is runtime-agnostic — pick whichever dispatch mechanism your host supports.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
PROSE_FILE=$(mktemp -t np-prose-XXXXXX.json)
|
|
100
|
+
# Host dispatches agent with buildDocumenterPrompt(facts) and writes JSON
|
|
101
|
+
# to $PROSE_FILE. Validate JSON before proceeding.
|
|
102
|
+
python -c 'import json,sys; json.load(open(sys.argv[1]))' "$PROSE_FILE"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Batch pacing: the user opted into batches during Step 1. Between batches,
|
|
106
|
+
show a progress line (`[37/120 modules documented]`) and give the user a
|
|
107
|
+
chance to pause with Ctrl-C. Never eat interrupt signals.
|
|
108
|
+
|
|
109
|
+
### Step 3: Apply prose per module
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
node np-tools.cjs scan-codebase --apply-prose \
|
|
113
|
+
--module "$MODULE_ID" \
|
|
114
|
+
--prose-file "$PROSE_FILE"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The subcommand re-reads the module's source hashes (handles files that
|
|
118
|
+
changed between scan and apply), merges the prose, and atomically writes
|
|
119
|
+
`modules/<id>.md`.
|
|
120
|
+
|
|
121
|
+
### Step 4: Validate written artifacts
|
|
122
|
+
|
|
123
|
+
Before declaring success:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
test -f .nubos-pilot/codebase/INDEX.md
|
|
127
|
+
test -f .nubos-pilot/codebase/.hashes.json
|
|
128
|
+
test -f .nubos-pilot/codebase/.doc-index.json
|
|
129
|
+
ls .nubos-pilot/codebase/modules/ | wc -l
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Warn if a module doc is still `_TBD_` — user may have opted out mid-run.
|
|
133
|
+
|
|
134
|
+
## Output
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
np:scan-codebase complete.
|
|
138
|
+
|
|
139
|
+
Indexed: .nubos-pilot/codebase/INDEX.md
|
|
140
|
+
Modules: <N> (documented: <M>, stubs only: <N-M>)
|
|
141
|
+
Manifest: .nubos-pilot/codebase/.hashes.json
|
|
142
|
+
|
|
143
|
+
Dev-agents will now read INDEX.md + relevant module docs before editing.
|
|
144
|
+
Next change → np:update-docs runs automatically from np:execute-* workflows.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Errors
|
|
148
|
+
|
|
149
|
+
| Code | Trigger | User action |
|
|
150
|
+
|------|---------|-------------|
|
|
151
|
+
| `scan-codebase-not-initialized` | `.nubos-pilot/` missing | Run `np:new-project` first |
|
|
152
|
+
| `scan-codebase-missing-module` | `--apply-prose` without `--module` | Supply flag |
|
|
153
|
+
| `scan-codebase-missing-prose` | `--apply-prose` without `--prose-file` | Supply flag |
|
|
154
|
+
| `scan-codebase-module-not-found` | id does not exist in current scan | Re-list via default mode |
|
|
155
|
+
| `scan-codebase-prose-unreadable` | prose JSON unreadable or invalid | Fix JSON; re-dispatch agent |
|