@nepopsx/cli 0.0.21 → 0.0.23
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/dist/agents/catalog.d.ts.map +1 -1
- package/dist/agents/catalog.js +2 -1
- package/dist/agents/catalog.js.map +1 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +29 -9
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/doctor.js +5 -6
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +18 -7
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/push-learnings.d.ts.map +1 -1
- package/dist/commands/push-learnings.js +38 -27
- package/dist/commands/push-learnings.js.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +4 -2
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +21 -9
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +6 -1
- package/dist/commands/up.js.map +1 -1
- package/dist/enrichment/workflow.d.ts.map +1 -1
- package/dist/enrichment/workflow.js +2 -1
- package/dist/enrichment/workflow.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/licensing/entitlement-cache.d.ts +25 -0
- package/dist/licensing/entitlement-cache.d.ts.map +1 -0
- package/dist/licensing/entitlement-cache.js +42 -0
- package/dist/licensing/entitlement-cache.js.map +1 -0
- package/dist/licensing/index.d.ts +3 -1
- package/dist/licensing/index.d.ts.map +1 -1
- package/dist/licensing/index.js +3 -1
- package/dist/licensing/index.js.map +1 -1
- package/dist/licensing/installer.d.ts.map +1 -1
- package/dist/licensing/installer.js +3 -2
- package/dist/licensing/installer.js.map +1 -1
- package/dist/licensing/license-manager.d.ts +30 -7
- package/dist/licensing/license-manager.d.ts.map +1 -1
- package/dist/licensing/license-manager.js +76 -13
- package/dist/licensing/license-manager.js.map +1 -1
- package/dist/licensing/template-fetch.d.ts.map +1 -1
- package/dist/licensing/template-fetch.js +6 -1
- package/dist/licensing/template-fetch.js.map +1 -1
- package/dist/licensing/workspace-name.d.ts +36 -0
- package/dist/licensing/workspace-name.d.ts.map +1 -0
- package/dist/licensing/workspace-name.js +54 -0
- package/dist/licensing/workspace-name.js.map +1 -0
- package/dist/utils/disk-cache.d.ts +14 -0
- package/dist/utils/disk-cache.d.ts.map +1 -0
- package/dist/utils/disk-cache.js +53 -0
- package/dist/utils/disk-cache.js.map +1 -0
- package/dist/utils/fetch-plan-manifest.d.ts +20 -0
- package/dist/utils/fetch-plan-manifest.d.ts.map +1 -0
- package/dist/utils/fetch-plan-manifest.js +93 -0
- package/dist/utils/fetch-plan-manifest.js.map +1 -0
- package/dist/utils/handle-402.d.ts +17 -0
- package/dist/utils/handle-402.d.ts.map +1 -0
- package/dist/utils/handle-402.js +31 -0
- package/dist/utils/handle-402.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,93 @@
|
|
|
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 { TIER_LIMITS, } from '@nepopsx/core';
|
|
10
|
+
import { resolveApiBase } from '../config/api-config.js';
|
|
11
|
+
import { fetchWithTimeout } from './fetch.js';
|
|
12
|
+
import { API_TIMEOUT_MS } from '../constants.js';
|
|
13
|
+
import { readDiskCache, writeDiskCache } from './disk-cache.js';
|
|
14
|
+
const MANIFEST_CACHE_FILE = 'plan-manifest.json';
|
|
15
|
+
/** Plan copy changes rarely; an hour of display caching is plenty. */
|
|
16
|
+
const MANIFEST_CACHE_TTL_MS = 60 * 60 * 1000;
|
|
17
|
+
/** `Infinity` (core's "unlimited") → `null` (the manifest wire encoding). */
|
|
18
|
+
function toQuota(n) {
|
|
19
|
+
return Number.isFinite(n) ? n : null;
|
|
20
|
+
}
|
|
21
|
+
/** Display-only seat defaults for the offline fallback (real values come from the API). */
|
|
22
|
+
const FALLBACK_SEATS = { free: 1, team: 5, enterprise: null };
|
|
23
|
+
function fallbackSpec(id, sortOrder) {
|
|
24
|
+
const t = TIER_LIMITS[id];
|
|
25
|
+
const paid = id !== 'free';
|
|
26
|
+
const limits = {
|
|
27
|
+
seats: FALLBACK_SEATS[id],
|
|
28
|
+
workspaces: toQuota(t.max_workspaces),
|
|
29
|
+
servicesPerWorkspace: toQuota(t.max_services),
|
|
30
|
+
agentPackages: toQuota(t.max_agents),
|
|
31
|
+
apiRatePerMin: t.api_rate_per_min,
|
|
32
|
+
marketplacePublishesPerMonth: t.publish_allowed ? null : 0,
|
|
33
|
+
};
|
|
34
|
+
const features = {
|
|
35
|
+
marketplacePublish: t.publish_allowed,
|
|
36
|
+
governanceLab: paid,
|
|
37
|
+
liveRecallMcp: paid,
|
|
38
|
+
githubSync: paid,
|
|
39
|
+
aiScan: t.scan_allowed,
|
|
40
|
+
auditExport: id === 'enterprise',
|
|
41
|
+
sso: id === 'enterprise',
|
|
42
|
+
selfHosted: id === 'enterprise',
|
|
43
|
+
webhooks: id === 'enterprise',
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
id,
|
|
47
|
+
label: id.charAt(0).toUpperCase() + id.slice(1),
|
|
48
|
+
pricing: id === 'enterprise'
|
|
49
|
+
? { salesLed: true, priceNpr: null, period: null }
|
|
50
|
+
: { salesLed: false, priceNpr: 0, period: 'month' },
|
|
51
|
+
sortOrder,
|
|
52
|
+
limits,
|
|
53
|
+
features,
|
|
54
|
+
isActive: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** A manifest derived from core `TIER_LIMITS` — used when the API is unreachable/old. */
|
|
58
|
+
export function fallbackManifest() {
|
|
59
|
+
return {
|
|
60
|
+
version: 0, // 0 = synthesized fallback (not a real server version)
|
|
61
|
+
updatedAt: new Date(0).toISOString(),
|
|
62
|
+
updatedBy: null,
|
|
63
|
+
trial: { tier: 'team', days: 14, oncePerOrg: true },
|
|
64
|
+
plans: [fallbackSpec('free', 0), fallbackSpec('team', 1), fallbackSpec('enterprise', 2)],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Return the plan manifest: cache → API → `TIER_LIMITS` fallback. Never throws.
|
|
69
|
+
*/
|
|
70
|
+
export async function fetchPlanManifest(rootDir, opts = {}) {
|
|
71
|
+
if (!opts.force) {
|
|
72
|
+
const cached = readDiskCache(rootDir, MANIFEST_CACHE_FILE);
|
|
73
|
+
if (cached?.plans?.length)
|
|
74
|
+
return cached;
|
|
75
|
+
}
|
|
76
|
+
const apiBase = resolveApiBase(rootDir);
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetchWithTimeout(`${apiBase}/plans`, { method: 'GET', headers: { Accept: 'application/json' } }, API_TIMEOUT_MS);
|
|
79
|
+
if (res.ok) {
|
|
80
|
+
const manifest = (await res.json());
|
|
81
|
+
if (manifest?.plans?.length) {
|
|
82
|
+
writeDiskCache(rootDir, MANIFEST_CACHE_FILE, manifest, MANIFEST_CACHE_TTL_MS);
|
|
83
|
+
return manifest;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// 404 (older backend) or empty → fall through to fallback.
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// offline / timeout → fall through to fallback.
|
|
90
|
+
}
|
|
91
|
+
return fallbackManifest();
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=fetch-plan-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-plan-manifest.js","sourceRoot":"","sources":["../../src/utils/fetch-plan-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render the backend's `402 Payment Required` entitlement error (ADR 0002 §2.7) as a friendly
|
|
3
|
+
* upgrade prompt. The server is the single hard authority; the CLI never denies locally, it just
|
|
4
|
+
* surfaces the server's decision. The `reason` field is the stable discriminator (not the status).
|
|
5
|
+
*/
|
|
6
|
+
export interface EntitlementErrorBody {
|
|
7
|
+
reason?: 'feature_locked' | 'quota_exceeded';
|
|
8
|
+
key?: string;
|
|
9
|
+
requiredTier?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* If `res` is a 402, print an upgrade prompt and return `true` (caller should stop). Otherwise
|
|
14
|
+
* return `false`. Safe to call on any response; never throws.
|
|
15
|
+
*/
|
|
16
|
+
export declare function reportIfPaymentRequired(res: Response): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=handle-402.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle-402.d.ts","sourceRoot":"","sources":["../../src/utils/handle-402.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB7E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render the backend's `402 Payment Required` entitlement error (ADR 0002 §2.7) as a friendly
|
|
3
|
+
* upgrade prompt. The server is the single hard authority; the CLI never denies locally, it just
|
|
4
|
+
* surfaces the server's decision. The `reason` field is the stable discriminator (not the status).
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
/**
|
|
8
|
+
* If `res` is a 402, print an upgrade prompt and return `true` (caller should stop). Otherwise
|
|
9
|
+
* return `false`. Safe to call on any response; never throws.
|
|
10
|
+
*/
|
|
11
|
+
export async function reportIfPaymentRequired(res) {
|
|
12
|
+
if (res.status !== 402)
|
|
13
|
+
return false;
|
|
14
|
+
let body = {};
|
|
15
|
+
try {
|
|
16
|
+
body = (await res.clone().json());
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// non-JSON 402 — fall back to generic copy
|
|
20
|
+
}
|
|
21
|
+
const subject = body.key ? ` (${body.key})` : '';
|
|
22
|
+
const requires = body.requiredTier ? ` Requires the ${body.requiredTier} plan.` : '';
|
|
23
|
+
const headline = body.message ??
|
|
24
|
+
(body.reason === 'quota_exceeded'
|
|
25
|
+
? 'You have reached your plan limit'
|
|
26
|
+
: 'This feature needs a higher plan');
|
|
27
|
+
console.error(chalk.yellow(`\n🔒 ${headline}${subject}.${requires}`));
|
|
28
|
+
console.log(chalk.dim(' Upgrade at https://nepopsx.dev/pricing\n'));
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=handle-402.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle-402.js","sourceRoot":"","sources":["../../src/utils/handle-402.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAa;IACzD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAErC,IAAI,IAAI,GAAyB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAyB,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,QAAQ,GACZ,IAAI,CAAC,OAAO;QACZ,CAAC,IAAI,CAAC,MAAM,KAAK,gBAAgB;YAC/B,CAAC,CAAC,kCAAkC;YACpC,CAAC,CAAC,kCAAkC,CAAC,CAAC;IAE1C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,QAAQ,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nepopsx/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "NEPOPSX CLI — generate AI agent workspaces from configuration",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"inquirer": "^12.3.2",
|
|
29
29
|
"ora": "^8.2.0",
|
|
30
30
|
"yaml": "^2.7.0",
|
|
31
|
-
"@nepopsx/core": "^0.0.
|
|
31
|
+
"@nepopsx/core": "^0.0.12"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/archiver": "^7.0.0",
|