scriveno 2.0.5 → 2.0.7
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 +4 -4
- package/bin/install.js +144 -7
- package/commands/scr/autopilot-publish.md +28 -0
- package/commands/scr/autopilot-translate.md +29 -0
- package/commands/scr/autopilot.md +29 -0
- package/commands/scr/beta-reader.md +22 -0
- package/commands/scr/continuity-check.md +21 -0
- package/commands/scr/draft.md +21 -0
- package/commands/scr/editor-review.md +26 -0
- package/commands/scr/health.md +19 -0
- package/commands/scr/map-manuscript.md +26 -0
- package/commands/scr/new-work.md +1 -1
- package/commands/scr/next.md +40 -0
- package/commands/scr/plan.md +22 -0
- package/commands/scr/progress.md +25 -0
- package/commands/scr/quick-write.md +23 -0
- package/commands/scr/save.md +21 -0
- package/commands/scr/scan.md +20 -0
- package/commands/scr/session-report.md +19 -0
- package/commands/scr/sync.md +51 -3
- package/commands/scr/track.md +20 -0
- package/commands/scr/translate.md +25 -0
- package/commands/scr/voice-check.md +20 -0
- package/data/CONSTRAINTS.json +1 -1
- package/docs/auto-invoke-policy.md +100 -0
- package/docs/configuration.md +1 -1
- package/docs/release-notes.md +65 -0
- package/docs/runtime-support.md +20 -10
- 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
|
|
|
@@ -203,11 +203,11 @@ Scriveno currently ships installer targets for these AI tooling environments:
|
|
|
203
203
|
|
|
204
204
|
## Status
|
|
205
205
|
|
|
206
|
-
**Version:** 2.0.
|
|
206
|
+
**Version:** 2.0.7
|
|
207
207
|
|
|
208
|
-
Scriveno's core command surface is stable across 112 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,
|
|
208
|
+
Scriveno's core command surface is stable across 112 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, and proactive auto-invoke visibility work through `2.0.7`. See [Shipped Assets](docs/shipped-assets.md) for the canonical asset inventory and [Runtime Support](docs/runtime-support.md) for the runtime compatibility matrix.
|
|
209
209
|
|
|
210
|
-
Version `2.0.
|
|
210
|
+
Version `2.0.7` 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.
|
|
211
211
|
|
|
212
212
|
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).
|
|
213
213
|
|
package/bin/install.js
CHANGED
|
@@ -155,6 +155,7 @@ const RUNTIMES = {
|
|
|
155
155
|
agents_dir_global: path.join(os.homedir(), '.codex', 'agents'),
|
|
156
156
|
agents_dir_project: '.codex/agents',
|
|
157
157
|
skill_style: 'per-command',
|
|
158
|
+
agent_metadata: 'toml',
|
|
158
159
|
detect: () => fs.existsSync(path.join(os.homedir(), '.codex')),
|
|
159
160
|
},
|
|
160
161
|
'opencode': {
|
|
@@ -414,6 +415,58 @@ function collectCommandEntries(commandsRoot) {
|
|
|
414
415
|
return entries;
|
|
415
416
|
}
|
|
416
417
|
|
|
418
|
+
function stripMarkdownFrontmatter(content) {
|
|
419
|
+
if (typeof content !== 'string' || content.length === 0) return '';
|
|
420
|
+
const stripped = content.charCodeAt(0) === 0xFEFF ? content.slice(1) : content;
|
|
421
|
+
const lines = stripped.split(/\r?\n/);
|
|
422
|
+
if (lines[0] !== '---') return stripped;
|
|
423
|
+
for (let i = 1; i < lines.length; i++) {
|
|
424
|
+
if (lines[i] === '---' || lines[i] === '...') {
|
|
425
|
+
return lines.slice(i + 1).join('\n').replace(/^\n/, '');
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return stripped;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function collectAgentEntries(agentsRoot = path.join(PKG_ROOT, 'agents')) {
|
|
432
|
+
if (!fs.existsSync(agentsRoot)) return [];
|
|
433
|
+
const entries = [];
|
|
434
|
+
for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) {
|
|
435
|
+
if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
|
|
436
|
+
const relativePath = entry.name;
|
|
437
|
+
const filePath = path.join(agentsRoot, relativePath);
|
|
438
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
439
|
+
const stem = entry.name.replace(/\.md$/, '');
|
|
440
|
+
const frontmatter = readFrontmatterValues(content);
|
|
441
|
+
const name = frontmatter.name || stem;
|
|
442
|
+
const description = frontmatter.description || `${stem.replace(/-/g, ' ')} agent`;
|
|
443
|
+
entries.push({
|
|
444
|
+
name,
|
|
445
|
+
description,
|
|
446
|
+
relativePath,
|
|
447
|
+
metadataFileName: `${name}.toml`,
|
|
448
|
+
content,
|
|
449
|
+
body: stripMarkdownFrontmatter(content),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
453
|
+
return entries;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function tomlString(value) {
|
|
457
|
+
return JSON.stringify(String(value));
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function generateCodexAgentMetadata(entry) {
|
|
461
|
+
return [
|
|
462
|
+
`name = ${tomlString(entry.name)}`,
|
|
463
|
+
`description = ${tomlString(entry.description)}`,
|
|
464
|
+
'sandbox_mode = "workspace-write"',
|
|
465
|
+
`developer_instructions = ${tomlString(entry.body)}`,
|
|
466
|
+
'',
|
|
467
|
+
].join('\n');
|
|
468
|
+
}
|
|
469
|
+
|
|
417
470
|
// Both Claude (flat scr-foo.md filename) and Codex (per-command skill dir
|
|
418
471
|
// scr-foo/SKILL.md) install commands keyed by the same skill-name function:
|
|
419
472
|
// /scr:foo and /scr:foo:bar both flatten under commandRefToCodexSkillName by
|
|
@@ -686,7 +739,7 @@ function rewriteInstalledCommandRefs(content, transform) {
|
|
|
686
739
|
}
|
|
687
740
|
|
|
688
741
|
function markInstalledCommand(content, runtimeKey, commandRef, sourcePath) {
|
|
689
|
-
const marker = `<!-- scriveno-
|
|
742
|
+
const marker = `<!-- scriveno-installed-command runtime:${runtimeKey} command:${commandRef} source:${sourcePath} -->`;
|
|
690
743
|
return insertMarkerComment(content, marker);
|
|
691
744
|
}
|
|
692
745
|
|
|
@@ -708,7 +761,7 @@ function generateCodexCommandContent(entry, sourceContent) {
|
|
|
708
761
|
function isScrivenoInstalledCommandFile(filePath) {
|
|
709
762
|
if (!fs.existsSync(filePath)) return false;
|
|
710
763
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
711
|
-
return content.includes('scriveno-cli-installed-command');
|
|
764
|
+
return content.includes('scriveno-installed-command') || content.includes('scriveno-cli-installed-command');
|
|
712
765
|
}
|
|
713
766
|
|
|
714
767
|
function cleanFlatCommandFiles(commandsDir, currentFileNames, legacyDirs = []) {
|
|
@@ -754,7 +807,7 @@ function cleanFlatCommandFiles(commandsDir, currentFileNames, legacyDirs = []) {
|
|
|
754
807
|
function writeInstalledCommandManifest(commandsDir, runtimeKey, fileNames) {
|
|
755
808
|
const manifestPath = path.join(commandsDir, '.scriveno-installed.json');
|
|
756
809
|
const manifest = {
|
|
757
|
-
installer: 'scriveno
|
|
810
|
+
installer: 'scriveno',
|
|
758
811
|
version: VERSION,
|
|
759
812
|
runtime: runtimeKey,
|
|
760
813
|
files: fileNames,
|
|
@@ -1194,7 +1247,7 @@ function cleanCodexSkillDirs(skillsDir, currentSkillNames) {
|
|
|
1194
1247
|
function writeCodexSkillManifest(skillsDir, skillNames) {
|
|
1195
1248
|
const manifestPath = path.join(skillsDir, '.scriveno-installed.json');
|
|
1196
1249
|
const manifest = {
|
|
1197
|
-
installer: 'scriveno
|
|
1250
|
+
installer: 'scriveno',
|
|
1198
1251
|
version: VERSION,
|
|
1199
1252
|
skills: skillNames,
|
|
1200
1253
|
generated_at: new Date().toISOString(),
|
|
@@ -1202,6 +1255,64 @@ function writeCodexSkillManifest(skillsDir, skillNames) {
|
|
|
1202
1255
|
atomicWriteFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
1203
1256
|
}
|
|
1204
1257
|
|
|
1258
|
+
function isScrivenoCodexAgentMetadataFile(filePath) {
|
|
1259
|
+
if (!fs.existsSync(filePath)) return false;
|
|
1260
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
1261
|
+
return content.includes('developer_instructions = ') && (
|
|
1262
|
+
content.includes('# Drafter agent')
|
|
1263
|
+
|| content.includes('# Voice checker agent')
|
|
1264
|
+
|| content.includes('# Continuity checker agent')
|
|
1265
|
+
|| content.includes('# Plan checker agent')
|
|
1266
|
+
|| content.includes('# Researcher agent')
|
|
1267
|
+
|| content.includes('# Translator agent')
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
function cleanCodexAgentFiles(agentsDir, currentFileNames) {
|
|
1272
|
+
if (!fs.existsSync(agentsDir)) return 0;
|
|
1273
|
+
|
|
1274
|
+
const manifestPath = path.join(agentsDir, '.scriveno-agents-installed.json');
|
|
1275
|
+
const manifest = readJsonIfExists(manifestPath);
|
|
1276
|
+
const currentFileSet = new Set(currentFileNames);
|
|
1277
|
+
const knownFileNames = new Set(Array.isArray(manifest?.files) ? manifest.files : []);
|
|
1278
|
+
|
|
1279
|
+
for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
|
|
1280
|
+
if (!entry.isFile() || !entry.name.endsWith('.toml')) continue;
|
|
1281
|
+
const filePath = path.join(agentsDir, entry.name);
|
|
1282
|
+
if (isScrivenoCodexAgentMetadataFile(filePath)) {
|
|
1283
|
+
knownFileNames.add(entry.name);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
removePathIfExists(manifestPath);
|
|
1288
|
+
|
|
1289
|
+
let removed = 0;
|
|
1290
|
+
for (const fileName of knownFileNames) {
|
|
1291
|
+
if (!currentFileSet.has(fileName) && removePathIfExists(path.join(agentsDir, fileName))) {
|
|
1292
|
+
removed++;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
for (const fileName of currentFileNames) {
|
|
1297
|
+
if (removePathIfExists(path.join(agentsDir, fileName))) {
|
|
1298
|
+
removed++;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
return removed;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
function writeCodexAgentManifest(agentsDir, fileNames) {
|
|
1306
|
+
const manifestPath = path.join(agentsDir, '.scriveno-agents-installed.json');
|
|
1307
|
+
const manifest = {
|
|
1308
|
+
installer: 'scriveno',
|
|
1309
|
+
version: VERSION,
|
|
1310
|
+
files: fileNames,
|
|
1311
|
+
generated_at: new Date().toISOString(),
|
|
1312
|
+
};
|
|
1313
|
+
atomicWriteFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1205
1316
|
async function main() {
|
|
1206
1317
|
const parsed = parseArgs(process.argv.slice(2));
|
|
1207
1318
|
if (parsed.showHelp) {
|
|
@@ -1342,6 +1453,26 @@ function installManifestSkillRuntime(runtime, isGlobal, log) {
|
|
|
1342
1453
|
log(` ${c('green', 'OK')} ${runtime.label}: ${agentCount} agent prompts -> ${c('dim', path.join(skillsDir, 'agents'))}`);
|
|
1343
1454
|
}
|
|
1344
1455
|
|
|
1456
|
+
function installCodexAgentsWithMetadata(agentsDir) {
|
|
1457
|
+
const agentEntries = collectAgentEntries(path.join(PKG_ROOT, 'agents'));
|
|
1458
|
+
const currentFileNames = agentEntries.flatMap((entry) => [entry.relativePath, entry.metadataFileName]);
|
|
1459
|
+
|
|
1460
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
1461
|
+
const removed = cleanCodexAgentFiles(agentsDir, currentFileNames);
|
|
1462
|
+
|
|
1463
|
+
for (const entry of agentEntries) {
|
|
1464
|
+
atomicWriteFileSync(path.join(agentsDir, entry.relativePath), entry.content);
|
|
1465
|
+
atomicWriteFileSync(path.join(agentsDir, entry.metadataFileName), generateCodexAgentMetadata(entry));
|
|
1466
|
+
}
|
|
1467
|
+
writeCodexAgentManifest(agentsDir, currentFileNames);
|
|
1468
|
+
|
|
1469
|
+
return {
|
|
1470
|
+
agentCount: agentEntries.length,
|
|
1471
|
+
metadataCount: agentEntries.length,
|
|
1472
|
+
removed,
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1345
1476
|
function installCodexRuntime(runtime, isGlobal, log) {
|
|
1346
1477
|
const skillsDir = isGlobal ? runtime.skills_dir_global : path.resolve(runtime.skills_dir_project);
|
|
1347
1478
|
const commandsDir = isGlobal ? runtime.commands_dir_global : path.resolve(runtime.commands_dir_project);
|
|
@@ -1355,7 +1486,6 @@ function installCodexRuntime(runtime, isGlobal, log) {
|
|
|
1355
1486
|
removePathIfExists(commandsDir);
|
|
1356
1487
|
fs.mkdirSync(skillsDir, { recursive: true });
|
|
1357
1488
|
const removedSkillDirs = cleanCodexSkillDirs(skillsDir, skillNames);
|
|
1358
|
-
const removedAgentFiles = cleanMirroredFiles(path.join(PKG_ROOT, 'agents'), agentsDir);
|
|
1359
1489
|
|
|
1360
1490
|
// NOTE: `collectCommandEntries` returns .md files only, and the authoritative
|
|
1361
1491
|
// `commands/scr/**` tree is .md-only today. No non-.md assets need mirroring.
|
|
@@ -1373,7 +1503,7 @@ function installCodexRuntime(runtime, isGlobal, log) {
|
|
|
1373
1503
|
commandCount++;
|
|
1374
1504
|
}
|
|
1375
1505
|
|
|
1376
|
-
const
|
|
1506
|
+
const agentInstall = installCodexAgentsWithMetadata(agentsDir);
|
|
1377
1507
|
|
|
1378
1508
|
for (const entry of commandEntries) {
|
|
1379
1509
|
const skillDir = path.join(skillsDir, entry.skillName);
|
|
@@ -1385,7 +1515,7 @@ function installCodexRuntime(runtime, isGlobal, log) {
|
|
|
1385
1515
|
|
|
1386
1516
|
log(` ${c('green', 'OK')} ${runtime.label}: ${commandEntries.length} \$scr-* skills -> ${c('dim', skillsDir)}${removedSkillDirs ? c('dim', ` (cleaned ${removedSkillDirs} stale dirs)`) : ''}`);
|
|
1387
1517
|
log(` ${c('green', 'OK')} ${runtime.label}: ${commandCount} command files -> ${c('dim', commandsDir)}`);
|
|
1388
|
-
log(` ${c('green', 'OK')} ${runtime.label}: ${agentCount} agent prompts -> ${c('dim', agentsDir)}${
|
|
1518
|
+
log(` ${c('green', 'OK')} ${runtime.label}: ${agentInstall.agentCount} agent prompts + ${agentInstall.metadataCount} metadata files -> ${c('dim', agentsDir)}${agentInstall.removed ? c('dim', ` (cleaned ${agentInstall.removed} stale files)`) : ''}`);
|
|
1389
1519
|
}
|
|
1390
1520
|
|
|
1391
1521
|
function installGuidedRuntime(runtime, isGlobal, dataDir, log) {
|
|
@@ -1577,16 +1707,23 @@ module.exports = {
|
|
|
1577
1707
|
parseArgs,
|
|
1578
1708
|
resolveInstallRequest,
|
|
1579
1709
|
collectCommandEntries,
|
|
1710
|
+
collectAgentEntries,
|
|
1580
1711
|
assertNoSkillNameCollisions,
|
|
1581
1712
|
cleanCodexSkillDirs,
|
|
1713
|
+
cleanCodexAgentFiles,
|
|
1582
1714
|
commandRefToCodexSkillName,
|
|
1583
1715
|
commandRefToClaudeInvocation,
|
|
1584
1716
|
commandRefToCodexInvocation,
|
|
1585
1717
|
commandEntryToFlatCommandFileName,
|
|
1586
1718
|
generateClaudeCommandContent,
|
|
1587
1719
|
generateCodexCommandContent,
|
|
1720
|
+
generateCodexAgentMetadata,
|
|
1588
1721
|
rewriteInstalledCommandRefs,
|
|
1722
|
+
installCommandRuntime,
|
|
1723
|
+
installClaudeCommandRuntime,
|
|
1724
|
+
installManifestSkillRuntime,
|
|
1589
1725
|
installCodexRuntime,
|
|
1726
|
+
installCodexAgentsWithMetadata,
|
|
1590
1727
|
cleanFlatCommandFiles,
|
|
1591
1728
|
generateCodexSkill,
|
|
1592
1729
|
generateSkillManifest,
|
|
@@ -182,6 +182,34 @@ If any steps failed, show them in the "Errors" section with actionable fix instr
|
|
|
182
182
|
|
|
183
183
|
---
|
|
184
184
|
|
|
185
|
+
## Automation Status
|
|
186
|
+
|
|
187
|
+
Every progress update and final response must include a compact status trail. This is how the writer can tell whether Scriveno auto-chained commands, spawned agents, or only updated local files.
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
Automation status:
|
|
191
|
+
Trigger: /scr:autopilot-publish --preset {preset}
|
|
192
|
+
Auto-invoked commands:
|
|
193
|
+
- /scr:voice-check: yes/no
|
|
194
|
+
- /scr:continuity-check: yes/no
|
|
195
|
+
- /scr:front-matter: yes/no
|
|
196
|
+
- /scr:back-matter: yes/no
|
|
197
|
+
- /scr:cover-art: yes/no
|
|
198
|
+
- /scr:export: {count} run(s)
|
|
199
|
+
Spawned agents:
|
|
200
|
+
- voice-checker: {count}
|
|
201
|
+
- continuity-checker: {count}
|
|
202
|
+
Local operations:
|
|
203
|
+
- prerequisite scan: yes/no
|
|
204
|
+
- quality report files written: yes/no
|
|
205
|
+
- export package files written: {count}
|
|
206
|
+
Quality gate:
|
|
207
|
+
- status: warn-only
|
|
208
|
+
- reason: autopilot-publish reports quality findings but continues to export
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
If a quality command cannot spawn its native agent type, use the installed agent prompt in a fresh context and say `prompt-run fallback used` in the status block.
|
|
212
|
+
|
|
185
213
|
## Response Contract
|
|
186
214
|
|
|
187
215
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
|
@@ -213,6 +213,35 @@ Next Steps:
|
|
|
213
213
|
- **NEVER** continue past a blocking error without logging it -- all errors must appear in the completion summary
|
|
214
214
|
- **NEVER** modify the source manuscript -- translation works on copies in `.manuscript/translation/{lang}/`
|
|
215
215
|
|
|
216
|
+
## Automation Status
|
|
217
|
+
|
|
218
|
+
Every progress update and final response must include a compact status trail. This is how the writer can tell whether Scriveno auto-chained commands, spawned agents, or only updated local files.
|
|
219
|
+
|
|
220
|
+
```text
|
|
221
|
+
Automation status:
|
|
222
|
+
Trigger: /scr:autopilot-translate {languages}
|
|
223
|
+
Languages: {count}
|
|
224
|
+
Auto-invoked commands per language:
|
|
225
|
+
- /scr:translation-glossary: yes/no
|
|
226
|
+
- /scr:translate: yes/no
|
|
227
|
+
- /scr:translation-memory --build: yes/no
|
|
228
|
+
- /scr:cultural-adaptation: yes/no
|
|
229
|
+
- /scr:back-translate: yes/no
|
|
230
|
+
- /scr:multi-publish: yes/no
|
|
231
|
+
Spawned agents:
|
|
232
|
+
- translator: {count} fresh-context invocation(s)
|
|
233
|
+
Local operations:
|
|
234
|
+
- glossary files written: {count}
|
|
235
|
+
- translation memory files updated: {count}
|
|
236
|
+
- adaptation reports written: {count}
|
|
237
|
+
- export files written: {count}
|
|
238
|
+
Pause:
|
|
239
|
+
- status: none/blocking-error/writer-requested
|
|
240
|
+
- reason: {one sentence}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
If the translator native agent type is unavailable, use the installed `agents/translator.md` prompt in a fresh context per unit and say `prompt-run fallback used` in the status block.
|
|
244
|
+
|
|
216
245
|
## Response Contract
|
|
217
246
|
|
|
218
247
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
|
@@ -147,6 +147,35 @@ On pause or stop:
|
|
|
147
147
|
2. Include what was just completed and what the next action would be
|
|
148
148
|
3. Record the writer's notes if they provide any
|
|
149
149
|
|
|
150
|
+
## Automation Status
|
|
151
|
+
|
|
152
|
+
Every progress update and final response must include a compact status trail. This is how the writer can tell whether Scriveno auto-chained commands, spawned agents, or only updated local files.
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
Automation status:
|
|
156
|
+
Trigger: /scr:autopilot --profile {profile}
|
|
157
|
+
Profile: guided/supervised/full-auto
|
|
158
|
+
Auto-invoked commands:
|
|
159
|
+
- /scr:discuss N: yes/no
|
|
160
|
+
- /scr:plan N: yes/no
|
|
161
|
+
- /scr:draft N: yes/no
|
|
162
|
+
- /scr:editor-review N: yes/no
|
|
163
|
+
- /scr:submit N: yes/no
|
|
164
|
+
Spawned agents:
|
|
165
|
+
- plan-checker: {count}
|
|
166
|
+
- drafter: {count}
|
|
167
|
+
- voice-checker: {count}
|
|
168
|
+
- continuity-checker: {count}
|
|
169
|
+
Local operations:
|
|
170
|
+
- STATE.md updated: yes/no
|
|
171
|
+
- HISTORY.log updated: yes/no
|
|
172
|
+
Pause:
|
|
173
|
+
- status: none/guided/supervised/quality-gate/blocker
|
|
174
|
+
- reason: {one sentence}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
If a command in the chain runs local file operations only, say so under `Local operations` rather than listing it as a spawned agent. If a native agent type is unavailable and an installed prompt-run fallback is used, include that in `Spawned agents`.
|
|
178
|
+
|
|
150
179
|
## Response Contract
|
|
151
180
|
|
|
152
181
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
|
@@ -67,12 +67,34 @@ Load `.manuscript/config.json` to get `work_type`. Load Scriveno's installed/sha
|
|
|
67
67
|
</task>
|
|
68
68
|
</beta_reader_agent>
|
|
69
69
|
|
|
70
|
+
If the host runtime cannot spawn a beta reader worker, run the beta reader persona in an isolated fresh context. Report that fallback in the status block.
|
|
71
|
+
|
|
70
72
|
### OUTPUT
|
|
71
73
|
|
|
72
74
|
Save to `.manuscript/{act_num}-BETA-READER-NOTES.md`
|
|
73
75
|
|
|
74
76
|
Present findings conversationally to the writer -- this should feel like getting feedback from a trusted reader, not a technical report.
|
|
75
77
|
|
|
78
|
+
## Agent Status
|
|
79
|
+
|
|
80
|
+
Every response must include a short status block that makes invocation visible:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
Agent status:
|
|
84
|
+
Trigger: /scr:beta-reader {scope}
|
|
85
|
+
Spawned agents:
|
|
86
|
+
- beta-reader: 1 fresh-context reader invocation
|
|
87
|
+
Local operations:
|
|
88
|
+
- drafted files checked: {count}
|
|
89
|
+
- focus area applied: yes/no
|
|
90
|
+
- report written: yes/no
|
|
91
|
+
Auto-invoked:
|
|
92
|
+
- none
|
|
93
|
+
Why: beta-reader is experiential feedback only; revision remains a writer decision
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If native worker spawning is unavailable, say `prompt-run fallback used` in the status block.
|
|
97
|
+
|
|
76
98
|
## Response Contract
|
|
77
99
|
|
|
78
100
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
|
@@ -27,6 +27,8 @@ Invoke the installed `continuity-checker.md` agent for the writer's active Scriv
|
|
|
27
27
|
- DOCTRINES.md, LINEAGES.md, and CHRONOLOGY.md when present (sacred only)
|
|
28
28
|
- The previous continuity report if one exists, so the agent can verify resolved issues stayed resolved instead of re-flagging them
|
|
29
29
|
|
|
30
|
+
If the host runtime cannot spawn a native `continuity-checker` agent type, load the installed `agents/continuity-checker.md` prompt from the active runtime and run it in an isolated fresh context. Record that fallback in the status block.
|
|
31
|
+
|
|
30
32
|
The agent reads all drafted scenes and checks:
|
|
31
33
|
|
|
32
34
|
If RECORD.md contradicts the drafted text, flag the mismatch as a RECORD drift finding. If the drafted text reveals established facts or open threads that are missing from RECORD.md, list compact suggested updates under a "Record updates" section without rewriting the file unless the writer asked for fixes.
|
|
@@ -105,6 +107,25 @@ For each issue:
|
|
|
105
107
|
|
|
106
108
|
Save to `.manuscript/{act_num}-CONTINUITY-REPORT.md` or `.manuscript/FULL-CONTINUITY-REPORT.md`. For technical work types, use `CONSISTENCY-REPORT` in the writer-facing title even if the file path stays the same.
|
|
107
109
|
|
|
110
|
+
## Agent Status
|
|
111
|
+
|
|
112
|
+
Every response must include a short status block that makes invocation visible:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
Agent status:
|
|
116
|
+
Trigger: /scr:continuity-check {scope}
|
|
117
|
+
Spawned agents:
|
|
118
|
+
- continuity-checker: 1 fresh-context diagnostic invocation
|
|
119
|
+
Local operations:
|
|
120
|
+
- drafted files checked: {count}
|
|
121
|
+
- RECORD.md checked: yes/no
|
|
122
|
+
- prior report checked: yes/no
|
|
123
|
+
- report written: yes/no
|
|
124
|
+
Auto-invoked:
|
|
125
|
+
- none
|
|
126
|
+
Why: continuity-check is diagnostic only; fixes are writer-chosen handoffs
|
|
127
|
+
```
|
|
128
|
+
|
|
108
129
|
## Response Contract
|
|
109
130
|
|
|
110
131
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
package/commands/scr/draft.md
CHANGED
|
@@ -53,6 +53,27 @@ Require `.manuscript/plans/{N}-*-PLAN.md` files to exist. If none exist, also ch
|
|
|
53
53
|
|
|
54
54
|
8. **Tell the writer:** "Drafted {unit} {N}: X words across Y {atomic_units}. Voice consistency: Z%. Updated RECORD.md with what the draft established. Ready for editor review? Run `/scr:editor-review N` or `/scr:next`."
|
|
55
55
|
|
|
56
|
+
## Agent and Automation Status
|
|
57
|
+
|
|
58
|
+
Every response must include a short status block that makes invocation visible:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
Agent status:
|
|
62
|
+
Trigger: /scr:draft N
|
|
63
|
+
Spawned agents:
|
|
64
|
+
- drafter: {count} fresh-context invocation(s)
|
|
65
|
+
- voice-checker: 1 diagnostic pass, or none if no draft was produced
|
|
66
|
+
Local operations:
|
|
67
|
+
- draft files written: {count}
|
|
68
|
+
- RECORD.md updated: yes/no
|
|
69
|
+
- STATE.md updated: yes/no
|
|
70
|
+
Auto-invoked:
|
|
71
|
+
- /scr:editor-review N: yes/no
|
|
72
|
+
Why: {autopilot.enabled true, full-auto profile, supervised pause, or writer-facing manual mode}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
If the host runtime cannot spawn a native `drafter` or `voice-checker` agent type, load the installed agent prompt from the active runtime's `agents/` directory and run it in an isolated fresh context. In the status block, write `Spawned agents: native unavailable; prompt-run fallback used` so the writer can see what happened.
|
|
76
|
+
|
|
56
77
|
## History log
|
|
57
78
|
|
|
58
79
|
After all atomic units in this invocation are drafted, append one line to `.manuscript/HISTORY.log` per `docs/history-protocol.md`:
|
|
@@ -101,6 +101,8 @@ For any issues flagged, spawn a diagnostic agent:
|
|
|
101
101
|
</task>
|
|
102
102
|
</diagnostic_agent>
|
|
103
103
|
|
|
104
|
+
If the host runtime cannot spawn a dedicated diagnostic worker, run the revision diagnosis in an isolated fresh context for each flagged issue group. Report that fallback in the status block.
|
|
105
|
+
|
|
104
106
|
---
|
|
105
107
|
|
|
106
108
|
### STEP 4: GENERATE EDITOR NOTES
|
|
@@ -408,6 +410,30 @@ Together these form a complete accountability trail. Neither party's work is los
|
|
|
408
410
|
|
|
409
411
|
---
|
|
410
412
|
|
|
413
|
+
## Agent and Automation Status
|
|
414
|
+
|
|
415
|
+
Every response must include a short status block that makes invocation visible:
|
|
416
|
+
|
|
417
|
+
```text
|
|
418
|
+
Agent status:
|
|
419
|
+
Trigger: /scr:editor-review {mode}
|
|
420
|
+
Spawned agents:
|
|
421
|
+
- revision-diagnostic: {count} fresh-context invocation(s)
|
|
422
|
+
Local operations:
|
|
423
|
+
- reviewable units checked: {count}
|
|
424
|
+
- review report written: yes/no
|
|
425
|
+
- proposal decisions written: yes/no
|
|
426
|
+
- editor notes written: yes/no
|
|
427
|
+
- writer responses written: yes/no
|
|
428
|
+
Auto-invoked:
|
|
429
|
+
- none
|
|
430
|
+
Why: editor-review surfaces decisions and recommended handoffs; it does not revise prose without writer choice
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
If there were no flagged issues in standard review mode, report `revision-diagnostic: none`. In collaboration modes, report `revision-diagnostic: none` unless diagnosis was explicitly requested.
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
411
437
|
## Writer-Friendly Language Guide
|
|
412
438
|
|
|
413
439
|
This command uses writer-friendly terminology throughout:
|
package/commands/scr/health.md
CHANGED
|
@@ -7,6 +7,8 @@ argument-hint: "[--repair]"
|
|
|
7
7
|
|
|
8
8
|
You are a project health checker. Diagnose problems in the current Scriveno project and optionally fix what can be auto-fixed.
|
|
9
9
|
|
|
10
|
+
Follow the auto-invoke policy. In the source repository it is documented at `docs/auto-invoke-policy.md`. `/scr:health` is local and diagnostic. It does not spawn agents.
|
|
11
|
+
|
|
10
12
|
## Diagnostic mode (default, no flags)
|
|
11
13
|
|
|
12
14
|
Run these checks in order and report results with status indicators:
|
|
@@ -85,6 +87,23 @@ With `--repair`, fix what can be auto-fixed:
|
|
|
85
87
|
|
|
86
88
|
After repair: re-run diagnostics and show the updated health report.
|
|
87
89
|
|
|
90
|
+
## Automation Status
|
|
91
|
+
|
|
92
|
+
Every response must include a compact status block:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
Automation status:
|
|
96
|
+
Trigger: /scr:health {flags}
|
|
97
|
+
Spawned agents:
|
|
98
|
+
- none
|
|
99
|
+
Local operations:
|
|
100
|
+
- health checks run: {count}
|
|
101
|
+
- repairs applied: {count}
|
|
102
|
+
Auto-invoked:
|
|
103
|
+
- none
|
|
104
|
+
Why: health uses deterministic local checks; non-deterministic repairs stay manual
|
|
105
|
+
```
|
|
106
|
+
|
|
88
107
|
## Response Contract
|
|
89
108
|
|
|
90
109
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
|
@@ -98,6 +98,8 @@ Spawn 6 parallel analysis agents:
|
|
|
98
98
|
</agent>
|
|
99
99
|
</analysis_agents>
|
|
100
100
|
|
|
101
|
+
If the host runtime cannot spawn these named analysis workers in parallel, run each selected analysis in an isolated fresh context sequentially. Report that fallback clearly. These analysis roles are command-local workers, not installed Scriveno agent prompt files.
|
|
102
|
+
|
|
101
103
|
### OUTPUT
|
|
102
104
|
|
|
103
105
|
Save all analysis files to `.manuscript/analysis/`
|
|
@@ -110,6 +112,30 @@ Present a summary to the writer showing:
|
|
|
110
112
|
|
|
111
113
|
This analysis is automatically loaded by `/scr:new-work` and `/scr:new-revision` when it exists.
|
|
112
114
|
|
|
115
|
+
## Agent and Automation Status
|
|
116
|
+
|
|
117
|
+
Every response must include a short status block that makes invocation visible:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
Agent status:
|
|
121
|
+
Trigger: /scr:map-manuscript {area}
|
|
122
|
+
Spawned agents:
|
|
123
|
+
- voice-analyst: yes/no
|
|
124
|
+
- structure-analyst: yes/no
|
|
125
|
+
- character-analyst: yes/no
|
|
126
|
+
- theme-analyst: yes/no
|
|
127
|
+
- world-analyst: yes/no
|
|
128
|
+
- pacing-analyst: yes/no
|
|
129
|
+
Local operations:
|
|
130
|
+
- manuscript files read: {count}
|
|
131
|
+
- analysis files written: {count}
|
|
132
|
+
Auto-invoked:
|
|
133
|
+
- none
|
|
134
|
+
Why: map-manuscript produces analysis artifacts that later commands load when present
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If parallel worker spawning is unavailable, say `parallel unavailable; sequential isolated analysis used` in the status block.
|
|
138
|
+
|
|
113
139
|
## Response Contract
|
|
114
140
|
|
|
115
141
|
Every writer-facing response must end with one to four next-command suggestions. Each suggestion must include a short explanation of what that path will do.
|
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.0.
|
|
72
|
+
"scriveno_version": "2.0.7",
|
|
73
73
|
"work_type": "<chosen>",
|
|
74
74
|
"group": "<group>",
|
|
75
75
|
"command_unit": "<unit>",
|
package/commands/scr/next.md
CHANGED
|
@@ -6,6 +6,8 @@ description: Auto-detect what to do next in your workflow and run it. The one co
|
|
|
6
6
|
|
|
7
7
|
You are routing the writer to the right next step in their workflow. This command is the universal interface -- a writer who only ever types `/scr:next` should be able to complete an entire novel.
|
|
8
8
|
|
|
9
|
+
Follow the auto-invoke policy. In the source repository it is documented at `docs/auto-invoke-policy.md`. `/scr:next` is Level 1 only by default: it may inspect disk state and suggest the safest next command, but it does not spawn agents or mutate files unless autopilot mode explicitly routes into another command.
|
|
10
|
+
|
|
9
11
|
## What to do
|
|
10
12
|
|
|
11
13
|
1. **Check for `.manuscript/` directory.** If none, the writer has no project. Run `/scr:new-work` to start one (or tell them to).
|
|
@@ -32,6 +34,25 @@ You are routing the writer to the right next step in their workflow. This comman
|
|
|
32
34
|
- "Chapter 4 has a plan but no draft yet -- drafting it."
|
|
33
35
|
- "You haven't discussed the next chapter -- shaping Chapter 5."
|
|
34
36
|
|
|
37
|
+
8. **Run the proactive sweep before choosing the final route.** This is read-only unless autopilot mode has already taken over:
|
|
38
|
+
- Check whether `CONTEXT.md` is missing, stale, or older than STATE.md or the newest draft.
|
|
39
|
+
- Check whether `HISTORY.log` is missing or the last command failed.
|
|
40
|
+
- Check whether voice, continuity, editor-review, beta-reader, or translation reports contain unresolved items.
|
|
41
|
+
- Check whether translation folders, target language config, editor notes, track proposals, stale exports, or unsaved manuscript changes imply a better next command than the linear lifecycle.
|
|
42
|
+
- Check whether STATE.md and disk disagree enough that `/scr:scan` should be recommended first.
|
|
43
|
+
|
|
44
|
+
Display a compact proactive block when any signal changes the recommendation:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
Proactive checks:
|
|
48
|
+
State: <fresh | stale, suggest /scr:scan>
|
|
49
|
+
Session: <fresh | context stale, suggest /scr:resume-work>
|
|
50
|
+
Reviews: <none | N pending, suggest review command>
|
|
51
|
+
Translation: <none | follow-up available>
|
|
52
|
+
Export: <fresh | stale, suggest /scr:export>
|
|
53
|
+
Save: <clean | unsaved manuscript changes, suggest /scr:save>
|
|
54
|
+
```
|
|
55
|
+
|
|
35
56
|
## Routing logic
|
|
36
57
|
|
|
37
58
|
Use the core writing lifecycle as the default map:
|
|
@@ -93,6 +114,25 @@ Use progressive surfacing rules:
|
|
|
93
114
|
- **Non-blocking craft question or watchpoint** -- If only `QUESTION: Non-blocking`, `HUNCH`, or `WATCHPOINT` items remain, allow the next draft or review step and mention the watchpoint in one sentence.
|
|
94
115
|
- **Autopilot mode** -- If config has `autopilot.enabled: true`, run multiple steps in sequence without asking, pausing only per the profile's rules (guided, supervised, full-auto).
|
|
95
116
|
|
|
117
|
+
## Agent and Automation Status
|
|
118
|
+
|
|
119
|
+
Every `/scr:next` response must include a short status block when it inspected proactive signals or handed off to another command:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
Automation status:
|
|
123
|
+
Trigger: /scr:next
|
|
124
|
+
Spawned agents:
|
|
125
|
+
- none
|
|
126
|
+
Local operations:
|
|
127
|
+
- proactive sweep: read-only
|
|
128
|
+
- state route computed: yes/no
|
|
129
|
+
Auto-invoked:
|
|
130
|
+
- <recommended command>: yes/no
|
|
131
|
+
Why: /scr:next routes from disk state; it only runs follow-up commands under autopilot or explicit writer intent
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If autopilot causes `/scr:next` to run another command, the follow-up command must provide its own agent or automation status block.
|
|
135
|
+
|
|
96
136
|
## Adaptive naming
|
|
97
137
|
|
|
98
138
|
Use canonical runnable commands, and adapt the terminology in prompts/output for the current work type. If `command_unit` is `surah`, run `/scr:draft` and frame the work as drafting a surah; keep the command id stable and treat unit labels as presentation only.
|