@bvdm/delano 0.2.3 → 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/README.md +3 -2
- package/.delano/viewer/public/app.js +13 -1
- package/.delano/viewer/public/app.jsx +2312 -0
- package/.delano/viewer/public/delano-mark.svg +4 -0
- package/.delano/viewer/public/index.html +12 -14
- package/.delano/viewer/public/styles.css +1005 -833
- package/.delano/viewer/server.js +46 -5
- package/README.md +63 -3
- package/assets/install-manifest.json +7 -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/hooks/README.md +6 -1
- package/assets/payload/.agents/hooks/codex-session-status.js +123 -0
- package/assets/payload/.agents/schemas/status-transitions.json +35 -0
- package/assets/payload/.agents/scripts/README.md +1 -1
- package/assets/payload/.agents/scripts/check-status-transitions.mjs +171 -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/status.sh +135 -28
- package/assets/payload/.agents/scripts/pm/validate.sh +16 -0
- package/assets/payload/.codex/hooks.json +17 -0
- package/assets/payload/.delano/viewer/README.md +3 -2
- package/assets/payload/.delano/viewer/public/app.js +13 -1
- package/assets/payload/.delano/viewer/public/index.html +12 -14
- package/assets/payload/.delano/viewer/public/styles.css +1005 -833
- package/assets/payload/.delano/viewer/server.js +46 -5
- 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/install.js +2 -1
- package/src/cli/commands/state.js +689 -0
- package/src/cli/commands/viewer.js +2 -1
- package/src/cli/commands/wrapper.js +29 -5
- package/src/cli/index.js +120 -7
- package/src/cli/lib/install.js +179 -2
- package/src/cli/lib/project-state.js +918 -0
|
@@ -12,7 +12,16 @@ const { spawn, spawnSync } = require('node:child_process');
|
|
|
12
12
|
const repoRoot = path.resolve(process.env.DELANO_VIEWER_ROOT || path.resolve(__dirname, '..', '..'));
|
|
13
13
|
const projectRoot = path.join(repoRoot, '.project');
|
|
14
14
|
const publicRoot = path.join(__dirname, 'public');
|
|
15
|
-
const
|
|
15
|
+
const DEFAULT_PORT = 3977;
|
|
16
|
+
const MAX_PORT = 65535;
|
|
17
|
+
const MAX_PORT_ATTEMPTS = 100;
|
|
18
|
+
const startPort = normalizePort(process.env.DELANO_VIEWER_PORT || process.env.PORT, DEFAULT_PORT);
|
|
19
|
+
|
|
20
|
+
function normalizePort(value, fallback) {
|
|
21
|
+
const parsed = Number(value || fallback);
|
|
22
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_PORT) return fallback;
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
16
25
|
|
|
17
26
|
function isInside(parent, child) {
|
|
18
27
|
const rel = path.relative(parent, child);
|
|
@@ -332,6 +341,7 @@ function sendStatic(res, pathname) {
|
|
|
332
341
|
const ext = path.extname(resolved).toLowerCase();
|
|
333
342
|
const mimeMap = {
|
|
334
343
|
'.js': 'text/javascript',
|
|
344
|
+
'.jsx': 'text/javascript',
|
|
335
345
|
'.css': 'text/css',
|
|
336
346
|
'.svg': 'image/svg+xml',
|
|
337
347
|
'.png': 'image/png',
|
|
@@ -340,7 +350,7 @@ function sendStatic(res, pathname) {
|
|
|
340
350
|
'.webp': 'image/webp',
|
|
341
351
|
'.ico': 'image/x-icon',
|
|
342
352
|
};
|
|
343
|
-
const isText = ext === '.js' || ext === '.css' || ext === '.svg' || ext === '' || ext === '.html';
|
|
353
|
+
const isText = ext === '.js' || ext === '.jsx' || ext === '.css' || ext === '.svg' || ext === '' || ext === '.html';
|
|
344
354
|
const type = mimeMap[ext] || 'text/html';
|
|
345
355
|
const headers = isText ? { 'content-type': `${type}; charset=utf-8` } : { 'content-type': type };
|
|
346
356
|
res.writeHead(200, headers);
|
|
@@ -384,6 +394,37 @@ const server = http.createServer((req, res) => {
|
|
|
384
394
|
}
|
|
385
395
|
});
|
|
386
396
|
|
|
387
|
-
server
|
|
388
|
-
|
|
389
|
-
|
|
397
|
+
function listenWithPortFallback(server, firstPort, host = '127.0.0.1') {
|
|
398
|
+
let port = firstPort;
|
|
399
|
+
let attempts = 0;
|
|
400
|
+
|
|
401
|
+
const listen = () => {
|
|
402
|
+
server.once('error', onError);
|
|
403
|
+
server.listen(port, host);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const onError = (error) => {
|
|
407
|
+
if (error.code === 'EADDRINUSE' && port < MAX_PORT && attempts < MAX_PORT_ATTEMPTS) {
|
|
408
|
+
attempts += 1;
|
|
409
|
+
port += 1;
|
|
410
|
+
listen();
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
console.error(`Failed to start Delano viewer on ${host}:${port}: ${error.message}`);
|
|
415
|
+
process.exitCode = 1;
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const onListening = () => {
|
|
419
|
+
server.removeListener('error', onError);
|
|
420
|
+
const address = server.address();
|
|
421
|
+
const actualPort = typeof address === 'object' && address ? address.port : port;
|
|
422
|
+
const skipped = actualPort !== firstPort ? ` (${firstPort} was unavailable)` : '';
|
|
423
|
+
console.log(`Delano read-only viewer: http://${host}:${actualPort}${skipped}`);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
server.on('listening', onListening);
|
|
427
|
+
listen();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
listenWithPortFallback(server, startPort);
|
|
@@ -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
|
}
|
|
@@ -30,7 +30,7 @@ function getInstallHelp() {
|
|
|
30
30
|
" -h, --help Show command help.",
|
|
31
31
|
"",
|
|
32
32
|
"Categories:",
|
|
33
|
-
" agent-runtime, skills, viewer, project-context, project-templates,",
|
|
33
|
+
" agent-runtime, codex-hooks, skills, viewer, project-context, project-templates,",
|
|
34
34
|
" project-registry, project-projects, handbook, legacy-installer",
|
|
35
35
|
"",
|
|
36
36
|
"Behavior:",
|
|
@@ -38,6 +38,7 @@ function getInstallHelp() {
|
|
|
38
38
|
" - Aborts on conflicts by default.",
|
|
39
39
|
" - Filters the plan before conflict detection when --only or --exclude is used.",
|
|
40
40
|
" - Treats .project/context, .project/projects, and .project/registry as repo-owned state after install.",
|
|
41
|
+
" - Merges .codex/hooks.json when it exists; invalid or non-file hook configs are skipped without blocking install.",
|
|
41
42
|
" - Only installs the approved base payload; top-level adapter entry docs remain opt-in and are not installed in v1.",
|
|
42
43
|
"",
|
|
43
44
|
"Examples:",
|