@polardbx/pxbaas 0.0.0-stage → 0.1.0-beta.10
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/README.md +223 -2
- package/bin/pxbaas.js +13 -0
- package/dist/app/local-index.d.ts +70 -0
- package/dist/app/local-index.d.ts.map +1 -0
- package/dist/app/local-index.js +140 -0
- package/dist/app/local-index.js.map +1 -0
- package/dist/app/preflight.d.ts +61 -0
- package/dist/app/preflight.d.ts.map +1 -0
- package/dist/app/preflight.js +115 -0
- package/dist/app/preflight.js.map +1 -0
- package/dist/app/spec-lint.d.ts +45 -0
- package/dist/app/spec-lint.d.ts.map +1 -0
- package/dist/app/spec-lint.js +423 -0
- package/dist/app/spec-lint.js.map +1 -0
- package/dist/app/templates.d.ts +167 -0
- package/dist/app/templates.d.ts.map +1 -0
- package/dist/app/templates.js +151 -0
- package/dist/app/templates.js.map +1 -0
- package/dist/cli/help-guides.d.ts +17 -0
- package/dist/cli/help-guides.d.ts.map +1 -0
- package/dist/cli/help-guides.js +132 -0
- package/dist/cli/help-guides.js.map +1 -0
- package/dist/cli/root.d.ts +3 -0
- package/dist/cli/root.d.ts.map +1 -0
- package/dist/cli/root.js +75 -0
- package/dist/cli/root.js.map +1 -0
- package/dist/commands/app/index.d.ts +8 -0
- package/dist/commands/app/index.d.ts.map +1 -0
- package/dist/commands/app/index.js +1907 -0
- package/dist/commands/app/index.js.map +1 -0
- package/dist/commands/auth/index.d.ts +3 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +198 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/completion/index.d.ts +3 -0
- package/dist/commands/completion/index.d.ts.map +1 -0
- package/dist/commands/completion/index.js +14 -0
- package/dist/commands/completion/index.js.map +1 -0
- package/dist/commands/data/index.d.ts +55 -0
- package/dist/commands/data/index.d.ts.map +1 -0
- package/dist/commands/data/index.js +407 -0
- package/dist/commands/data/index.js.map +1 -0
- package/dist/commands/db/index.d.ts +29 -0
- package/dist/commands/db/index.d.ts.map +1 -0
- package/dist/commands/db/index.js +500 -0
- package/dist/commands/db/index.js.map +1 -0
- package/dist/commands/doctor/index.d.ts +3 -0
- package/dist/commands/doctor/index.d.ts.map +1 -0
- package/dist/commands/doctor/index.js +305 -0
- package/dist/commands/doctor/index.js.map +1 -0
- package/dist/commands/functions/delete.d.ts +3 -0
- package/dist/commands/functions/delete.d.ts.map +1 -0
- package/dist/commands/functions/delete.js +55 -0
- package/dist/commands/functions/delete.js.map +1 -0
- package/dist/commands/functions/deploy.d.ts +3 -0
- package/dist/commands/functions/deploy.d.ts.map +1 -0
- package/dist/commands/functions/deploy.js +118 -0
- package/dist/commands/functions/deploy.js.map +1 -0
- package/dist/commands/functions/index.d.ts +3 -0
- package/dist/commands/functions/index.d.ts.map +1 -0
- package/dist/commands/functions/index.js +15 -0
- package/dist/commands/functions/index.js.map +1 -0
- package/dist/commands/functions/list.d.ts +6 -0
- package/dist/commands/functions/list.d.ts.map +1 -0
- package/dist/commands/functions/list.js +63 -0
- package/dist/commands/functions/list.js.map +1 -0
- package/dist/commands/functions/new.d.ts +7 -0
- package/dist/commands/functions/new.d.ts.map +1 -0
- package/dist/commands/functions/new.js +72 -0
- package/dist/commands/functions/new.js.map +1 -0
- package/dist/commands/gen/index.d.ts +3 -0
- package/dist/commands/gen/index.d.ts.map +1 -0
- package/dist/commands/gen/index.js +323 -0
- package/dist/commands/gen/index.js.map +1 -0
- package/dist/commands/guide/index.d.ts +8 -0
- package/dist/commands/guide/index.d.ts.map +1 -0
- package/dist/commands/guide/index.js +20 -0
- package/dist/commands/guide/index.js.map +1 -0
- package/dist/commands/instance/index.d.ts +8 -0
- package/dist/commands/instance/index.d.ts.map +1 -0
- package/dist/commands/instance/index.js +481 -0
- package/dist/commands/instance/index.js.map +1 -0
- package/dist/commands/login/index.d.ts +3 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +145 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/logout/index.d.ts +3 -0
- package/dist/commands/logout/index.d.ts.map +1 -0
- package/dist/commands/logout/index.js +41 -0
- package/dist/commands/logout/index.js.map +1 -0
- package/dist/commands/profile/import-env.d.ts +18 -0
- package/dist/commands/profile/import-env.d.ts.map +1 -0
- package/dist/commands/profile/import-env.js +206 -0
- package/dist/commands/profile/import-env.js.map +1 -0
- package/dist/commands/profile/index.d.ts +3 -0
- package/dist/commands/profile/index.d.ts.map +1 -0
- package/dist/commands/profile/index.js +124 -0
- package/dist/commands/profile/index.js.map +1 -0
- package/dist/commands/rest/index.d.ts +3 -0
- package/dist/commands/rest/index.d.ts.map +1 -0
- package/dist/commands/rest/index.js +102 -0
- package/dist/commands/rest/index.js.map +1 -0
- package/dist/commands/skill/index.d.ts +11 -0
- package/dist/commands/skill/index.d.ts.map +1 -0
- package/dist/commands/skill/index.js +228 -0
- package/dist/commands/skill/index.js.map +1 -0
- package/dist/commands/status/index.d.ts +3 -0
- package/dist/commands/status/index.d.ts.map +1 -0
- package/dist/commands/status/index.js +59 -0
- package/dist/commands/status/index.js.map +1 -0
- package/dist/commands/storage/index.d.ts +3 -0
- package/dist/commands/storage/index.d.ts.map +1 -0
- package/dist/commands/storage/index.js +400 -0
- package/dist/commands/storage/index.js.map +1 -0
- package/dist/commands/tenant/index.d.ts +19 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +667 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/commands/whoami/index.d.ts +3 -0
- package/dist/commands/whoami/index.d.ts.map +1 -0
- package/dist/commands/whoami/index.js +101 -0
- package/dist/commands/whoami/index.js.map +1 -0
- package/dist/credentials/commit.d.ts +38 -0
- package/dist/credentials/commit.d.ts.map +1 -0
- package/dist/credentials/commit.js +57 -0
- package/dist/credentials/commit.js.map +1 -0
- package/dist/credentials/credential-store.d.ts +86 -0
- package/dist/credentials/credential-store.d.ts.map +1 -0
- package/dist/credentials/credential-store.js +282 -0
- package/dist/credentials/credential-store.js.map +1 -0
- package/dist/credentials/env-file.d.ts +85 -0
- package/dist/credentials/env-file.d.ts.map +1 -0
- package/dist/credentials/env-file.js +193 -0
- package/dist/credentials/env-file.js.map +1 -0
- package/dist/credentials/formatter.d.ts +39 -0
- package/dist/credentials/formatter.d.ts.map +1 -0
- package/dist/credentials/formatter.js +79 -0
- package/dist/credentials/formatter.js.map +1 -0
- package/dist/credentials/index.d.ts +13 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +13 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/credentials/jwt-introspect.d.ts +39 -0
- package/dist/credentials/jwt-introspect.d.ts.map +1 -0
- package/dist/credentials/jwt-introspect.js +64 -0
- package/dist/credentials/jwt-introspect.js.map +1 -0
- package/dist/credentials/masker.d.ts +23 -0
- package/dist/credentials/masker.d.ts.map +1 -0
- package/dist/credentials/masker.js +40 -0
- package/dist/credentials/masker.js.map +1 -0
- package/dist/credentials/profile.d.ts +95 -0
- package/dist/credentials/profile.d.ts.map +1 -0
- package/dist/credentials/profile.js +207 -0
- package/dist/credentials/profile.js.map +1 -0
- package/dist/credentials/tenant-guard.d.ts +16 -0
- package/dist/credentials/tenant-guard.d.ts.map +1 -0
- package/dist/credentials/tenant-guard.js +53 -0
- package/dist/credentials/tenant-guard.js.map +1 -0
- package/dist/credentials/tty-guard.d.ts +29 -0
- package/dist/credentials/tty-guard.d.ts.map +1 -0
- package/dist/credentials/tty-guard.js +79 -0
- package/dist/credentials/tty-guard.js.map +1 -0
- package/dist/db/apply-schema.d.ts +144 -0
- package/dist/db/apply-schema.d.ts.map +1 -0
- package/dist/db/apply-schema.js +359 -0
- package/dist/db/apply-schema.js.map +1 -0
- package/dist/db/introspect.d.ts +54 -0
- package/dist/db/introspect.d.ts.map +1 -0
- package/dist/db/introspect.js +140 -0
- package/dist/db/introspect.js.map +1 -0
- package/dist/db/sql-file.d.ts +104 -0
- package/dist/db/sql-file.d.ts.map +1 -0
- package/dist/db/sql-file.js +584 -0
- package/dist/db/sql-file.js.map +1 -0
- package/dist/instance/provision.d.ts +89 -0
- package/dist/instance/provision.d.ts.map +1 -0
- package/dist/instance/provision.js +139 -0
- package/dist/instance/provision.js.map +1 -0
- package/dist/instance/zero-store.d.ts +47 -0
- package/dist/instance/zero-store.d.ts.map +1 -0
- package/dist/instance/zero-store.js +91 -0
- package/dist/instance/zero-store.js.map +1 -0
- package/dist/instance/zero-whitelist.d.ts +39 -0
- package/dist/instance/zero-whitelist.d.ts.map +1 -0
- package/dist/instance/zero-whitelist.js +67 -0
- package/dist/instance/zero-whitelist.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +69 -0
- package/dist/main.js.map +1 -0
- package/dist/skill/agents-md.d.ts +25 -0
- package/dist/skill/agents-md.d.ts.map +1 -0
- package/dist/skill/agents-md.js +62 -0
- package/dist/skill/agents-md.js.map +1 -0
- package/dist/skill/assets.d.ts +38 -0
- package/dist/skill/assets.d.ts.map +1 -0
- package/dist/skill/assets.js +111 -0
- package/dist/skill/assets.js.map +1 -0
- package/dist/skill/hint.d.ts +39 -0
- package/dist/skill/hint.d.ts.map +1 -0
- package/dist/skill/hint.js +109 -0
- package/dist/skill/hint.js.map +1 -0
- package/dist/skill/hosts.d.ts +45 -0
- package/dist/skill/hosts.d.ts.map +1 -0
- package/dist/skill/hosts.js +96 -0
- package/dist/skill/hosts.js.map +1 -0
- package/dist/skill/installer.d.ts +100 -0
- package/dist/skill/installer.d.ts.map +1 -0
- package/dist/skill/installer.js +241 -0
- package/dist/skill/installer.js.map +1 -0
- package/dist/skill/ownership.d.ts +35 -0
- package/dist/skill/ownership.d.ts.map +1 -0
- package/dist/skill/ownership.js +52 -0
- package/dist/skill/ownership.js.map +1 -0
- package/dist/tenant/bundle.d.ts +66 -0
- package/dist/tenant/bundle.d.ts.map +1 -0
- package/dist/tenant/bundle.js +132 -0
- package/dist/tenant/bundle.js.map +1 -0
- package/dist/tenant/guide.d.ts +50 -0
- package/dist/tenant/guide.d.ts.map +1 -0
- package/dist/tenant/guide.js +152 -0
- package/dist/tenant/guide.js.map +1 -0
- package/dist/tenant/probe.d.ts +65 -0
- package/dist/tenant/probe.d.ts.map +1 -0
- package/dist/tenant/probe.js +159 -0
- package/dist/tenant/probe.js.map +1 -0
- package/dist/tenant/verify.d.ts +37 -0
- package/dist/tenant/verify.d.ts.map +1 -0
- package/dist/tenant/verify.js +132 -0
- package/dist/tenant/verify.js.map +1 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +65 -0
- package/dist/version.js.map +1 -0
- package/package.json +63 -3
- package/skills/pxbaas-app-spec/SKILL.md +165 -0
- package/skills/pxbaas-app-spec/references/deploy-options.md +158 -0
- package/skills/pxbaas-app-spec/references/guardrails-pitfalls.md +89 -0
- package/skills/pxbaas-app-spec/references/runtime-contract.md +151 -0
- package/skills/pxbaas-app-spec/references/ssr-session.md +121 -0
- package/skills/pxbaas-app-spec/references/templates-examples.md +311 -0
- package/skills/pxbaas-cli/SKILL.md +186 -0
- package/skills/pxbaas-cli/references/api-reference.md +68 -0
- package/skills/pxbaas-cli/references/app-deploy.md +186 -0
- package/skills/pxbaas-cli/references/auth-and-credentials.md +116 -0
- package/skills/pxbaas-cli/references/data-postgrest.md +101 -0
- package/skills/pxbaas-cli/references/db-and-meta.md +102 -0
- package/skills/pxbaas-cli/references/edge-functions.md +71 -0
- package/skills/pxbaas-cli/references/multi-tenant-apps.md +138 -0
- package/skills/pxbaas-cli/references/provision.md +101 -0
- package/skills/pxbaas-cli/references/safety-and-two-phase.md +78 -0
- package/skills/pxbaas-cli/references/storage.md +61 -0
- package/skills/pxbaas-cli/references/tenant-admin.md +122 -0
- package/skills/pxbaas-cli/references/troubleshooting.md +76 -0
- package/templates/webapp/api/index.ts +55 -0
- package/templates/webapp/csr-bff/README.md +81 -0
- package/templates/webapp/csr-bff/backend/index.ts +168 -0
- package/templates/webapp/csr-bff/db/rls.json +13 -0
- package/templates/webapp/csr-bff/db/schema.sql +49 -0
- package/templates/webapp/csr-bff/frontend/dist/admin.html +101 -0
- package/templates/webapp/csr-bff/frontend/dist/article.html +44 -0
- package/templates/webapp/csr-bff/frontend/dist/blog.js +206 -0
- package/templates/webapp/csr-bff/frontend/dist/blogger.html +53 -0
- package/templates/webapp/csr-bff/frontend/dist/index.html +70 -0
- package/templates/webapp/csr-bff/frontend/dist/login.html +56 -0
- package/templates/webapp/csr-bff/frontend/dist/profile.html +59 -0
- package/templates/webapp/csr-bff/frontend/dist/signup.html +78 -0
- package/templates/webapp/csr-bff/frontend/dist/style.css +27 -0
- package/templates/webapp/manifest.json +419 -0
- package/templates/webapp/mpa/about.html +29 -0
- package/templates/webapp/mpa/app.js +42 -0
- package/templates/webapp/mpa/index.html +42 -0
- package/templates/webapp/mpa/index.ts +60 -0
- package/templates/webapp/mpa/style.css +42 -0
- package/templates/webapp/react-vite/frontend/index.html +12 -0
- package/templates/webapp/react-vite/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite/frontend/package.json +23 -0
- package/templates/webapp/react-vite/frontend/src/App.tsx +34 -0
- package/templates/webapp/react-vite/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite/frontend/src/style.css +46 -0
- package/templates/webapp/react-vite/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite/frontend/vite.config.ts +10 -0
- package/templates/webapp/react-vite-hono/backend/index.ts +38 -0
- package/templates/webapp/react-vite-hono/frontend/index.html +12 -0
- package/templates/webapp/react-vite-hono/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite-hono/frontend/package.json +23 -0
- package/templates/webapp/react-vite-hono/frontend/src/App.tsx +47 -0
- package/templates/webapp/react-vite-hono/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite-hono/frontend/src/style.css +66 -0
- package/templates/webapp/react-vite-hono/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite-hono/frontend/vite.config.ts +10 -0
- package/templates/webapp/spa/index.ts +119 -0
- package/templates/webapp/ssr-auth/backend/index.ts +133 -0
- package/templates/webapp/ssr-auth/frontend/dist/index.html +15 -0
- package/templates/webapp/ssr-blog/README.md +111 -0
- package/templates/webapp/ssr-blog/backend/index.ts +764 -0
- package/templates/webapp/ssr-blog/db/rls.json +13 -0
- package/templates/webapp/ssr-blog/db/schema.sql +51 -0
- package/templates/webapp/ssr-blog/frontend/dist/index.html +39 -0
- package/templates/webapp/ssr-frameworks/README.md +64 -0
- package/templates/webapp/ssr-frameworks/backend/index.ts +241 -0
- package/templates/webapp/ssr-frameworks/frontend/dist/index.html +31 -0
- package/templates/webapp/ssr-hono/backend/index.ts +111 -0
- package/templates/webapp/ssr-hono/frontend/dist/index.html +12 -0
- package/templates/webapp/ssr-shop/README.md +80 -0
- package/templates/webapp/ssr-shop/backend/index.ts +491 -0
- package/templates/webapp/ssr-shop/db/rls.json +16 -0
- package/templates/webapp/ssr-shop/db/schema.sql +90 -0
- package/templates/webapp/ssr-shop/frontend/dist/index.html +12 -0
- package/templates/webapp/vanilla-static/frontend/dist/app.js +6 -0
- package/templates/webapp/vanilla-static/frontend/dist/index.html +19 -0
- package/templates/webapp/vanilla-static/frontend/dist/style.css +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/skill/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillManager — install/list/remove ALL bundled Agent Skills (e.g. `pxbaas-cli`,
|
|
3
|
+
* `pxbaas-app-spec`) into supported Agent hosts.
|
|
4
|
+
*
|
|
5
|
+
* Purely local and offline: never touches credentials, profiles, or the network,
|
|
6
|
+
* so agents can run it without `pxbaas login`. `homeDir` and `skillsRoot` are
|
|
7
|
+
* injectable for testing.
|
|
8
|
+
*
|
|
9
|
+
* Layout: each host has a skills root (`~/.<host>/skills`); every bundled skill is
|
|
10
|
+
* installed into `<skillsRoot>/<skillName>/` with its own fail-closed owner marker.
|
|
11
|
+
*/
|
|
12
|
+
import { copyFile, mkdir, rm, rename } from 'node:fs/promises';
|
|
13
|
+
import { existsSync } from 'node:fs';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { dirname, join } from 'node:path';
|
|
16
|
+
import { listBundledSkillsIn, listSkillFiles, readCliVersion, resolveSkillsRoot } from './assets.js';
|
|
17
|
+
import { ALL_EXCLUDED_HOSTS, detectInstalledHosts, hostSkillsRoot, projectSkillsRoot, PROJECT_HOSTS, } from './hosts.js';
|
|
18
|
+
import { classifyTarget, readMarker, sha256File, writeMarker } from './ownership.js';
|
|
19
|
+
export class SkillManager {
|
|
20
|
+
homeDir;
|
|
21
|
+
skillsRoot;
|
|
22
|
+
cliVersion;
|
|
23
|
+
projectRoot;
|
|
24
|
+
skillsCache = null;
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.homeDir = options.homeDir ?? homedir();
|
|
27
|
+
this.skillsRoot = options.skillsRoot ?? resolveSkillsRoot();
|
|
28
|
+
this.cliVersion = options.cliVersion ?? 'unknown';
|
|
29
|
+
this.projectRoot = options.projectRoot ?? process.cwd();
|
|
30
|
+
}
|
|
31
|
+
/** Async factory that resolves the CLI version from package.json. */
|
|
32
|
+
static async create(options = {}) {
|
|
33
|
+
const cliVersion = options.cliVersion ?? (await readCliVersion());
|
|
34
|
+
return new SkillManager({ ...options, cliVersion });
|
|
35
|
+
}
|
|
36
|
+
/** Bundled skill names (memoized). */
|
|
37
|
+
async bundledSkills() {
|
|
38
|
+
if (!this.skillsCache) {
|
|
39
|
+
this.skillsCache = await listBundledSkillsIn(this.skillsRoot);
|
|
40
|
+
}
|
|
41
|
+
return this.skillsCache;
|
|
42
|
+
}
|
|
43
|
+
async selectedSkills(filter) {
|
|
44
|
+
const all = await this.bundledSkills();
|
|
45
|
+
if (!filter || filter.length === 0)
|
|
46
|
+
return all;
|
|
47
|
+
const unknown = filter.filter((s) => !all.includes(s));
|
|
48
|
+
if (unknown.length > 0) {
|
|
49
|
+
throw new Error(`Unknown skill(s): ${unknown.join(', ')}. Bundled: ${all.join(', ')}.`);
|
|
50
|
+
}
|
|
51
|
+
return filter;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolve which host skills-roots to act on.
|
|
55
|
+
* - `--dir` wins (single custom skills-root, host label "custom")
|
|
56
|
+
* - `--scope project` requires `--host` (a ProjectHost) or `--dir`; `--all` is
|
|
57
|
+
* user-scope only because writing every vendor repo directory is spammy
|
|
58
|
+
* - `--all` (user scope) → every detected host except ALL_EXCLUDED_HOSTS
|
|
59
|
+
* - `--host <h>` → that host
|
|
60
|
+
* - none → auto-detect: exactly one detected host is used; 0 or >1 is an error
|
|
61
|
+
*/
|
|
62
|
+
resolveTargets(opts) {
|
|
63
|
+
const scope = opts.scope ?? 'user';
|
|
64
|
+
if (scope === 'project') {
|
|
65
|
+
if (opts.all) {
|
|
66
|
+
throw new Error(`--all is user-scope only. For --scope project pass --host <${PROJECT_HOSTS.join('|')}> or --dir <path>.`);
|
|
67
|
+
}
|
|
68
|
+
if (opts.dir) {
|
|
69
|
+
return [{ host: 'custom', destRoot: opts.dir, scope }];
|
|
70
|
+
}
|
|
71
|
+
if (!opts.host || !PROJECT_HOSTS.includes(opts.host)) {
|
|
72
|
+
throw new Error(`--scope project requires --host <${PROJECT_HOSTS.join('|')}> (or --dir <path>).`);
|
|
73
|
+
}
|
|
74
|
+
const host = opts.host;
|
|
75
|
+
return [{ host, destRoot: projectSkillsRoot(host, this.projectRoot), scope }];
|
|
76
|
+
}
|
|
77
|
+
if (opts.dir) {
|
|
78
|
+
return [{ host: 'custom', destRoot: opts.dir, scope }];
|
|
79
|
+
}
|
|
80
|
+
if (opts.all) {
|
|
81
|
+
const detected = detectInstalledHosts(this.homeDir).filter((h) => !ALL_EXCLUDED_HOSTS.includes(h));
|
|
82
|
+
if (detected.length === 0) {
|
|
83
|
+
throw new Error(`No supported host directory found under ${this.homeDir}. Pass --host <name> or --dir <path>.`);
|
|
84
|
+
}
|
|
85
|
+
return detected.map((host) => ({ host, destRoot: hostSkillsRoot(host, this.homeDir), scope }));
|
|
86
|
+
}
|
|
87
|
+
if (opts.host) {
|
|
88
|
+
return [{ host: opts.host, destRoot: hostSkillsRoot(opts.host, this.homeDir), scope }];
|
|
89
|
+
}
|
|
90
|
+
const detected = detectInstalledHosts(this.homeDir);
|
|
91
|
+
if (detected.length === 1) {
|
|
92
|
+
return [{ host: detected[0], destRoot: hostSkillsRoot(detected[0], this.homeDir), scope }];
|
|
93
|
+
}
|
|
94
|
+
if (detected.length === 0) {
|
|
95
|
+
throw new Error(`No supported host directory found under ${this.homeDir}. Pass --host <name> or --dir <path>.`);
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Multiple hosts detected (${detected.join(', ')}). Pass --host <name> to pick one, or --all for every detected host.`);
|
|
98
|
+
}
|
|
99
|
+
/** Install all (or selected) bundled skills into each target's skills root. */
|
|
100
|
+
async install(targets, options = {}) {
|
|
101
|
+
const skills = await this.selectedSkills(options.skills);
|
|
102
|
+
const filesBySkill = new Map();
|
|
103
|
+
for (const s of skills) {
|
|
104
|
+
filesBySkill.set(s, await listSkillFiles(join(this.skillsRoot, s)));
|
|
105
|
+
}
|
|
106
|
+
const results = [];
|
|
107
|
+
for (const target of targets) {
|
|
108
|
+
for (const skill of skills) {
|
|
109
|
+
const destDir = join(target.destRoot, skill);
|
|
110
|
+
results.push(await this.installOne(target.host, skill, destDir, filesBySkill.get(skill) ?? [], options, target.scope));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
async installOne(host, skill, targetDir, files, options, scope = 'user') {
|
|
116
|
+
const assetDir = join(this.skillsRoot, skill);
|
|
117
|
+
const state = await classifyTarget(targetDir);
|
|
118
|
+
if (state === 'foreign' && !options.force) {
|
|
119
|
+
return {
|
|
120
|
+
host,
|
|
121
|
+
skill,
|
|
122
|
+
targetDir,
|
|
123
|
+
status: 'skipped-foreign',
|
|
124
|
+
scope,
|
|
125
|
+
reason: 'Directory exists but is not managed by pxbaas-cli. Re-run with --force to back it up and overwrite.',
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const plannedStatus = state === 'owned' ? 'updated' : 'installed';
|
|
129
|
+
if (options.dryRun) {
|
|
130
|
+
const verb = state === 'owned' ? 'update' : 'install';
|
|
131
|
+
return { host, skill, targetDir, status: 'dry-run', scope, filesWritten: files, reason: `would ${verb}` };
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
if (state === 'foreign' && options.force) {
|
|
135
|
+
await rename(targetDir, `${targetDir}.bak.${Date.now()}`);
|
|
136
|
+
}
|
|
137
|
+
await mkdir(targetDir, { recursive: true });
|
|
138
|
+
const hashes = {};
|
|
139
|
+
for (const rel of files) {
|
|
140
|
+
const src = join(assetDir, rel);
|
|
141
|
+
const dst = join(targetDir, rel);
|
|
142
|
+
await mkdir(dirname(dst), { recursive: true });
|
|
143
|
+
await copyFile(src, dst);
|
|
144
|
+
hashes[rel] = await sha256File(dst);
|
|
145
|
+
}
|
|
146
|
+
const marker = {
|
|
147
|
+
owner: 'pxbaas-cli',
|
|
148
|
+
skillName: skill,
|
|
149
|
+
skillVersion: this.cliVersion,
|
|
150
|
+
cliVersion: this.cliVersion,
|
|
151
|
+
host,
|
|
152
|
+
installedAt: new Date().toISOString(),
|
|
153
|
+
files: hashes,
|
|
154
|
+
};
|
|
155
|
+
await writeMarker(targetDir, marker);
|
|
156
|
+
for (const rel of files) {
|
|
157
|
+
if (!existsSync(join(targetDir, rel))) {
|
|
158
|
+
throw new Error(`Verification failed: missing ${rel} after copy`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { host, skill, targetDir, status: plannedStatus, scope, filesWritten: files, skillVersion: this.cliVersion };
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
return { host, skill, targetDir, status: 'error', scope, reason: err instanceof Error ? err.message : String(err) };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Report install state of every bundled skill across all detected hosts. */
|
|
168
|
+
async list(options = {}) {
|
|
169
|
+
const skills = await this.selectedSkills(options.skills);
|
|
170
|
+
const results = [];
|
|
171
|
+
for (const host of detectInstalledHosts(this.homeDir)) {
|
|
172
|
+
const destRoot = hostSkillsRoot(host, this.homeDir);
|
|
173
|
+
for (const skill of skills) {
|
|
174
|
+
results.push(await this.listOne(host, skill, join(destRoot, skill), 'user'));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return results;
|
|
178
|
+
}
|
|
179
|
+
/** Report install state of bundled skills in repository-level directories. */
|
|
180
|
+
async listProject(options = {}) {
|
|
181
|
+
const skills = await this.selectedSkills(options.skills);
|
|
182
|
+
const results = [];
|
|
183
|
+
const seenRoots = new Set();
|
|
184
|
+
for (const host of PROJECT_HOSTS) {
|
|
185
|
+
const destRoot = projectSkillsRoot(host, this.projectRoot);
|
|
186
|
+
// codex and the neutral `agents` key share .agents/skills: report once.
|
|
187
|
+
if (seenRoots.has(destRoot))
|
|
188
|
+
continue;
|
|
189
|
+
seenRoots.add(destRoot);
|
|
190
|
+
if (!existsSync(destRoot))
|
|
191
|
+
continue;
|
|
192
|
+
for (const skill of skills) {
|
|
193
|
+
results.push(await this.listOne(host, skill, join(destRoot, skill), 'project'));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return results;
|
|
197
|
+
}
|
|
198
|
+
async listOne(host, skill, targetDir, scope = 'user') {
|
|
199
|
+
const state = await classifyTarget(targetDir);
|
|
200
|
+
if (state === 'absent')
|
|
201
|
+
return { host, skill, targetDir, status: 'not-installed', scope };
|
|
202
|
+
if (state === 'foreign') {
|
|
203
|
+
return { host, skill, targetDir, status: 'foreign', scope, reason: 'directory exists but is not managed by pxbaas-cli' };
|
|
204
|
+
}
|
|
205
|
+
const marker = await readMarker(targetDir);
|
|
206
|
+
return { host, skill, targetDir, status: 'installed', scope, skillVersion: marker?.skillVersion, installedAt: marker?.installedAt };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Remove bundled skills from each target. Only removes directories owned by
|
|
210
|
+
* pxbaas-cli. Two-phase: without `confirm` (or with `dryRun`) it only previews.
|
|
211
|
+
*/
|
|
212
|
+
async remove(targets, options = {}) {
|
|
213
|
+
const skills = await this.selectedSkills(options.skills);
|
|
214
|
+
const results = [];
|
|
215
|
+
for (const target of targets) {
|
|
216
|
+
for (const skill of skills) {
|
|
217
|
+
results.push(await this.removeOne(target.host, skill, join(target.destRoot, skill), options, target.scope));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return results;
|
|
221
|
+
}
|
|
222
|
+
async removeOne(host, skill, targetDir, options, scope = 'user') {
|
|
223
|
+
const state = await classifyTarget(targetDir);
|
|
224
|
+
if (state === 'absent')
|
|
225
|
+
return { host, skill, targetDir, status: 'not-installed', scope };
|
|
226
|
+
if (state === 'foreign') {
|
|
227
|
+
return { host, skill, targetDir, status: 'skipped-foreign', scope, reason: 'Directory is not managed by pxbaas-cli; refusing to delete.' };
|
|
228
|
+
}
|
|
229
|
+
if (options.dryRun || !options.confirm) {
|
|
230
|
+
return { host, skill, targetDir, status: 'dry-run', scope, reason: options.dryRun ? 'would remove' : 'pass --confirm to remove' };
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
await rm(targetDir, { recursive: true, force: true });
|
|
234
|
+
return { host, skill, targetDir, status: 'removed', scope };
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
return { host, skill, targetDir, status: 'error', scope, reason: err instanceof Error ? err.message : String(err) };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/skill/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail-closed ownership tracking for installed skills (lightweight, per-dir).
|
|
3
|
+
*
|
|
4
|
+
* Each installed skill directory carries a `.baas-skill-owner.json` marker
|
|
5
|
+
* recording the owner, versions, timestamp, and a sha256 per file. This lets
|
|
6
|
+
* `install` update its own assets idempotently, refuse to clobber foreign
|
|
7
|
+
* directories (unless `--force`), and lets `remove` delete only what it owns.
|
|
8
|
+
*
|
|
9
|
+
* This is the M1 lightweight model; a ctxdb0-style central manifest
|
|
10
|
+
* (`~/.baas/skill-installations.json`) is deferred to M2.
|
|
11
|
+
*/
|
|
12
|
+
export declare const MARKER_FILE = ".baas-skill-owner.json";
|
|
13
|
+
export declare const OWNER_ID = "pxbaas-cli";
|
|
14
|
+
export interface OwnerMarker {
|
|
15
|
+
owner: typeof OWNER_ID;
|
|
16
|
+
skillName: string;
|
|
17
|
+
skillVersion: string;
|
|
18
|
+
cliVersion: string;
|
|
19
|
+
host: string;
|
|
20
|
+
installedAt: string;
|
|
21
|
+
files: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
export type TargetState = 'absent' | 'owned' | 'foreign';
|
|
24
|
+
export declare function sha256File(path: string): Promise<string>;
|
|
25
|
+
/** Read and validate the owner marker in a directory; null when absent/invalid. */
|
|
26
|
+
export declare function readMarker(dir: string): Promise<OwnerMarker | null>;
|
|
27
|
+
export declare function writeMarker(dir: string, marker: OwnerMarker): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Classify a target skill directory:
|
|
30
|
+
* - `absent` : directory does not exist
|
|
31
|
+
* - `owned` : exists and carries a valid pxbaas-cli marker (safe to update)
|
|
32
|
+
* - `foreign` : exists without our marker (must NOT be overwritten unless forced)
|
|
33
|
+
*/
|
|
34
|
+
export declare function classifyTarget(dir: string): Promise<TargetState>;
|
|
35
|
+
//# sourceMappingURL=ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.d.ts","sourceRoot":"","sources":["../../src/skill/ownership.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,eAAO,MAAM,WAAW,2BAA2B,CAAC;AACpD,eAAO,MAAM,QAAQ,eAAe,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,QAAQ,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D;AAED,mFAAmF;AACnF,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAUzE;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjF;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAItE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail-closed ownership tracking for installed skills (lightweight, per-dir).
|
|
3
|
+
*
|
|
4
|
+
* Each installed skill directory carries a `.baas-skill-owner.json` marker
|
|
5
|
+
* recording the owner, versions, timestamp, and a sha256 per file. This lets
|
|
6
|
+
* `install` update its own assets idempotently, refuse to clobber foreign
|
|
7
|
+
* directories (unless `--force`), and lets `remove` delete only what it owns.
|
|
8
|
+
*
|
|
9
|
+
* This is the M1 lightweight model; a ctxdb0-style central manifest
|
|
10
|
+
* (`~/.baas/skill-installations.json`) is deferred to M2.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from 'node:crypto';
|
|
13
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { existsSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
export const MARKER_FILE = '.baas-skill-owner.json';
|
|
17
|
+
export const OWNER_ID = 'pxbaas-cli';
|
|
18
|
+
export async function sha256File(path) {
|
|
19
|
+
const buf = await readFile(path);
|
|
20
|
+
return createHash('sha256').update(buf).digest('hex');
|
|
21
|
+
}
|
|
22
|
+
/** Read and validate the owner marker in a directory; null when absent/invalid. */
|
|
23
|
+
export async function readMarker(dir) {
|
|
24
|
+
const markerPath = join(dir, MARKER_FILE);
|
|
25
|
+
if (!existsSync(markerPath))
|
|
26
|
+
return null;
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(await readFile(markerPath, 'utf8'));
|
|
29
|
+
if (parsed?.owner !== OWNER_ID || typeof parsed.skillName !== 'string')
|
|
30
|
+
return null;
|
|
31
|
+
return parsed;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function writeMarker(dir, marker) {
|
|
38
|
+
await writeFile(join(dir, MARKER_FILE), JSON.stringify(marker, null, 2) + '\n', 'utf8');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Classify a target skill directory:
|
|
42
|
+
* - `absent` : directory does not exist
|
|
43
|
+
* - `owned` : exists and carries a valid pxbaas-cli marker (safe to update)
|
|
44
|
+
* - `foreign` : exists without our marker (must NOT be overwritten unless forced)
|
|
45
|
+
*/
|
|
46
|
+
export async function classifyTarget(dir) {
|
|
47
|
+
if (!existsSync(dir))
|
|
48
|
+
return 'absent';
|
|
49
|
+
const marker = await readMarker(dir);
|
|
50
|
+
return marker ? 'owned' : 'foreign';
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.js","sourceRoot":"","sources":["../../src/skill/ownership.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AACpD,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC;AAcrC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAyB,CAAC;QACtF,IAAI,MAAM,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpF,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,MAAmB;IAChE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 租户交付包(tenant access bundle)。
|
|
3
|
+
*
|
|
4
|
+
* 解决的问题:管理员在 CLI 里拿到了新租户的密钥之后,怎么把它交给"另一个真人"。
|
|
5
|
+
* 交付物是一份**规范 env 文件**,格式与 `pxbaas profile import` 的多租户输入契约逐字
|
|
6
|
+
* 对齐(credentials/env-file.ts 的 TENANT_* 分支),所以收件人不需要手改任何字段名。
|
|
7
|
+
*
|
|
8
|
+
* 三条硬纪律:
|
|
9
|
+
* 1. **字段白名单**。bundle 内容由本模块**逐字段显式拼装**,因此结构上不可能包含
|
|
10
|
+
* `jwt_secret`(租户签名母密钥)、`DASHBOARD_*`(实例管理口令)或 `GLOBAL_*`
|
|
11
|
+
* (平台全局密钥)。这不是"记得过滤",而是根本没有把它们写进去的入口。
|
|
12
|
+
* 2. **明文只落 0600 文件,绝不进 stdout / `--json` / 日志**。终端上只出现指纹。
|
|
13
|
+
* 3. **不留存于内存之外**:调用方拿到 keys 后要么写钥匙串,要么交给本模块写文件。
|
|
14
|
+
*/
|
|
15
|
+
export declare const BUNDLE_VERSION = 1;
|
|
16
|
+
export interface BundleInput {
|
|
17
|
+
tenantId: string;
|
|
18
|
+
/** Kong 网关地址;必须已是网关,不能是 Studio 端口。 */
|
|
19
|
+
endpoint: string;
|
|
20
|
+
anonKey: string;
|
|
21
|
+
serviceRoleKey: string;
|
|
22
|
+
/** 同 VPC 使用者可加内网入口,导入时用 --intranet 优先。 */
|
|
23
|
+
intranetEndpoint?: string;
|
|
24
|
+
issuedBy?: string;
|
|
25
|
+
/** 供注释头标注有效期语义(当前平台签发约 10 年且不可撤销)。 */
|
|
26
|
+
generatedAt?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface HandoffRecord {
|
|
29
|
+
tenantId: string;
|
|
30
|
+
endpoint: string;
|
|
31
|
+
generatedAt: string;
|
|
32
|
+
anonFingerprint: string;
|
|
33
|
+
serviceFingerprint: string;
|
|
34
|
+
bundlePath: string;
|
|
35
|
+
/** 交付包整文件 sha256,用于收件人比对"拿到的是不是同一份"。 */
|
|
36
|
+
bundleSha256: string;
|
|
37
|
+
issuedBy?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface WriteBundleResult {
|
|
40
|
+
path: string;
|
|
41
|
+
bytes: number;
|
|
42
|
+
record: HandoffRecord;
|
|
43
|
+
instructions: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 渲染交付包文本。只输出这 5(+1)个变量:
|
|
47
|
+
* MULTI_TENANT_MODE / SUPABASE_URL / DEFAULT_TENANT_ID / TENANT_ANON_KEY /
|
|
48
|
+
* TENANT_SERVICE_ROLE_KEY(可选 SUPABASE_INTRANET_URL)。
|
|
49
|
+
*/
|
|
50
|
+
export declare function renderBundle(input: BundleInput): string;
|
|
51
|
+
/**
|
|
52
|
+
* 写交付包。目标已存在时**必须**显式 `overwrite`,否则拒绝 —— 不静默覆盖别人的接入包。
|
|
53
|
+
*/
|
|
54
|
+
export declare function writeBundle(file: string, input: BundleInput, options?: {
|
|
55
|
+
overwrite?: boolean;
|
|
56
|
+
homeDir?: string;
|
|
57
|
+
}): Promise<WriteBundleResult>;
|
|
58
|
+
/** 可直接复制转发给使用者的交接说明(不含任何密钥值)。 */
|
|
59
|
+
export declare function renderInstructions(record: HandoffRecord): string;
|
|
60
|
+
export declare function listHandoffs(homeDir?: string): Promise<HandoffRecord[]>;
|
|
61
|
+
/**
|
|
62
|
+
* 签发台账:只记指纹与文件哈希,**不含任何明文密钥**。0600。
|
|
63
|
+
* 泄露事件回溯时这是唯一能回答"我发过哪些包、对应哪个租户"的记录。
|
|
64
|
+
*/
|
|
65
|
+
export declare function appendHandoffRecord(record: HandoffRecord, homeDir?: string): Promise<void>;
|
|
66
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/tenant/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA0BvD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACtD,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAgBhE;AAID,wBAAsB,YAAY,CAChC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,EAAE,CAAC,CAY1B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 租户交付包(tenant access bundle)。
|
|
3
|
+
*
|
|
4
|
+
* 解决的问题:管理员在 CLI 里拿到了新租户的密钥之后,怎么把它交给"另一个真人"。
|
|
5
|
+
* 交付物是一份**规范 env 文件**,格式与 `pxbaas profile import` 的多租户输入契约逐字
|
|
6
|
+
* 对齐(credentials/env-file.ts 的 TENANT_* 分支),所以收件人不需要手改任何字段名。
|
|
7
|
+
*
|
|
8
|
+
* 三条硬纪律:
|
|
9
|
+
* 1. **字段白名单**。bundle 内容由本模块**逐字段显式拼装**,因此结构上不可能包含
|
|
10
|
+
* `jwt_secret`(租户签名母密钥)、`DASHBOARD_*`(实例管理口令)或 `GLOBAL_*`
|
|
11
|
+
* (平台全局密钥)。这不是"记得过滤",而是根本没有把它们写进去的入口。
|
|
12
|
+
* 2. **明文只落 0600 文件,绝不进 stdout / `--json` / 日志**。终端上只出现指纹。
|
|
13
|
+
* 3. **不留存于内存之外**:调用方拿到 keys 后要么写钥匙串,要么交给本模块写文件。
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import { existsSync } from 'node:fs';
|
|
17
|
+
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { dirname, join, resolve } from 'node:path';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { computeFingerprint } from '../credentials/index.js';
|
|
21
|
+
export const BUNDLE_VERSION = 1;
|
|
22
|
+
/**
|
|
23
|
+
* 渲染交付包文本。只输出这 5(+1)个变量:
|
|
24
|
+
* MULTI_TENANT_MODE / SUPABASE_URL / DEFAULT_TENANT_ID / TENANT_ANON_KEY /
|
|
25
|
+
* TENANT_SERVICE_ROLE_KEY(可选 SUPABASE_INTRANET_URL)。
|
|
26
|
+
*/
|
|
27
|
+
export function renderBundle(input) {
|
|
28
|
+
const endpoint = stripSlash(input.endpoint);
|
|
29
|
+
const generatedAt = input.generatedAt ?? new Date().toISOString();
|
|
30
|
+
// 注释头:parseEnvText 会安全忽略 '#' 行,因此头部不需要解析器改动。
|
|
31
|
+
const header = [
|
|
32
|
+
'# PolarDB-X BaaS 租户接入包 (tenant access bundle)',
|
|
33
|
+
`# tenant_id : ${input.tenantId}`,
|
|
34
|
+
`# instance : ${endpoint} (Kong 网关,勿改成 Studio/内网调试端口)`,
|
|
35
|
+
`# created_at : ${generatedAt}`,
|
|
36
|
+
input.issuedBy ? `# issued_by : ${input.issuedBy}` : undefined,
|
|
37
|
+
'#',
|
|
38
|
+
'# ⚠ 本文件含明文租户密钥,且:有效期约 10 年、当前平台不支持撤销。',
|
|
39
|
+
'# - 只通过安全通道传输(受控网盘 / 密邮正文 / 当面拷贝);不要贴进 IM 群、工单附件、截图或聊天记录',
|
|
40
|
+
'# - 收件人导入成功后请删除本文件(凭据会进入其操作系统钥匙串)',
|
|
41
|
+
'# - 怀疑泄露:当前只能由平台侧重建该租户',
|
|
42
|
+
'# ============================================================',
|
|
43
|
+
'MULTI_TENANT_MODE=true',
|
|
44
|
+
`SUPABASE_URL=${endpoint}`,
|
|
45
|
+
`DEFAULT_TENANT_ID=${input.tenantId}`,
|
|
46
|
+
`TENANT_ANON_KEY=${input.anonKey}`,
|
|
47
|
+
`TENANT_SERVICE_ROLE_KEY=${input.serviceRoleKey}`,
|
|
48
|
+
];
|
|
49
|
+
if (input.intranetEndpoint) {
|
|
50
|
+
header.push(`SUPABASE_INTRANET_URL=${stripSlash(input.intranetEndpoint)}`);
|
|
51
|
+
}
|
|
52
|
+
return header.join('\n') + '\n';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 写交付包。目标已存在时**必须**显式 `overwrite`,否则拒绝 —— 不静默覆盖别人的接入包。
|
|
56
|
+
*/
|
|
57
|
+
export async function writeBundle(file, input, options = {}) {
|
|
58
|
+
const path = resolve(file);
|
|
59
|
+
if (existsSync(path) && !options.overwrite) {
|
|
60
|
+
throw new Error(`Bundle file already exists: ${path}. Pass --overwrite to replace it (the old bundle's keys stay valid — overwriting the file does NOT revoke them).`);
|
|
61
|
+
}
|
|
62
|
+
const text = renderBundle(input);
|
|
63
|
+
const dir = dirname(path);
|
|
64
|
+
if (!existsSync(dir)) {
|
|
65
|
+
await mkdir(dir, { mode: 0o700, recursive: true });
|
|
66
|
+
}
|
|
67
|
+
await writeFile(path, text, { mode: 0o600 });
|
|
68
|
+
await chmod(path, 0o600);
|
|
69
|
+
const generatedAt = input.generatedAt ?? new Date().toISOString();
|
|
70
|
+
const record = {
|
|
71
|
+
tenantId: input.tenantId,
|
|
72
|
+
endpoint: stripSlash(input.endpoint),
|
|
73
|
+
generatedAt,
|
|
74
|
+
anonFingerprint: computeFingerprint(input.anonKey),
|
|
75
|
+
serviceFingerprint: computeFingerprint(input.serviceRoleKey),
|
|
76
|
+
bundlePath: path,
|
|
77
|
+
bundleSha256: createHash('sha256').update(text).digest('hex'),
|
|
78
|
+
issuedBy: input.issuedBy,
|
|
79
|
+
};
|
|
80
|
+
await appendHandoffRecord(record, options.homeDir);
|
|
81
|
+
return { path, bytes: Buffer.byteLength(text), record, instructions: renderInstructions(record) };
|
|
82
|
+
}
|
|
83
|
+
/** 可直接复制转发给使用者的交接说明(不含任何密钥值)。 */
|
|
84
|
+
export function renderInstructions(record) {
|
|
85
|
+
return [
|
|
86
|
+
`下一步:把 ${record.bundlePath} 通过安全通道发给该租户的使用者,并附上以下说明。`,
|
|
87
|
+
'',
|
|
88
|
+
` 1) 安装 CLI(需 Node.js >= 20): npm install -g @polardbx/pxbaas@beta`,
|
|
89
|
+
` 2) 导入接入包: pxbaas profile import ${record.bundlePath.split('/').pop()} --name ${record.tenantId} --json`,
|
|
90
|
+
' 3) 自检: pxbaas whoami --json → 期望 mode=multi-tenant、tenantId=' + record.tenantId,
|
|
91
|
+
' 4) 健康检查: pxbaas doctor --json → 5 项全 pass,Tenant Consistency 必须 pass',
|
|
92
|
+
' 5) 打通数据面: pxbaas db tables --json',
|
|
93
|
+
' 6) 全部通过后删除该 env 文件',
|
|
94
|
+
'',
|
|
95
|
+
' 指纹核对(证明收件人拿到的就是这份包,防传输途中被替换):',
|
|
96
|
+
` anon: ${record.anonFingerprint}`,
|
|
97
|
+
` service_role: ${record.serviceFingerprint}`,
|
|
98
|
+
' 收件人在 `pxbaas whoami --json` 里比对 anonKey.fingerprint / serviceKey.fingerprint 是否一致。',
|
|
99
|
+
].join('\n');
|
|
100
|
+
}
|
|
101
|
+
const HANDOFF_FILE_NAME = 'handoffs.json';
|
|
102
|
+
export async function listHandoffs(homeDir) {
|
|
103
|
+
const path = join(homeDir ?? join(homedir(), '.baas'), HANDOFF_FILE_NAME);
|
|
104
|
+
if (!existsSync(path))
|
|
105
|
+
return [];
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(await readFile(path, 'utf-8'));
|
|
108
|
+
return parsed.records ?? [];
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 签发台账:只记指纹与文件哈希,**不含任何明文密钥**。0600。
|
|
116
|
+
* 泄露事件回溯时这是唯一能回答"我发过哪些包、对应哪个租户"的记录。
|
|
117
|
+
*/
|
|
118
|
+
export async function appendHandoffRecord(record, homeDir) {
|
|
119
|
+
const dir = homeDir ?? join(homedir(), '.baas');
|
|
120
|
+
const path = join(dir, HANDOFF_FILE_NAME);
|
|
121
|
+
const records = await listHandoffs(dir);
|
|
122
|
+
records.push(record);
|
|
123
|
+
if (!existsSync(dir)) {
|
|
124
|
+
await mkdir(dir, { mode: 0o700, recursive: true });
|
|
125
|
+
}
|
|
126
|
+
await writeFile(path, JSON.stringify({ version: BUNDLE_VERSION, records }, null, 2) + '\n', { mode: 0o600 });
|
|
127
|
+
await chmod(path, 0o600);
|
|
128
|
+
}
|
|
129
|
+
function stripSlash(value) {
|
|
130
|
+
return value.replace(/\/+$/, '');
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/tenant/bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 多租户接入缺口的诊断与引导(方案文档 §5.4)。
|
|
3
|
+
*
|
|
4
|
+
* 原来 `profile import` 撞到"多租户 env 却没有租户级凭据"时只抛一句拒绝,而它给出的
|
|
5
|
+
* 两个建议("重新生成 client.env"、"用 per-tenant key 登录")**都是使用者自己做不到**
|
|
6
|
+
* 的动作——租户级密钥由平台签发。结果是 CLI 把用户堵在门口,还让他以为是自己的错。
|
|
7
|
+
*
|
|
8
|
+
* 本模块把这一处变成两条明确出口:
|
|
9
|
+
* - 非管理员 → 一份可以直接转给实例管理员的**申请清单**(要哪个租户、哪两把值、
|
|
10
|
+
* 以及怎么判断拿到的到底是不是租户级密钥);
|
|
11
|
+
* - 具备管理面能力 → 指出可以用 `pxbaas tenant ...` 自助开通/取键,并给出命令。
|
|
12
|
+
*
|
|
13
|
+
* 边界:这里**只读、只打印**,绝不在失败分支里创建租户(读路径不携带建库/建账号/
|
|
14
|
+
* 占配额这类写副作用,见方案 N2)。管理凭据也只做**临时**探测,绝不落库(N3)。
|
|
15
|
+
*/
|
|
16
|
+
import { type ParsedEnv } from '../credentials/index.js';
|
|
17
|
+
import { type TenantProbeResult } from './probe.js';
|
|
18
|
+
export interface KeyFinding {
|
|
19
|
+
variable: string;
|
|
20
|
+
role?: string;
|
|
21
|
+
/** JWT 里的 tenant_id claim;无 = 平台全局密钥,无法访问租户资源。 */
|
|
22
|
+
tenantId?: string;
|
|
23
|
+
expired: boolean;
|
|
24
|
+
fingerprint: string;
|
|
25
|
+
note: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TenantGapDiagnostics {
|
|
28
|
+
envFile?: string;
|
|
29
|
+
endpoint?: string;
|
|
30
|
+
multiTenantMode?: string;
|
|
31
|
+
defaultTenantId?: string;
|
|
32
|
+
tenantLevelKeysPresent: string[];
|
|
33
|
+
keyFindings: KeyFinding[];
|
|
34
|
+
/** env 文件里是否有成对的 dashboard 凭据(仅报告存在,不导入)。 */
|
|
35
|
+
adminCredentialsPresent: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** 纯本地解析:不联网、不写任何状态。 */
|
|
38
|
+
export declare function diagnoseTenantCredentialGap(env: ParsedEnv, options?: {
|
|
39
|
+
envFile?: string;
|
|
40
|
+
}): TenantGapDiagnostics;
|
|
41
|
+
/** 非管理员出口:一份可原样转给实例管理员的申请清单。 */
|
|
42
|
+
export declare function renderRequestChecklist(diag: TenantGapDiagnostics): string;
|
|
43
|
+
/** 管理员出口:指出可以自助的动作与命令。 */
|
|
44
|
+
export declare function renderAdminPath(diag: TenantGapDiagnostics, probe: TenantProbeResult): string;
|
|
45
|
+
/**
|
|
46
|
+
* 用 env 里的 dashboard 凭据做一次**临时**探测:只在内存里使用,不落库、不写文件。
|
|
47
|
+
* 没有成对凭据时返回 undefined(调用方走非管理员出口)。
|
|
48
|
+
*/
|
|
49
|
+
export declare function tryProbeFromEnv(env: ParsedEnv, endpoint: string | undefined): Promise<TenantProbeResult | undefined>;
|
|
50
|
+
//# sourceMappingURL=guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/tenant/guide.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAExF,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AActE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6CAA6C;IAC7C,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,wBAAwB;AACxB,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,SAAS,EACd,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,oBAAoB,CAiDtB;AAED,gCAAgC;AAChC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAiCzE;AAED,0BAA0B;AAC1B,wBAAgB,eAAe,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAwB5F;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAUxC"}
|