scriveno 2.7.1 → 2.7.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 +3 -3
- package/commands/scr/new-work.md +1 -1
- package/commands/scr/scan.md +3 -3
- package/data/CONSTRAINTS.json +1 -1
- package/docs/configuration.md +1 -1
- package/docs/release-notes.md +13 -1
- package/docs/route-graph.md +1 -1
- package/lib/auto-invoke-engine.js +81 -6
- package/package.json +1 -1
- package/templates/config.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/aihxp/scriveno/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](CHANGELOG.md)
|
|
6
6
|
[](https://www.npmjs.com/package/scriveno)
|
|
7
7
|
[](https://www.npmjs.com/package/scriveno)
|
|
8
8
|
[](docs/runtime-support.md#shared-auto-invoke-engine)
|
|
@@ -246,11 +246,11 @@ Scriveno currently ships installer targets for these AI tooling environments:
|
|
|
246
246
|
|
|
247
247
|
## Status
|
|
248
248
|
|
|
249
|
-
**Version:** 2.7.
|
|
249
|
+
**Version:** 2.7.2
|
|
250
250
|
|
|
251
251
|
Scriveno's core command surface is stable across 113 commands, 50 work types, and 11 installer targets. The current repo baseline includes shipped planning milestones through `v2.0 Publishing Cover Packaging`, plus the creative-context, record-store, branching-next, runtime-sync, adaptive concierge, human-first writing-safeguard, authenticity-diagnostic, domain-grilling, installer-marker cleanup, cross-runtime agent metadata, visible automation status, the shared `scriveno status --project .` auto-invoke engine, route-intelligence lanes, safe apply reporting, runtime smoke checks, agent availability checks, route graph audits, the full audit repair pass through `2.0.11`, the first-run proof surface in `2.5.0`, and the executable `/scr:first-run` path. See [Quick Proof](docs/quick-proof.md) for the fastest proof path, [Shipped Assets](docs/shipped-assets.md) for the canonical asset inventory, and [Runtime Support](docs/runtime-support.md) for the runtime compatibility matrix.
|
|
252
252
|
|
|
253
|
-
Version `2.7.
|
|
253
|
+
Version `2.7.2` publishes Scriveno under the package name `scriveno`, so the current install command is `npx scriveno@latest`. The older `scriveno-cli` package name is historical and was unpublished during the rename, so npm cannot attach a deprecation notice to it while it has no active registry record. The older `scriven-cli` package remains on npm only as a deprecated legacy name that points users to `scriveno`. Do not treat either legacy package name as active unless a deliberate compatibility shim is republished. See [CHANGELOG](CHANGELOG.md) for the full list and [docs/release-notes.md](docs/release-notes.md) for the public-facing summary.
|
|
254
254
|
|
|
255
255
|
Package history is tracked in [CHANGELOG.md](CHANGELOG.md), and the public-facing summary for this release is in [docs/release-notes.md](docs/release-notes.md).
|
|
256
256
|
|
package/commands/scr/new-work.md
CHANGED
|
@@ -69,7 +69,7 @@ Always create `RECORD.md` from `templates/RECORD.md` without renaming it. It is
|
|
|
69
69
|
Write `.manuscript/config.json` by starting from `templates/config.json` and filling the project-specific values. The generated config must include the shared settings blocks that later commands read:
|
|
70
70
|
```json
|
|
71
71
|
{
|
|
72
|
-
"scriveno_version": "2.7.
|
|
72
|
+
"scriveno_version": "2.7.2",
|
|
73
73
|
"work_type": "<chosen>",
|
|
74
74
|
"group": "<group>",
|
|
75
75
|
"command_unit": "<unit>",
|
package/commands/scr/scan.md
CHANGED
|
@@ -38,8 +38,8 @@ Run every check. Do not stop on first finding. Bundle them all into one report.
|
|
|
38
38
|
Read `STATE.md` for `Units drafted`, `Units planned`, `Units reviewed`, and `Total words`. Then count what is actually on disk:
|
|
39
39
|
|
|
40
40
|
- **Units drafted** = files matching `.manuscript/drafts/body/*-DRAFT.md`
|
|
41
|
-
- **Units planned** = files matching `.manuscript
|
|
42
|
-
- **Units reviewed** = files matching `.manuscript/*-EDITOR-NOTES.md`
|
|
41
|
+
- **Units planned** = files matching `.manuscript/plans/*-PLAN.md`; legacy root-level `.manuscript/*-PLAN.md` also counts
|
|
42
|
+
- **Units reviewed** = files matching `.manuscript/reviews/*-REVIEW.md`; legacy root-level `.manuscript/*-EDITOR-NOTES.md` also counts
|
|
43
43
|
- **Total words** = `wc -w` summed across all `drafts/body/*-DRAFT.md` files
|
|
44
44
|
|
|
45
45
|
For each metric where STATE.md value != filesystem value, emit:
|
|
@@ -67,7 +67,7 @@ For each orphan, emit one finding with the unit identifier and the file path.
|
|
|
67
67
|
|
|
68
68
|
### CHECK 3: Plan vs. draft alignment
|
|
69
69
|
|
|
70
|
-
For each `*-PLAN.md` file in `.manuscript
|
|
70
|
+
For each `*-PLAN.md` file in `.manuscript/plans/` (and any legacy root-level `*-PLAN.md` file), check whether the corresponding `*-DRAFT.md` exists in `drafts/body/`. If a plan exists but no draft:
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
INFO Unit 8 has a plan ({N}-{A}-PLAN.md) but no draft yet.
|
package/data/CONSTRAINTS.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./constraints.schema.json",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Scriveno constraint system: work types, command availability, exports, and dependencies. Every command checks this file at runtime.",
|
|
5
5
|
"_notes": {
|
|
6
6
|
"sacred_keys": "Sacred subcommands live at commands/scr/sacred/<name>.md and run as /scr:sacred:<name>. Their CONSTRAINTS keys use the sacred:<name> form so /scr:help can render the runnable slash-command path directly. The sacred-numbering-format entry is a separate flat command (commands/scr/sacred-numbering-format.md) that surfaces the active tradition's numbering format. It used to be named sacred-verse-numbering, which collided with sacred:verse-numbering at install time -- both flattened to scr-sacred-verse-numbering. Renamed in v1.6.x; the installer now refuses to install when two sources share a flat skill name."
|
package/docs/configuration.md
CHANGED
package/docs/release-notes.md
CHANGED
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
This document is the public-facing summary of what changed between package releases. For package history, see the root [CHANGELOG](../CHANGELOG.md).
|
|
4
4
|
|
|
5
|
+
## 2.7.2 - 2026-05-30
|
|
6
|
+
|
|
7
|
+
### What changed
|
|
8
|
+
|
|
9
|
+
- Progress ledger correctness: reviewed units with open editor notes now stay in progress instead of being counted as done. Submitted units still count as done, and clean reviews count as done when the workflow stops at review.
|
|
10
|
+
- `/scr:scan` now points its plan and review counts at the canonical `.manuscript/plans/` and `.manuscript/reviews/` directories, with legacy root-level fallbacks.
|
|
11
|
+
- The 2.7.1 release text now matches the actual `scriveno status` output.
|
|
12
|
+
|
|
13
|
+
### Why it matters
|
|
14
|
+
|
|
15
|
+
The progress bar now reflects the writer's real state of work: review notes still waiting on revision no longer look finished.
|
|
16
|
+
|
|
5
17
|
## 2.7.1 - 2026-05-30
|
|
6
18
|
|
|
7
19
|
### What changed
|
|
8
20
|
|
|
9
|
-
- `scriveno status` now prints the progress ledger directly (a `Progress:` line with bar
|
|
21
|
+
- `scriveno status` now prints the progress ledger directly (a `Progress:` line with the bar and done / in progress / untouched counts), so the deliverable view is visible from the bundled CLI, not only to runtimes that load the engine module.
|
|
10
22
|
- Documentation-integrity pass: corrected the context-integrity layer description (now five files), added `PROGRESS.md` to the scan trust-file lists and the architecture template tree, and refreshed stale version and count references across the docs.
|
|
11
23
|
|
|
12
24
|
### Why it matters
|
package/docs/route-graph.md
CHANGED
|
@@ -13,7 +13,7 @@ The text report summarizes command count, graph edges, agent-capable routes, loc
|
|
|
13
13
|
|
|
14
14
|
## Current Shape
|
|
15
15
|
|
|
16
|
-
As of `2.7.
|
|
16
|
+
As of `2.7.2`, the route graph contains:
|
|
17
17
|
|
|
18
18
|
- 113 commands
|
|
19
19
|
- intent-order edges from `command_intents`
|
|
@@ -91,6 +91,7 @@ const REVIEW_KEYWORDS = [
|
|
|
91
91
|
'VOICE DRIFT',
|
|
92
92
|
'CONTINUITY',
|
|
93
93
|
];
|
|
94
|
+
const OPEN_REVIEW_KEYWORDS = REVIEW_KEYWORDS.filter((keyword) => keyword !== 'CONTINUITY');
|
|
94
95
|
|
|
95
96
|
const CORE_PROJECT_FILES = [
|
|
96
97
|
'WORK.md',
|
|
@@ -1404,6 +1405,30 @@ function ledgerUnitNumbers(dir, suffixRegex) {
|
|
|
1404
1405
|
return found;
|
|
1405
1406
|
}
|
|
1406
1407
|
|
|
1408
|
+
function ledgerUnitFileMap(dir, suffixRegex) {
|
|
1409
|
+
const found = new Map();
|
|
1410
|
+
let entries;
|
|
1411
|
+
try {
|
|
1412
|
+
entries = fs.readdirSync(dir);
|
|
1413
|
+
} catch (err) {
|
|
1414
|
+
return found;
|
|
1415
|
+
}
|
|
1416
|
+
for (const name of entries) {
|
|
1417
|
+
const match = name.match(suffixRegex);
|
|
1418
|
+
if (match) {
|
|
1419
|
+
found.set(parseInt(match[1], 10), path.join(dir, name));
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
return found;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
function mergeUnitFileMaps(target, source) {
|
|
1426
|
+
for (const [unit, file] of source.entries()) {
|
|
1427
|
+
if (!target.has(unit)) target.set(unit, file);
|
|
1428
|
+
}
|
|
1429
|
+
return target;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1407
1432
|
function ledgerOutlineUnitCount(manuscriptDir) {
|
|
1408
1433
|
let text;
|
|
1409
1434
|
try {
|
|
@@ -1426,6 +1451,39 @@ function ledgerBar(done, total, width) {
|
|
|
1426
1451
|
return '█'.repeat(clamped) + '░'.repeat(cells - clamped);
|
|
1427
1452
|
}
|
|
1428
1453
|
|
|
1454
|
+
function ledgerReferencedUnits(text) {
|
|
1455
|
+
const units = new Set();
|
|
1456
|
+
const pattern = /\b(?:unit|chapter|scene|section|act|part|surah|procedure|poem)\s*#?\s*(\d+)\b/gi;
|
|
1457
|
+
let match;
|
|
1458
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
1459
|
+
const unit = parseInt(match[1], 10);
|
|
1460
|
+
if (unit > 0) units.add(unit);
|
|
1461
|
+
}
|
|
1462
|
+
return units;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
function stateOpenRevisionUnits(manuscriptDir) {
|
|
1466
|
+
const text = readText(path.join(manuscriptDir, 'STATE.md'));
|
|
1467
|
+
const open = new Set();
|
|
1468
|
+
for (const line of text.split(/\r?\n/)) {
|
|
1469
|
+
if (!/(open revisions|unresolved review|editor notes.*awaiting revision|awaiting revision|revisions pending)/i.test(line)) {
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
for (const unit of ledgerReferencedUnits(line)) open.add(unit);
|
|
1473
|
+
}
|
|
1474
|
+
return open;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
function stateSubmittedUnits(manuscriptDir) {
|
|
1478
|
+
const text = readText(path.join(manuscriptDir, 'STATE.md'));
|
|
1479
|
+
const submitted = new Set();
|
|
1480
|
+
for (const line of text.split(/\r?\n/)) {
|
|
1481
|
+
if (!/\b(submit|submitted)\b/i.test(line)) continue;
|
|
1482
|
+
for (const unit of ledgerReferencedUnits(line)) submitted.add(unit);
|
|
1483
|
+
}
|
|
1484
|
+
return submitted;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1429
1487
|
// Returns deliverable progress for a project's .manuscript directory: total
|
|
1430
1488
|
// units, per-stage counts, the done / in-progress / untouched buckets, a
|
|
1431
1489
|
// percent, a rendered bar, and the unit-number sets. Derived purely from disk
|
|
@@ -1439,17 +1497,30 @@ function computeProgressLedger(manuscriptDir) {
|
|
|
1439
1497
|
for (const unit of ledgerUnitNumbers(manuscriptDir, /^(\d+)\D.*PLAN\.md$/i)) {
|
|
1440
1498
|
planned.add(unit);
|
|
1441
1499
|
}
|
|
1442
|
-
const
|
|
1443
|
-
|
|
1444
|
-
|
|
1500
|
+
const reviewFiles = ledgerUnitFileMap(path.join(manuscriptDir, 'reviews'), /^(\d+)\D.*REVIEW\.md$/i);
|
|
1501
|
+
mergeUnitFileMaps(reviewFiles, ledgerUnitFileMap(manuscriptDir, /^(\d+)\D.*EDITOR-NOTES\.md$/i));
|
|
1502
|
+
const reviewed = new Set(reviewFiles.keys());
|
|
1503
|
+
const submitted = stateSubmittedUnits(manuscriptDir);
|
|
1504
|
+
const openReviews = stateOpenRevisionUnits(manuscriptDir);
|
|
1505
|
+
for (const [unit, file] of reviewFiles.entries()) {
|
|
1506
|
+
if (containsAny(readText(file), OPEN_REVIEW_KEYWORDS)) {
|
|
1507
|
+
openReviews.add(unit);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
for (const unit of submitted) {
|
|
1511
|
+
openReviews.delete(unit);
|
|
1512
|
+
}
|
|
1513
|
+
const doneUnits = new Set(submitted);
|
|
1514
|
+
for (const unit of reviewed) {
|
|
1515
|
+
if (!openReviews.has(unit)) doneUnits.add(unit);
|
|
1445
1516
|
}
|
|
1446
1517
|
|
|
1447
|
-
const worked = new Set([...planned, ...drafted, ...reviewed]);
|
|
1518
|
+
const worked = new Set([...planned, ...drafted, ...reviewed, ...submitted]);
|
|
1448
1519
|
const maxWorked = worked.size ? Math.max(...worked) : 0;
|
|
1449
1520
|
const total = Math.max(ledgerOutlineUnitCount(manuscriptDir), worked.size, maxWorked);
|
|
1450
1521
|
|
|
1451
|
-
const done =
|
|
1452
|
-
const inProgress = [...worked].filter((unit) => !
|
|
1522
|
+
const done = doneUnits.size;
|
|
1523
|
+
const inProgress = [...worked].filter((unit) => !doneUnits.has(unit)).length;
|
|
1453
1524
|
const untouched = Math.max(0, total - worked.size);
|
|
1454
1525
|
const percent = total > 0 ? Math.round((done / total) * 100) : 0;
|
|
1455
1526
|
|
|
@@ -1458,6 +1529,7 @@ function computeProgressLedger(manuscriptDir) {
|
|
|
1458
1529
|
drafted: drafted.size,
|
|
1459
1530
|
planned: planned.size,
|
|
1460
1531
|
reviewed: reviewed.size,
|
|
1532
|
+
submitted: submitted.size,
|
|
1461
1533
|
done,
|
|
1462
1534
|
inProgress,
|
|
1463
1535
|
untouched,
|
|
@@ -1467,6 +1539,9 @@ function computeProgressLedger(manuscriptDir) {
|
|
|
1467
1539
|
drafted: [...drafted].sort((a, b) => a - b),
|
|
1468
1540
|
planned: [...planned].sort((a, b) => a - b),
|
|
1469
1541
|
reviewed: [...reviewed].sort((a, b) => a - b),
|
|
1542
|
+
submitted: [...submitted].sort((a, b) => a - b),
|
|
1543
|
+
openReviews: [...openReviews].sort((a, b) => a - b),
|
|
1544
|
+
done: [...doneUnits].sort((a, b) => a - b),
|
|
1470
1545
|
},
|
|
1471
1546
|
};
|
|
1472
1547
|
}
|
package/package.json
CHANGED
package/templates/config.json
CHANGED