coder-config 0.45.14 → 0.46.0-beta.10
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/config-loader.js +7 -2
- package/lib/apply.js +28 -7
- package/lib/cli.js +19 -0
- package/lib/config.js +20 -5
- package/lib/constants.js +5 -3
- package/lib/mcps.js +123 -0
- package/package.json +1 -1
- package/scripts/release.sh +74 -39
- package/ui/dist/assets/index-5fdGyVCQ.css +32 -0
- package/ui/dist/assets/{index-DoeTG2Q1.js → index-DcGE7HjA.js} +129 -123
- package/ui/dist/index.html +2 -2
- package/ui/routes/configs.js +87 -0
- package/ui/routes/file-explorer.js +18 -0
- package/ui/routes/updates.js +21 -11
- package/ui/server.cjs +24 -1
- package/ui/dist/assets/index-B4hzEzCz.css +0 -32
package/config-loader.js
CHANGED
|
@@ -22,7 +22,7 @@ const { VERSION, TOOL_PATHS } = require('./lib/constants');
|
|
|
22
22
|
const { loadJson, saveJson, loadEnvFile, interpolate, resolveEnvVars, copyDirRecursive } = require('./lib/utils');
|
|
23
23
|
const { findProjectRoot, findAllConfigs, mergeConfigs, getConfigPath, collectFilesFromHierarchy, findAllConfigsForTool } = require('./lib/config');
|
|
24
24
|
const { apply, applyForAntigravity, applyForGemini, detectInstalledTools, applyForTools } = require('./lib/apply');
|
|
25
|
-
const { list, add, remove } = require('./lib/mcps');
|
|
25
|
+
const { list, add, remove, listGlobal, addGlobal, removeGlobal } = require('./lib/mcps');
|
|
26
26
|
const { registryList, registryAdd, registryRemove } = require('./lib/registry');
|
|
27
27
|
const { init, show } = require('./lib/init');
|
|
28
28
|
const { memoryList, memoryInit, memoryAdd, memorySearch } = require('./lib/memory');
|
|
@@ -138,11 +138,16 @@ class ClaudeConfigManager {
|
|
|
138
138
|
getToolPaths() { return TOOL_PATHS; }
|
|
139
139
|
applyForTools(projectDir, tools) { return applyForTools(this.registryPath, projectDir, tools); }
|
|
140
140
|
|
|
141
|
-
// MCPs
|
|
141
|
+
// MCPs (project)
|
|
142
142
|
list() { return list(this.registryPath); }
|
|
143
143
|
add(mcpNames) { return add(this.registryPath, this.installDir, mcpNames); }
|
|
144
144
|
remove(mcpNames) { return remove(this.installDir, mcpNames); }
|
|
145
145
|
|
|
146
|
+
// MCPs (global - ~/.claude.json)
|
|
147
|
+
globalList() { return listGlobal(); }
|
|
148
|
+
globalAdd(mcpNames) { return addGlobal(this.registryPath, mcpNames); }
|
|
149
|
+
globalRemove(mcpNames) { return removeGlobal(mcpNames); }
|
|
150
|
+
|
|
146
151
|
// Registry
|
|
147
152
|
registryList() { return registryList(this.registryPath); }
|
|
148
153
|
registryAdd(name, configJson) { return registryAdd(this.registryPath, name, configJson); }
|
package/lib/apply.js
CHANGED
|
@@ -29,16 +29,37 @@ function apply(registryPath, projectDir = null) {
|
|
|
29
29
|
return false;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const loadedConfigs = configLocations.map(loc =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const loadedConfigs = configLocations.map(loc => {
|
|
33
|
+
const rawConfig = loadJson(loc.configPath);
|
|
34
|
+
|
|
35
|
+
// Handle ~/.claude.json format (global MCPs under mcpServers key)
|
|
36
|
+
if (loc.isGlobalClaudeJson && rawConfig) {
|
|
37
|
+
return {
|
|
38
|
+
...loc,
|
|
39
|
+
config: {
|
|
40
|
+
include: [],
|
|
41
|
+
mcpServers: rawConfig.mcpServers || {}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
return {
|
|
47
|
+
...loc,
|
|
48
|
+
config: rawConfig
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Filter out empty configs and show hierarchy
|
|
53
|
+
const activeConfigs = loadedConfigs.filter(c => c.config);
|
|
54
|
+
if (activeConfigs.length > 1) {
|
|
38
55
|
console.log('📚 Config hierarchy (merged):');
|
|
39
|
-
for (const { dir: d, configPath } of
|
|
56
|
+
for (const { dir: d, configPath, isGlobalClaudeJson } of activeConfigs) {
|
|
40
57
|
const relPath = d === process.env.HOME ? '~' : path.relative(process.cwd(), d) || '.';
|
|
41
|
-
|
|
58
|
+
if (isGlobalClaudeJson) {
|
|
59
|
+
console.log(` • ~/.claude.json (global MCPs)`);
|
|
60
|
+
} else {
|
|
61
|
+
console.log(` • ${relPath}/.claude/mcps.json`);
|
|
62
|
+
}
|
|
42
63
|
}
|
|
43
64
|
console.log('');
|
|
44
65
|
}
|
package/lib/cli.js
CHANGED
|
@@ -63,6 +63,17 @@ function runCli(manager) {
|
|
|
63
63
|
manager.remove(args.slice(1));
|
|
64
64
|
break;
|
|
65
65
|
|
|
66
|
+
// Global MCPs (~/.claude.json)
|
|
67
|
+
case 'global':
|
|
68
|
+
if (args[1] === 'add') {
|
|
69
|
+
manager.globalAdd(args.slice(2));
|
|
70
|
+
} else if (args[1] === 'remove' || args[1] === 'rm') {
|
|
71
|
+
manager.globalRemove(args.slice(2));
|
|
72
|
+
} else {
|
|
73
|
+
manager.globalList();
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
|
|
66
77
|
// Registry management
|
|
67
78
|
case 'registry':
|
|
68
79
|
if (args[1] === 'add') {
|
|
@@ -371,6 +382,14 @@ ${chalk.dim('Configuration manager for AI coding tools (Claude Code, Gemini CLI,
|
|
|
371
382
|
]));
|
|
372
383
|
console.log();
|
|
373
384
|
|
|
385
|
+
// Global MCPs (~/.claude.json)
|
|
386
|
+
console.log(box('Global MCPs', [
|
|
387
|
+
cmd('global', 'List global MCPs (~/.claude.json)'),
|
|
388
|
+
cmd('global add <mcp> [mcp...]', 'Add MCP(s) to global config'),
|
|
389
|
+
cmd('global remove <mcp>', 'Remove MCP from global config'),
|
|
390
|
+
]));
|
|
391
|
+
console.log();
|
|
392
|
+
|
|
374
393
|
// Memory Commands
|
|
375
394
|
console.log(box('Memory', [
|
|
376
395
|
cmd('memory', 'Show memory status'),
|
package/lib/config.js
CHANGED
|
@@ -23,8 +23,11 @@ function findProjectRoot(startDir = process.cwd()) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Find ALL .claude/mcps.json configs from cwd up to root (and ~/.claude)
|
|
26
|
+
* Find ALL .claude/mcps.json configs from cwd up to root (and ~/.claude.json for global)
|
|
27
27
|
* Returns array from root to leaf (so child overrides parent when merged)
|
|
28
|
+
*
|
|
29
|
+
* Global MCPs: Read from ~/.claude.json under mcpServers key (Claude Code's native format)
|
|
30
|
+
* Project MCPs: Read from .claude/mcps.json files in hierarchy
|
|
28
31
|
*/
|
|
29
32
|
function findAllConfigs(startDir = process.cwd()) {
|
|
30
33
|
const configs = [];
|
|
@@ -32,6 +35,7 @@ function findAllConfigs(startDir = process.cwd()) {
|
|
|
32
35
|
const root = path.parse(dir).root;
|
|
33
36
|
const homeDir = process.env.HOME || '';
|
|
34
37
|
|
|
38
|
+
// Find project configs in hierarchy
|
|
35
39
|
while (dir !== root) {
|
|
36
40
|
const configPath = path.join(dir, '.claude', 'mcps.json');
|
|
37
41
|
if (fs.existsSync(configPath)) {
|
|
@@ -40,10 +44,21 @@ function findAllConfigs(startDir = process.cwd()) {
|
|
|
40
44
|
dir = path.dirname(dir);
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
// Read global MCPs from ~/.claude.json (Claude Code's native config)
|
|
48
|
+
const claudeJsonPath = path.join(homeDir, '.claude.json');
|
|
49
|
+
if (fs.existsSync(claudeJsonPath)) {
|
|
50
|
+
configs.unshift({
|
|
51
|
+
dir: homeDir,
|
|
52
|
+
configPath: claudeJsonPath,
|
|
53
|
+
isGlobalClaudeJson: true // Flag to handle different format
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Legacy: Also check ~/.claude/mcps.json for backwards compatibility
|
|
58
|
+
const legacyHomeConfig = path.join(homeDir, '.claude', 'mcps.json');
|
|
59
|
+
if (fs.existsSync(legacyHomeConfig)) {
|
|
60
|
+
if (!configs.some(c => c.configPath === legacyHomeConfig)) {
|
|
61
|
+
configs.unshift({ dir: homeDir, configPath: legacyHomeConfig, isLegacy: true });
|
|
47
62
|
}
|
|
48
63
|
}
|
|
49
64
|
|
package/lib/constants.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Constants and tool path configurations
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const VERSION = '0.
|
|
5
|
+
const VERSION = '0.46.0-beta.10';
|
|
6
6
|
|
|
7
7
|
// Tool-specific path configurations
|
|
8
8
|
const TOOL_PATHS = {
|
|
@@ -10,14 +10,16 @@ const TOOL_PATHS = {
|
|
|
10
10
|
name: 'Claude Code',
|
|
11
11
|
icon: 'sparkles',
|
|
12
12
|
color: 'orange',
|
|
13
|
-
|
|
13
|
+
// Global MCPs are embedded in ~/.claude.json under mcpServers key (no separate file)
|
|
14
|
+
globalConfig: '~/.claude.json',
|
|
14
15
|
globalSettings: '~/.claude/settings.json',
|
|
16
|
+
globalMcpKey: 'mcpServers', // MCPs are under this key in globalConfig
|
|
15
17
|
projectFolder: '.claude',
|
|
16
18
|
projectRules: '.claude/rules',
|
|
17
19
|
projectCommands: '.claude/commands',
|
|
18
20
|
projectWorkflows: '.claude/workflows',
|
|
19
21
|
projectInstructions: 'CLAUDE.md',
|
|
20
|
-
outputFile: '.mcp.json',
|
|
22
|
+
outputFile: '.mcp.json', // Per-project MCPs go here (shared via git)
|
|
21
23
|
supportsEnvInterpolation: true,
|
|
22
24
|
},
|
|
23
25
|
gemini: {
|
package/lib/mcps.js
CHANGED
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
* MCP add/remove commands
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
const fs = require('fs');
|
|
5
6
|
const path = require('path');
|
|
6
7
|
const { loadJson, saveJson } = require('./utils');
|
|
7
8
|
const { findProjectRoot } = require('./config');
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Get path to Claude's global config (~/.claude.json)
|
|
12
|
+
*/
|
|
13
|
+
function getGlobalConfigPath() {
|
|
14
|
+
const homeDir = process.env.HOME || '';
|
|
15
|
+
return path.join(homeDir, '.claude.json');
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
/**
|
|
10
19
|
* List available MCPs
|
|
11
20
|
*/
|
|
@@ -132,8 +141,122 @@ function remove(installDir, mcpNames) {
|
|
|
132
141
|
return removed.length > 0;
|
|
133
142
|
}
|
|
134
143
|
|
|
144
|
+
/**
|
|
145
|
+
* List global MCPs from ~/.claude.json
|
|
146
|
+
*/
|
|
147
|
+
function listGlobal() {
|
|
148
|
+
const configPath = getGlobalConfigPath();
|
|
149
|
+
const config = loadJson(configPath);
|
|
150
|
+
|
|
151
|
+
if (!config || !config.mcpServers) {
|
|
152
|
+
console.log('\n📚 Global MCPs (~/.claude.json): None configured\n');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const mcps = Object.keys(config.mcpServers);
|
|
157
|
+
console.log('\n📚 Global MCPs (~/.claude.json):\n');
|
|
158
|
+
for (const name of mcps) {
|
|
159
|
+
const server = config.mcpServers[name];
|
|
160
|
+
const type = server.type || 'stdio';
|
|
161
|
+
console.log(` • ${name} (${type})`);
|
|
162
|
+
}
|
|
163
|
+
console.log(`\n Total: ${mcps.length} global MCP(s)\n`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Add MCP(s) to global config (~/.claude.json)
|
|
168
|
+
*/
|
|
169
|
+
function addGlobal(registryPath, mcpNames) {
|
|
170
|
+
if (!mcpNames || mcpNames.length === 0) {
|
|
171
|
+
console.error('Usage: coder-config global add <mcp-name> [mcp-name...]');
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const configPath = getGlobalConfigPath();
|
|
176
|
+
let config = loadJson(configPath) || {};
|
|
177
|
+
|
|
178
|
+
if (!config.mcpServers) {
|
|
179
|
+
config.mcpServers = {};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const registry = loadJson(registryPath);
|
|
183
|
+
const added = [];
|
|
184
|
+
const notFound = [];
|
|
185
|
+
const alreadyExists = [];
|
|
186
|
+
|
|
187
|
+
for (const name of mcpNames) {
|
|
188
|
+
if (config.mcpServers[name]) {
|
|
189
|
+
alreadyExists.push(name);
|
|
190
|
+
} else if (registry?.mcpServers?.[name]) {
|
|
191
|
+
config.mcpServers[name] = registry.mcpServers[name];
|
|
192
|
+
added.push(name);
|
|
193
|
+
} else {
|
|
194
|
+
notFound.push(name);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (added.length) {
|
|
199
|
+
saveJson(configPath, config);
|
|
200
|
+
console.log(`✓ Added to ~/.claude.json: ${added.join(', ')}`);
|
|
201
|
+
console.log(' (Global MCPs apply to all projects)');
|
|
202
|
+
}
|
|
203
|
+
if (alreadyExists.length) {
|
|
204
|
+
console.log(`Already in global config: ${alreadyExists.join(', ')}`);
|
|
205
|
+
}
|
|
206
|
+
if (notFound.length) {
|
|
207
|
+
console.log(`Not in registry: ${notFound.join(', ')}`);
|
|
208
|
+
console.log(' (Use "coder-config list" to see available MCPs)');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return added.length > 0;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Remove MCP(s) from global config (~/.claude.json)
|
|
216
|
+
*/
|
|
217
|
+
function removeGlobal(mcpNames) {
|
|
218
|
+
if (!mcpNames || mcpNames.length === 0) {
|
|
219
|
+
console.error('Usage: coder-config global remove <mcp-name> [mcp-name...]');
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const configPath = getGlobalConfigPath();
|
|
224
|
+
let config = loadJson(configPath);
|
|
225
|
+
|
|
226
|
+
if (!config || !config.mcpServers) {
|
|
227
|
+
console.error('No global MCPs configured in ~/.claude.json');
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const removed = [];
|
|
232
|
+
const notFound = [];
|
|
233
|
+
|
|
234
|
+
for (const name of mcpNames) {
|
|
235
|
+
if (config.mcpServers[name]) {
|
|
236
|
+
delete config.mcpServers[name];
|
|
237
|
+
removed.push(name);
|
|
238
|
+
} else {
|
|
239
|
+
notFound.push(name);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (removed.length) {
|
|
244
|
+
saveJson(configPath, config);
|
|
245
|
+
console.log(`✓ Removed from ~/.claude.json: ${removed.join(', ')}`);
|
|
246
|
+
}
|
|
247
|
+
if (notFound.length) {
|
|
248
|
+
console.log(`Not in global config: ${notFound.join(', ')}`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return removed.length > 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
135
254
|
module.exports = {
|
|
136
255
|
list,
|
|
137
256
|
add,
|
|
138
257
|
remove,
|
|
258
|
+
listGlobal,
|
|
259
|
+
addGlobal,
|
|
260
|
+
removeGlobal,
|
|
261
|
+
getGlobalConfigPath,
|
|
139
262
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coder-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0-beta.10",
|
|
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",
|
package/scripts/release.sh
CHANGED
|
@@ -1,45 +1,78 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# Usage:
|
|
4
|
-
#
|
|
5
|
-
#
|
|
2
|
+
# Stable release script
|
|
3
|
+
# Usage: npm run release # Interactive, prompts for version
|
|
4
|
+
# npm run release -- 0.46.0 # Specific version
|
|
5
|
+
# npm run release -- --minor # Bump minor version
|
|
6
|
+
# npm run release -- --major # Bump major version
|
|
6
7
|
|
|
7
8
|
set -e
|
|
8
9
|
|
|
9
|
-
if [ -z "$1" ]; then
|
|
10
|
-
echo "Usage: $0 \"commit message\" [--minor|--major]"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
MESSAGE="$1"
|
|
15
|
-
BUMP_TYPE="${2:---patch}"
|
|
16
|
-
|
|
17
10
|
# Get current version
|
|
18
|
-
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
11
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version.split('-')[0]")
|
|
19
12
|
|
|
20
|
-
# Parse version
|
|
13
|
+
# Parse current version
|
|
21
14
|
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
|
|
22
15
|
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
16
|
+
# Determine new version
|
|
17
|
+
if [ -n "$1" ]; then
|
|
18
|
+
case "$1" in
|
|
19
|
+
--major)
|
|
20
|
+
MAJOR=$((MAJOR + 1))
|
|
21
|
+
MINOR=0
|
|
22
|
+
PATCH=0
|
|
23
|
+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
24
|
+
;;
|
|
25
|
+
--minor)
|
|
26
|
+
MINOR=$((MINOR + 1))
|
|
27
|
+
PATCH=0
|
|
28
|
+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
29
|
+
;;
|
|
30
|
+
--patch)
|
|
31
|
+
PATCH=$((PATCH + 1))
|
|
32
|
+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
33
|
+
;;
|
|
34
|
+
*)
|
|
35
|
+
# Assume it's a version number
|
|
36
|
+
NEW_VERSION="$1"
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
else
|
|
40
|
+
# Interactive mode
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Current version: $CURRENT_VERSION"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "Enter new version (or press Enter for patch bump):"
|
|
45
|
+
read -r INPUT_VERSION
|
|
46
|
+
|
|
47
|
+
if [ -z "$INPUT_VERSION" ]; then
|
|
35
48
|
PATCH=$((PATCH + 1))
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
50
|
+
else
|
|
51
|
+
NEW_VERSION="$INPUT_VERSION"
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Validate version format
|
|
56
|
+
if ! [[ "$NEW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
57
|
+
echo "Invalid version format: $NEW_VERSION"
|
|
58
|
+
echo "Expected format: X.Y.Z (e.g., 0.46.0)"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
38
61
|
|
|
39
|
-
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
40
62
|
TAG="v$NEW_VERSION"
|
|
41
63
|
|
|
42
|
-
echo "
|
|
64
|
+
echo ""
|
|
65
|
+
echo "📦 Releasing: $CURRENT_VERSION -> $NEW_VERSION"
|
|
66
|
+
echo ""
|
|
67
|
+
|
|
68
|
+
# Check for uncommitted changes
|
|
69
|
+
if [ -n "$(git status --porcelain)" ]; then
|
|
70
|
+
echo "⚠️ You have uncommitted changes:"
|
|
71
|
+
git status --short
|
|
72
|
+
echo ""
|
|
73
|
+
echo "Commit them first, or press Enter to continue anyway:"
|
|
74
|
+
read -r
|
|
75
|
+
fi
|
|
43
76
|
|
|
44
77
|
# Update version in package.json
|
|
45
78
|
node -e "
|
|
@@ -52,20 +85,22 @@ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
|
52
85
|
# Sync version to other files
|
|
53
86
|
npm run version:sync
|
|
54
87
|
|
|
55
|
-
# Stage
|
|
56
|
-
git add
|
|
88
|
+
# Stage version files
|
|
89
|
+
git add package.json lib/constants.js ui/package.json
|
|
57
90
|
|
|
58
|
-
# Commit
|
|
59
|
-
git commit -m "$
|
|
91
|
+
# Commit (skip hooks)
|
|
92
|
+
SKIP_AUTO_PUSH=1 git commit -m "release: v$NEW_VERSION"
|
|
60
93
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
# Tag
|
|
94
|
+
# Create tag
|
|
64
95
|
git tag "$TAG"
|
|
65
96
|
|
|
66
|
-
# Push
|
|
97
|
+
# Push commit and tag
|
|
98
|
+
echo ""
|
|
99
|
+
echo "🚀 Pushing $TAG..."
|
|
67
100
|
git push && git push --tags
|
|
68
101
|
|
|
69
102
|
echo ""
|
|
70
103
|
echo "✅ Released $TAG"
|
|
71
|
-
echo "
|
|
104
|
+
echo ""
|
|
105
|
+
echo "CI will publish to npm with 'latest' tag."
|
|
106
|
+
echo "Users will get this version with: npm install -g coder-config"
|