robrain 2.4.7 → 2.4.8

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.
Files changed (61) hide show
  1. package/README.md +3 -0
  2. package/dist/commands/check.d.ts.map +1 -1
  3. package/dist/commands/check.js +6 -8
  4. package/dist/commands/check.js.map +1 -1
  5. package/dist/commands/explain.d.ts.map +1 -1
  6. package/dist/commands/explain.js +5 -8
  7. package/dist/commands/explain.js.map +1 -1
  8. package/dist/commands/export-interchange.d.ts.map +1 -1
  9. package/dist/commands/export-interchange.js +4 -9
  10. package/dist/commands/export-interchange.js.map +1 -1
  11. package/dist/commands/export-memory.d.ts.map +1 -1
  12. package/dist/commands/export-memory.js +4 -9
  13. package/dist/commands/export-memory.js.map +1 -1
  14. package/dist/commands/inject.d.ts.map +1 -1
  15. package/dist/commands/inject.js +5 -9
  16. package/dist/commands/inject.js.map +1 -1
  17. package/dist/commands/install.d.ts +7 -1
  18. package/dist/commands/install.d.ts.map +1 -1
  19. package/dist/commands/install.js +40 -3
  20. package/dist/commands/install.js.map +1 -1
  21. package/dist/commands/install.test.js +89 -0
  22. package/dist/commands/install.test.js.map +1 -1
  23. package/dist/commands/outcomes.d.ts.map +1 -1
  24. package/dist/commands/outcomes.js +5 -13
  25. package/dist/commands/outcomes.js.map +1 -1
  26. package/dist/commands/review.d.ts.map +1 -1
  27. package/dist/commands/review.js +4 -5
  28. package/dist/commands/review.js.map +1 -1
  29. package/dist/commands/status.d.ts +20 -0
  30. package/dist/commands/status.d.ts.map +1 -1
  31. package/dist/commands/status.js +87 -29
  32. package/dist/commands/status.js.map +1 -1
  33. package/dist/commands/status.test.d.ts +2 -0
  34. package/dist/commands/status.test.d.ts.map +1 -0
  35. package/dist/commands/status.test.js +201 -0
  36. package/dist/commands/status.test.js.map +1 -0
  37. package/dist/index.js +1 -1
  38. package/dist/lib/auth.d.ts +30 -2
  39. package/dist/lib/auth.d.ts.map +1 -1
  40. package/dist/lib/auth.js +45 -5
  41. package/dist/lib/auth.js.map +1 -1
  42. package/dist/lib/auth.test.d.ts +2 -0
  43. package/dist/lib/auth.test.d.ts.map +1 -0
  44. package/dist/lib/auth.test.js +46 -0
  45. package/dist/lib/auth.test.js.map +1 -0
  46. package/dist/lib/perception-errors.d.ts +33 -0
  47. package/dist/lib/perception-errors.d.ts.map +1 -0
  48. package/dist/lib/perception-errors.js +104 -0
  49. package/dist/lib/perception-errors.js.map +1 -0
  50. package/dist/lib/perception-errors.test.d.ts +2 -0
  51. package/dist/lib/perception-errors.test.d.ts.map +1 -0
  52. package/dist/lib/perception-errors.test.js +64 -0
  53. package/dist/lib/perception-errors.test.js.map +1 -0
  54. package/dist/lib/project.d.ts +9 -0
  55. package/dist/lib/project.d.ts.map +1 -1
  56. package/dist/lib/project.js +17 -9
  57. package/dist/lib/project.js.map +1 -1
  58. package/package.json +2 -2
  59. package/vendor/sensing-mcp/dist/index.js +1 -1
  60. package/vendor/sensing-mcp/package.json +1 -1
  61. package/vendor/synthesis/package.json +1 -1
@@ -2,8 +2,73 @@
2
2
  // robrain status — shows current state of the memory system
3
3
  import chalk from 'chalk';
4
4
  import { readConfig, isAuthenticated } from '../lib/config.js';
5
- import { gatherProjectInfo } from '../lib/project.js';
5
+ import { findPinnedProjectId, gatherProjectInfo } from '../lib/project.js';
6
6
  import { cwd } from 'process';
