@bvdm/delano 0.2.4 → 0.2.5
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/.delano/viewer/public/styles.css +1 -1
- package/README.md +35 -0
- package/assets/install-manifest.json +5 -0
- package/assets/payload/.agents/adapters/manifest.schema.json +103 -0
- package/assets/payload/.agents/adapters/spec-kit/adapter.json +71 -0
- package/assets/payload/.agents/schemas/status-transitions.json +17 -0
- package/assets/payload/.agents/scripts/check-status-transitions.mjs +83 -2
- package/assets/payload/.agents/scripts/pm/import-spec-kit.sh +605 -0
- package/assets/payload/.agents/scripts/pm/init.sh +31 -2
- package/assets/payload/.agents/scripts/pm/research.sh +296 -0
- package/assets/payload/.agents/scripts/pm/validate.sh +14 -0
- package/assets/payload/.delano/viewer/public/styles.css +1 -1
- package/assets/payload/.project/templates/decisions.md +18 -0
- package/assets/payload/.project/templates/plan.md +17 -0
- package/assets/payload/.project/templates/spec.md +12 -0
- package/assets/payload/.project/templates/task.md +6 -0
- package/assets/payload/.project/templates/workstream.md +1 -0
- package/package.json +4 -2
- package/src/cli/commands/state.js +689 -0
- package/src/cli/commands/wrapper.js +16 -3
- package/src/cli/index.js +119 -7
- package/src/cli/lib/project-state.js +918 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
cat <<'USAGE'
|
|
6
|
+
Usage:
|
|
7
|
+
research.sh <project-slug> <research-slug> [options]
|
|
8
|
+
|
|
9
|
+
Creates a repo-native Delano research intake folder for a project.
|
|
10
|
+
|
|
11
|
+
Required arguments:
|
|
12
|
+
project-slug Existing Delano project slug
|
|
13
|
+
research-slug Research folder slug in kebab-case
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--title <title> Human-readable research title
|
|
17
|
+
--question <question> Primary research question
|
|
18
|
+
--owner <owner> Research owner, defaults to team
|
|
19
|
+
--no-validate Create artifacts without running Delano validation
|
|
20
|
+
--json Print a single machine-readable JSON result
|
|
21
|
+
-h, --help Show this help
|
|
22
|
+
|
|
23
|
+
Agent notes:
|
|
24
|
+
- Use this before mutating spec/plan/tasks when intent is unclear.
|
|
25
|
+
- Update findings.md and progress.md during investigation.
|
|
26
|
+
- Fold durable conclusions forward into spec.md, plan.md, decisions.md, workstreams, tasks, or updates.
|
|
27
|
+
- Research files are supporting discovery state, not executable task truth.
|
|
28
|
+
USAGE
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
resolve_python() {
|
|
32
|
+
if command -v python3 >/dev/null 2>&1 && python3 -c "import sys" >/dev/null 2>&1; then
|
|
33
|
+
PYTHON_CMD=(python3)
|
|
34
|
+
elif command -v py >/dev/null 2>&1 && py -3 -c "import sys" >/dev/null 2>&1; then
|
|
35
|
+
PYTHON_CMD=(py -3)
|
|
36
|
+
elif command -v python >/dev/null 2>&1 && python -c "import sys" >/dev/null 2>&1; then
|
|
37
|
+
PYTHON_CMD=(python)
|
|
38
|
+
else
|
|
39
|
+
echo "Error: Python runtime not found. Install python3, python, or py -3." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
resolve_python
|
|
45
|
+
|
|
46
|
+
json_escape() {
|
|
47
|
+
"${PYTHON_CMD[@]}" -c 'import json,sys; print(json.dumps(sys.stdin.read().rstrip("\n")))'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if [[ "${1:-}" == "" || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
51
|
+
usage
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
if [[ "${2:-}" == "" ]]; then
|
|
56
|
+
usage
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
project_slug="$1"
|
|
61
|
+
research_slug="$2"
|
|
62
|
+
shift 2
|
|
63
|
+
|
|
64
|
+
title=""
|
|
65
|
+
question=""
|
|
66
|
+
owner="team"
|
|
67
|
+
validate="true"
|
|
68
|
+
json="false"
|
|
69
|
+
|
|
70
|
+
while [[ $# -gt 0 ]]; do
|
|
71
|
+
case "$1" in
|
|
72
|
+
--title)
|
|
73
|
+
title="${2:-}"
|
|
74
|
+
if [[ -z "$title" ]]; then echo "Error: --title requires a value"; exit 1; fi
|
|
75
|
+
shift 2
|
|
76
|
+
;;
|
|
77
|
+
--question)
|
|
78
|
+
question="${2:-}"
|
|
79
|
+
if [[ -z "$question" ]]; then echo "Error: --question requires a value"; exit 1; fi
|
|
80
|
+
shift 2
|
|
81
|
+
;;
|
|
82
|
+
--owner)
|
|
83
|
+
owner="${2:-}"
|
|
84
|
+
if [[ -z "$owner" ]]; then echo "Error: --owner requires a value"; exit 1; fi
|
|
85
|
+
shift 2
|
|
86
|
+
;;
|
|
87
|
+
--no-validate)
|
|
88
|
+
validate="false"
|
|
89
|
+
shift
|
|
90
|
+
;;
|
|
91
|
+
--json)
|
|
92
|
+
json="true"
|
|
93
|
+
shift
|
|
94
|
+
;;
|
|
95
|
+
-h|--help)
|
|
96
|
+
usage
|
|
97
|
+
exit 0
|
|
98
|
+
;;
|
|
99
|
+
--)
|
|
100
|
+
shift
|
|
101
|
+
;;
|
|
102
|
+
--*)
|
|
103
|
+
echo "Error: unknown option: $1"
|
|
104
|
+
exit 1
|
|
105
|
+
;;
|
|
106
|
+
*)
|
|
107
|
+
echo "Error: unexpected positional argument: $1"
|
|
108
|
+
exit 1
|
|
109
|
+
;;
|
|
110
|
+
esac
|
|
111
|
+
done
|
|
112
|
+
|
|
113
|
+
if [[ ! "$project_slug" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
|
|
114
|
+
echo "Error: project-slug must be kebab-case"
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
if [[ ! "$research_slug" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
|
|
119
|
+
echo "Error: research-slug must be kebab-case"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
124
|
+
cd "$root"
|
|
125
|
+
|
|
126
|
+
project_dir=".project/projects/$project_slug"
|
|
127
|
+
if [[ ! -d "$project_dir" ]]; then
|
|
128
|
+
echo "Error: Delano project not found: $project_dir"
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
research_dir="$project_dir/research/$research_slug"
|
|
133
|
+
if [[ -d "$research_dir" ]]; then
|
|
134
|
+
echo "Error: research intake already exists at $research_dir"
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
now="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
139
|
+
title="${title:-${research_slug//-/ }}"
|
|
140
|
+
question="${question:-<primary research question>}"
|
|
141
|
+
|
|
142
|
+
mkdir -p "$research_dir"
|
|
143
|
+
|
|
144
|
+
cat > "$research_dir/task_plan.md" <<PLAN
|
|
145
|
+
---
|
|
146
|
+
type: research_intake
|
|
147
|
+
project: $project_slug
|
|
148
|
+
slug: $research_slug
|
|
149
|
+
owner: $owner
|
|
150
|
+
status: opened
|
|
151
|
+
created: $now
|
|
152
|
+
updated: $now
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
# Research Plan: $title
|
|
156
|
+
|
|
157
|
+
## Goal
|
|
158
|
+
|
|
159
|
+
Answer the research question and fold durable conclusions into canonical Delano project artifacts.
|
|
160
|
+
|
|
161
|
+
## Primary Question
|
|
162
|
+
|
|
163
|
+
$question
|
|
164
|
+
|
|
165
|
+
## Scope
|
|
166
|
+
|
|
167
|
+
### In Scope
|
|
168
|
+
|
|
169
|
+
- Gather relevant evidence.
|
|
170
|
+
- Capture findings and decisions.
|
|
171
|
+
- Identify changes needed in \`spec.md\`, \`plan.md\`, \`decisions.md\`, workstreams, tasks, or updates.
|
|
172
|
+
|
|
173
|
+
### Out of Scope
|
|
174
|
+
|
|
175
|
+
- Marking delivery tasks done from research alone.
|
|
176
|
+
- External sync writes without normal Delano approval semantics.
|
|
177
|
+
- Storing secrets, credentials, or private machine paths.
|
|
178
|
+
|
|
179
|
+
## Current Phase
|
|
180
|
+
|
|
181
|
+
Opened
|
|
182
|
+
|
|
183
|
+
## Phases
|
|
184
|
+
|
|
185
|
+
- [x] Open research intake
|
|
186
|
+
- [ ] Investigate sources and options
|
|
187
|
+
- [ ] Summarize findings
|
|
188
|
+
- [ ] Fold forward into canonical project artifacts or explicitly close as no-action
|
|
189
|
+
|
|
190
|
+
## Decisions Made
|
|
191
|
+
|
|
192
|
+
| Decision | Rationale |
|
|
193
|
+
| --- | --- |
|
|
194
|
+
|
|
195
|
+
## Blockers
|
|
196
|
+
|
|
197
|
+
| Blocker | Owner | Check-back |
|
|
198
|
+
| --- | --- | --- |
|
|
199
|
+
PLAN
|
|
200
|
+
|
|
201
|
+
cat > "$research_dir/findings.md" <<FINDINGS
|
|
202
|
+
---
|
|
203
|
+
type: research_findings
|
|
204
|
+
project: $project_slug
|
|
205
|
+
slug: $research_slug
|
|
206
|
+
created: $now
|
|
207
|
+
updated: $now
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
# Findings: $title
|
|
211
|
+
|
|
212
|
+
## Source References
|
|
213
|
+
|
|
214
|
+
- <source, file, command, or artifact inspected>
|
|
215
|
+
|
|
216
|
+
## Observations
|
|
217
|
+
|
|
218
|
+
- <finding>
|
|
219
|
+
|
|
220
|
+
## Options Considered
|
|
221
|
+
|
|
222
|
+
| Option | Pros | Cons | Decision |
|
|
223
|
+
| --- | --- | --- | --- |
|
|
224
|
+
|
|
225
|
+
## Fold-Forward Candidates
|
|
226
|
+
|
|
227
|
+
| Finding | Target Artifact | Proposed Change |
|
|
228
|
+
| --- | --- | --- |
|
|
229
|
+
|
|
230
|
+
## Open Questions
|
|
231
|
+
|
|
232
|
+
- <question>
|
|
233
|
+
FINDINGS
|
|
234
|
+
|
|
235
|
+
cat > "$research_dir/progress.md" <<PROGRESS
|
|
236
|
+
---
|
|
237
|
+
type: research_progress
|
|
238
|
+
project: $project_slug
|
|
239
|
+
slug: $research_slug
|
|
240
|
+
created: $now
|
|
241
|
+
updated: $now
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
# Progress: $title
|
|
245
|
+
|
|
246
|
+
## $now
|
|
247
|
+
|
|
248
|
+
- Opened research intake for project \`$project_slug\`.
|
|
249
|
+
- Primary question: $question
|
|
250
|
+
|
|
251
|
+
## Validation Evidence
|
|
252
|
+
|
|
253
|
+
- Pending.
|
|
254
|
+
|
|
255
|
+
## Handoff Summary
|
|
256
|
+
|
|
257
|
+
- Pending.
|
|
258
|
+
PROGRESS
|
|
259
|
+
|
|
260
|
+
validation_status="skipped"
|
|
261
|
+
ok="true"
|
|
262
|
+
error=""
|
|
263
|
+
if [[ "$validate" == "true" ]]; then
|
|
264
|
+
if [[ "$json" == "true" ]]; then
|
|
265
|
+
validation_log="$(mktemp)"
|
|
266
|
+
if "$root/.agents/scripts/pm/validate.sh" >"$validation_log" 2>&1; then
|
|
267
|
+
validation_status="passed"
|
|
268
|
+
else
|
|
269
|
+
validation_status="failed"
|
|
270
|
+
ok="false"
|
|
271
|
+
error="validation_failed"
|
|
272
|
+
fi
|
|
273
|
+
rm -f "$validation_log"
|
|
274
|
+
else
|
|
275
|
+
"$root/.agents/scripts/pm/validate.sh"
|
|
276
|
+
validation_status="passed"
|
|
277
|
+
fi
|
|
278
|
+
fi
|
|
279
|
+
|
|
280
|
+
if [[ "$json" == "true" ]]; then
|
|
281
|
+
project_json="$(printf '%s' "$project_dir" | json_escape)"
|
|
282
|
+
research_json="$(printf '%s' "$research_dir" | json_escape)"
|
|
283
|
+
validation_json="$(printf '%s' "$validation_status" | json_escape)"
|
|
284
|
+
if [[ "$ok" == "true" ]]; then
|
|
285
|
+
printf '{"ok":true,"command":"research","project":%s,"research":%s,"files":["task_plan.md","findings.md","progress.md"],"validation":%s}\n' "$project_json" "$research_json" "$validation_json"
|
|
286
|
+
else
|
|
287
|
+
error_json="$(printf '%s' "$error" | json_escape)"
|
|
288
|
+
printf '{"ok":false,"command":"research","project":%s,"research":%s,"files":["task_plan.md","findings.md","progress.md"],"validation":%s,"error":%s}\n' "$project_json" "$research_json" "$validation_json" "$error_json"
|
|
289
|
+
exit 1
|
|
290
|
+
fi
|
|
291
|
+
else
|
|
292
|
+
echo "Created Delano research intake: $research_dir"
|
|
293
|
+
echo "Files: task_plan.md, findings.md, progress.md"
|
|
294
|
+
echo "Validation: $validation_status"
|
|
295
|
+
echo "Next: update findings.md and progress.md, then fold conclusions into canonical Delano artifacts."
|
|
296
|
+
fi
|
|
@@ -467,6 +467,20 @@ if [[ -n "$artifact_schema_check" ]]; then
|
|
|
467
467
|
fi
|
|
468
468
|
fi
|
|
469
469
|
|
|
470
|
+
if [[ -f scripts/check-adapter-manifests.mjs ]]; then
|
|
471
|
+
echo ""
|
|
472
|
+
if command -v node >/dev/null 2>&1; then
|
|
473
|
+
if node scripts/check-adapter-manifests.mjs; then
|
|
474
|
+
true
|
|
475
|
+
else
|
|
476
|
+
errors=$((errors + 1))
|
|
477
|
+
fi
|
|
478
|
+
else
|
|
479
|
+
echo "❌ Node runtime not found for adapter manifest check"
|
|
480
|
+
errors=$((errors + 1))
|
|
481
|
+
fi
|
|
482
|
+
fi
|
|
483
|
+
|
|
470
484
|
operating_modes_check=""
|
|
471
485
|
if [[ -f .agents/scripts/check-operating-modes.mjs ]]; then
|
|
472
486
|
operating_modes_check=".agents/scripts/check-operating-modes.mjs"
|
|
@@ -602,7 +602,7 @@ button { font-family: inherit; font-size: inherit; color: inherit; background: n
|
|
|
602
602
|
/* ---------- Workspace dashboard ---------- */
|
|
603
603
|
.project-grid {
|
|
604
604
|
display: grid;
|
|
605
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
605
|
+
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
|
606
606
|
gap: 14px;
|
|
607
607
|
padding-top: 16px;
|
|
608
608
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: <project-name>
|
|
3
|
+
slug: <kebab-case>
|
|
4
|
+
owner: <person-or-team>
|
|
5
|
+
created: <ISO8601 UTC>
|
|
6
|
+
updated: <ISO8601 UTC>
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Decisions: <project-name>
|
|
10
|
+
|
|
11
|
+
## Active Decisions
|
|
12
|
+
- No decisions recorded at creation.
|
|
13
|
+
|
|
14
|
+
## Superseded Decisions
|
|
15
|
+
- None.
|
|
16
|
+
|
|
17
|
+
## Open Decision Questions
|
|
18
|
+
- None recorded at creation.
|
|
@@ -13,8 +13,25 @@ spec_status_at_plan_time: <planned|active|complete|deferred>
|
|
|
13
13
|
|
|
14
14
|
## What Changed After Probe
|
|
15
15
|
|
|
16
|
+
## Technical Context
|
|
17
|
+
|
|
16
18
|
## Architecture Decisions
|
|
17
19
|
|
|
20
|
+
## Policy and Contract Checks
|
|
21
|
+
- [ ] `.project` remains the execution source of truth
|
|
22
|
+
- [ ] Probe decision is explicit
|
|
23
|
+
- [ ] Evidence gates are defined before handoff
|
|
24
|
+
- [ ] External sync writes require dry-run or operator approval
|
|
25
|
+
|
|
26
|
+
## Generated Artifact Map
|
|
27
|
+
- `spec.md`: <source or generation notes>
|
|
28
|
+
- `plan.md`: <source or generation notes>
|
|
29
|
+
- `workstreams/`: <source or generation notes>
|
|
30
|
+
- `tasks/`: <source or generation notes>
|
|
31
|
+
|
|
32
|
+
## Complexity Exceptions
|
|
33
|
+
- <exception, rationale, and owner>
|
|
34
|
+
|
|
18
35
|
## Probe-Driven Architecture Changes
|
|
19
36
|
|
|
20
37
|
## Workstream Design
|
|
@@ -19,6 +19,12 @@ probe_status: <pending|skipped|completed>
|
|
|
19
19
|
|
|
20
20
|
## Outcome and Success Metrics
|
|
21
21
|
|
|
22
|
+
## User Stories
|
|
23
|
+
- US-001: As a <user>, I want <capability>, so that <outcome>.
|
|
24
|
+
|
|
25
|
+
## Acceptance Scenarios
|
|
26
|
+
- AC-001: Given <context>, when <action>, then <observable result>.
|
|
27
|
+
|
|
22
28
|
## Scope
|
|
23
29
|
### In Scope
|
|
24
30
|
### Out of Scope
|
|
@@ -27,6 +33,12 @@ probe_status: <pending|skipped|completed>
|
|
|
27
33
|
|
|
28
34
|
## Non-Functional Requirements
|
|
29
35
|
|
|
36
|
+
## Assumptions
|
|
37
|
+
- <assumption to validate>
|
|
38
|
+
|
|
39
|
+
## Needs Clarification
|
|
40
|
+
- <question that must be answered before activation or execution>
|
|
41
|
+
|
|
30
42
|
## Hypotheses and Unknowns
|
|
31
43
|
|
|
32
44
|
## Touchpoints to Exercise
|
|
@@ -13,6 +13,8 @@ conflicts_with: []
|
|
|
13
13
|
parallel: true
|
|
14
14
|
priority: medium
|
|
15
15
|
estimate: M
|
|
16
|
+
story_id:
|
|
17
|
+
acceptance_criteria_ids: []
|
|
16
18
|
---
|
|
17
19
|
|
|
18
20
|
# Task: <task-title>
|
|
@@ -22,6 +24,10 @@ estimate: M
|
|
|
22
24
|
## Acceptance Criteria
|
|
23
25
|
- [ ]
|
|
24
26
|
|
|
27
|
+
## Traceability
|
|
28
|
+
- Story: <story_id or none>
|
|
29
|
+
- Acceptance criteria: <acceptance criteria ids or none>
|
|
30
|
+
|
|
25
31
|
## Technical Notes
|
|
26
32
|
|
|
27
33
|
## Definition of Done
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bvdm/delano",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "CLI for the Delano delivery runtime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
"check:project-metrics": "node scripts/summarize-project-metrics.mjs --json",
|
|
59
59
|
"check:context-audit": "node scripts/check-context-audit.mjs",
|
|
60
60
|
"check:skill-output-evals": "node scripts/check-skill-output-evals.mjs",
|
|
61
|
-
"check:closeout-learning": "node scripts/propose-closeout-learning.mjs --json && node scripts/check-closeout-learning-proposals.mjs"
|
|
61
|
+
"check:closeout-learning": "node scripts/propose-closeout-learning.mjs --json && node scripts/check-closeout-learning-proposals.mjs",
|
|
62
|
+
"check:spec-kit-interop": "node scripts/check-spec-kit-interop-fixtures.mjs",
|
|
63
|
+
"check:adapter-manifests": "node scripts/check-adapter-manifests.mjs"
|
|
62
64
|
}
|
|
63
65
|
}
|