@nepopsx/cli 0.0.22 → 0.0.24

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 (54) hide show
  1. package/dist/commands/init.js +1 -1
  2. package/dist/commands/init.js.map +1 -1
  3. package/dist/commands/install.d.ts.map +1 -1
  4. package/dist/commands/install.js +15 -8
  5. package/dist/commands/install.js.map +1 -1
  6. package/dist/commands/login.d.ts +3 -3
  7. package/dist/commands/login.d.ts.map +1 -1
  8. package/dist/commands/login.js +14 -36
  9. package/dist/commands/login.js.map +1 -1
  10. package/dist/commands/sync.d.ts.map +1 -1
  11. package/dist/commands/sync.js +11 -4
  12. package/dist/commands/sync.js.map +1 -1
  13. package/dist/config/api-config.d.ts +9 -0
  14. package/dist/config/api-config.d.ts.map +1 -1
  15. package/dist/config/api-config.js +10 -1
  16. package/dist/config/api-config.js.map +1 -1
  17. package/dist/index.js +0 -6
  18. package/dist/index.js.map +1 -1
  19. package/dist/licensing/entitlement-cache.d.ts +25 -0
  20. package/dist/licensing/entitlement-cache.d.ts.map +1 -0
  21. package/dist/licensing/entitlement-cache.js +42 -0
  22. package/dist/licensing/entitlement-cache.js.map +1 -0
  23. package/dist/licensing/index.d.ts +2 -1
  24. package/dist/licensing/index.d.ts.map +1 -1
  25. package/dist/licensing/index.js +2 -1
  26. package/dist/licensing/index.js.map +1 -1
  27. package/dist/licensing/installer.d.ts +7 -8
  28. package/dist/licensing/installer.d.ts.map +1 -1
  29. package/dist/licensing/installer.js +9 -17
  30. package/dist/licensing/installer.js.map +1 -1
  31. package/dist/licensing/license-manager.d.ts +26 -41
  32. package/dist/licensing/license-manager.d.ts.map +1 -1
  33. package/dist/licensing/license-manager.js +67 -257
  34. package/dist/licensing/license-manager.js.map +1 -1
  35. package/dist/licensing/template-fetch.d.ts.map +1 -1
  36. package/dist/licensing/template-fetch.js +4 -0
  37. package/dist/licensing/template-fetch.js.map +1 -1
  38. package/dist/mcp/config-generator.d.ts +6 -6
  39. package/dist/mcp/config-generator.d.ts.map +1 -1
  40. package/dist/mcp/config-generator.js +4 -4
  41. package/dist/mcp/config-generator.js.map +1 -1
  42. package/dist/utils/disk-cache.d.ts +14 -0
  43. package/dist/utils/disk-cache.d.ts.map +1 -0
  44. package/dist/utils/disk-cache.js +53 -0
  45. package/dist/utils/disk-cache.js.map +1 -0
  46. package/dist/utils/fetch-plan-manifest.d.ts +20 -0
  47. package/dist/utils/fetch-plan-manifest.d.ts.map +1 -0
  48. package/dist/utils/fetch-plan-manifest.js +93 -0
  49. package/dist/utils/fetch-plan-manifest.js.map +1 -0
  50. package/dist/utils/handle-402.d.ts +17 -0
  51. package/dist/utils/handle-402.d.ts.map +1 -0
  52. package/dist/utils/handle-402.js +31 -0
  53. package/dist/utils/handle-402.js.map +1 -0
  54. package/package.json +2 -2
@@ -1,132 +1,54 @@
1
1
  /**
2
- * License manager handles license activation, validation,
3
- * online refresh, and tier-based feature gating.
2
+ * Auth/session helpers. Post-migration the CLI has ONE credential: the opaque
3
+ * device token from `nepopsx login`, stored in `.nepopsx/config.json`. The
4
+ * `License` shape is kept as a thin compatibility view — `.key` IS the device
5
+ * token — so existing commands send the right Bearer credential unchanged. Auth
6
+ * and entitlement are server-authoritative now (the backend 401/402s); there is
7
+ * no license.json, no machine binding, and no online validate/refresh.
4
8
  */
