gramatr 0.3.59 → 0.3.62

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.
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gramatr clear-creds — Nuke ALL stored gramatr credentials.
4
+ *
5
+ * Stronger than `gramatr logout` (which only removes ~/.gmtr.json).
6
+ * This sweeps every credential location in the resolveAuthToken chain
7
+ * (core/auth.ts), so the next install/login is forced through OAuth.
8
+ *
9
+ * Locations cleared:
10
+ * 1. ~/.gmtr.json — deleted entirely
11
+ * 2. ~/gmtr-client/settings.json `auth.api_key` — stripped, file preserved
12
+ *
13
+ * Env vars (GRAMATR_API_KEY, GMTR_TOKEN) cannot be cleared from a child
14
+ * process — they live in the parent shell. We detect them and warn.
15
+ *
16
+ * Not-logged-in is not an error: exits 0 with a clean message.
17
+ */
18
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs";
19
+ import { homedir } from "os";
20
+ import { join } from "path";
21
+
22
+ function getHome(): string {
23
+ return process.env.HOME || process.env.USERPROFILE || homedir();
24
+ }
25
+
26
+ function gmtrJsonPath(): string {
27
+ return join(getHome(), ".gmtr.json");
28
+ }
29
+
30
+ function legacySettingsPath(): string {
31
+ const gmtrDir = process.env.GMTR_DIR || join(getHome(), "gmtr-client");
32
+ return join(gmtrDir, "settings.json");
33
+ }
34
+
35
+ function log(msg: string = ""): void {
36
+ process.stdout.write(`${msg}\n`);
37
+ }
38
+
39
+ function showHelp(): void {
40
+ log(`gramatr clear-creds — Remove every stored gramatr credential
41
+
42
+ Usage:
43
+ gramatr clear-creds Sweep ~/.gmtr.json + auth.api_key from gmtr-client/settings.json
44
+
45
+ After running, the next install or login will be forced through OAuth.
46
+
47
+ Env vars (GRAMATR_API_KEY, GMTR_TOKEN) cannot be unset from this process.
48
+ If they are set, this command warns and tells you the shell command to run.`);
49
+ }
50
+
51
+ interface ClearResult {
52
+ removedGmtrJson: boolean;
53
+ strippedLegacyKey: boolean;
54
+ envVarsSet: string[];
55
+ }
56
+
57
+ export function clearAll(): ClearResult {
58
+ const result: ClearResult = {
59
+ removedGmtrJson: false,
60
+ strippedLegacyKey: false,
61
+ envVarsSet: [],
62
+ };
63
+
64
+ // 1. ~/.gmtr.json — delete entirely
65
+ const gj = gmtrJsonPath();
66
+ if (existsSync(gj)) {
67
+ unlinkSync(gj);
68
+ result.removedGmtrJson = true;
69
+ }
70
+
71
+ // 2. ~/gmtr-client/settings.json — strip auth.api_key, preserve rest
72
+ const ls = legacySettingsPath();
73
+ if (existsSync(ls)) {
74
+ try {
75
+ const data = JSON.parse(readFileSync(ls, "utf8"));
76
+ if (data && data.auth && typeof data.auth === "object" && "api_key" in data.auth) {
77
+ delete data.auth.api_key;
78
+ // If auth is now empty, remove it too to keep the file tidy
79
+ if (Object.keys(data.auth).length === 0) delete data.auth;
80
+ writeFileSync(ls, `${JSON.stringify(data, null, 2)}\n`);
81
+ result.strippedLegacyKey = true;
82
+ }
83
+ } catch {
84
+ // malformed JSON — leave it alone, user can fix manually
85
+ }
86
+ }
87
+
88
+ // 3. Env vars — detect only, cannot mutate parent shell
89
+ for (const v of ["GRAMATR_API_KEY", "GMTR_TOKEN"]) {
90
+ if (process.env[v]) result.envVarsSet.push(v);
91
+ }
92
+
93
+ return result;
94
+ }
95
+
96
+ export function main(argv: string[] = process.argv.slice(2)): number {
97
+ if (argv.includes("--help") || argv.includes("-h")) {
98
+ showHelp();
99
+ return 0;
100
+ }
101
+
102
+ const r = clearAll();
103
+
104
+ if (!r.removedGmtrJson && !r.strippedLegacyKey && r.envVarsSet.length === 0) {
105
+ log("No stored credentials found. Already fully cleared.");
106
+ return 0;
107
+ }
108
+
109
+ if (r.removedGmtrJson) log(`Removed ${gmtrJsonPath()}`);
110
+ if (r.strippedLegacyKey) log(`Stripped auth.api_key from ${legacySettingsPath()}`);
111
+
112
+ if (r.envVarsSet.length > 0) {
113
+ log("");
114
+ log(`WARNING: the following env vars are still set in your shell:`);
115
+ for (const v of r.envVarsSet) log(` ${v}`);
116
+ log("");
117
+ log("These take precedence over file-based credentials. To clear them:");
118
+ log(` unset ${r.envVarsSet.join(" ")} # bash/zsh`);
119
+ log(` Remove-Item Env:${r.envVarsSet.join(", Env:")} # PowerShell`);
120
+ log("");
121
+ log("Until then, the next install will still resolve a token from the env.");
122
+ return 0;
123
+ }
124
+
125
+ log("");
126
+ log("All credentials cleared. Next 'gramatr login' or 'gramatr install' will use OAuth.");
127
+ return 0;
128
+ }
129
+
130
+ const isDirect = (() => {
131
+ try {
132
+ const invoked = process.argv[1] || "";
133
+ return invoked.endsWith("clear-creds.ts") || invoked.endsWith("clear-creds.js");
134
+ } catch {
135
+ return false;
136
+ }
137
+ })();
138
+
139
+ if (isDirect) {
140
+ process.exit(main());
141
+ }
package/bin/gramatr.js CHANGED
@@ -2,9 +2,19 @@
2
2
  /**
3
3
  * gramatr CLI entry point — thin JS wrapper that bootstraps TypeScript.
4
4
  * tsx is a production dependency, resolved directly from node_modules.
5
+ *
6
+ * ESM module: packages/client/package.json has "type": "module" (added in
7
+ * PR #487 to support top-level await in bin/gmtr-login.ts). This file must
8
+ * use ESM imports — bare `require()` will throw ReferenceError at load time.
9
+ * v0.3.60 hotfix: #487 converted the .ts bin files but missed this .js twin.
5
10
  */
