declare-cc 0.3.2 → 0.3.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/bin/install.js +85 -59
- package/commands/declare/future.md +3 -3
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -475,7 +475,7 @@ function convertClaudeToOpencodeFrontmatter(content) {
|
|
|
475
475
|
convertedContent = convertedContent.replace(/\bSlashCommand\b/g, 'skill');
|
|
476
476
|
convertedContent = convertedContent.replace(/\bTodoWrite\b/g, 'todowrite');
|
|
477
477
|
// Replace /gsd:command with /gsd-command for opencode (flat command structure)
|
|
478
|
-
convertedContent = convertedContent.replace(/\/
|
|
478
|
+
convertedContent = convertedContent.replace(/\/declare:/g, '/declare-');
|
|
479
479
|
// Replace ~/.claude with ~/.config/opencode (OpenCode's correct config location)
|
|
480
480
|
convertedContent = convertedContent.replace(/~\/\.claude\b/g, '~/.config/opencode');
|
|
481
481
|
// Replace general-purpose subagent type with OpenCode's equivalent "general"
|
|
@@ -662,10 +662,12 @@ function copyFlattenedCommands(srcDir, destDir, prefix, pathPrefix, runtime) {
|
|
|
662
662
|
const localClaudeRegex = /\.\/\.claude\//g;
|
|
663
663
|
const opencodeDirRegex = /~\/\.opencode\//g;
|
|
664
664
|
const distToolsRegex = /dist\/declare-tools\.cjs/g;
|
|
665
|
+
const workflowsRegex = /@workflows\//g;
|
|
665
666
|
content = content.replace(globalClaudeRegex, pathPrefix);
|
|
666
667
|
content = content.replace(localClaudeRegex, `./${getDirName(runtime)}/`);
|
|
667
668
|
content = content.replace(opencodeDirRegex, pathPrefix);
|
|
668
669
|
content = content.replace(distToolsRegex, `${pathPrefix}declare-tools.cjs`);
|
|
670
|
+
content = content.replace(workflowsRegex, `@${pathPrefix}workflows/`);
|
|
669
671
|
content = processAttribution(content, getCommitAttribution(runtime));
|
|
670
672
|
content = convertClaudeToOpencodeFrontmatter(content);
|
|
671
673
|
|
|
@@ -706,9 +708,11 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix, runtime) {
|
|
|
706
708
|
const globalClaudeRegex = /~\/\.claude\//g;
|
|
707
709
|
const localClaudeRegex = /\.\/\.claude\//g;
|
|
708
710
|
const distToolsRegex = /dist\/declare-tools\.cjs/g;
|
|
711
|
+
const workflowsRegex = /@workflows\//g;
|
|
709
712
|
content = content.replace(globalClaudeRegex, pathPrefix);
|
|
710
713
|
content = content.replace(localClaudeRegex, `./${dirName}/`);
|
|
711
714
|
content = content.replace(distToolsRegex, `${pathPrefix}declare-tools.cjs`);
|
|
715
|
+
content = content.replace(workflowsRegex, `@${pathPrefix}workflows/`);
|
|
712
716
|
content = processAttribution(content, getCommitAttribution(runtime));
|
|
713
717
|
|
|
714
718
|
// Convert frontmatter for opencode compatibility
|
|
@@ -737,7 +741,7 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix, runtime) {
|
|
|
737
741
|
function cleanupOrphanedFiles(configDir) {
|
|
738
742
|
const orphanedFiles = [
|
|
739
743
|
'hooks/gsd-notify.sh', // Removed in v1.6.x
|
|
740
|
-
'hooks/statusline.js', // Renamed to
|
|
744
|
+
'hooks/statusline.js', // Renamed to declare-statusline.js in v1.9.0
|
|
741
745
|
];
|
|
742
746
|
|
|
743
747
|
for (const relPath of orphanedFiles) {
|
|
@@ -755,7 +759,7 @@ function cleanupOrphanedFiles(configDir) {
|
|
|
755
759
|
function cleanupOrphanedHooks(settings) {
|
|
756
760
|
const orphanedHookPatterns = [
|
|
757
761
|
'gsd-notify.sh', // Removed in v1.6.x
|
|
758
|
-
'hooks/statusline.js', // Renamed to
|
|
762
|
+
'hooks/statusline.js', // Renamed to declare-statusline.js in v1.9.0
|
|
759
763
|
'gsd-intel-index.js', // Removed in v1.9.2
|
|
760
764
|
'gsd-intel-session.js', // Removed in v1.9.2
|
|
761
765
|
'gsd-intel-prune.js', // Removed in v1.9.2
|
|
@@ -794,13 +798,13 @@ function cleanupOrphanedHooks(settings) {
|
|
|
794
798
|
// Fix #330: Update statusLine if it points to old statusline.js path
|
|
795
799
|
if (settings.statusLine && settings.statusLine.command &&
|
|
796
800
|
settings.statusLine.command.includes('statusline.js') &&
|
|
797
|
-
!settings.statusLine.command.includes('
|
|
801
|
+
!settings.statusLine.command.includes('declare-statusline.js')) {
|
|
798
802
|
// Replace old path with new path
|
|
799
803
|
settings.statusLine.command = settings.statusLine.command.replace(
|
|
800
804
|
/statusline\.js/,
|
|
801
|
-
'
|
|
805
|
+
'declare-statusline.js'
|
|
802
806
|
);
|
|
803
|
-
console.log(` ${green}✓${reset} Updated statusline path (statusline.js →
|
|
807
|
+
console.log(` ${green}✓${reset} Updated statusline path (statusline.js → declare-statusline.js)`);
|
|
804
808
|
}
|
|
805
809
|
|
|
806
810
|
return settings;
|
|
@@ -829,7 +833,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
829
833
|
if (runtime === 'opencode') runtimeLabel = 'OpenCode';
|
|
830
834
|
if (runtime === 'gemini') runtimeLabel = 'Gemini';
|
|
831
835
|
|
|
832
|
-
console.log(` Uninstalling
|
|
836
|
+
console.log(` Uninstalling Declare from ${cyan}${runtimeLabel}${reset} at ${cyan}${locationLabel}${reset}\n`);
|
|
833
837
|
|
|
834
838
|
// Check if target directory exists
|
|
835
839
|
if (!fs.existsSync(targetDir)) {
|
|
@@ -840,59 +844,63 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
840
844
|
|
|
841
845
|
let removedCount = 0;
|
|
842
846
|
|
|
843
|
-
// 1. Remove
|
|
847
|
+
// 1. Remove Declare commands directory
|
|
844
848
|
if (isOpencode) {
|
|
845
|
-
// OpenCode: remove command/
|
|
849
|
+
// OpenCode: remove command/declare-*.md files (and old gsd-*.md)
|
|
846
850
|
const commandDir = path.join(targetDir, 'command');
|
|
847
851
|
if (fs.existsSync(commandDir)) {
|
|
848
852
|
const files = fs.readdirSync(commandDir);
|
|
849
853
|
for (const file of files) {
|
|
850
|
-
if (file.startsWith('gsd-') && file.endsWith('.md')) {
|
|
854
|
+
if ((file.startsWith('declare-') || file.startsWith('gsd-')) && file.endsWith('.md')) {
|
|
851
855
|
fs.unlinkSync(path.join(commandDir, file));
|
|
852
856
|
removedCount++;
|
|
853
857
|
}
|
|
854
858
|
}
|
|
855
|
-
console.log(` ${green}✓${reset} Removed
|
|
859
|
+
console.log(` ${green}✓${reset} Removed Declare commands from command/`);
|
|
856
860
|
}
|
|
857
861
|
} else {
|
|
858
|
-
// Claude Code & Gemini: remove commands/gsd/
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
fs.
|
|
862
|
-
|
|
863
|
-
|
|
862
|
+
// Claude Code & Gemini: remove commands/declare/ (and legacy commands/gsd/)
|
|
863
|
+
for (const dir of ['declare', 'gsd']) {
|
|
864
|
+
const cmdDir = path.join(targetDir, 'commands', dir);
|
|
865
|
+
if (fs.existsSync(cmdDir)) {
|
|
866
|
+
fs.rmSync(cmdDir, { recursive: true });
|
|
867
|
+
removedCount++;
|
|
868
|
+
console.log(` ${green}✓${reset} Removed commands/${dir}/`);
|
|
869
|
+
}
|
|
864
870
|
}
|
|
865
871
|
}
|
|
866
872
|
|
|
867
|
-
// 2. Remove get-shit-done
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
fs.
|
|
871
|
-
|
|
872
|
-
|
|
873
|
+
// 2. Remove declare/ metadata directory (and legacy get-shit-done/)
|
|
874
|
+
for (const dir of ['declare', 'get-shit-done']) {
|
|
875
|
+
const metaDir = path.join(targetDir, dir);
|
|
876
|
+
if (fs.existsSync(metaDir)) {
|
|
877
|
+
fs.rmSync(metaDir, { recursive: true });
|
|
878
|
+
removedCount++;
|
|
879
|
+
console.log(` ${green}✓${reset} Removed ${dir}/`);
|
|
880
|
+
}
|
|
873
881
|
}
|
|
874
882
|
|
|
875
|
-
// 3. Remove
|
|
883
|
+
// 3. Remove Declare agents (declare-*.md and legacy gsd-*.md files)
|
|
876
884
|
const agentsDir = path.join(targetDir, 'agents');
|
|
877
885
|
if (fs.existsSync(agentsDir)) {
|
|
878
886
|
const files = fs.readdirSync(agentsDir);
|
|
879
887
|
let agentCount = 0;
|
|
880
888
|
for (const file of files) {
|
|
881
|
-
if (file.startsWith('gsd-') && file.endsWith('.md')) {
|
|
889
|
+
if ((file.startsWith('declare-') || file.startsWith('gsd-')) && file.endsWith('.md')) {
|
|
882
890
|
fs.unlinkSync(path.join(agentsDir, file));
|
|
883
891
|
agentCount++;
|
|
884
892
|
}
|
|
885
893
|
}
|
|
886
894
|
if (agentCount > 0) {
|
|
887
895
|
removedCount++;
|
|
888
|
-
console.log(` ${green}✓${reset} Removed ${agentCount}
|
|
896
|
+
console.log(` ${green}✓${reset} Removed ${agentCount} Declare agents`);
|
|
889
897
|
}
|
|
890
898
|
}
|
|
891
899
|
|
|
892
|
-
// 4. Remove
|
|
900
|
+
// 4. Remove Declare hooks
|
|
893
901
|
const hooksDir = path.join(targetDir, 'hooks');
|
|
894
902
|
if (fs.existsSync(hooksDir)) {
|
|
895
|
-
const gsdHooks = ['
|
|
903
|
+
const gsdHooks = ['declare-statusline.js', 'declare-check-update.js', 'gsd-check-update.sh', 'gsd-statusline.js', 'gsd-check-update.js'];
|
|
896
904
|
let hookCount = 0;
|
|
897
905
|
for (const hook of gsdHooks) {
|
|
898
906
|
const hookPath = path.join(hooksDir, hook);
|
|
@@ -929,30 +937,35 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
929
937
|
let settings = readSettings(settingsPath);
|
|
930
938
|
let settingsModified = false;
|
|
931
939
|
|
|
932
|
-
// Remove GSD statusline if it references our
|
|
940
|
+
// Remove Declare/GSD statusline if it references our hooks
|
|
933
941
|
if (settings.statusLine && settings.statusLine.command &&
|
|
934
|
-
settings.statusLine.command.includes('
|
|
942
|
+
(settings.statusLine.command.includes('declare-statusline') ||
|
|
943
|
+
settings.statusLine.command.includes('gsd-statusline'))) {
|
|
935
944
|
delete settings.statusLine;
|
|
936
945
|
settingsModified = true;
|
|
937
|
-
console.log(` ${green}✓${reset} Removed
|
|
946
|
+
console.log(` ${green}✓${reset} Removed Declare statusline from settings`);
|
|
938
947
|
}
|
|
939
948
|
|
|
940
|
-
// Remove GSD hooks from SessionStart
|
|
949
|
+
// Remove Declare/GSD hooks from SessionStart
|
|
941
950
|
if (settings.hooks && settings.hooks.SessionStart) {
|
|
942
951
|
const before = settings.hooks.SessionStart.length;
|
|
943
952
|
settings.hooks.SessionStart = settings.hooks.SessionStart.filter(entry => {
|
|
944
953
|
if (entry.hooks && Array.isArray(entry.hooks)) {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
954
|
+
const hasDeclareHook = entry.hooks.some(h =>
|
|
955
|
+
h.command && (
|
|
956
|
+
h.command.includes('declare-check-update') ||
|
|
957
|
+
h.command.includes('declare-statusline') ||
|
|
958
|
+
h.command.includes('gsd-check-update') ||
|
|
959
|
+
h.command.includes('gsd-statusline')
|
|
960
|
+
)
|
|
948
961
|
);
|
|
949
|
-
return !
|
|
962
|
+
return !hasDeclareHook;
|
|
950
963
|
}
|
|
951
964
|
return true;
|
|
952
965
|
});
|
|
953
966
|
if (settings.hooks.SessionStart.length < before) {
|
|
954
967
|
settingsModified = true;
|
|
955
|
-
console.log(` ${green}✓${reset} Removed
|
|
968
|
+
console.log(` ${green}✓${reset} Removed Declare hooks from settings`);
|
|
956
969
|
}
|
|
957
970
|
// Clean up empty array
|
|
958
971
|
if (settings.hooks.SessionStart.length === 0) {
|
|
@@ -989,7 +1002,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
989
1002
|
if (config.permission[permType]) {
|
|
990
1003
|
const keys = Object.keys(config.permission[permType]);
|
|
991
1004
|
for (const key of keys) {
|
|
992
|
-
if (key.includes('get-shit-done')) {
|
|
1005
|
+
if (key.includes('get-shit-done') || key.includes('/declare/')) {
|
|
993
1006
|
delete config.permission[permType][key];
|
|
994
1007
|
modified = true;
|
|
995
1008
|
}
|
|
@@ -1017,11 +1030,11 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1017
1030
|
}
|
|
1018
1031
|
|
|
1019
1032
|
if (removedCount === 0) {
|
|
1020
|
-
console.log(` ${yellow}⚠${reset} No
|
|
1033
|
+
console.log(` ${yellow}⚠${reset} No Declare files found to remove.`);
|
|
1021
1034
|
}
|
|
1022
1035
|
|
|
1023
1036
|
console.log(`
|
|
1024
|
-
${green}Done!${reset}
|
|
1037
|
+
${green}Done!${reset} Declare has been uninstalled from ${runtimeLabel}.
|
|
1025
1038
|
Your other files and settings have been preserved.
|
|
1026
1039
|
`);
|
|
1027
1040
|
}
|
|
@@ -1123,12 +1136,12 @@ function configureOpencodePermissions(isGlobal = true) {
|
|
|
1123
1136
|
config.permission = {};
|
|
1124
1137
|
}
|
|
1125
1138
|
|
|
1126
|
-
// Build the
|
|
1139
|
+
// Build the Declare path using the actual config directory
|
|
1127
1140
|
// Use ~ shorthand if it's in the default location, otherwise use full path
|
|
1128
1141
|
const defaultConfigDir = path.join(os.homedir(), '.config', 'opencode');
|
|
1129
1142
|
const gsdPath = opencodeConfigDir === defaultConfigDir
|
|
1130
|
-
? '~/.config/opencode/
|
|
1131
|
-
: `${opencodeConfigDir.replace(/\\/g, '/')}/
|
|
1143
|
+
? '~/.config/opencode/declare/*'
|
|
1144
|
+
: `${opencodeConfigDir.replace(/\\/g, '/')}/declare/*`;
|
|
1132
1145
|
|
|
1133
1146
|
let modified = false;
|
|
1134
1147
|
|
|
@@ -1156,7 +1169,7 @@ function configureOpencodePermissions(isGlobal = true) {
|
|
|
1156
1169
|
|
|
1157
1170
|
// Write config back
|
|
1158
1171
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
1159
|
-
console.log(` ${green}✓${reset} Configured read permission for
|
|
1172
|
+
console.log(` ${green}✓${reset} Configured read permission for Declare docs`);
|
|
1160
1173
|
}
|
|
1161
1174
|
|
|
1162
1175
|
/**
|
|
@@ -1201,8 +1214,8 @@ function verifyFileInstalled(filePath, description) {
|
|
|
1201
1214
|
// Local Patch Persistence
|
|
1202
1215
|
// ──────────────────────────────────────────────────────
|
|
1203
1216
|
|
|
1204
|
-
const PATCHES_DIR_NAME = '
|
|
1205
|
-
const MANIFEST_NAME = '
|
|
1217
|
+
const PATCHES_DIR_NAME = 'declare-local-patches';
|
|
1218
|
+
const MANIFEST_NAME = 'declare-file-manifest.json';
|
|
1206
1219
|
|
|
1207
1220
|
/**
|
|
1208
1221
|
* Compute SHA256 hash of file contents
|
|
@@ -1236,19 +1249,19 @@ function generateManifest(dir, baseDir) {
|
|
|
1236
1249
|
* Write file manifest after installation for future modification detection
|
|
1237
1250
|
*/
|
|
1238
1251
|
function writeManifest(configDir) {
|
|
1239
|
-
const
|
|
1240
|
-
const commandsDir = path.join(configDir, 'commands', '
|
|
1252
|
+
const declareDir = path.join(configDir, 'declare');
|
|
1253
|
+
const commandsDir = path.join(configDir, 'commands', 'declare');
|
|
1241
1254
|
const agentsDir = path.join(configDir, 'agents');
|
|
1242
1255
|
const manifest = { version: pkg.version, timestamp: new Date().toISOString(), files: {} };
|
|
1243
1256
|
|
|
1244
|
-
const
|
|
1245
|
-
for (const [rel, hash] of Object.entries(
|
|
1246
|
-
manifest.files['
|
|
1257
|
+
const declareHashes = generateManifest(declareDir);
|
|
1258
|
+
for (const [rel, hash] of Object.entries(declareHashes)) {
|
|
1259
|
+
manifest.files['declare/' + rel] = hash;
|
|
1247
1260
|
}
|
|
1248
1261
|
if (fs.existsSync(commandsDir)) {
|
|
1249
1262
|
const cmdHashes = generateManifest(commandsDir);
|
|
1250
1263
|
for (const [rel, hash] of Object.entries(cmdHashes)) {
|
|
1251
|
-
manifest.files['commands/
|
|
1264
|
+
manifest.files['commands/declare/' + rel] = hash;
|
|
1252
1265
|
}
|
|
1253
1266
|
}
|
|
1254
1267
|
if (fs.existsSync(agentsDir)) {
|
|
@@ -1323,7 +1336,7 @@ function reportLocalPatches(configDir) {
|
|
|
1323
1336
|
}
|
|
1324
1337
|
console.log('');
|
|
1325
1338
|
console.log(' Your modifications are saved in ' + cyan + PATCHES_DIR_NAME + '/' + reset);
|
|
1326
|
-
console.log(' Run ' + cyan + '/
|
|
1339
|
+
console.log(' Run ' + cyan + '/declare:reapply-patches' + reset + ' to merge them into the new version.');
|
|
1327
1340
|
console.log(' Or manually compare and merge the files.');
|
|
1328
1341
|
console.log('');
|
|
1329
1342
|
}
|
|
@@ -1439,6 +1452,19 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1439
1452
|
}
|
|
1440
1453
|
}
|
|
1441
1454
|
|
|
1455
|
+
// Copy workflows/ so @workflows/ references in commands resolve correctly
|
|
1456
|
+
const workflowsSrc = path.join(src, 'workflows');
|
|
1457
|
+
if (fs.existsSync(workflowsSrc)) {
|
|
1458
|
+
const workflowsDest = path.join(targetDir, 'workflows');
|
|
1459
|
+
fs.mkdirSync(workflowsDest, { recursive: true });
|
|
1460
|
+
for (const entry of fs.readdirSync(workflowsSrc, { withFileTypes: true })) {
|
|
1461
|
+
if (entry.isFile()) {
|
|
1462
|
+
fs.copyFileSync(path.join(workflowsSrc, entry.name), path.join(workflowsDest, entry.name));
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
console.log(` ${green}✓${reset} Installed workflows/`);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1442
1468
|
// Copy declare-tools.cjs bundle so commands can run `node {pathPrefix}declare-tools.cjs`
|
|
1443
1469
|
const bundleSrc = path.join(src, 'dist', 'declare-tools.cjs');
|
|
1444
1470
|
const bundleDest = path.join(targetDir, 'declare-tools.cjs');
|
|
@@ -1520,11 +1546,11 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1520
1546
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
1521
1547
|
const settings = cleanupOrphanedHooks(readSettings(settingsPath));
|
|
1522
1548
|
const statuslineCommand = isGlobal
|
|
1523
|
-
? buildHookCommand(targetDir, '
|
|
1524
|
-
: 'node ' + dirName + '/hooks/
|
|
1549
|
+
? buildHookCommand(targetDir, 'declare-statusline.js')
|
|
1550
|
+
: 'node ' + dirName + '/hooks/declare-statusline.js';
|
|
1525
1551
|
const updateCheckCommand = isGlobal
|
|
1526
|
-
? buildHookCommand(targetDir, '
|
|
1527
|
-
: 'node ' + dirName + '/hooks/
|
|
1552
|
+
? buildHookCommand(targetDir, 'declare-check-update.js')
|
|
1553
|
+
: 'node ' + dirName + '/hooks/declare-check-update.js';
|
|
1528
1554
|
|
|
1529
1555
|
// Enable experimental agents for Gemini CLI (required for custom sub-agents)
|
|
1530
1556
|
if (isGemini) {
|
|
@@ -1642,13 +1668,13 @@ function handleStatusline(settings, isInteractive, callback) {
|
|
|
1642
1668
|
Your current statusline:
|
|
1643
1669
|
${dim}command: ${existingCmd}${reset}
|
|
1644
1670
|
|
|
1645
|
-
|
|
1671
|
+
Declare includes a statusline showing:
|
|
1646
1672
|
• Model name
|
|
1647
1673
|
• Current task (from todo list)
|
|
1648
1674
|
• Context window usage (color-coded)
|
|
1649
1675
|
|
|
1650
1676
|
${cyan}1${reset}) Keep existing
|
|
1651
|
-
${cyan}2${reset}) Replace with
|
|
1677
|
+
${cyan}2${reset}) Replace with Declare statusline
|
|
1652
1678
|
`);
|
|
1653
1679
|
|
|
1654
1680
|
rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
|
|
@@ -14,7 +14,7 @@ Guide the user through declaring their project's future as present-tense truth s
|
|
|
14
14
|
**Step 1: Load current graph state.**
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
node
|
|
17
|
+
node dist/declare-tools.cjs load-graph
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Parse the JSON output. If the output contains an `error` field (e.g., "No Declare project found"), tell the user to run `/declare:init` first and stop.
|
|
@@ -30,7 +30,7 @@ Note the existing declarations from the graph (if any) -- the workflow needs thi
|
|
|
30
30
|
|
|
31
31
|
Read and follow the full workflow instructions:
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
@workflows/future.md
|
|
34
34
|
|
|
35
35
|
Pass the loaded graph state into the workflow so it knows about existing declarations.
|
|
36
36
|
|
|
@@ -39,7 +39,7 @@ Pass the loaded graph state into the workflow so it knows about existing declara
|
|
|
39
39
|
After each declaration passes language detection and NSR validation and the user confirms it, persist it:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
node
|
|
42
|
+
node dist/declare-tools.cjs add-declaration --title "Short Title" --statement "Full present-tense declaration statement"
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
Parse the JSON output to confirm the declaration was created and note its assigned ID (e.g., D-01).
|
package/package.json
CHANGED