5
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
6
- import { join } from 'node:path';
7
- import { TIER_LIMITS, generateMachineId, generateFingerprint, checkExpiry, } from '@nepopsx/core';
8
- import { resolveApiBase } from '../config/api-config.js';
9
- import { fetchWithTimeout } from '../utils/fetch.js';
10
- import { API_TIMEOUT_MS } from '../constants.js';
9
+ import { TIER_LIMITS, generateMachineId, generateFingerprint, } from '@nepopsx/core';
10
+ import { readLocalConfig } from '../config/api-config.js';
11
+ import { fetchPlanManifest } from '../utils/fetch-plan-manifest.js';
11
12
  import { readWorkspaceNameFromDisk } from './workspace-name.js';
12
- const LICENSE_DIR = '.nepopsx';
13
- const LICENSE_FILE = 'license.json';
14
- // ─── License file operations ────────────────────────────────
13
+ import { getCachedEntitlement } from './entitlement-cache.js';
14
+ // ─── Session (device token) ─────────────────────────────────
15
15
  /**
16
- * Read the local license file. Returns null if not found or invalid.
16
+ * Build a `License`-shaped view from the stored device token. `.key` IS the opaque
17
+ * `opsx_dvc_…` token sent as a Bearer credential; `org`/`tier` come from the plan
18
+ * captured at login; `workspace` is the live local name. Returns null if not
19
+ * logged in. (No license.json — the device token in config.json is the credential.)
17
20
  */
18
21
  export function readLicense(rootDir) {
19
- const licensePath = join(rootDir, LICENSE_DIR, LICENSE_FILE);
20
- if (!existsSync(licensePath))
22
+ const auth = readLocalConfig(rootDir).auth;
23
+ if (!auth?.token)
21
24
  return null;
22
- try {
23
- const raw = readFileSync(licensePath, 'utf-8');
24
- const data = JSON.parse(raw);
25
- // Basic shape validation
26
- if (!data.key || !data.org || !data.tier || !data.valid_until || !data.machine_id) {
27
- return null;
28
- }
29
- return data;
30
- }
31
- catch {
32
- return null;
33
- }
25
+ return {
26
+ key: auth.token,
27
+ org: auth.org ?? '',
28
+ tier: auth.plan ?? 'free',
29
+ valid_until: '',
30
+ refresh_token: '',
31
+ machine_id: generateMachineId(),
32
+ workspace: readWorkspaceNameFromDisk(rootDir) ?? 'unknown',
33
+ activated_at: '',
34
+ last_refreshed: '',
35
+ };
34
36
  }