6
- const { spawnSync } = require('child_process');
7
- const { join, dirname } = require('path');
11
+ import { spawnSync } from 'node:child_process';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { createRequire } from 'node:module';
15
+
16
+ const require = createRequire(import.meta.url);
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
18
 
9
19
  const script = join(__dirname, 'gramatr.ts');
10
20
  const args = process.argv.slice(2);
package/bin/gramatr.ts CHANGED
@@ -312,6 +312,9 @@ function main(): void {
312
312
  case 'logout':
313
313
  runTs(join(binDir, 'logout.ts'), raw.slice(1));
314
314
  return;
315
+ case 'clear-creds':
316
+ runTs(join(binDir, 'clear-creds.ts'), raw.slice(1));
317
+ return;
315
318
  case 'detect':
316
319
  renderDetections();
317
320
  return;
@@ -333,7 +336,8 @@ function main(): void {
333
336
  log(' install [target] Install gramatr (claude-code, codex, gemini-cli, all)');
334
337
  log(' login Authenticate with the gramatr server (OAuth)');
335
338
  log(' add-api-key Add an API key explicitly (interactive / piped / --from-env)');
336
- log(' logout Clear stored credentials (~/.gmtr.json)');
339
+ log(' logout Clear session token (~/.gmtr.json)');
340
+ log(' clear-creds Nuke ALL stored credentials, force OAuth on next login');
337
341
  log(' detect Show detected CLI platforms');
338
342
  log(' doctor Check installation health');
339
343
  log(' upgrade Upgrade all installed targets');
package/bin/statusline.ts CHANGED
@@ -129,7 +129,7 @@ const c = {
129
129
  // Text hierarchy (warm neutrals)
130
130
  text: '\x1b[38;2;236;236;236m', // #ECECEC — primary text
131
131
  textSec: '\x1b[38;2;136;136;136m', // #888888 — secondary
132
- textMuted: '\x1b[38;2;102;102;102m', // #666666 — muted/labels
132
+ textMuted: '\x1b[38;2;192;192;192m', // #C0C0C0 — muted/labels (dimmer than primary, readable on light backgrounds)
133
133
  // Brand
134
134
  primary: '\x1b[38;2;59;130;246m', // #3B82F6 — blue accent
135
135
  accent: '\x1b[38;2;96;165;250m', // #60A5FA — lighter blue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramatr",
3
- "version": "0.3.59",
3
+ "version": "0.3.62",
4
4
  "description": "grāmatr — context engineering layer for AI coding agents. Every prompt gets a pre-computed intelligence packet: decision routing, capability audit, behavioral directives, memory pre-load, and ISC scaffolds. Continuity across sessions for Claude Code, Codex, and Gemini CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",