declare-cc 0.3.2 → 0.3.4
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 +68 -59
- 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"
|
|
@@ -737,7 +737,7 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix, runtime) {
|
|
|
737
737
|
function cleanupOrphanedFiles(configDir) {
|
|
738
738
|
const orphanedFiles = [
|
|
739
739
|
'hooks/gsd-notify.sh', // Removed in v1.6.x
|
|
740
|
-
'hooks/statusline.js', // Renamed to
|
|
740
|
+
'hooks/statusline.js', // Renamed to declare-statusline.js in v1.9.0
|
|
741
741
|
];
|
|
742
742
|
|
|
743
743
|
for (const relPath of orphanedFiles) {
|
|
@@ -755,7 +755,7 @@ function cleanupOrphanedFiles(configDir) {
|
|
|
755
755
|
function cleanupOrphanedHooks(settings) {
|
|
756
756
|
const orphanedHookPatterns = [
|
|
757
757
|
'gsd-notify.sh', // Removed in v1.6.x
|
|
758
|
-
'hooks/statusline.js', // Renamed to
|
|
758
|
+
'hooks/statusline.js', // Renamed to declare-statusline.js in v1.9.0
|
|
759
759
|
'gsd-intel-index.js', // Removed in v1.9.2
|
|
760
760
|
'gsd-intel-session.js', // Removed in v1.9.2
|
|
761
761
|
'gsd-intel-prune.js', // Removed in v1.9.2
|
|
@@ -794,13 +794,13 @@ function cleanupOrphanedHooks(settings) {
|
|
|
794
794
|
// Fix #330: Update statusLine if it points to old statusline.js path
|
|
795
795
|
if (settings.statusLine && settings.statusLine.command &&
|
|
796
796
|
settings.statusLine.command.includes('statusline.js') &&
|
|
797
|
-
!settings.statusLine.command.includes('
|
|
797
|
+
!settings.statusLine.command.includes('declare-statusline.js')) {
|
|
798
798
|
// Replace old path with new path
|
|
799
799
|
settings.statusLine.command = settings.statusLine.command.replace(
|
|
800
800
|
/statusline\.js/,
|
|
801
|
-
'
|
|
801
|
+
'declare-statusline.js'
|
|
802
802
|
);
|
|
803
|
-
console.log(` ${green}✓${reset} Updated statusline path (statusline.js →
|
|
803
|
+
console.log(` ${green}✓${reset} Updated statusline path (statusline.js → declare-statusline.js)`);
|
|
804
804
|
}
|
|
805
805
|
|
|
806
806
|
return settings;
|
|
@@ -829,7 +829,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
829
829
|
if (runtime === 'opencode') runtimeLabel = 'OpenCode';
|
|
830
830
|
if (runtime === 'gemini') runtimeLabel = 'Gemini';
|
|
831
831
|
|
|
832
|
-
console.log(` Uninstalling
|
|
832
|
+
console.log(` Uninstalling Declare from ${cyan}${runtimeLabel}${reset} at ${cyan}${locationLabel}${reset}\n`);
|
|
833
833
|
|
|
834
834
|
// Check if target directory exists
|
|
835
835
|
if (!fs.existsSync(targetDir)) {
|
|
@@ -840,59 +840,63 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
840
840
|
|
|
841
841
|
let removedCount = 0;
|
|
842
842
|
|
|
843
|
-
// 1. Remove
|
|
843
|
+
// 1. Remove Declare commands directory
|
|
844
844
|
if (isOpencode) {
|
|
845
|
-
// OpenCode: remove command/
|
|
845
|
+
// OpenCode: remove command/declare-*.md files (and old gsd-*.md)
|
|
846
846
|
const commandDir = path.join(targetDir, 'command');
|
|
847
847
|
if (fs.existsSync(commandDir)) {
|
|
848
848
|
const files = fs.readdirSync(commandDir);
|
|
849
849
|
for (const file of files) {
|
|
850
|
-
if (file.startsWith('gsd-') && file.endsWith('.md')) {
|
|
850
|
+
if ((file.startsWith('declare-') || file.startsWith('gsd-')) && file.endsWith('.md')) {
|
|
851
851
|
fs.unlinkSync(path.join(commandDir, file));
|
|
852
852
|
removedCount++;
|
|
853
853
|
}
|
|
854
854
|
}
|
|
855
|
-
console.log(` ${green}✓${reset} Removed
|
|
855
|
+
console.log(` ${green}✓${reset} Removed Declare commands from command/`);
|
|
856
856
|
}
|
|
857
857
|
} else {
|
|
858
|
-
// Claude Code & Gemini: remove commands/gsd/
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
fs.
|
|
862
|
-
|
|
863
|
-
|
|
858
|
+
// Claude Code & Gemini: remove commands/declare/ (and legacy commands/gsd/)
|
|
859
|
+
for (const dir of ['declare', 'gsd']) {
|
|
860
|
+
const cmdDir = path.join(targetDir, 'commands', dir);
|
|
861
|
+
if (fs.existsSync(cmdDir)) {
|
|
862
|
+
fs.rmSync(cmdDir, { recursive: true });
|
|
863
|
+
removedCount++;
|
|
864
|
+
console.log(` ${green}✓${reset} Removed commands/${dir}/`);
|
|
865
|
+
}
|
|
864
866
|
}
|
|
865
867
|
}
|
|
866
868
|
|
|
867
|
-
// 2. Remove get-shit-done
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
fs.
|
|
871
|
-
|
|
872
|
-
|
|
869
|
+
// 2. Remove declare/ metadata directory (and legacy get-shit-done/)
|
|
870
|
+
for (const dir of ['declare', 'get-shit-done']) {
|
|
871
|
+
const metaDir = path.join(targetDir, dir);
|
|
872
|
+
if (fs.existsSync(metaDir)) {
|
|
873
|
+
fs.rmSync(metaDir, { recursive: true });
|
|
874
|
+
removedCount++;
|
|
875
|
+
console.log(` ${green}✓${reset} Removed ${dir}/`);
|
|
876
|
+
}
|
|
873
877
|
}
|
|
874
878
|
|
|
875
|
-
// 3. Remove
|
|
879
|
+
// 3. Remove Declare agents (declare-*.md and legacy gsd-*.md files)
|
|
876
880
|
const agentsDir = path.join(targetDir, 'agents');
|
|
877
881
|
if (fs.existsSync(agentsDir)) {
|
|
878
882
|
const files = fs.readdirSync(agentsDir);
|
|
879
883
|
let agentCount = 0;
|
|
880
884
|
for (const file of files) {
|
|
881
|
-
if (file.startsWith('gsd-') && file.endsWith('.md')) {
|
|
885
|
+
if ((file.startsWith('declare-') || file.startsWith('gsd-')) && file.endsWith('.md')) {
|
|
882
886
|
fs.unlinkSync(path.join(agentsDir, file));
|
|
883
887
|
agentCount++;
|
|
884
888
|
}
|
|
885
889
|
}
|
|
886
890
|
if (agentCount > 0) {
|
|
887
891
|
removedCount++;
|
|
888
|
-
console.log(` ${green}✓${reset} Removed ${agentCount}
|
|
892
|
+
console.log(` ${green}✓${reset} Removed ${agentCount} Declare agents`);
|
|
889
893
|
}
|
|
890
894
|
}
|
|
891
895
|
|
|
892
|
-
// 4. Remove
|
|
896
|
+
// 4. Remove Declare hooks
|
|
893
897
|
const hooksDir = path.join(targetDir, 'hooks');
|
|
894
898
|
if (fs.existsSync(hooksDir)) {
|
|
895
|
-
const gsdHooks = ['
|
|
899
|
+
const gsdHooks = ['declare-statusline.js', 'declare-check-update.js', 'gsd-check-update.sh', 'gsd-statusline.js', 'gsd-check-update.js'];
|
|
896
900
|
let hookCount = 0;
|
|
897
901
|
for (const hook of gsdHooks) {
|
|
898
902
|
const hookPath = path.join(hooksDir, hook);
|
|
@@ -929,30 +933,35 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
929
933
|
let settings = readSettings(settingsPath);
|
|
930
934
|
let settingsModified = false;
|
|
931
935
|
|
|
932
|
-
// Remove GSD statusline if it references our
|
|
936
|
+
// Remove Declare/GSD statusline if it references our hooks
|
|
933
937
|
if (settings.statusLine && settings.statusLine.command &&
|
|
934
|
-
settings.statusLine.command.includes('
|
|
938
|
+
(settings.statusLine.command.includes('declare-statusline') ||
|
|
939
|
+
settings.statusLine.command.includes('gsd-statusline'))) {
|
|
935
940
|
delete settings.statusLine;
|
|
936
941
|
settingsModified = true;
|
|
937
|
-
console.log(` ${green}✓${reset} Removed
|
|
942
|
+
console.log(` ${green}✓${reset} Removed Declare statusline from settings`);
|
|
938
943
|
}
|
|
939
944
|
|
|
940
|
-
// Remove GSD hooks from SessionStart
|
|
945
|
+
// Remove Declare/GSD hooks from SessionStart
|
|
941
946
|
if (settings.hooks && settings.hooks.SessionStart) {
|
|
942
947
|
const before = settings.hooks.SessionStart.length;
|
|
943
948
|
settings.hooks.SessionStart = settings.hooks.SessionStart.filter(entry => {
|
|
944
949
|
if (entry.hooks && Array.isArray(entry.hooks)) {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
950
|
+
const hasDeclareHook = entry.hooks.some(h =>
|
|
951
|
+
h.command && (
|
|
952
|
+
h.command.includes('declare-check-update') ||
|
|
953
|
+
h.command.includes('declare-statusline') ||
|
|
954
|
+
h.command.includes('gsd-check-update') ||
|
|
955
|
+
h.command.includes('gsd-statusline')
|
|
956
|
+
)
|
|
948
957
|
);
|
|
949
|
-
return !
|
|
958
|
+
return !hasDeclareHook;
|
|
950
959
|
}
|
|
951
960
|
return true;
|
|
952
961
|
});
|
|
953
962
|
if (settings.hooks.SessionStart.length < before) {
|
|
954
963
|
settingsModified = true;
|
|
955
|
-
console.log(` ${green}✓${reset} Removed
|
|
964
|
+
console.log(` ${green}✓${reset} Removed Declare hooks from settings`);
|
|
956
965
|
}
|
|
957
966
|
// Clean up empty array
|
|
958
967
|
if (settings.hooks.SessionStart.length === 0) {
|
|
@@ -989,7 +998,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
989
998
|
if (config.permission[permType]) {
|
|
990
999
|
const keys = Object.keys(config.permission[permType]);
|
|
991
1000
|
for (const key of keys) {
|
|
992
|
-
if (key.includes('get-shit-done')) {
|
|
1001
|
+
if (key.includes('get-shit-done') || key.includes('/declare/')) {
|
|
993
1002
|
delete config.permission[permType][key];
|
|
994
1003
|
modified = true;
|
|
995
1004
|
}
|
|
@@ -1017,11 +1026,11 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1017
1026
|
}
|
|
1018
1027
|
|
|
1019
1028
|
if (removedCount === 0) {
|
|
1020
|
-
console.log(` ${yellow}⚠${reset} No
|
|
1029
|
+
console.log(` ${yellow}⚠${reset} No Declare files found to remove.`);
|
|
1021
1030
|
}
|
|
1022
1031
|
|
|
1023
1032
|
console.log(`
|
|
1024
|
-
${green}Done!${reset}
|
|
1033
|
+
${green}Done!${reset} Declare has been uninstalled from ${runtimeLabel}.
|
|
1025
1034
|
Your other files and settings have been preserved.
|
|
1026
1035
|
`);
|
|
1027
1036
|
}
|
|
@@ -1123,12 +1132,12 @@ function configureOpencodePermissions(isGlobal = true) {
|
|
|
1123
1132
|
config.permission = {};
|
|
1124
1133
|
}
|
|
1125
1134
|
|
|
1126
|
-
// Build the
|
|
1135
|
+
// Build the Declare path using the actual config directory
|
|
1127
1136
|
// Use ~ shorthand if it's in the default location, otherwise use full path
|
|
1128
1137
|
const defaultConfigDir = path.join(os.homedir(), '.config', 'opencode');
|
|
1129
1138
|
const gsdPath = opencodeConfigDir === defaultConfigDir
|
|
1130
|
-
? '~/.config/opencode/
|
|
1131
|
-
: `${opencodeConfigDir.replace(/\\/g, '/')}/
|
|
1139
|
+
? '~/.config/opencode/declare/*'
|
|
1140
|
+
: `${opencodeConfigDir.replace(/\\/g, '/')}/declare/*`;
|
|
1132
1141
|
|
|
1133
1142
|
let modified = false;
|
|
1134
1143
|
|
|
@@ -1156,7 +1165,7 @@ function configureOpencodePermissions(isGlobal = true) {
|
|
|
1156
1165
|
|
|
1157
1166
|
// Write config back
|
|
1158
1167
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
1159
|
-
console.log(` ${green}✓${reset} Configured read permission for
|
|
1168
|
+
console.log(` ${green}✓${reset} Configured read permission for Declare docs`);
|
|
1160
1169
|
}
|
|
1161
1170
|
|
|
1162
1171
|
/**
|
|
@@ -1201,8 +1210,8 @@ function verifyFileInstalled(filePath, description) {
|
|
|
1201
1210
|
// Local Patch Persistence
|
|
1202
1211
|
// ──────────────────────────────────────────────────────
|
|
1203
1212
|
|
|
1204
|
-
const PATCHES_DIR_NAME = '
|
|
1205
|
-
const MANIFEST_NAME = '
|
|
1213
|
+
const PATCHES_DIR_NAME = 'declare-local-patches';
|
|
1214
|
+
const MANIFEST_NAME = 'declare-file-manifest.json';
|
|
1206
1215
|
|
|
1207
1216
|
/**
|
|
1208
1217
|
* Compute SHA256 hash of file contents
|
|
@@ -1236,19 +1245,19 @@ function generateManifest(dir, baseDir) {
|
|
|
1236
1245
|
* Write file manifest after installation for future modification detection
|
|
1237
1246
|
*/
|
|
1238
1247
|
function writeManifest(configDir) {
|
|
1239
|
-
const
|
|
1240
|
-
const commandsDir = path.join(configDir, 'commands', '
|
|
1248
|
+
const declareDir = path.join(configDir, 'declare');
|
|
1249
|
+
const commandsDir = path.join(configDir, 'commands', 'declare');
|
|
1241
1250
|
const agentsDir = path.join(configDir, 'agents');
|
|
1242
1251
|
const manifest = { version: pkg.version, timestamp: new Date().toISOString(), files: {} };
|
|
1243
1252
|
|
|
1244
|
-
const
|
|
1245
|
-
for (const [rel, hash] of Object.entries(
|
|
1246
|
-
manifest.files['
|
|
1253
|
+
const declareHashes = generateManifest(declareDir);
|
|
1254
|
+
for (const [rel, hash] of Object.entries(declareHashes)) {
|
|
1255
|
+
manifest.files['declare/' + rel] = hash;
|
|
1247
1256
|
}
|
|
1248
1257
|
if (fs.existsSync(commandsDir)) {
|
|
1249
1258
|
const cmdHashes = generateManifest(commandsDir);
|
|
1250
1259
|
for (const [rel, hash] of Object.entries(cmdHashes)) {
|
|
1251
|
-
manifest.files['commands/
|
|
1260
|
+
manifest.files['commands/declare/' + rel] = hash;
|
|
1252
1261
|
}
|
|
1253
1262
|
}
|
|
1254
1263
|
if (fs.existsSync(agentsDir)) {
|
|
@@ -1323,7 +1332,7 @@ function reportLocalPatches(configDir) {
|
|
|
1323
1332
|
}
|
|
1324
1333
|
console.log('');
|
|
1325
1334
|
console.log(' Your modifications are saved in ' + cyan + PATCHES_DIR_NAME + '/' + reset);
|
|
1326
|
-
console.log(' Run ' + cyan + '/
|
|
1335
|
+
console.log(' Run ' + cyan + '/declare:reapply-patches' + reset + ' to merge them into the new version.');
|
|
1327
1336
|
console.log(' Or manually compare and merge the files.');
|
|
1328
1337
|
console.log('');
|
|
1329
1338
|
}
|
|
@@ -1520,11 +1529,11 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1520
1529
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
1521
1530
|
const settings = cleanupOrphanedHooks(readSettings(settingsPath));
|
|
1522
1531
|
const statuslineCommand = isGlobal
|
|
1523
|
-
? buildHookCommand(targetDir, '
|
|
1524
|
-
: 'node ' + dirName + '/hooks/
|
|
1532
|
+
? buildHookCommand(targetDir, 'declare-statusline.js')
|
|
1533
|
+
: 'node ' + dirName + '/hooks/declare-statusline.js';
|
|
1525
1534
|
const updateCheckCommand = isGlobal
|
|
1526
|
-
? buildHookCommand(targetDir, '
|
|
1527
|
-
: 'node ' + dirName + '/hooks/
|
|
1535
|
+
? buildHookCommand(targetDir, 'declare-check-update.js')
|
|
1536
|
+
: 'node ' + dirName + '/hooks/declare-check-update.js';
|
|
1528
1537
|
|
|
1529
1538
|
// Enable experimental agents for Gemini CLI (required for custom sub-agents)
|
|
1530
1539
|
if (isGemini) {
|
|
@@ -1642,13 +1651,13 @@ function handleStatusline(settings, isInteractive, callback) {
|
|
|
1642
1651
|
Your current statusline:
|
|
1643
1652
|
${dim}command: ${existingCmd}${reset}
|
|
1644
1653
|
|
|
1645
|
-
|
|
1654
|
+
Declare includes a statusline showing:
|
|
1646
1655
|
• Model name
|
|
1647
1656
|
• Current task (from todo list)
|
|
1648
1657
|
• Context window usage (color-coded)
|
|
1649
1658
|
|
|
1650
1659
|
${cyan}1${reset}) Keep existing
|
|
1651
|
-
${cyan}2${reset}) Replace with
|
|
1660
|
+
${cyan}2${reset}) Replace with Declare statusline
|
|
1652
1661
|
`);
|
|
1653
1662
|
|
|
1654
1663
|
rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
|
package/package.json
CHANGED