@gramatr/client 0.6.1 → 0.6.2
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.ts +13 -3
- package/codex/install.ts +8 -0
- package/core/migration.ts +120 -4
- package/gemini/install.ts +8 -0
- package/package.json +1 -1
package/bin/install.ts
CHANGED
|
@@ -20,6 +20,11 @@ import { createInterface } from 'readline';
|
|
|
20
20
|
import { buildClaudeHooksFile } from '../core/install.ts';
|
|
21
21
|
import { VERSION } from '../core/version.ts';
|
|
22
22
|
import { resolveAuthToken } from '../core/auth.ts';
|
|
23
|
+
import {
|
|
24
|
+
sanitizeLegacyEnvBlock,
|
|
25
|
+
detectShellRcLegacyEnv,
|
|
26
|
+
formatShellRcLegacyWarning,
|
|
27
|
+
} from '../core/migration.ts';
|
|
23
28
|
|
|
24
29
|
// ── Constants ──
|
|
25
30
|
|
|
@@ -513,8 +518,8 @@ function updateClaudeSettings(url: string, token: string): void {
|
|
|
513
518
|
|
|
514
519
|
const settings = readJson(CLAUDE_SETTINGS);
|
|
515
520
|
|
|
516
|
-
// Env vars
|
|
517
|
-
settings.env = settings.env
|
|
521
|
+
// Env vars — sanitize legacy GMTR_* keys before writing (v0.6.2+ fix)
|
|
522
|
+
settings.env = sanitizeLegacyEnvBlock(settings.env);
|
|
518
523
|
settings.env.GRAMATR_DIR = CLIENT_DIR;
|
|
519
524
|
settings.env.GRAMATR_URL = url;
|
|
520
525
|
settings.env.PATH = `${HOME}/.gramatr/bin:/usr/local/bin:/usr/bin:/bin`;
|
|
@@ -584,7 +589,8 @@ function registerMcpServer(url: string, token: string): void {
|
|
|
584
589
|
|
|
585
590
|
// Register in ~/.claude.json
|
|
586
591
|
mergeJson(CLAUDE_JSON, (data) => {
|
|
587
|
-
|
|
592
|
+
// Sanitize legacy GMTR_* keys before writing (v0.6.2+ fix)
|
|
593
|
+
data.env = sanitizeLegacyEnvBlock(data.env);
|
|
588
594
|
if (token) data.env.GRAMATR_TOKEN = token;
|
|
589
595
|
delete data.env.AIOS_MCP_TOKEN;
|
|
590
596
|
|
|
@@ -737,6 +743,10 @@ async function main(): Promise<void> {
|
|
|
737
743
|
log(' 2. Already authenticated (token found in ~/.gramatr.json)');
|
|
738
744
|
}
|
|
739
745
|
log('');
|
|
746
|
+
|
|
747
|
+
// v0.6.2+: detect legacy GMTR_* exports in user shell rc files and warn
|
|
748
|
+
const rcHits = detectShellRcLegacyEnv(HOME);
|
|
749
|
+
if (rcHits.length > 0) log(formatShellRcLegacyWarning(rcHits));
|
|
740
750
|
} else {
|
|
741
751
|
log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
742
752
|
log(' Install completed with warnings');
|
package/codex/install.ts
CHANGED
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
mergeHooksFile,
|
|
10
10
|
upsertManagedBlock,
|
|
11
11
|
} from './lib/codex-install-utils.ts';
|
|
12
|
+
import {
|
|
13
|
+
detectShellRcLegacyEnv,
|
|
14
|
+
formatShellRcLegacyWarning,
|
|
15
|
+
} from '../core/migration.ts';
|
|
12
16
|
|
|
13
17
|
const START_MARKER = '<!-- GMTR-CODEX-START -->';
|
|
14
18
|
const END_MARKER = '<!-- GMTR-CODEX-END -->';
|
|
@@ -107,6 +111,10 @@ export function main(): void {
|
|
|
107
111
|
log('');
|
|
108
112
|
log('Codex installer complete.');
|
|
109
113
|
log('Restart Codex or start a new session to load the updated hook configuration.');
|
|
114
|
+
|
|
115
|
+
// v0.6.2+: detect legacy GMTR_* exports in shell rc and warn
|
|
116
|
+
const rcHits = detectShellRcLegacyEnv(home);
|
|
117
|
+
if (rcHits.length > 0) log(formatShellRcLegacyWarning(rcHits));
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
// Run directly when executed as a script
|
package/core/migration.ts
CHANGED
|
@@ -308,6 +308,33 @@ function stripLegacyEntriesFromHookEvent(value: unknown): unknown {
|
|
|
308
308
|
.filter(Boolean);
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Env-var key prefixes that were used by earlier gramatr versions and are
|
|
313
|
+
* now either renamed or removed. Any key matching one of these prefixes that
|
|
314
|
+
* survives in a user's config file across an upgrade is a legacy leak and
|
|
315
|
+
* must be scrubbed before we write the new env block.
|
|
316
|
+
*
|
|
317
|
+
* Issue: v0.6.0 renamed GMTR_* → GRAMATR_* but the installer's env merge
|
|
318
|
+
* only SET new keys without removing old ones. Users upgrading from v0.5.x
|
|
319
|
+
* kept the stale GMTR_DIR, GMTR_URL, GMTR_TOKEN in their config files
|
|
320
|
+
* forever. v0.6.2 fixes this by sanitizing on every install.
|
|
321
|
+
*/
|
|
322
|
+
export const LEGACY_ENV_KEY_PREFIXES: ReadonlyArray<string> = ['GMTR_'];
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Strip any env-var key matching a legacy prefix. Returns a new object;
|
|
326
|
+
* input is not mutated. Safe on null/undefined (returns {}).
|
|
327
|
+
*/
|
|
328
|
+
export function sanitizeLegacyEnvBlock(env: unknown): JsonObject {
|
|
329
|
+
if (!isRecord(env)) return {};
|
|
330
|
+
const next: JsonObject = {};
|
|
331
|
+
for (const [key, value] of Object.entries(env)) {
|
|
332
|
+
if (LEGACY_ENV_KEY_PREFIXES.some((prefix) => key.startsWith(prefix))) continue;
|
|
333
|
+
next[key] = value;
|
|
334
|
+
}
|
|
335
|
+
return next;
|
|
336
|
+
}
|
|
337
|
+
|
|
311
338
|
export function sanitizeClaudeSettings(
|
|
312
339
|
settings: JsonObject,
|
|
313
340
|
clientDir: string,
|
|
@@ -326,14 +353,103 @@ export function sanitizeClaudeSettings(
|
|
|
326
353
|
}
|
|
327
354
|
|
|
328
355
|
next.hooks = hooks;
|
|
356
|
+
// Sanitize legacy env keys (v0.6.2+)
|
|
357
|
+
next.env = sanitizeLegacyEnvBlock(next.env);
|
|
329
358
|
return next;
|
|
330
359
|
}
|
|
331
360
|
|
|
332
361
|
export function sanitizeClaudeJson(claudeJson: JsonObject): JsonObject {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
362
|
+
const next = { ...claudeJson };
|
|
363
|
+
if (isRecord(claudeJson.mcpServers)) {
|
|
364
|
+
const mcpServers = { ...claudeJson.mcpServers };
|
|
365
|
+
delete mcpServers.aios;
|
|
366
|
+
next.mcpServers = mcpServers;
|
|
367
|
+
}
|
|
368
|
+
// Sanitize legacy env keys (v0.6.2+)
|
|
369
|
+
next.env = sanitizeLegacyEnvBlock(claudeJson.env);
|
|
370
|
+
return next;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ── Shell rc legacy env detection (v0.6.2+) ──────────────────────────────
|
|
374
|
+
//
|
|
375
|
+
// Users who added `export GMTR_TOKEN=...` lines to their shell rc files
|
|
376
|
+
// before v0.6.0 will keep those vars live across every new shell until they
|
|
377
|
+
// manually edit the files. Our installer cannot mutate user dotfiles
|
|
378
|
+
// without permission, but it CAN detect and warn.
|
|
379
|
+
|
|
380
|
+
export interface ShellRcLegacyHit {
|
|
381
|
+
file: string;
|
|
382
|
+
lineNumber: number;
|
|
383
|
+
line: string;
|
|
384
|
+
variableName: string;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const SHELL_RC_CANDIDATES: ReadonlyArray<string> = [
|
|
388
|
+
'.bashrc',
|
|
389
|
+
'.bash_profile',
|
|
390
|
+
'.zshrc',
|
|
391
|
+
'.zprofile',
|
|
392
|
+
'.profile',
|
|
393
|
+
];
|
|
394
|
+
|
|
395
|
+
const LEGACY_EXPORT_RE = /^\s*export\s+(GMTR_[A-Z_]+)=/;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Scan shell rc files for `export GMTR_*=...` lines. Returns a list of hits,
|
|
399
|
+
* each with file path, line number, raw line, and the variable name. Never
|
|
400
|
+
* mutates any file — read-only detection.
|
|
401
|
+
*/
|
|
402
|
+
export function detectShellRcLegacyEnv(homeDir: string): ShellRcLegacyHit[] {
|
|
403
|
+
const out: ShellRcLegacyHit[] = [];
|
|
404
|
+
for (const basename of SHELL_RC_CANDIDATES) {
|
|
405
|
+
const path = `${homeDir}/${basename}`;
|
|
406
|
+
if (!existsSync(path)) continue;
|
|
407
|
+
let content: string;
|
|
408
|
+
try {
|
|
409
|
+
content = readFileSync(path, 'utf8');
|
|
410
|
+
} catch {
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
const lines = content.split(/\r?\n/);
|
|
414
|
+
for (let i = 0; i < lines.length; i++) {
|
|
415
|
+
const match = lines[i].match(LEGACY_EXPORT_RE);
|
|
416
|
+
if (match) {
|
|
417
|
+
out.push({
|
|
418
|
+
file: path,
|
|
419
|
+
lineNumber: i + 1,
|
|
420
|
+
line: lines[i],
|
|
421
|
+
variableName: match[1],
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return out;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Format shell-rc legacy hits as a human-readable block of warning text.
|
|
431
|
+
* Returns an empty string if there are no hits. Writes no files.
|
|
432
|
+
*/
|
|
433
|
+
export function formatShellRcLegacyWarning(hits: ShellRcLegacyHit[]): string {
|
|
434
|
+
if (hits.length === 0) return '';
|
|
435
|
+
const lines: string[] = [];
|
|
436
|
+
lines.push('');
|
|
437
|
+
lines.push('⚠ Legacy GMTR_* exports detected in your shell rc files:');
|
|
438
|
+
lines.push('');
|
|
439
|
+
for (const hit of hits) {
|
|
440
|
+
lines.push(` ${hit.file}:${hit.lineNumber}`);
|
|
441
|
+
lines.push(` ${hit.line.trim()}`);
|
|
442
|
+
}
|
|
443
|
+
const uniqueVars = Array.from(new Set(hits.map((h) => h.variableName)));
|
|
444
|
+
lines.push('');
|
|
445
|
+
lines.push(' These vars are no longer read by gramatr (since v0.6.0) but');
|
|
446
|
+
lines.push(' remain in your shell environment on every login. To clean up:');
|
|
447
|
+
lines.push('');
|
|
448
|
+
lines.push(' 1. Edit the files above and delete the matching export lines');
|
|
449
|
+
lines.push(` 2. Run in each open terminal: unset ${uniqueVars.join(' ')}`);
|
|
450
|
+
lines.push(' 3. Or just start a fresh shell session');
|
|
451
|
+
lines.push('');
|
|
452
|
+
return lines.join('\n');
|
|
337
453
|
}
|
|
338
454
|
|
|
339
455
|
export function findStaleArtifacts(
|
package/gemini/install.ts
CHANGED
|
@@ -17,6 +17,10 @@ import {
|
|
|
17
17
|
getGramatrExtensionDir,
|
|
18
18
|
readStoredApiKey,
|
|
19
19
|
} from './lib/gemini-install-utils.ts';
|
|
20
|
+
import {
|
|
21
|
+
detectShellRcLegacyEnv,
|
|
22
|
+
formatShellRcLegacyWarning,
|
|
23
|
+
} from '../core/migration.ts';
|
|
20
24
|
|
|
21
25
|
function log(message: string): void {
|
|
22
26
|
process.stdout.write(`${message}\n`);
|
|
@@ -272,6 +276,10 @@ export async function main(): Promise<void> {
|
|
|
272
276
|
log('');
|
|
273
277
|
log(' Restart Gemini CLI to load the extension.');
|
|
274
278
|
log('');
|
|
279
|
+
|
|
280
|
+
// v0.6.2+: detect legacy GMTR_* exports in shell rc and warn
|
|
281
|
+
const rcHits = detectShellRcLegacyEnv(home);
|
|
282
|
+
if (rcHits.length > 0) log(formatShellRcLegacyWarning(rcHits));
|
|
275
283
|
}
|
|
276
284
|
|
|
277
285
|
// Run directly when executed as a script
|