coder-config 0.43.16 → 0.43.18

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/lib/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Constants and tool path configurations
3
3
  */
4
4
 
5
- const VERSION = '0.43.16';
5
+ const VERSION = '0.43.18';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
@@ -1124,37 +1124,42 @@ function workstreamInstallCdHook() {
1124
1124
  ? path.join(process.env.HOME || '', '.zshrc')
1125
1125
  : path.join(process.env.HOME || '', '.bashrc');
1126
1126
 
1127
- const hookMarker = '# coder-config workstream cd hook';
1127
+ const hookMarker = '# coder-config workstream hooks';
1128
+ const oldHookMarker = '# coder-config workstream cd hook';
1129
+ const endMarker = '# end coder-config workstream hooks';
1130
+ const oldEndMarker = '# end coder-config workstream cd hook';
1131
+
1128
1132
  const hookCode = `
1129
1133
  ${hookMarker}
1130
- coder_workstream_cd() {
1131
- # Run cd directly (not in subshell) - if it fails, it prints its own error
1132
- builtin cd "$@" || return $?
1133
-
1134
- # Check for matching workstreams
1135
- local result
1136
- result=$(coder-config workstream check-folder "$PWD" --json 2>/dev/null)
1134
+ # Wrap coder-config to handle 'workstream use' specially (sets env in current shell)
1135
+ coder-config() {
1136
+ if [ "$1" = "workstream" ] && [ "$2" = "use" ] && [ -n "$3" ]; then
1137
+ # workstream use <name> - activate in current shell
1138
+ shift 2 # remove 'workstream use'
1139
+ eval "$(command coder-config workstream use "$@" --eval)"
1140
+ else
1141
+ # All other commands - pass through
1142
+ command coder-config "$@"
1143
+ fi
1144
+ }
1137
1145
 
1146
+ # Auto-activate workstream on cd
1147
+ _coder_workstream_cd() {
1148
+ builtin cd "$@" || return $?
1149
+ local result count current
1150
+ result=$(command coder-config workstream check-folder "$PWD" --json 2>/dev/null)
1138
1151
  [ -z "$result" ] && return 0
1139
-
1140
- local count current
1141
1152
  count=$(echo "$result" | grep -o '"count":[0-9]*' | cut -d: -f2)
1142
1153
  current=$(echo "$result" | grep -o '"current":true' || echo "")
1143
-
1144
- # Already on matching workstream
1145
1154
  [ -n "$current" ] && return 0
1146
-
1147
1155
  [ "$count" = "0" ] && return 0
1148
-
1149
1156
  if [ "$count" = "1" ]; then
1150
- # Single match - auto-activate
1151
1157
  local name id
1152
1158
  name=$(echo "$result" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
1153
1159
  id=$(echo "$result" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
1154
1160
  export CODER_WORKSTREAM="$id"
1155
1161
  echo "📂 Workstream: $name"
1156
1162
  elif [ "$count" -gt 1 ]; then
1157
- # Multiple matches - prompt
1158
1163
  echo "Multiple workstreams match this folder:"
1159
1164
  local i=1
1160
1165
  echo "$result" | grep -o '"name":"[^"]*"' | cut -d'"' -f4 | while read -r name; do
@@ -1167,67 +1172,45 @@ coder_workstream_cd() {
1167
1172
  local id name
1168
1173
  id=$(echo "$result" | grep -o '"id":"[^"]*"' | sed -n "\${choice}p" | cut -d'"' -f4)
1169
1174
  name=$(echo "$result" | grep -o '"name":"[^"]*"' | sed -n "\${choice}p" | cut -d'"' -f4)
1170
- if [ -n "$id" ]; then
1171
- export CODER_WORKSTREAM="$id"
1172
- echo "📂 Workstream: $name"
1173
- fi
1175
+ [ -n "$id" ] && export CODER_WORKSTREAM="$id" && echo "📂 Workstream: $name"
1174
1176
  fi
1175
1177
  fi
1176
1178
  }
1177
- alias cd='coder_workstream_cd'
1178
-
1179
- # cws - workstream use shortcut (activates workstream in current shell)
1180
- cws() {
1181
- if [ -z "$1" ]; then
1182
- coder-config workstream use
1183
- else
1184
- eval "$(coder-config workstream use "$@" --eval)"
1185
- fi
1186
- }
1187
- # end coder-config workstream cd hook
1179
+ alias cd='_coder_workstream_cd'
1180
+ ${endMarker}
1188
1181
  `;
1189
1182
 
1190
- // Check if hook already installed
1183
+ let content = '';
1191
1184
  if (fs.existsSync(rcFile)) {
1192
- const content = fs.readFileSync(rcFile, 'utf8');
1193
- if (content.includes(hookMarker)) {
1194
- // Check if cws function is already there (might be old install without it)
1195
- if (!content.includes('cws()')) {
1196
- // Add just the cws function
1197
- const cwsFunc = `
1198
- # cws - workstream use shortcut (activates workstream in current shell)
1199
- cws() {
1200
- if [ -z "$1" ]; then
1201
- coder-config workstream use
1202
- else
1203
- eval "$(coder-config workstream use "$@" --eval)"
1204
- fi
1205
- }
1206
- `;
1207
- // Insert before the end marker
1208
- const endMarker = '# end coder-config workstream cd hook';
1209
- const newContent = content.replace(endMarker, cwsFunc + endMarker);
1210
- fs.writeFileSync(rcFile, newContent);
1211
- console.log('✓ Added cws function to existing hook');
1212
- console.log(` Location: ${rcFile}`);
1213
- console.log('');
1214
- console.log('Restart your shell or run:');
1215
- console.log(` source ${rcFile}`);
1216
- return true;
1185
+ content = fs.readFileSync(rcFile, 'utf8');
1186
+ }
1187
+
1188
+ // Remove old hook block if present (either old or new marker)
1189
+ if (content.includes(oldHookMarker) || content.includes(hookMarker)) {
1190
+ const startMarker = content.includes(hookMarker) ? hookMarker : oldHookMarker;
1191
+ const endMark = content.includes(endMarker) ? endMarker : oldEndMarker;
1192
+ const startIdx = content.indexOf(startMarker);
1193
+ const endIdx = content.indexOf(endMark);
1194
+ if (startIdx !== -1 && endIdx !== -1) {
1195
+ // Remove the block including any leading newline
1196
+ let removeStart = startIdx;
1197
+ if (startIdx > 0 && content[startIdx - 1] === '\n') {
1198
+ removeStart = startIdx - 1;
1217
1199
  }
1218
- console.log('✓ Workstream cd hook already installed');
1219
- console.log(` Location: ${rcFile}`);
1220
- return true;
1200
+ content = content.slice(0, removeStart) + content.slice(endIdx + endMark.length);
1221
1201
  }
1222
1202
  }
1223
1203
 
1224
- // Append hook to rc file
1225
- fs.appendFileSync(rcFile, hookCode);
1226
- console.log(`✓ Installed workstream cd hook`);
1204
+ // Append new hook
1205
+ fs.writeFileSync(rcFile, content + hookCode);
1206
+ console.log(`✓ Installed workstream hooks`);
1227
1207
  console.log(` Location: ${rcFile}`);
1228
1208
  console.log('');
1229
1209
  console.log('Restart your shell or run:');
1230
1210
  console.log(` source ${rcFile}`);
1211
+ console.log('');
1212
+ console.log('Now you can use:');
1213
+ console.log(' coder-config workstream use <name> # activates in current shell');
1231
1214
 
1232
1215
  return true;
1233
1216
  }
@@ -1247,34 +1230,38 @@ function workstreamUninstallCdHook() {
1247
1230
  return false;
1248
1231
  }
1249
1232
 
1250
- const content = fs.readFileSync(rcFile, 'utf8');
1251
- const hookMarker = '# coder-config workstream cd hook';
1252
- const endMarker = '# end coder-config workstream cd hook';
1253
-
1254
- if (!content.includes(hookMarker)) {
1255
- console.log('Workstream cd hook not installed');
1256
- return false;
1233
+ let content = fs.readFileSync(rcFile, 'utf8');
1234
+
1235
+ // Support both old and new marker names
1236
+ const markers = [
1237
+ { start: '# coder-config workstream hooks', end: '# end coder-config workstream hooks' },
1238
+ { start: '# coder-config workstream cd hook', end: '# end coder-config workstream cd hook' },
1239
+ ];
1240
+
1241
+ let found = false;
1242
+ for (const { start, end } of markers) {
1243
+ if (content.includes(start)) {
1244
+ const startIdx = content.indexOf(start);
1245
+ const endIdx = content.indexOf(end);
1246
+ if (startIdx !== -1 && endIdx !== -1) {
1247
+ let removeStart = startIdx;
1248
+ if (startIdx > 0 && content[startIdx - 1] === '\n') {
1249
+ removeStart = startIdx - 1;
1250
+ }
1251
+ content = content.slice(0, removeStart) + content.slice(endIdx + end.length);
1252
+ found = true;
1253
+ }
1254
+ }
1257
1255
  }
1258
1256
 
1259
- // Remove the hook block
1260
- const startIdx = content.indexOf(hookMarker);
1261
- const endIdx = content.indexOf(endMarker);
1262
-
1263
- if (startIdx === -1 || endIdx === -1) {
1264
- console.error('Could not find hook boundaries');
1257
+ if (!found) {
1258
+ console.log('Workstream hooks not installed');
1265
1259
  return false;
1266
1260
  }
1267
1261
 
1268
- // Find the newline before the marker (to remove leading blank line)
1269
- let removeStart = startIdx;
1270
- if (startIdx > 0 && content[startIdx - 1] === '\n') {
1271
- removeStart = startIdx - 1;
1272
- }
1273
-
1274
- const newContent = content.slice(0, removeStart) + content.slice(endIdx + endMarker.length);
1275
- fs.writeFileSync(rcFile, newContent);
1262
+ fs.writeFileSync(rcFile, content);
1276
1263
 
1277
- console.log(`✓ Uninstalled workstream cd hook from ${rcFile}`);
1264
+ console.log(`✓ Uninstalled workstream hooks from ${rcFile}`);
1278
1265
  console.log('');
1279
1266
  console.log('Restart your shell or run:');
1280
1267
  console.log(` source ${rcFile}`);
@@ -1297,7 +1284,9 @@ function workstreamCdHookStatus() {
1297
1284
  }
1298
1285
 
1299
1286
  const content = fs.readFileSync(rcFile, 'utf8');
1300
- const installed = content.includes('# coder-config workstream cd hook');
1287
+ // Check for both old and new markers
1288
+ const installed = content.includes('# coder-config workstream hooks') ||
1289
+ content.includes('# coder-config workstream cd hook');
1301
1290
 
1302
1291
  return { installed, shell: isZsh ? 'zsh' : 'bash', rcFile };
1303
1292
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.43.16",
3
+ "version": "0.43.18",
4
4
  "description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
5
5
  "author": "regression.io",
6
6
  "main": "config-loader.js",