@arjunkhera/atlas 0.4.55 → 0.4.56
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/.claude-plugin/plugin.json +1 -1
- package/door/lib/install.mjs +41 -2
- package/package.json +1 -1
package/door/lib/install.mjs
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
// The catalog is one folder on the Mac, ~/.atlas/catalog. It holds one entry
|
|
7
7
|
// that pins an exact npm version, so nothing moves Atlas to another version
|
|
8
8
|
// without `atlas upgrade`. The installer writes that one file and asks Claude
|
|
9
|
-
// Code to add the catalog and install the plugin.
|
|
9
|
+
// Code to add the catalog and install the plugin. On a Mac it writes no
|
|
10
|
+
// settings file. With --cloud it also sets one key, env.MCP_TIMEOUT, in the
|
|
11
|
+
// user settings file, so the tools server has time for the refresh at
|
|
12
|
+
// session start (item ade7d96a, decision c71facc9; the owner asked on
|
|
13
|
+
// 7 November 2026 to make it the same for every project).
|
|
10
14
|
import { execFileSync } from 'node:child_process';
|
|
11
15
|
import { createHash } from 'node:crypto';
|
|
12
16
|
import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
@@ -32,6 +36,35 @@ export function repoOf(packageRoot) {
|
|
|
32
36
|
export const catalogDir = (env) => join(env.HOME, '.atlas', 'catalog');
|
|
33
37
|
export const catalogFile = (env) => join(catalogDir(env), '.claude-plugin', 'marketplace.json');
|
|
34
38
|
|
|
39
|
+
// The start time that a cloud setup gives each tools server, in ms. Claude
|
|
40
|
+
// Code reads MCP_TIMEOUT from the env block of its user settings file too
|
|
41
|
+
// (probe of 7 November 2026: a server that starts in 40 s failed with no
|
|
42
|
+
// value and served its tool with this one).
|
|
43
|
+
export const CLOUD_MCP_TIMEOUT = '90000';
|
|
44
|
+
export const userSettingsFile = (env) => join(env.CLAUDE_CONFIG_DIR || join(env.HOME, '.claude'), 'settings.json');
|
|
45
|
+
|
|
46
|
+
// What a cloud install does to the user settings file. It adds the key only
|
|
47
|
+
// when no value is set, here or in the environment, and it never rewrites a
|
|
48
|
+
// file it cannot read.
|
|
49
|
+
export function cloudTimeout(env) {
|
|
50
|
+
const file = userSettingsFile(env);
|
|
51
|
+
if (env.MCP_TIMEOUT) return { file, state: 'environment' };
|
|
52
|
+
let settings = {};
|
|
53
|
+
if (existsSync(file)) {
|
|
54
|
+
try { settings = JSON.parse(readFileSync(file, 'utf8')); } catch { return { file, state: 'unreadable' }; }
|
|
55
|
+
if (!settings || typeof settings !== 'object' || Array.isArray(settings)) return { file, state: 'unreadable' };
|
|
56
|
+
}
|
|
57
|
+
if (settings.env && (typeof settings.env !== 'object' || Array.isArray(settings.env))) return { file, state: 'unreadable' };
|
|
58
|
+
if (settings.env?.MCP_TIMEOUT !== undefined) return { file, state: 'set' };
|
|
59
|
+
return { file, state: 'add', text: `${JSON.stringify({ ...settings, env: { ...(settings.env ?? {}), MCP_TIMEOUT: CLOUD_MCP_TIMEOUT } }, null, 2)}\n` };
|
|
60
|
+
}
|
|
61
|
+
const TIMEOUT_NOTE = {
|
|
62
|
+
add: 'adds env.MCP_TIMEOUT = "90000", the start time for the refresh',
|
|
63
|
+
set: 'unchanged: it already sets env.MCP_TIMEOUT',
|
|
64
|
+
environment: 'unchanged: the environment sets MCP_TIMEOUT',
|
|
65
|
+
unreadable: 'unchanged: the file is not a settings object, so Atlas does not touch it',
|
|
66
|
+
};
|
|
67
|
+
|
|
35
68
|
// The one file the installer writes. `local` puts a copy of the package inside
|
|
36
69
|
// the catalog instead of naming npm; CI and a development Mac use it.
|
|
37
70
|
export function catalogFor({ name, version, local = false }) {
|
|
@@ -105,6 +138,7 @@ export async function install({ packageRoot, options = {}, line = console.log, e
|
|
|
105
138
|
const file = catalogFile(env);
|
|
106
139
|
const before = existsSync(file) ? readFileSync(file, 'utf8') : null;
|
|
107
140
|
const after = `${JSON.stringify(catalog, null, 2)}\n`;
|
|
141
|
+
const timeout = options.cloud ? cloudTimeout(env) : null;
|
|
108
142
|
|
|
109
143
|
line(`Install Atlas ${version} for every folder on this Mac.`);
|
|
110
144
|
line('');
|
|
@@ -114,6 +148,7 @@ export async function install({ packageRoot, options = {}, line = console.log, e
|
|
|
114
148
|
`write ${file} (${before === null ? 'new file' : before === after ? 'unchanged' : 'changed'}; it pins ${local ? 'a local copy' : `exactly ${version}`})`,
|
|
115
149
|
`claude plugin marketplace add ${catalogDir(env)}`,
|
|
116
150
|
`claude plugin install ${PLUGIN_ID} --scope user`,
|
|
151
|
+
timeout ? `write ${timeout.file} (${TIMEOUT_NOTE[timeout.state]})` : null,
|
|
117
152
|
'atlas doctor',
|
|
118
153
|
].filter(Boolean);
|
|
119
154
|
steps.forEach((step, index) => line(` ${index + 1}. ${step}`));
|
|
@@ -121,7 +156,7 @@ export async function install({ packageRoot, options = {}, line = console.log, e
|
|
|
121
156
|
line('Claude Code itself then writes two keys into ~/.claude/settings.json, and nothing else:');
|
|
122
157
|
line(` extraKnownMarketplaces.${CATALOG_NAME} (the catalog folder)`);
|
|
123
158
|
line(` enabledPlugins["${PLUGIN_ID}"] = true`);
|
|
124
|
-
line('This command writes no settings file of its own.');
|
|
159
|
+
line(timeout ? 'With --cloud, this command writes only the MCP_TIMEOUT key named above into a settings file.' : 'This command writes no settings file of its own.');
|
|
125
160
|
if (before !== null && before !== after) { line(''); line('The catalog file changes from:'); line(before); line('to:'); line(after); }
|
|
126
161
|
if (!options.yes && !(await ask('Go ahead?'))) { line('Nothing was changed.'); return 1; }
|
|
127
162
|
|
|
@@ -140,6 +175,10 @@ export async function install({ packageRoot, options = {}, line = console.log, e
|
|
|
140
175
|
exec('claude', hasCatalog ? ['plugin', 'marketplace', 'update', CATALOG_NAME] : ['plugin', 'marketplace', 'add', catalogDir(env)]);
|
|
141
176
|
const installArgs = ['plugin', 'install', PLUGIN_ID, '--scope', 'user'];
|
|
142
177
|
exec('claude', installArgs);
|
|
178
|
+
if (timeout?.state === 'add') {
|
|
179
|
+
mkdirSync(join(timeout.file, '..'), { recursive: true });
|
|
180
|
+
writeFileSync(timeout.file, timeout.text);
|
|
181
|
+
}
|
|
143
182
|
line('');
|
|
144
183
|
// A cloud setup script runs before any session: the key comes from the
|
|
145
184
|
// environment variable, and no tools server has started yet (item 92cfbba3).
|
package/package.json
CHANGED