35
- /**
36
- * Write license to disk. Creates .nepopsx/ if needed.
37
- */
38
- export function writeLicense(rootDir, license) {
39
- const dir = join(rootDir, LICENSE_DIR);
40
- if (!existsSync(dir)) {
41
- mkdirSync(dir, { recursive: true });
42
- }
43
- writeFileSync(join(dir, LICENSE_FILE), JSON.stringify(license, null, 2) + '\n', 'utf-8');
37
+ /** No-op: the workspace is sourced live from disk in `readLicense` now. */
38
+ export function reconcileLicenseWorkspace(_rootDir, license) {
39
+ return license;
44
40
  }
45
- /**
46
- * Heal the license's `workspace` field against the live `workspace.yaml`.
47
- *
48
- * The license is activated before `workspace.yaml` exists, so it is born with
49
- * `workspace: "unknown"`. Once the real config exists, reconcile the in-memory
50
- * license (and persist it) so every downstream `license.workspace` read — and
51
- * every backend call derived from it — uses the live workspace name instead of
52
- * the stale snapshot. Best-effort: returns the license unchanged when the config
53
- * is absent or already matches. Accepts/returns `null` for the no-license path.
54
- */
55
- export function reconcileLicenseWorkspace(rootDir, license) {
56
- if (!license)
57
- return license;
58
- const liveName = readWorkspaceNameFromDisk(rootDir);
59
- if (!liveName || liveName === license.workspace)
60
- return license;
61
- const reconciled = { ...license, workspace: liveName };
62
- try {
63
- writeLicense(rootDir, reconciled);
64
- }
65
- catch {
66
- // Persisting is best-effort — the in-memory heal is what callers rely on.
67
- }
68
- return reconciled;
41
+ /** No-op kept for callers: there is no license.json to write any more. */
42
+ export function writeLicense(_rootDir, _license) {
43
+ /* the device token is written to config.json by `nepopsx login` */
69
44
  }
45
+ // ─── Validation (local, advisory) ───────────────────────────
70
46
  /**
71
- * Activate a license key for this machine + workspace.
72
- * Calls the remote API to validate the key and bind it.
47
+ * Confirm a device token is present. Auth + entitlement are enforced by the
48
+ * backend (401/402) this no longer calls the server.
73
49
  */
74
- export async function activateLicense(rootDir, licenseKey, workspaceName) {
75
- const machineId = generateMachineId();
76
- const apiBase = resolveApiBase(rootDir);
77
- try {
78
- const response = await fetchWithTimeout(`${apiBase}/license/activate`, {
79
- method: 'POST',
80
- headers: { 'Content-Type': 'application/json' },
81
- body: JSON.stringify({
82
- key: licenseKey,
83
- machine_id: machineId,
84
- workspace: workspaceName,
85
- }),
86
- }, API_TIMEOUT_MS);
87
- if (!response.ok) {
88
- const body = await response.text();
89
- return {
90
- success: false,
91
- error: `Activation failed (${response.status}): ${body}`,
92
- };
93
- }
94
- const data = await response.json();
95
- const license = {
96
- key: licenseKey,
97
- org: data.org,
98
- tier: data.tier,
99
- valid_until: data.valid_until,
100
- refresh_token: data.refresh_token,
101
- machine_id: machineId,
102
- workspace: workspaceName,
103
- activated_at: new Date().toISOString(),
104
- last_refreshed: new Date().toISOString(),
105
- };
106
- writeLicense(rootDir, license);
107
- return { success: true, license };
108
- }
109
- catch (err) {
110
- // Network failure — might be offline
111
- return {
112
- success: false,
113
- error: `Cannot reach NEPOPSX API: ${err instanceof Error ? err.message : String(err)}. Check your internet connection.`,
114
- };
115
- }
116
- }
117
- // ─── Validation ─────────────────────────────────────────────
118
- /**
119
- * Validate the current license. Attempts online refresh if expired.
120
- * Returns detailed status.
121
- */
122
- export async function validateLicense(rootDir, config) {
123
- // Heal a stale `workspace: "unknown"` against the live config before any
124
- // backend call uses it. validateLicense always runs with a loaded config, so
125
- // this self-heals license.json and every later readLicense() returns the
126
- // correct workspace.
127
- const license = reconcileLicenseWorkspace(rootDir, readLicense(rootDir));
128
- const apiBase = resolveApiBase(rootDir);
129
- // No license file
50
+ export async function validateLicense(rootDir, _config) {
51
+ const license = readLicense(rootDir);
130
52
  if (!license) {
131
53
  return {
132
54
  valid: false,
@@ -135,156 +57,48 @@ export async function validateLicense(rootDir, config) {
135
57
  tier: 'free',
136
58
  org: '',
137
59
  fingerprint: '',
138
- message: 'No license found. Run `nepopsx activate <key>` to activate.',
139
- };
140
- }
141
- // Machine binding check
142
- const currentMachineId = generateMachineId();
143
- if (license.machine_id !== currentMachineId) {
144
- return {
145
- valid: false,
146
- expired: false,
147
- days_remaining: 0,
148
- tier: license.tier,
149
- org: license.org,
150
- fingerprint: '',
151
- message: 'License is bound to a different machine. Run `nepopsx activate <key>` to re-activate.',
152
- };
153
- }
154
- const { expired, daysRemaining } = checkExpiry(license.valid_until);
155
- const fingerprint = generateFingerprint(license.org, license.key, license.workspace);
156
- // Still valid — return immediately
157
- if (!expired) {
158
- try {
159
- const response = await fetchWithTimeout(`${apiBase}/license/validate`, {
160
- method: 'POST',
161
- headers: { 'Content-Type': 'application/json' },
162
- body: JSON.stringify({
163
- key: license.key,
164
- machine_id: license.machine_id,
165
- workspace: license.workspace,
166
- }),
167
- }, API_TIMEOUT_MS);
168
- if (response.ok) {
169
- const data = await response.json();
170
- if (data.valid) {
171
- const updatedLicense = {
172
- ...license,
173
- org: data.org,
174
- tier: data.tier,
175
- valid_until: data.valid_until,
176
- last_refreshed: new Date().toISOString(),
177
- };
178
- writeLicense(rootDir, updatedLicense);
179
- const onlineExpiry = checkExpiry(updatedLicense.valid_until);
180
- return {
181
- valid: true,
182
- expired: false,
183
- days_remaining: onlineExpiry.daysRemaining,
184
- tier: updatedLicense.tier,
185
- org: updatedLicense.org,
186
- fingerprint,
187
- message: data.message,
188
- };
189
- }
190
- return {
191
- valid: false,
192
- expired: false,
193
- days_remaining: daysRemaining,
194
- tier: license.tier,
195
- org: license.org,
196
- fingerprint,
197
- message: data.message,
198
- };
199
- }
200
- }
201
- catch {
202
- // Fall back to local validation when offline or backend is unavailable.
203
- }
204
- return {
205
- valid: true,
206
- expired: false,
207
- days_remaining: daysRemaining,
208
- tier: license.tier,
209
- org: license.org,
210
- fingerprint,
211
- message: daysRemaining <= 7
212
- ? `License expires in ${daysRemaining} day(s). Renew at nepopsx.dev.`
213
- : `Licensed to ${license.org} (${license.tier}).`,
60
+ message: 'Not logged in. Run `nepopsx login` to authorize this machine.',
214
61
  };
215
62
  }
216
- // Expired — attempt online refresh
217
- const refreshed = await refreshLicense(rootDir, license);
218
- if (refreshed) {
219
- const newExpiry = checkExpiry(refreshed.valid_until);
220
- return {
221
- valid: true,
222
- expired: false,
223
- days_remaining: newExpiry.daysRemaining,
224
- tier: refreshed.tier,
225
- org: refreshed.org,
226
- fingerprint,
227
- message: `License refreshed. Valid until ${refreshed.valid_until}.`,
228
- };
229
- }
230
- // Refresh failed — license is truly expired
231
63
  return {
232
- valid: false,
233
- expired: true,
234
- days_remaining: daysRemaining,
64
+ valid: true,
65
+ expired: false,
66
+ days_remaining: 365,
235
67
  tier: license.tier,
236
68
  org: license.org,
237
- fingerprint,
238
- message: `License expired on ${license.valid_until}. Renew at nepopsx.dev or run \`nepopsx activate <key>\`.`,
69
+ fingerprint: generateFingerprint(license.org, license.key, license.workspace),
70
+ message: `Logged in to ${license.org || 'your org'} (${license.tier}).`,
239
71
  };
240
72
  }
241
- // ─── Refresh ────────────────────────────────────────────────
73
+ // ─── Resolved entitlement (display / advisory) ──────────────
242
74
  /**
243
- * Attempt to refresh the license via the remote API.
244
- * Returns updated license on success, null on failure.
75
+ * Resolve the org's entitlement for DISPLAY: cache → synthesized from the plan
76
+ * manifest + the session's plan. Advisory only — the backend's 402s are the hard
77
+ * authority. Never throws.
245
78
  */
246
- async function refreshLicense(rootDir, license) {
247
- const apiBase = resolveApiBase(rootDir);
248
- try {
249
- const response = await fetchWithTimeout(`${apiBase}/license/refresh`, {
250
- method: 'POST',
251
- headers: { 'Content-Type': 'application/json' },
252
- body: JSON.stringify({
253
- refresh_token: license.refresh_token,
254
- machine_id: license.machine_id,
255
- }),
256
- }, API_TIMEOUT_MS);
257
- if (!response.ok)
258
- return null;
259
- const data = await response.json();
260
- const updated = {
261
- ...license,
262
- tier: data.tier,
263
- valid_until: data.valid_until,
264
- refresh_token: data.refresh_token,
265
- last_refreshed: new Date().toISOString(),
266
- };
267
- writeLicense(rootDir, updated);
268
- return updated;
269
- }
270
- catch {
271
- // Network failure — can't refresh
272
- return null;
273
- }
79
+ export async function resolveEntitlement(rootDir, license) {
80
+ const cached = getCachedEntitlement(rootDir, license.key);
81
+ if (cached)
82
+ return cached;
83
+ const manifest = await fetchPlanManifest(rootDir);
84
+ const spec = manifest.plans.find((p) => p.id === license.tier) ?? manifest.plans[0];
85
+ return {
86
+ tier: license.tier,
87
+ status: license.tier === 'free' ? 'free' : 'active',
88
+ limits: spec.limits,
89
+ features: spec.features,
90
+ validUntil: null,
91
+ trialEndsAt: null,
92
+ };
274
93
  }
275
94
  /**
276
- /**
277
- * Check if the workspace config exceeds the license tier's limits.
278
- *
279
- * Only scale limits are enforced here — agent quality (customs, philosophy,
280
- * prompts) is identical across all tiers. The differentiators are:
281
- * - how many services / agent packages are allowed
282
- * - access to LLM-powered scan (team+)
95
+ * Check whether the workspace config exceeds the tier's scale limits.
96
+ * **Advisory only** the server is the enforcement authority (402). Surface as a
97
+ * warning + upgrade hint and proceed; never hard-block on this result.
283
98
  */
284
99
  export function enforceTierLimits(config, tier) {
285
100
  const limits = TIER_LIMITS[tier];
286
101
  const violations = [];
287
- // Service count
288
102
  if (config.services.length > limits.max_services) {
289
103
  violations.push({
290
104
  feature: 'services',
@@ -293,7 +107,6 @@ export function enforceTierLimits(config, tier) {
293
107
  required_tier: tier === 'free' ? 'team' : 'enterprise',
294
108
  });
295
109
  }
296
- // Agent count
297
110
  if (config.agents) {
298
111
  const enabledAgents = Object.values(config.agents).filter((a) => a.enabled).length;
299
112
  if (enabledAgents > limits.max_agents) {
@@ -308,10 +121,7 @@ export function enforceTierLimits(config, tier) {
308
121
  return violations;
309
122
  }
310
123
  // ─── Dev mode bypass ────────────────────────────────────────
311
- /**
312
- * Check if the CLI is running in dev mode (for NEPOPSX agent developers).
313
- * Set NEPOPSX_DEV=1 to bypass license checks.
314
- */
124
+ /** Set NEPOPSX_DEV=1 to bypass auth checks (for NEPOPSX agent developers). */
315
125
  export function isDevMode() {
316
126
  return process.env.NEPOPSX_DEV === '1';
317
127
  }
@@ -1 +1 @@
1
- {"version":3,"file":"license-manager.js","sourceRoot":"","sources":["../../src/licensing/license-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"license-manager.js","sourceRoot":"","sources":["../../src/licensing/license-manager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"template-fetch.d.ts","sourceRoot":"","sources":["../../src/licensing/template-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAM7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,sDAAsD;IACtD,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC5B;AAMD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,kBAAkB,GAAE,iBAAiB,EAAO,EAC5C,SAAS,GAAE,cAAc,EAAO,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAyChC"}
1
+ {"version":3,"file":"template-fetch.d.ts","sourceRoot":"","sources":["../../src/licensing/template-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAO7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,sDAAsD;IACtD,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC5B;AAMD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,kBAAkB,GAAE,iBAAiB,EAAO,EAC5C,SAAS,GAAE,cAAc,EAAO,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4ChC"}
@@ -14,6 +14,7 @@ import { resolveApiBase } from '../config/api-config.js';
14
14
  import { fetchWithTimeout } from '../utils/fetch.js';
15
15
  import { decryptBundle as decryptBundleRaw } from './installer.js';
16
16
  import { DOWNLOAD_TIMEOUT_MS } from '../constants.js';
17
+ import { reportIfPaymentRequired } from '../utils/handle-402.js';
17
18
  import { resolveWorkspaceName } from './workspace-name.js';
18
19
  // EncryptedBundle is imported from installer.ts
19
20
  // ─── Public API ─────────────────────────────────────────────
@@ -42,6 +43,9 @@ export async function fetchRemoteTemplates(rootDir, license, agentName, agentVer
42
43
  }),
43
44
  }, DOWNLOAD_TIMEOUT_MS);
44
45
  if (!response.ok) {
46
+ // Surface a plan gate (402) as an upgrade prompt instead of silently using local
47
+ // fallback; any other error falls through to the local-template path.
48
+ await reportIfPaymentRequired(response);
45
49
  return null;
46
50
  }
47
51
  const encrypted = await response.json();
@@ -1 +1 @@
1
- {"version":3,"file":"template-fetch.js","sourceRoot":"","sources":["../../src/licensing/template-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAwB,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAgB3D,gDAAgD;AAEhD,+DAA+D;AAE/D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe,EACf,OAAgB,EAChB,SAAiB,EACjB,YAAoB,EACpB,qBAA0C,EAAE,EAC5C,YAA8B,EAAE;IAEhC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CACrC,GAAG,OAAO,cAAc,SAAS,IAAI,YAAY,EAAE,EACnD;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,OAAO,CAAC,GAAG,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,SAAS,EAAE,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC;gBACjD,mBAAmB,EAAE,kBAAkB;gBACvC,wEAAwE;gBACxE,+DAA+D;gBAC/D,SAAS;aACV,CAAC;SACH,EACD,mBAAmB,CACpB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAqB,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAA2B,CAAC;QAEjG,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,YAAY;YACrB,SAAS;YACT,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+DAA+D;AAE/D,8CAA8C;AAE9C,+DAA+D;AAE/D,0DAA0D"}
1
+ {"version":3,"file":"template-fetch.js","sourceRoot":"","sources":["../../src/licensing/template-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAwB,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAgB3D,gDAAgD;AAEhD,+DAA+D;AAE/D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe,EACf,OAAgB,EAChB,SAAiB,EACjB,YAAoB,EACpB,qBAA0C,EAAE,EAC5C,YAA8B,EAAE;IAEhC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CACrC,GAAG,OAAO,cAAc,SAAS,IAAI,YAAY,EAAE,EACnD;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,OAAO,CAAC,GAAG,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,SAAS,EAAE,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC;gBACjD,mBAAmB,EAAE,kBAAkB;gBACvC,wEAAwE;gBACxE,+DAA+D;gBAC/D,SAAS;aACV,CAAC;SACH,EACD,mBAAmB,CACpB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,iFAAiF;YACjF,sEAAsE;YACtE,MAAM,uBAAuB,CAAC,QAAQ,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAqB,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAA2B,CAAC;QAEjG,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,YAAY;YACrB,SAAS;YACT,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+DAA+D;AAE/D,8CAA8C;AAE9C,+DAA+D;AAE/D,0DAA0D"}
@@ -4,12 +4,12 @@
4
4
  * `learning_search` / `learning_store` for governed team recall.
5
5
  *
6
6
  * Claude Code's remote HTTP MCP form is `{ type: "http", url, headers }`, and it
7
- * expands `${VAR}` in the config — so we embed the license key as an env
8
- * placeholder (`${NEPOPSX_LICENSE_KEY}`) rather than the raw secret, keeping the
9
- * committed `.mcp.json` shareable across the team without leaking the key.
7
+ * expands `${VAR}` in the config — so we embed the device token as an env
8
+ * placeholder (`${NEPOPSX_DEVICE_TOKEN}`) rather than the raw secret, keeping the
9
+ * committed `.mcp.json` shareable across the team without leaking the token.
10
10
  */
11
11
  export declare const MEMORY_SERVER_NAME = "nepopsx-memory";
12
- export declare const LICENSE_ENV_VAR = "NEPOPSX_LICENSE_KEY";
12
+ export declare const LICENSE_ENV_VAR = "NEPOPSX_DEVICE_TOKEN";
13
13
  export interface McpHttpServer {
14
14
  type: 'http';
15
15
  url: string;
@@ -23,9 +23,9 @@ export interface McpSetupOptions {
23
23
  rootDir: string;
24
24
  /** Backend API base, including `/v1` (e.g. http://localhost:3100/v1). */
25
25
  apiUrl: string;
26
- /** Raw license key — only embedded when `inlineKey` is true (dev convenience). */
26
+ /** Raw device token — only embedded when `inlineKey` is true (dev convenience). */
27
27
  licenseKey?: string;
28
- /** Embed the raw key instead of the `${NEPOPSX_LICENSE_KEY}` placeholder. */
28
+ /** Embed the raw token instead of the `${NEPOPSX_DEVICE_TOKEN}` placeholder. */
29
29
  inlineKey?: boolean;
30
30
  }
31
31
  /** Build the `nepopsx-memory` HTTP server entry for `.mcp.json`. */
@@ -1 +1 @@
1
- {"version":3,"file":"config-generator.d.ts","sourceRoot":"","sources":["../../src/mcp/config-generator.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AACnD,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,aAAa,CAWf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CA4BpE"}
1
+ {"version":3,"file":"config-generator.d.ts","sourceRoot":"","sources":["../../src/mcp/config-generator.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AACnD,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,aAAa,CAWf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CA4BpE"}
@@ -6,12 +6,12 @@ import { join } from 'node:path';
6
6
  * `learning_search` / `learning_store` for governed team recall.
7
7
  *
8
8
  * Claude Code's remote HTTP MCP form is `{ type: "http", url, headers }`, and it
9
- * expands `${VAR}` in the config — so we embed the license key as an env
10
- * placeholder (`${NEPOPSX_LICENSE_KEY}`) rather than the raw secret, keeping the
11
- * committed `.mcp.json` shareable across the team without leaking the key.
9
+ * expands `${VAR}` in the config — so we embed the device token as an env
10
+ * placeholder (`${NEPOPSX_DEVICE_TOKEN}`) rather than the raw secret, keeping the
11
+ * committed `.mcp.json` shareable across the team without leaking the token.
12
12
  */
13
13
  export const MEMORY_SERVER_NAME = 'nepopsx-memory';
14
- export const LICENSE_ENV_VAR = 'NEPOPSX_LICENSE_KEY';
14
+ export const LICENSE_ENV_VAR = 'NEPOPSX_DEVICE_TOKEN';
15
15
  /** Build the `nepopsx-memory` HTTP server entry for `.mcp.json`. */
16
16
  export function buildMemoryServerEntry(apiUrl, opts = {}) {
17
17
  const base = apiUrl.replace(/\/+$/, '');
@@ -1 +1 @@
1
- {"version":3,"file":"config-generator.js","sourceRoot":"","sources":["../../src/mcp/config-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAuBrD,oEAAoE;AACpE,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,OAAqD,EAAE;IAEvD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,KAAK,GACT,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU;QAC/B,CAAC,CAAC,IAAI,CAAC,UAAU;QACjB,CAAC,CAAC,IAAI,GAAG,eAAe,GAAG,GAAG,CAAC;IACnC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,GAAG,IAAI,MAAM;QAClB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEtD,IAAI,QAAQ,GAAkB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACjD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAY,CAAC;YACrE,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,GAA8B,CAAC;gBAC3C,MAAM,OAAO,GACX,GAAG,CAAC,UAAU,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;oBAClD,CAAC,CAAE,GAAG,CAAC,UAA4C;oBACnD,CAAC,CAAC,EAAE,CAAC;gBACT,QAAQ,GAAG,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC;YACpD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,QAAQ,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,sBAAsB,CAC9D,OAAO,CAAC,MAAM,EACd,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACjE,CAAC;IAEF,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7E,OAAO,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"config-generator.js","sourceRoot":"","sources":["../../src/mcp/config-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAuBtD,oEAAoE;AACpE,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,OAAqD,EAAE;IAEvD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,KAAK,GACT,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU;QAC/B,CAAC,CAAC,IAAI,CAAC,UAAU;QACjB,CAAC,CAAC,IAAI,GAAG,eAAe,GAAG,GAAG,CAAC;IACnC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,GAAG,IAAI,MAAM;QAClB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEtD,IAAI,QAAQ,GAAkB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACjD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAY,CAAC;YACrE,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,GAA8B,CAAC;gBAC3C,MAAM,OAAO,GACX,GAAG,CAAC,UAAU,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;oBAClD,CAAC,CAAE,GAAG,CAAC,UAA4C;oBACnD,CAAC,CAAC,EAAE,CAAC;gBACT,QAAQ,GAAG,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC;YACpD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,QAAQ,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,sBAAsB,CAC9D,OAAO,CAAC,MAAM,EACd,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACjE,CAAC;IAEF,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7E,OAAO,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Minimal TTL JSON disk cache under `.nepopsx/cache/`.
3
+ *
4
+ * Used for read-only, advisory data the CLI displays (the plan manifest and the org's
5
+ * resolved entitlement). Every read self-expires; every write is best-effort. Nothing
6
+ * here is an enforcement authority — a miss simply means "ask the server / fall back".
7
+ */
8
+ /** Read a cached value, or `null` if absent, unreadable, malformed, or expired. */
9
+ export declare function readDiskCache<T>(rootDir: string, file: string): T | null;
10
+ /** Write a value with a TTL. Best-effort: a write failure is swallowed (cache is optional). */
11
+ export declare function writeDiskCache<T>(rootDir: string, file: string, value: T, ttlMs: number): void;
12
+ /** Delete a cache entry (used to bust on org/key change). */
13
+ export declare function clearDiskCache(rootDir: string, file: string): void;
14
+ //# sourceMappingURL=disk-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-cache.d.ts","sourceRoot":"","sources":["../../src/utils/disk-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAWxE;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAS9F;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMlE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Minimal TTL JSON disk cache under `.nepopsx/cache/`.
3
+ *
4
+ * Used for read-only, advisory data the CLI displays (the plan manifest and the org's
5
+ * resolved entitlement). Every read self-expires; every write is best-effort. Nothing
6
+ * here is an enforcement authority — a miss simply means "ask the server / fall back".
7
+ */
8
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ const CACHE_SUBDIR = join('.nepopsx', 'cache');
11
+ function cachePath(rootDir, file) {
12
+ return join(rootDir, CACHE_SUBDIR, file);
13
+ }
14
+ /** Read a cached value, or `null` if absent, unreadable, malformed, or expired. */
15
+ export function readDiskCache(rootDir, file) {
16
+ try {
17
+ const path = cachePath(rootDir, file);
18
+ if (!existsSync(path))
19
+ return null;
20
+ const env = JSON.parse(readFileSync(path, 'utf-8'));
21
+ if (typeof env?.savedAt !== 'number' || typeof env?.ttlMs !== 'number')
22
+ return null;
23
+ if (Date.now() - env.savedAt > env.ttlMs)
24
+ return null;
25
+ return env.value;
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ /** Write a value with a TTL. Best-effort: a write failure is swallowed (cache is optional). */
32
+ export function writeDiskCache(rootDir, file, value, ttlMs) {
33
+ try {
34
+ const dir = join(rootDir, CACHE_SUBDIR);
35
+ if (!existsSync(dir))
36
+ mkdirSync(dir, { recursive: true });
37
+ const env = { savedAt: Date.now(), ttlMs, value };
38
+ writeFileSync(cachePath(rootDir, file), JSON.stringify(env), 'utf-8');
39
+ }
40
+ catch {
41
+ // best-effort cache; ignore
42
+ }
43
+ }
44
+ /** Delete a cache entry (used to bust on org/key change). */
45
+ export function clearDiskCache(rootDir, file) {
46
+ try {
47
+ rmSync(cachePath(rootDir, file), { force: true });
48
+ }
49
+ catch {
50
+ // ignore
51
+ }
52
+ }
53
+ //# sourceMappingURL=disk-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-cache.js","sourceRoot":"","sources":["../../src/utils/disk-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAQ/C,SAAS,SAAS,CAAC,OAAe,EAAE,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAI,OAAe,EAAE,IAAY;IAC5D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAqB,CAAC;QACxE,IAAI,OAAO,GAAG,EAAE,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,EAAE,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpF,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACtD,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,cAAc,CAAI,OAAe,EAAE,IAAY,EAAE,KAAQ,EAAE,KAAa;IACtF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAqB,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACpE,aAAa,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,IAAY;IAC1D,IAAI,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Fetch + cache the plan manifest from the public, read-only `GET /v1/plans` endpoint.
3
+ *
4
+ * The manifest is the backend's source of truth for plan limits/features (ADR 0002). The
5
+ * CLI consumes it for DISPLAY only. When the endpoint is unreachable or the backend predates
6
+ * it (404), we synthesize a manifest from core's `TIER_LIMITS` so the CLI never hard-fails —
7
+ * this keeps Phase 1 a no-op against the current backend (rollout step 1).
8
+ */
9
+ import { type PlanManifest } from '@nepopsx/core';
10
+ /** A manifest derived from core `TIER_LIMITS` — used when the API is unreachable/old. */
11
+ export declare function fallbackManifest(): PlanManifest;
12
+ export interface FetchManifestOptions {
13
+ /** Bypass the disk cache and hit the API. */
14
+ force?: boolean;
15
+ }
16
+ /**
17
+ * Return the plan manifest: cache → API → `TIER_LIMITS` fallback. Never throws.
18
+ */
19
+ export declare function fetchPlanManifest(rootDir: string, opts?: FetchManifestOptions): Promise<PlanManifest>;
20
+ //# sourceMappingURL=fetch-plan-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-plan-manifest.d.ts","sourceRoot":"","sources":["../../src/utils/fetch-plan-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,YAAY,EAOlB,MAAM,eAAe,CAAC;AAqDvB,yFAAyF;AACzF,wBAAgB,gBAAgB,IAAI,YAAY,CAQ/C;AAED,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAyBvB"}