7
+ export async function lookUpRegistration(config, projectId) {
8
+ if (!config.perceptionUrl)
9
+ return { reachable: false, state: 'unknown' };
10
+ try {
11
+ const health = await fetch(`${config.perceptionUrl}/health`);
12
+ if (!health.ok)
13
+ return { reachable: false, state: 'unknown' };
14
+ }
15
+ catch {
16
+ return { reachable: false, state: 'unknown' };
17
+ }
18
+ try {
19
+ const res = await fetch(`${config.perceptionUrl}/projects`, {
20
+ headers: config.perceptionKey ? { Authorization: `Bearer ${config.perceptionKey}` } : {},
21
+ });
22
+ // /health is deliberately unauthenticated, so a bad key reaches us here as
23
+ // a healthy store that rejects the read — actionable, unlike plain unknown.
24
+ if (res.status === 401 || res.status === 403)
25
+ return { reachable: true, state: 'auth_failed' };
26
+ if (!res.ok)
27
+ return { reachable: true, state: 'unknown' };
28
+ const data = await res.json();
29
+ // Only a well-formed list can prove absence. An unexpected shape (a cloud
30
+ // API that answers differently) must not read as "your project is gone" —
31
+ // that sends someone to re-init a project that already exists.
32
+ if (!Array.isArray(data.projects))
33
+ return { reachable: true, state: 'unknown' };
34
+ const row = data.projects.find(p => p.id === projectId);
35
+ if (!row)
36
+ return { reachable: true, state: 'unregistered' };
37
+ return { reachable: true, state: 'registered', decisions: row.decision_count };
38
+ }
39
+ catch {
40
+ return { reachable: true, state: 'unknown' };
41
+ }
42
+ }
43
+ /** One-line state for the `Memory:` row. Any follow-up goes in registrationHint. */
44
+ export function describeRegistration(reg) {
45
+ if (reg.state === 'registered') {
46
+ const n = reg.decisions;
47
+ if (typeof n !== 'number')
48
+ return chalk.green('registered');
49
+ // 0 on a registered project is the silent-Sensing tell — call it out.
50
+ return chalk.green('registered') + chalk.dim(' · ')
51
+ + (n === 0 ? chalk.yellow('0 decisions') : `${n} decisions`);
52
+ }
53
+ if (reg.state === 'unregistered') {
54
+ return chalk.yellow('not registered') + chalk.dim(' — nothing is stored for this directory yet');
55
+ }
56
+ if (reg.state === 'auth_failed') {
57
+ return chalk.yellow('unknown') + chalk.dim(' — the memory store rejected this API key');
58
+ }
59
+ return chalk.dim('unknown — could not reach the memory store');
60
+ }
61
+ /**
62
+ * Remediation for the row above, printed on its own line: hand-aligning a
63
+ * continuation inside the value wraps badly in narrow terminals.
64
+ */
65
+ export function registrationHint(reg) {
66
+ if (reg.state === 'unregistered')
67
+ return 'Run `npx robrain init-project` from a project root.';
68
+ if (reg.state === 'auth_failed')
69
+ return 'Re-run `npx robrain install` to refresh credentials.';
70
+ return null;
71
+ }
7
72
  export async function statusCommand() {
8
73
  console.log();
9
74
  if (!isAuthenticated()) {
@@ -23,39 +88,32 @@ export async function statusCommand() {
23
88
  console.log(chalk.dim(' Embeddings: ') + (config.thin
24
89
  ? 'cloud (server-side)'
25
90
  : (config.embeddingProvider ?? 'not set')));
91
+ // Look up registration BEFORE printing the project block. "Current project:
92
+ // <id>" is computed locally (see below) and says nothing about whether that
93
+ // project exists — printing it bare reads as membership we never checked,
94
+ // which makes a clean uninstall look like a failed one.
95
+ const registration = await lookUpRegistration(config, info.id);
96
+ // The id is derived from the directory path unless an editor file pins one,
97
+ // so it is stable across reinstalls (and identical on two machines with the
98
+ // same path). Naming the exact source heads off "why is this the same id I
99
+ // had before I deleted everything?".
100
+ const pinned = findPinnedProjectId(cwd());
101
+ const idSource = pinned?.id === info.id
102
+ ? `pinned in ${pinned.source}`
103
+ : 'derived from this directory path';
26
104
  console.log();
27
105
  console.log(chalk.dim(' Current project'));
28
106
  console.log(chalk.dim(' ├ Name: ') + info.name);
29
- console.log(chalk.dim(' └ ID: ') + info.id);
107
+ console.log(chalk.dim(' ├ ID: ') + info.id + chalk.dim(` (${idSource})`));
108
+ console.log(chalk.dim(' └ Memory: ') + describeRegistration(registration));
109
+ const hint = registrationHint(registration);
110
+ if (hint)
111
+ console.log(chalk.dim(' ') + hint);
30
112
  console.log();
31
- // Ping Perception for live stats + decision count for this project (helps spot silent Sensing)
32
113
  if (config.perceptionUrl) {
33
- try {
34
- const res = await fetch(`${config.perceptionUrl}/health`);
35
- if (res.ok) {
36
- console.log(chalk.dim(' Perception: ') + chalk.green('● connected'));
37
- }
38
- else {
39
- console.log(chalk.dim(' Perception: ') + chalk.yellow('○ unreachable'));
40
- }
41
- try {
42
- const pr = await fetch(`${config.perceptionUrl}/projects`, {
43
- headers: config.perceptionKey ? { Authorization: `Bearer ${config.perceptionKey}` } : {},
44
- });
45
- if (pr.ok) {
46
- const data = await pr.json();
47
- const row = data.projects?.find(p => p.id === info.id);
48
- const n = row?.decision_count;
49
- if (typeof n === 'number') {
50
- console.log(chalk.dim(' Decisions: ') + (n === 0 ? chalk.yellow(String(n)) : String(n)) + chalk.dim(` (active rows for project ${info.id})`));
51
- }
52
- }
53
- }
54
- catch { /* ignore count */ }
55
- }
56
- catch {
57
- console.log(chalk.dim(' Perception: ') + chalk.yellow('○ unreachable'));
58
- }
114
+ console.log(chalk.dim(' Perception: ') + (registration.reachable
115
+ ? chalk.green('● connected')
116
+ : chalk.yellow('○ unreachable')));
59
117
  }
60
118
  if (config.planningUrl) {
61
119
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=status.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.test.d.ts","sourceRoot":"","sources":["../../src/commands/status.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,201 @@
1
+ import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { createServer } from 'node:http';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { after, describe, it } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ // config.ts resolves homedir() at import time — pin a hermetic HOME before the
8
+ // dynamic imports, so the integration test below owns ~/.robrain/config.json.
9
+ const fakeHome = mkdtempSync(join(tmpdir(), 'robrain-status-'));
10
+ process.env.HOME = fakeHome;
11
+ process.env.FORCE_COLOR = '0';
12
+ mkdirSync(join(fakeHome, '.robrain'), { recursive: true });
13
+ const { lookUpRegistration, describeRegistration, registrationHint, statusCommand } = await import('./status.js');
14
+ const { deriveProjectId } = await import('../lib/project.js');
15
+ /**
16
+ * Stub Perception. `projects` is what GET /projects returns; `null` = 500,
17
+ * `'401'` = an authenticated store rejecting the key (health stays OK, as it
18
+ * is unauthenticated by design).
19
+ */
20
+ async function withStub(projects, run) {
21
+ const server = createServer((req, res) => {
22
+ res.setHeader('content-type', 'application/json');
23
+ if (req.url === '/health') {
24
+ res.end('{"status":"ok"}');
25
+ return;
26
+ }
27
+ if (req.url?.startsWith('/projects')) {
28
+ if (projects === '401') {
29
+ res.statusCode = 401;
30
+ res.end('{"error":"Unauthorized"}');
31
+ return;
32
+ }
33
+ if (projects === null) {
34
+ res.statusCode = 500;
35
+ res.end('{}');
36
+ return;
37
+ }
38
+ if (projects === 'bad-shape') {
39
+ res.end('{"data":{"items":[]}}');
40
+ return;
41
+ }
42
+ res.end(JSON.stringify({ projects }));
43
+ return;
44
+ }
45
+ res.statusCode = 404;
46
+ res.end('{}');
47
+ });
48
+ await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
49
+ server.unref();
50
+ const address = server.address();
51
+ assert.ok(address && typeof address === 'object');
52
+ try {
53
+ await run(`http://127.0.0.1:${address.port}`);
54
+ }
55
+ finally {
56
+ server.closeAllConnections();
57
+ await new Promise(resolve => server.close(() => resolve()));
58
+ }
59
+ }
60
+ const originalCwd = process.cwd();
61
+ after(() => {
62
+ process.chdir(originalCwd);
63
+ rmSync(fakeHome, { recursive: true, force: true });
64
+ });
65
+ describe('status — project registration lookup', () => {
66
+ it('reports a registered project with its decision count', async () => {
67
+ await withStub([{ id: 'abc123', decision_count: 12 }], async (baseUrl) => {
68
+ const reg = await lookUpRegistration({ perceptionUrl: baseUrl }, 'abc123');
69
+ assert.deepEqual(reg, { reachable: true, state: 'registered', decisions: 12 });
70
+ });
71
+ });
72
+ it('reports unregistered when this directory has no project row', async () => {
73
+ // Radu's case: a clean install, init-project skipped, `status` run in a
74
+ // directory whose id is only ever derived from the path.
75
+ await withStub([{ id: 'someone-else', decision_count: 3 }], async (baseUrl) => {
76
+ const reg = await lookUpRegistration({ perceptionUrl: baseUrl }, 'abc123');
77
+ assert.deepEqual(reg, { reachable: true, state: 'unregistered' });
78
+ });
79
+ });
80
+ it('says unknown — never "unregistered" — when the store cannot be reached', async () => {
81
+ // Claiming a project is missing because the API is down would send people
82
+ // off to re-init a project that already exists.
83
+ const reg = await lookUpRegistration({ perceptionUrl: 'http://127.0.0.1:1' }, 'abc123');
84
+ assert.equal(reg.state, 'unknown');
85
+ assert.equal(reg.reachable, false);
86
+ });
87
+ it('says unknown when the projects endpoint errors but health is fine', async () => {
88
+ await withStub(null, async (baseUrl) => {
89
+ const reg = await lookUpRegistration({ perceptionUrl: baseUrl }, 'abc123');
90
+ assert.deepEqual(reg, { reachable: true, state: 'unknown' });
91
+ });
92
+ });
93
+ it('says unknown — not unregistered — when the response shape is unexpected', async () => {
94
+ // Absence is only provable from a well-formed list. A differently-shaped
95
+ // response (e.g. a cloud API that answers another way) previously landed
96
+ // on `unregistered`, which tells a user with a live project to re-init it.
97
+ await withStub('bad-shape', async (baseUrl) => {
98
+ const reg = await lookUpRegistration({ perceptionUrl: baseUrl }, 'abc123');
99
+ assert.deepEqual(reg, { reachable: true, state: 'unknown' });
100
+ });
101
+ });
102
+ it('says unknown with no Perception configured at all', async () => {
103
+ const reg = await lookUpRegistration({}, 'abc123');
104
+ assert.deepEqual(reg, { reachable: false, state: 'unknown' });
105
+ });
106
+ });
107
+ describe('status — how registration reads', () => {
108
+ it('points an unregistered directory at init-project', () => {
109
+ const reg = { reachable: true, state: 'unregistered' };
110
+ assert.match(describeRegistration(reg), /not registered/);
111
+ assert.match(String(registrationHint(reg)), /npx robrain init-project/);
112
+ });
113
+ it('flags a registered project with zero decisions (the silent-Sensing tell)', () => {
114
+ const text = describeRegistration({ reachable: true, state: 'registered', decisions: 0 });
115
+ assert.match(text, /registered/);
116
+ assert.match(text, /0 decisions/);
117
+ });
118
+ it('never tells the user to init-project when the answer is unknown', () => {
119
+ const reg = { reachable: false, state: 'unknown' };
120
+ assert.match(describeRegistration(reg), /unknown/);
121
+ assert.equal(registrationHint(reg), null);
122
+ });
123
+ it('distinguishes a rejected API key from a store it could not reach', async () => {
124
+ await withStub('401', async (baseUrl) => {
125
+ const reg = await lookUpRegistration({ perceptionUrl: baseUrl, perceptionKey: 'wrong' }, 'abc123');
126
+ assert.deepEqual(reg, { reachable: true, state: 'auth_failed' });
127
+ assert.match(describeRegistration(reg), /rejected this API key/);
128
+ assert.match(String(registrationHint(reg)), /robrain install/);
129
+ // Must not read as "your project is gone".
130
+ assert.doesNotMatch(describeRegistration(reg), /not registered/);
131
+ });
132
+ });
133
+ });
134
+ /** Run statusCommand in `dir` with console captured. */
135
+ async function runStatus(dir) {
136
+ const lines = [];
137
+ const { log } = console;
138
+ console.log = (...args) => { lines.push(args.join(' ')); };
139
+ process.chdir(dir);
140
+ try {
141
+ await statusCommand();
142
+ }
143
+ finally {
144
+ console.log = log;
145
+ process.chdir(originalCwd);
146
+ }
147
+ return lines.join('\n');
148
+ }
149
+ describe('status — rendered output', () => {
150
+ it('reports a registered project with its count, and names the id source', async () => {
151
+ // realpath: on macOS mkdtemp hands back /var/... while cwd() reports the
152
+ // resolved /private/var/... — the id is a hash of the path, so it must be
153
+ // derived from the same string statusCommand will see.
154
+ const projectDir = realpathSync(mkdtempSync(join(tmpdir(), 'robrain-status-proj-')));
155
+ const id = deriveProjectId(projectDir);
156
+ await withStub([{ id, decision_count: 7 }], async (baseUrl) => {
157
+ writeFileSync(join(fakeHome, '.robrain', 'config.json'), JSON.stringify({
158
+ selfHosted: true, perceptionUrl: baseUrl, installedAt: '2026-07-25T00:00:00Z',
159
+ }));
160
+ const out = await runStatus(projectDir);
161
+ assert.match(out, new RegExp(`ID:\\s+${id}`));
162
+ assert.match(out, /derived from this directory path/);
163
+ assert.match(out, /Memory:\s+registered · 7 decisions/);
164
+ assert.doesNotMatch(out, /init-project/);
165
+ });
166
+ rmSync(projectDir, { recursive: true, force: true });
167
+ });
168
+ it('says a directory is not registered instead of implying membership', async () => {
169
+ // The report that prompted this: clean install, init-project skipped, and
170
+ // `status` still looked like the user was inside a live project.
171
+ const projectDir = mkdtempSync(join(tmpdir(), 'robrain-status-unreg-'));
172
+ await withStub([], async (baseUrl) => {
173
+ writeFileSync(join(fakeHome, '.robrain', 'config.json'), JSON.stringify({
174
+ selfHosted: true, perceptionUrl: baseUrl, installedAt: '2026-07-25T00:00:00Z',
175
+ }));
176
+ const out = await runStatus(projectDir);
177
+ assert.match(out, /Memory:\s+not registered/);
178
+ assert.match(out, /npx robrain init-project/);
179
+ assert.doesNotMatch(out, /registered ·/); // no decision count for a project that isn't there
180
+ });
181
+ rmSync(projectDir, { recursive: true, force: true });
182
+ });
183
+ it('names the exact editor file when one pins the id', async () => {
184
+ // init-project writes three files; the Cursor rule is the easy one to
185
+ // forget, so the hint must name whichever actually supplied the id.
186
+ const projectDir = mkdtempSync(join(tmpdir(), 'robrain-status-pinned-'));
187
+ mkdirSync(join(projectDir, '.cursor', 'rules'), { recursive: true });
188
+ writeFileSync(join(projectDir, '.cursor', 'rules', 'robrain.mdc'), '<!-- robrain -->\nsensing_start_session(project_id="pinned123abc")\n<!-- /robrain -->\n');
189
+ await withStub([], async (baseUrl) => {
190
+ writeFileSync(join(fakeHome, '.robrain', 'config.json'), JSON.stringify({
191
+ selfHosted: true, perceptionUrl: baseUrl, installedAt: '2026-07-25T00:00:00Z',
192
+ }));
193
+ const out = await runStatus(projectDir);
194
+ assert.match(out, /ID:\s+pinned123abc/);
195
+ assert.match(out, /pinned in \.cursor\/rules\/robrain\.mdc/);
196
+ assert.doesNotMatch(out, /derived from this directory path/);
197
+ });
198
+ rmSync(projectDir, { recursive: true, force: true });
199
+ });
200
+ });
201
+ //# sourceMappingURL=status.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.test.js","sourceRoot":"","sources":["../../src/commands/status.test.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ import { projectsListCommand, projectsMergeCommand } from './commands/projects.j
30
30
  import { upCommand, downCommand, DEFAULT_IMAGE_REPO } from './commands/up.js';
31
31
  import { mcpCommand } from './commands/mcp.js';
32
32
  import { installHermesPlugin, resolveHermesHome } from './lib/hermes-plugin.js';
33
- const VERSION = '2.4.7';
33
+ const VERSION = '2.4.8';
34
34
  program
35
35
  .name('robrain')
36
36
  .description('Institutional memory for AI coding agents — by Rory Plans')
@@ -4,6 +4,30 @@ export interface AuthResult {
4
4
  perceptionUrl?: string;
5
5
  planningUrl?: string;
6
6
  error?: string;
7
+ /** Account is fine, the plan is not — see PlanRequirement. */
8
+ planRequired?: PlanRequirement;
9
+ }
10
+ /** "Your login worked; your plan doesn't include RoBrain cloud." */
11
+ export interface PlanRequirement {
12
+ /** Plan the account is on today, when the API reports it (e.g. "free"). */
13
+ currentPlan?: string;
14
+ /** Minimum plan that includes RoBrain cloud. */
15
+ requiredPlan: string;
16
+ /** Only false when the API says the trial is used up or unavailable. */
17
+ trialAvailable: boolean;
18
+ }
19
+ /**
20
+ * Recognize an entitlement refusal across the shapes the API might use, so the
21
+ * CLI can say "upgrade" instead of "authentication failed" / "contact support":
22
+ * • 402 Payment Required (preferred), or
23
+ * • 401/403 carrying a plan error code, or a message naming plan/subscription/upgrade/trial.
24
+ * Deliberately narrow on 401/403 — a plain bad token must stay an auth error.
25
+ */
26
+ export declare function detectPlanRequirement(status: number, body: unknown): PlanRequirement | null;
27
+ /** Outcome of provisioning: config, an entitlement refusal, or an opaque failure. */
28
+ export interface ProvisionResult {
29
+ config?: ProvisionedConfig;
30
+ planRequired?: PlanRequirement;
7
31
  }
8
32
  export interface ProvisionedConfig {
9
33
  perceptionUrl: string;
@@ -14,8 +38,12 @@ export interface ProvisionedConfig {
14
38
  }
15
39
  /** Validate a Rory Plans token and return account info */
16
40
  export declare function validateToken(token: string): Promise<AuthResult>;
17
- /** Fetch provisioned API config for this token */
18
- export declare function fetchProvisionedConfig(token: string): Promise<ProvisionedConfig | null>;
41
+ /**
42
+ * Fetch provisioned API config for this token. An account on a plan without
43
+ * RoBrain cloud lands here (the token is valid — there is just nothing to
44
+ * provision), so entitlement is reported rather than folded into a failure.
45
+ */
46
+ export declare function fetchProvisionedConfig(token: string): Promise<ProvisionResult>;
19
47
  /** Register a new project with Rory Plans */
20
48
  export declare function registerProject(token: string, projectId: string, projectName: string): Promise<boolean>;
21
49
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAa,OAAO,CAAA;IACtB,KAAK,CAAC,EAAS,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAG,MAAM,CAAA;IACrB,KAAK,CAAC,EAAS,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAI,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAI,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED,0DAA0D;AAC1D,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoCtE;AAED,kDAAkD;AAClD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAc7F;AAED,6CAA6C;AAC7C,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAclB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAa,OAAO,CAAA;IACtB,KAAK,CAAC,EAAS,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAG,MAAM,CAAA;IACrB,KAAK,CAAC,EAAS,MAAM,CAAA;IACrB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,eAAe,CAAA;CAC/B;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,WAAW,CAAC,EAAI,MAAM,CAAA;IACtB,gDAAgD;IAChD,YAAY,EAAI,MAAM,CAAA;IACtB,wEAAwE;IACxE,cAAc,EAAE,OAAO,CAAA;CACxB;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAoB3F;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAQ,iBAAiB,CAAA;IAChC,YAAY,CAAC,EAAE,eAAe,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAI,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAI,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED,0DAA0D;AAC1D,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsCtE;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAkBpF;AAED,6CAA6C;AAC7C,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAclB"}
package/dist/lib/auth.js CHANGED
@@ -5,6 +5,36 @@
5
5
  // Perception/Planning API URLs for this account.
6
6
  // ─────────────────────────────────────────────────────────────
7
7
  import { RORY_API_BASE } from './config.js';
8
+ const PLAN_ERROR_CODES = new Set([
9
+ 'plan_required', 'upgrade_required', 'subscription_required', 'payment_required',
10
+ ]);
11
+ /**
12
+ * Recognize an entitlement refusal across the shapes the API might use, so the
13
+ * CLI can say "upgrade" instead of "authentication failed" / "contact support":
14
+ * • 402 Payment Required (preferred), or
15
+ * • 401/403 carrying a plan error code, or a message naming plan/subscription/upgrade/trial.
16
+ * Deliberately narrow on 401/403 — a plain bad token must stay an auth error.
17
+ */
18
+ export function detectPlanRequirement(status, body) {
19
+ const b = (body ?? {});
20
+ const code = String(b.code ?? b.error ?? '').toLowerCase();
21
+ const text = String(b.message ?? b.error ?? '').toLowerCase();
22
+ const hasPlanCode = PLAN_ERROR_CODES.has(code);
23
+ const hasPlanText = /\b(plan|subscription|upgrade|trial|billing)\b/.test(text);
24
+ const hasPlanFields = typeof b.required_plan === 'string' ||
25
+ typeof b.plan === 'string' ||
26
+ typeof b.trial_available === 'boolean';
27
+ const looksLikePlan = hasPlanCode ||
28
+ ((status === 401 || status === 403 || status === 402) && hasPlanText) ||
29
+ (status === 402 && hasPlanFields);
30
+ if (!looksLikePlan)
31
+ return null;
32
+ return {
33
+ currentPlan: typeof b.plan === 'string' ? b.plan : undefined,
34
+ requiredPlan: typeof b.required_plan === 'string' ? b.required_plan : 'Pro',
35
+ trialAvailable: b.trial_available !== false,
36
+ };
37
+ }
8
38
  /** Validate a Rory Plans token and return account info */
9
39
  export async function validateToken(token) {
10
40
  try {
@@ -17,6 +47,9 @@ export async function validateToken(token) {
17
47
  });
18
48
  if (!res.ok) {
19
49
  const body = await res.json().catch(() => ({}));
50
+ const planRequired = detectPlanRequirement(res.status, body);
51
+ if (planRequired)
52
+ return { ok: false, planRequired };
20
53
  return {
21
54
  ok: false,
22
55
  error: body.error ?? `Authentication failed (${res.status})`,
@@ -37,20 +70,27 @@ export async function validateToken(token) {
37
70
  };
38
71
  }
39
72
  }
40
- /** Fetch provisioned API config for this token */
73
+ /**
74
+ * Fetch provisioned API config for this token. An account on a plan without
75
+ * RoBrain cloud lands here (the token is valid — there is just nothing to
76
+ * provision), so entitlement is reported rather than folded into a failure.
77
+ */
41
78
  export async function fetchProvisionedConfig(token) {
42
79
  try {
43
80
  const res = await fetch(`${RORY_API_BASE}/robrain/provision`, {
44
81
  method: 'GET',
45
82
  headers: { 'Authorization': `Bearer ${token}` },
46
83
  });
47
- if (!res.ok)
48
- return null;
84
+ if (!res.ok) {
85
+ const body = await res.json().catch(() => ({}));
86
+ const planRequired = detectPlanRequirement(res.status, body);
87
+ return planRequired ? { planRequired } : {};
88
+ }
49
89
  const data = await res.json();
50
- return data;
90
+ return { config: data };
51
91
  }
52
92
  catch {
53
- return null;
93
+ return {};
54
94
  }
55
95
  }
56
96
  /** Register a new project with Rory Plans */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,gEAAgE;AAChE,iDAAiD;AACjD,6DAA6D;AAC7D,iDAAiD;AACjD,gEAAgE;AAEhE,OAAO,EAAE,aAAa,EAAuB,MAAM,aAAa,CAAA;AAkBhE,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,wBAAwB,EAAE;YAChE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,KAAK,EAAE;gBAClC,cAAc,EAAG,kBAAkB;aACpC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAuB,CAAA;YACrE,OAAO;gBACL,EAAE,EAAK,KAAK;gBACZ,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,0BAA0B,GAAG,CAAC,MAAM,GAAG;aAC7D,CAAA;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAI1B,CAAA;QAED,OAAO;YACL,EAAE,EAAa,IAAI;YACnB,KAAK,EAAU,IAAI,CAAC,KAAK;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,WAAW,EAAI,IAAI,CAAC,WAAW;SAChC,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAK,KAAK;YACZ,KAAK,EAAE,+DAA+D;SACvE,CAAA;IACH,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAAa;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,oBAAoB,EAAE;YAC5D,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,KAAK,EAAE,EAAE;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QAExB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAuB,CAAA;QAClD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,SAAiB,EACjB,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,mBAAmB,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,KAAK,EAAE;gBAClC,cAAc,EAAG,kBAAkB;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SACnE,CAAC,CAAA;QACF,OAAO,GAAG,CAAC,EAAE,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.test.d.ts","sourceRoot":"","sources":["../../src/lib/auth.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { detectPlanRequirement } from './auth.js';
4
+ describe('detectPlanRequirement — entitlement vs. everything else', () => {
5
+ it('reads 402 Payment Required as a plan problem', () => {
6
+ const req = detectPlanRequirement(402, { error: 'plan_required', plan: 'free', required_plan: 'Pro' });
7
+ assert.deepEqual(req, { currentPlan: 'free', requiredPlan: 'Pro', trialAvailable: true });
8
+ });
9
+ it('does not misclassify ambiguous 402 errors as plan-required', () => {
10
+ assert.equal(detectPlanRequirement(402, { error: 'Payment Required' }), null);
11
+ assert.equal(detectPlanRequirement(402, {}), null);
12
+ });
13
+ it('reads a 403 carrying a plan error code', () => {
14
+ const req = detectPlanRequirement(403, { code: 'upgrade_required' });
15
+ assert.ok(req);
16
+ assert.equal(req.requiredPlan, 'Pro'); // default when the API does not name one
17
+ });
18
+ it('reads a 403 whose message names the plan, without a code', () => {
19
+ const req = detectPlanRequirement(403, { error: 'Your subscription does not include RoBrain' });
20
+ assert.ok(req);
21
+ });
22
+ it('leaves a plain bad token as an auth error', () => {
23
+ // The failure mode to avoid in both directions: a mistyped token must not
24
+ // be answered with "upgrade your plan".
25
+ assert.equal(detectPlanRequirement(401, { error: 'Invalid token' }), null);
26
+ assert.equal(detectPlanRequirement(401, {}), null);
27
+ assert.equal(detectPlanRequirement(403, { error: 'Forbidden' }), null);
28
+ });
29
+ it('leaves server and network failures alone', () => {
30
+ assert.equal(detectPlanRequirement(500, { error: 'Internal error' }), null);
31
+ assert.equal(detectPlanRequirement(404, {}), null);
32
+ assert.equal(detectPlanRequirement(502, undefined), null);
33
+ });
34
+ it('honours an exhausted trial, and assumes one is available otherwise', () => {
35
+ // Offering "start your free trial" to someone who already used theirs is
36
+ // the one line here that can be actively wrong.
37
+ assert.equal(detectPlanRequirement(402, { error: 'plan_required', trial_available: false })?.trialAvailable, false);
38
+ assert.equal(detectPlanRequirement(402, { error: 'plan_required' })?.trialAvailable, true);
39
+ });
40
+ it('passes through the plan names the API reports', () => {
41
+ const req = detectPlanRequirement(402, { error: 'plan_required', plan: 'free', required_plan: 'Teams' });
42
+ assert.equal(req?.currentPlan, 'free');
43
+ assert.equal(req?.requiredPlan, 'Teams');
44
+ });
45
+ });
46
+ //# sourceMappingURL=auth.test.js.map