@layers/amba 1.1.0 → 4.0.2
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 +1 -1
- package/dist/api-client.d.ts +33 -6
- package/dist/auth.d.ts +8 -0
- package/dist/bundle.d.ts +23 -9
- package/dist/commands/billing.d.ts +34 -0
- package/dist/commands/claim.d.ts +41 -0
- package/dist/commands/init.d.ts +24 -24
- package/dist/commands/projects.d.ts +8 -0
- package/dist/credentials.d.ts +259 -0
- package/dist/index.js +2418 -657
- package/dist/sandbox.d.ts +35 -37
- package/dist/skill-installer.d.ts +95 -0
- package/dist/skills/presets.d.ts +146 -0
- package/dist/skills.d.ts +239 -48
- package/package.json +4 -2
- package/skill-bundle/SKILL.md +324 -0
- package/skill-bundle/references/economy.md +331 -0
- package/skill-bundle/references/engagement.md +400 -0
- package/skill-bundle/references/gamification.md +316 -0
- package/skill-bundle/references/identity.md +395 -0
- package/skill-bundle/references/infrastructure.md +348 -0
- package/skill-bundle/references/social.md +366 -0
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ After restarting your MCP client, paste:
|
|
|
38
38
|
|
|
39
39
|
…to scaffold a full Expo app with Amba as the only backend. The skill
|
|
40
40
|
fetches the canonical prompt from
|
|
41
|
-
<https://docs.amba.dev/
|
|
41
|
+
<https://docs.amba.dev/prompts/expo-build> at invocation time and
|
|
42
42
|
falls back to an inlined snapshot when offline. Use `--no-skills` to
|
|
43
43
|
skip the skill install.
|
|
44
44
|
|
package/dist/api-client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface ProjectSummary {
|
|
|
20
20
|
platform: string;
|
|
21
21
|
environment?: string;
|
|
22
22
|
bundle_id?: string | null;
|
|
23
|
+
google_oauth_client_id?: string | null;
|
|
23
24
|
status?: string;
|
|
24
25
|
created_at?: string;
|
|
25
26
|
}
|
|
@@ -27,6 +28,12 @@ export declare function listProjects(): Promise<ApiListResponse<ProjectSummary>>
|
|
|
27
28
|
export declare function createProject(input: {
|
|
28
29
|
name: string;
|
|
29
30
|
bundle_id?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Google OAuth 2.0 client id. Doubles as the audience the server
|
|
33
|
+
* expects on Google Sign In id tokens — set this if your app uses
|
|
34
|
+
* Sign in with Google. Public identifier, not a secret.
|
|
35
|
+
*/
|
|
36
|
+
google_oauth_client_id?: string;
|
|
30
37
|
platform?: string;
|
|
31
38
|
/**
|
|
32
39
|
* Project environment. `'development'` flags the row as the developer's
|
|
@@ -40,6 +47,25 @@ export declare function createProject(input: {
|
|
|
40
47
|
platform: string;
|
|
41
48
|
environment?: string;
|
|
42
49
|
}>>;
|
|
50
|
+
/**
|
|
51
|
+
* PATCH /admin/projects/:projectId — update mutable fields. Server
|
|
52
|
+
* silently ignores unknown keys; we filter to the documented allow-list
|
|
53
|
+
* before sending so a typo at the CLI doesn't pass the wire silently.
|
|
54
|
+
*/
|
|
55
|
+
export declare function updateProject(projectId: string, patch: {
|
|
56
|
+
name?: string;
|
|
57
|
+
bundle_id?: string | null;
|
|
58
|
+
google_oauth_client_id?: string | null;
|
|
59
|
+
platform?: string;
|
|
60
|
+
environment?: string;
|
|
61
|
+
}): Promise<ApiResponse<{
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
bundle_id: string | null;
|
|
65
|
+
google_oauth_client_id: string | null;
|
|
66
|
+
platform: string;
|
|
67
|
+
environment: string;
|
|
68
|
+
}>>;
|
|
43
69
|
export declare function getProject(projectId: string): Promise<ApiResponse<{
|
|
44
70
|
id: string;
|
|
45
71
|
name: string;
|
|
@@ -53,15 +79,16 @@ export declare function deleteProject(projectId: string): Promise<ApiResponse<{
|
|
|
53
79
|
deleted: boolean;
|
|
54
80
|
}>>;
|
|
55
81
|
export declare function reprovisionProject(projectId: string): Promise<ApiResponse<{
|
|
56
|
-
|
|
82
|
+
projectId: string;
|
|
83
|
+
job_id?: string;
|
|
57
84
|
status?: string;
|
|
58
|
-
|
|
85
|
+
collapsed?: boolean;
|
|
59
86
|
}>>;
|
|
60
87
|
export declare function getProvisioningStatus(projectId: string): Promise<ApiResponse<{
|
|
61
88
|
projectId: string;
|
|
62
89
|
status: string;
|
|
63
|
-
|
|
64
|
-
|
|
90
|
+
provisioned_at: string | null;
|
|
91
|
+
region: string | null;
|
|
65
92
|
}>>;
|
|
66
93
|
export declare function createApiKey(projectId: string, keyType: 'client' | 'server', environment: 'development' | 'production'): Promise<ApiResponse<{
|
|
67
94
|
id: string;
|
|
@@ -521,8 +548,8 @@ export declare function dropCollection(projectId: string, name: string, confirm:
|
|
|
521
548
|
export type AiProviderName = 'anthropic' | 'openai';
|
|
522
549
|
export interface AiProviderRow {
|
|
523
550
|
name: AiProviderName;
|
|
524
|
-
/**
|
|
525
|
-
|
|
551
|
+
/** Whether an API key is currently configured for this provider. */
|
|
552
|
+
configured: boolean;
|
|
526
553
|
/** Preview cue printed to the CLI on register; NOT a real partial key. */
|
|
527
554
|
api_key_preview?: string;
|
|
528
555
|
created_at?: string;
|
package/dist/auth.d.ts
CHANGED
|
@@ -37,6 +37,14 @@ export declare function clearCredentials(): Promise<void>;
|
|
|
37
37
|
* `null` clears any prior override.
|
|
38
38
|
*/
|
|
39
39
|
export declare function setBearerOverride(token: string | null): void;
|
|
40
|
+
/**
|
|
41
|
+
* Read the current bearer override without consuming it. Returns
|
|
42
|
+
* `null` when no override is set. Used by commands that need to know
|
|
43
|
+
* "did the operator supply a PAT for this invocation?" — e.g. `init`
|
|
44
|
+
* branches on whether to bypass stored-creds and use the supplied
|
|
45
|
+
* token verbatim.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getBearerOverride(): string | null;
|
|
40
48
|
/** Test-only: reset the override between cases. */
|
|
41
49
|
export declare function __resetTokenOverride(): void;
|
|
42
50
|
/**
|
package/dist/bundle.d.ts
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Customer-function bundling for `amba functions deploy`.
|
|
3
3
|
*
|
|
4
|
-
* Uses esbuild
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* these resolve at dispatch time via platform-level bindings.
|
|
4
|
+
* Uses esbuild. Customer code is bundled into a single self-contained
|
|
5
|
+
* ES module — the upstream runtime resolves nothing at dispatch time
|
|
6
|
+
* except built-in JavaScript globals.
|
|
8
7
|
*
|
|
9
8
|
* Two checks gate the bundle before upload:
|
|
10
9
|
* 1. Pre-upload size check against `BUNDLE_MAX_SIZE_BYTES` (8 MB
|
|
11
10
|
* default — the platform's 10 MB compressed cap minus 2 MB
|
|
12
11
|
* headroom) with a clear error pointing at the externalization
|
|
13
12
|
* config.
|
|
14
|
-
* 2. Bundle-shape report — the CLI prints what's
|
|
15
|
-
*
|
|
13
|
+
* 2. Bundle-shape report — the CLI prints what's bundled vs
|
|
14
|
+
* externalized at deploy time so size issues are debuggable.
|
|
15
|
+
*
|
|
16
|
+
* History note (2026-05-27): the prior version of this file pinned
|
|
17
|
+
* `@layers/amba-functions` + `@layers/amba-api-middleware` as
|
|
18
|
+
* "platform-level bindings" externals. Neither is — they were
|
|
19
|
+
* server-side packages, and `@layers/amba-functions` was unpublished
|
|
20
|
+
* in the 4.0.2 cutover (a deprecated wrapper that never matched the
|
|
21
|
+
* actual runtime). Any function importing one of them was rejected
|
|
22
|
+
* upstream as "no such module." The default externals list is now
|
|
23
|
+
* empty; customer code is expected to be self-contained.
|
|
16
24
|
*/
|
|
17
25
|
import { type BuildOptions } from 'esbuild';
|
|
18
26
|
/**
|
|
19
|
-
* Modules
|
|
20
|
-
*
|
|
21
|
-
*
|
|
27
|
+
* Modules the bundler treats as `external` by default. The Amba
|
|
28
|
+
* function runtime exposes zero npm packages — there is no "platform
|
|
29
|
+
* stdlib" for customer functions to import. Keep this list empty.
|
|
30
|
+
*
|
|
31
|
+
* The `extraExternals` field on `BundleOptions` is a programmatic
|
|
32
|
+
* escape hatch (used by tests + future CLI wiring). It's intentionally
|
|
33
|
+
* not exposed as a `amba functions deploy` flag today — externalizing
|
|
34
|
+
* a module that isn't actually provided at runtime is exactly the
|
|
35
|
+
* footgun this list-defaults-to-empty change closes.
|
|
22
36
|
*/
|
|
23
37
|
export declare const RUNTIME_STDLIB_EXTERNALS: readonly string[];
|
|
24
38
|
/**
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `amba billing *` subcommands — CLI access to the per-project billing
|
|
3
|
+
* surface that ships behind `/v1/admin/projects/:id/billing/*`.
|
|
4
|
+
*
|
|
5
|
+
* amba billing status — tier, headroom on each
|
|
6
|
+
* metered axis, next-bill date,
|
|
7
|
+
* human_action_required.
|
|
8
|
+
*
|
|
9
|
+
* amba billing upgrade --tier <t> — print the Stripe Checkout
|
|
10
|
+
* URL for tier ∈ {pro, scale}
|
|
11
|
+
* [--interval month|year] at the chosen interval. CLI
|
|
12
|
+
* deliberately does NOT auto-
|
|
13
|
+
* open a browser: agents pipe
|
|
14
|
+
* the URL into a confirmation
|
|
15
|
+
* step, humans copy-paste.
|
|
16
|
+
*
|
|
17
|
+
* amba billing portal — print the Customer Portal
|
|
18
|
+
* URL for card / cancel / etc.
|
|
19
|
+
*
|
|
20
|
+
* amba billing set-ceiling <usd|off> — cap (or remove) the monthly
|
|
21
|
+
* spend ceiling.
|
|
22
|
+
*
|
|
23
|
+
* Project is resolved via `loadProjectConfig` (AMBA_PROJECT_ID env, then
|
|
24
|
+
* .env / .env.local in the cwd) — same pattern as `amba secrets *`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function billingStatusCommand(): Promise<void>;
|
|
27
|
+
export declare function billingUpgradeCommand(input: {
|
|
28
|
+
tier: 'pro' | 'scale';
|
|
29
|
+
interval?: 'month' | 'year';
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
export declare function billingPortalCommand(): Promise<void>;
|
|
32
|
+
export declare function billingSetCeilingCommand(input: {
|
|
33
|
+
ceiling: number | null;
|
|
34
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `amba claim <email>` — bind a sandbox account to a real email address
|
|
3
|
+
* via a one-click magic link.
|
|
4
|
+
*
|
|
5
|
+
* Sandbox accounts are minted with an auto-generated address
|
|
6
|
+
* (`sandbox-<epoch>-<nonce>@layers.com`) and remain capped at 100 MAU /
|
|
7
|
+
* 10 MB DB until the developer claims a real email. This command POSTs
|
|
8
|
+
* the target email to `/v1/auth/developer/claim` under the developer's
|
|
9
|
+
* stored PAT; the backend emails a single-use magic link that — when
|
|
10
|
+
* clicked — updates the developer row and flips the project tier from
|
|
11
|
+
* `sandbox` to `verified_free` (1,000 MAU, 500 MB DB).
|
|
12
|
+
*
|
|
13
|
+
* Wire shape:
|
|
14
|
+
*
|
|
15
|
+
* POST {AMBA_API_URL}/v1/auth/developer/claim
|
|
16
|
+
* Authorization: Bearer {pat}
|
|
17
|
+
* Content-Type: application/json
|
|
18
|
+
* Body: { "email": "<target-email>" }
|
|
19
|
+
*
|
|
20
|
+
* Success: HTTP 200 `{ "ok": true }`
|
|
21
|
+
* Errors: HTTP 400 INVALID_INPUT
|
|
22
|
+
* HTTP 409 EMAIL_TAKEN — that address already owns another account
|
|
23
|
+
* HTTP 409 ALREADY_CLAIMED — this account is already verified
|
|
24
|
+
* HTTP 429 — rate-limited
|
|
25
|
+
* HTTP 5xx — surface verbatim with code + message
|
|
26
|
+
*
|
|
27
|
+
* UX contract: a single ✓ line + a hint that the link expires in 15
|
|
28
|
+
* minutes. No copy-paste tokens, no follow-up commands. The click in
|
|
29
|
+
* the email is the whole flow.
|
|
30
|
+
*/
|
|
31
|
+
export interface ClaimCommandOptions {
|
|
32
|
+
/** Override the API root for tests + ops. Defaults to env or `https://api.amba.dev`. */
|
|
33
|
+
apiUrl?: string;
|
|
34
|
+
/** Inject a fetch implementation — test seam. */
|
|
35
|
+
fetchImpl?: typeof fetch;
|
|
36
|
+
/** Inject the developer PAT directly — test seam. Bypasses ~/.amba lookup. */
|
|
37
|
+
pat?: string;
|
|
38
|
+
/** Override `~/` resolution for credential lookup — test seam. */
|
|
39
|
+
homeDir?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function claimCommand(email: string, options?: ClaimCommandOptions): Promise<void>;
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -40,42 +40,42 @@ export declare function runSandboxInit(cwd: string, options: {
|
|
|
40
40
|
sandboxEmail?: string;
|
|
41
41
|
noMcpConfig?: boolean;
|
|
42
42
|
/**
|
|
43
|
-
* Skip the project-local
|
|
44
|
-
*
|
|
45
|
-
* "/amba-build <design>" invocation work). Set true in CI or
|
|
46
|
-
* during tests that don't want stray files written into the
|
|
47
|
-
* caller's CWD.
|
|
43
|
+
* Skip the project-local skill install. Default is to install. Set
|
|
44
|
+
* true in CI or during tests that don't want stray files written.
|
|
48
45
|
*/
|
|
49
46
|
noSkills?: boolean;
|
|
50
47
|
json?: boolean;
|
|
51
48
|
/**
|
|
52
49
|
* Override `~/` resolution. The CLI itself never passes this — it's
|
|
53
50
|
* the seam tests use to avoid touching the developer's actual home
|
|
54
|
-
* directory.
|
|
55
|
-
* dependency injection is the cleanest substitute.)
|
|
51
|
+
* directory.
|
|
56
52
|
*/
|
|
57
53
|
homeDir?: string;
|
|
58
54
|
}): Promise<SandboxResult>;
|
|
59
55
|
/**
|
|
60
56
|
* Build the plaintext (no ANSI) success-output block printed at the
|
|
61
|
-
* end of `amba init --sandbox`. Pure function — exported
|
|
62
|
-
* vitest cases that assert on per-line content. The CLI wraps
|
|
63
|
-
*
|
|
57
|
+
* end of `amba init --sandbox`. Pure function — exported for the
|
|
58
|
+
* vitest cases that assert on per-line content. The CLI wraps the
|
|
59
|
+
* output with picocolors in `printSandboxNextSteps` below.
|
|
64
60
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* was written (manual-paste path), falls back to a generic
|
|
72
|
-
* "quit + reopen" line.
|
|
73
|
-
* 4. Tail-line resume hint + sandbox limits + verify URL.
|
|
61
|
+
* Design: silent-until-done. The install (provision account, mint
|
|
62
|
+
* keys, write .env.local, write MCP config, install skill) is COMPLETE
|
|
63
|
+
* the moment this output lands. The MCP config has been persisted —
|
|
64
|
+
* it activates on the next launch of the developer's coding agent. We
|
|
65
|
+
* do NOT instruct the developer to restart anything; we just state
|
|
66
|
+
* what's wired and what's next.
|
|
74
67
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
68
|
+
* Shape (~6 lines, Vercel/Stripe aesthetic):
|
|
69
|
+
* ✓ Amba ready
|
|
70
|
+
* project: <id>
|
|
71
|
+
* keys → .env.local
|
|
72
|
+
* mcp → <paths> (active next agent launch)
|
|
73
|
+
* skill → <skill paths> (when installed)
|
|
74
|
+
*
|
|
75
|
+
* next: npm install <sdk-pkg>
|
|
76
|
+
* Amba.configure({ projectId, clientKey }) at app startup
|
|
77
|
+
*
|
|
78
|
+
* The fallback for "no MCP client config detected" is a one-line
|
|
79
|
+
* note + a paste-ready snippet — still no restart copy.
|
|
80
80
|
*/
|
|
81
81
|
export declare function buildSandboxNextStepsLines(r: SandboxResult): string[];
|
|
@@ -3,8 +3,16 @@ export declare function projectsCreateCommand(input: {
|
|
|
3
3
|
name: string;
|
|
4
4
|
env?: string;
|
|
5
5
|
bundleId?: string;
|
|
6
|
+
googleOauthClientId?: string;
|
|
6
7
|
platform?: string;
|
|
7
8
|
}): Promise<void>;
|
|
9
|
+
export declare function projectsUpdateCommand(projectId: string, input: {
|
|
10
|
+
name?: string;
|
|
11
|
+
bundleId?: string;
|
|
12
|
+
googleOauthClientId?: string;
|
|
13
|
+
platform?: string;
|
|
14
|
+
environment?: string;
|
|
15
|
+
}): Promise<void>;
|
|
8
16
|
export declare function projectsShowCommand(projectId: string): Promise<void>;
|
|
9
17
|
export declare function projectsDeleteCommand(projectId: string, opts?: {
|
|
10
18
|
yes?: boolean;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two-scope credential model for `amba init`.
|
|
3
|
+
*
|
|
4
|
+
* Identity is **developer-scoped** (one machine identity, persisted in
|
|
5
|
+
* `~/.amba/credentials.json`). State is **project-scoped** (one per
|
|
6
|
+
* project directory, persisted in `<cwd>/.amba/project.json`).
|
|
7
|
+
*
|
|
8
|
+
* One Amba account can own N projects. Running `amba init` in five
|
|
9
|
+
* different folders under one identity yields one developer row + five
|
|
10
|
+
* project rows — exactly the model `apps/console` and the API enforce.
|
|
11
|
+
*
|
|
12
|
+
* Backward compatibility
|
|
13
|
+
* ----------------------
|
|
14
|
+
* The legacy `~/.amba/credentials.json` (browser-OAuth era) carried
|
|
15
|
+
* `{ access_token, refresh_token, expires_at }`. We read both shapes —
|
|
16
|
+
* a missing `version` key signals legacy and triggers a one-shot
|
|
17
|
+
* in-place upgrade after the first successful `developer_me` verify.
|
|
18
|
+
*
|
|
19
|
+
* Idempotency
|
|
20
|
+
* -----------
|
|
21
|
+
* `ensureDeveloperIdentity` + `ensureProjectForCwd` are the two entry
|
|
22
|
+
* points. Both are safe to call on every `amba init` run:
|
|
23
|
+
* - identity: load → verify → upgrade-or-keep; only signs up if no
|
|
24
|
+
* verified PAT exists anywhere.
|
|
25
|
+
* - project: load `<cwd>/.amba/project.json` → verify the
|
|
26
|
+
* `project_id` still belongs to the current developer; if missing
|
|
27
|
+
* or stale, mint a new project under the dev's identity.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Developer identity stored at `~/.amba/credentials.json`.
|
|
31
|
+
*
|
|
32
|
+
* One per machine. Persists across project folders and re-runs.
|
|
33
|
+
*/
|
|
34
|
+
export interface DeveloperCredentials {
|
|
35
|
+
/** Schema version — increments when the shape changes incompatibly. */
|
|
36
|
+
version: 1;
|
|
37
|
+
/** Developer UUID from the control DB. Populated post-verify. */
|
|
38
|
+
developer_id: string | null;
|
|
39
|
+
/** Email on the developer row. May be auto-generated for sandbox accounts. */
|
|
40
|
+
email: string;
|
|
41
|
+
/** Personal Access Token (`amb_dpat_…`). Long-lived. */
|
|
42
|
+
pat: string;
|
|
43
|
+
/** API root the PAT was minted against. */
|
|
44
|
+
api_url: string;
|
|
45
|
+
/** How this identity was created. */
|
|
46
|
+
source: 'sandbox-init' | 'browser-auth' | 'manual' | 'legacy';
|
|
47
|
+
/** ISO timestamp when this record was written/upgraded. */
|
|
48
|
+
created_at: string;
|
|
49
|
+
/** Mirrors `pat`. */
|
|
50
|
+
access_token: string;
|
|
51
|
+
/** Empty string — PATs don't refresh. */
|
|
52
|
+
refresh_token: '';
|
|
53
|
+
/** Far-future ISO timestamp — PATs don't expire on the client side. */
|
|
54
|
+
expires_at: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Project state stored at `<cwd>/.amba/project.json`.
|
|
58
|
+
*
|
|
59
|
+
* One per project directory. Tracks which project this folder is
|
|
60
|
+
* attached to (so re-running `amba init` in the same folder is
|
|
61
|
+
* idempotent) plus the credentials needed for SDK init.
|
|
62
|
+
*/
|
|
63
|
+
export interface ProjectCredentials {
|
|
64
|
+
version: 1;
|
|
65
|
+
project_id: string;
|
|
66
|
+
project_name: string;
|
|
67
|
+
environment: 'development' | 'production';
|
|
68
|
+
client_key: string;
|
|
69
|
+
/** Server key — present when minted. Used by Node SDK / server code. */
|
|
70
|
+
server_key: string | null;
|
|
71
|
+
api_url: string;
|
|
72
|
+
/**
|
|
73
|
+
* List of Amba surfaces this project has been wired up with via the
|
|
74
|
+
* skill (e.g. `['identity','streaks','achievements']`). The skill
|
|
75
|
+
* consults this on re-runs to avoid re-creating existing resources.
|
|
76
|
+
*/
|
|
77
|
+
wired_surfaces: string[];
|
|
78
|
+
created_at: string;
|
|
79
|
+
updated_at: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Result returned by `verifyPat`. Subset of the API's
|
|
83
|
+
* `GET /v1/auth/developer/me` response — only the fields the CLI
|
|
84
|
+
* actually consumes.
|
|
85
|
+
*/
|
|
86
|
+
export interface DeveloperMeResult {
|
|
87
|
+
id: string;
|
|
88
|
+
email: string;
|
|
89
|
+
name?: string;
|
|
90
|
+
}
|
|
91
|
+
export declare function developerCredentialsPath(homeDir?: string): string;
|
|
92
|
+
export declare function projectCredentialsPath(cwd: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Read `~/.amba/credentials.json`. Returns null when the file is
|
|
95
|
+
* missing, malformed, or empty. Handles both new (versioned) and
|
|
96
|
+
* legacy shapes — legacy returns `version: 1` after migration but
|
|
97
|
+
* with `source: 'legacy'` so callers can tell.
|
|
98
|
+
*
|
|
99
|
+
* Does NOT verify the PAT against the API. Caller must follow up
|
|
100
|
+
* with `verifyPat` before trusting the identity.
|
|
101
|
+
*/
|
|
102
|
+
export declare function loadDeveloperCredentials(options?: {
|
|
103
|
+
homeDir?: string;
|
|
104
|
+
}): Promise<DeveloperCredentials | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Atomically write developer credentials to `~/.amba/credentials.json`
|
|
107
|
+
* with mode 0600. Writes to a sibling `.tmp` first and renames into
|
|
108
|
+
* place so a crash mid-write doesn't leave the file empty.
|
|
109
|
+
*
|
|
110
|
+
* Backs up an existing file when its `source` is not one of the
|
|
111
|
+
* managed sources OR when the existing PAT differs from the one being
|
|
112
|
+
* written. The backup goes to `credentials.json.bak-<unix-ms>`.
|
|
113
|
+
*/
|
|
114
|
+
export declare function writeDeveloperCredentials(creds: DeveloperCredentials, options?: {
|
|
115
|
+
homeDir?: string;
|
|
116
|
+
}): Promise<{
|
|
117
|
+
path: string;
|
|
118
|
+
backedUpTo: string | null;
|
|
119
|
+
}>;
|
|
120
|
+
export declare function loadProjectCredentials(cwd: string): Promise<ProjectCredentials | null>;
|
|
121
|
+
export declare function writeProjectCredentials(cwd: string, creds: ProjectCredentials): Promise<string>;
|
|
122
|
+
/**
|
|
123
|
+
* Verify a PAT by calling `GET /v1/auth/developer/me`. Returns the
|
|
124
|
+
* developer row on success, `null` on 401/403/404 (PAT invalid or
|
|
125
|
+
* developer not found), or throws on network / 5xx errors.
|
|
126
|
+
*
|
|
127
|
+
* This is the single source of truth for "do we have a working
|
|
128
|
+
* identity." Used at the top of every init run.
|
|
129
|
+
*/
|
|
130
|
+
export declare function verifyPat(pat: string, options?: {
|
|
131
|
+
apiUrl?: string;
|
|
132
|
+
fetchImpl?: typeof fetch;
|
|
133
|
+
}): Promise<DeveloperMeResult | null>;
|
|
134
|
+
export interface EnsureDeveloperOptions {
|
|
135
|
+
homeDir?: string;
|
|
136
|
+
apiUrl?: string;
|
|
137
|
+
fetchImpl?: typeof fetch;
|
|
138
|
+
/**
|
|
139
|
+
* When true, never call signup — if the existing credential is
|
|
140
|
+
* invalid, throw instead. Used by the interactive (non-headless)
|
|
141
|
+
* init path where the user expects a browser-auth fallback.
|
|
142
|
+
*/
|
|
143
|
+
signupOnMissing?: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Optional override for the auto-generated sandbox email. Surfaced
|
|
146
|
+
* by the CLI's `--email <addr>` flag for tests + manual sandbox
|
|
147
|
+
* provisioning under a known address. Ignored when an existing
|
|
148
|
+
* identity is reused.
|
|
149
|
+
*/
|
|
150
|
+
sandboxEmail?: string;
|
|
151
|
+
}
|
|
152
|
+
export interface EnsureDeveloperResult {
|
|
153
|
+
credentials: DeveloperCredentials;
|
|
154
|
+
/** True when we minted a fresh sandbox account this run. */
|
|
155
|
+
newlySignedUp: boolean;
|
|
156
|
+
/** Verified developer row from the API. */
|
|
157
|
+
developer: DeveloperMeResult;
|
|
158
|
+
/**
|
|
159
|
+
* The first project minted by signup, when `newlySignedUp` is true.
|
|
160
|
+
* Null when we re-used an existing identity — caller is expected to
|
|
161
|
+
* mint a new project under it via `ensureProjectForCwd`.
|
|
162
|
+
*/
|
|
163
|
+
firstProject: {
|
|
164
|
+
project_id: string;
|
|
165
|
+
client_key: string;
|
|
166
|
+
server_key: string | null;
|
|
167
|
+
provisioning_status?: string;
|
|
168
|
+
verify_url?: string;
|
|
169
|
+
} | null;
|
|
170
|
+
/**
|
|
171
|
+
* Absolute path of a backup file written when an existing credential
|
|
172
|
+
* was overwritten with a new one (different PAT). Null when no backup
|
|
173
|
+
* was needed (no prior file, same PAT verified, etc.).
|
|
174
|
+
*/
|
|
175
|
+
credentialsBackedUpTo: string | null;
|
|
176
|
+
/** Absolute path of `~/.amba/credentials.json`. */
|
|
177
|
+
credentialsPath: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Ensure the machine has a verified Amba developer identity.
|
|
181
|
+
*
|
|
182
|
+
* Decision tree:
|
|
183
|
+
* 1. Load existing `~/.amba/credentials.json`.
|
|
184
|
+
* 2. If found, verify the PAT via `developer/me`.
|
|
185
|
+
* - Valid → migrate shape if legacy, return.
|
|
186
|
+
* - Invalid → fall through to signup (unless `signupOnMissing: false`).
|
|
187
|
+
* 3. No creds (or invalid) + `signupOnMissing !== false` → call
|
|
188
|
+
* `performSandboxSignup` with generated email/password, write the
|
|
189
|
+
* result, return.
|
|
190
|
+
* 4. No creds + `signupOnMissing === false` → throw.
|
|
191
|
+
*/
|
|
192
|
+
export declare function ensureDeveloperIdentity(options?: EnsureDeveloperOptions): Promise<EnsureDeveloperResult>;
|
|
193
|
+
export interface EnsureProjectOptions {
|
|
194
|
+
/** Inject the dev-identity PAT into the api-client. */
|
|
195
|
+
pat: string;
|
|
196
|
+
/**
|
|
197
|
+
* When provided, attach this folder to the named project ID
|
|
198
|
+
* instead of creating a new one (e.g. user passed `--project-id`).
|
|
199
|
+
*/
|
|
200
|
+
attachToProjectId?: string;
|
|
201
|
+
/**
|
|
202
|
+
* Default project name when minting. Defaults to `basename(cwd)`.
|
|
203
|
+
*/
|
|
204
|
+
defaultName?: string;
|
|
205
|
+
/** `'development'` (default) or `'production'`. */
|
|
206
|
+
environment?: 'development' | 'production';
|
|
207
|
+
/**
|
|
208
|
+
* Optional pre-minted first-project payload from a sandbox-signup
|
|
209
|
+
* response. When provided AND no project.json exists yet, we use
|
|
210
|
+
* this without an extra `createProject` call. Saves a round-trip
|
|
211
|
+
* on the first-ever init.
|
|
212
|
+
*/
|
|
213
|
+
signupFirstProject?: {
|
|
214
|
+
project_id: string;
|
|
215
|
+
client_key: string;
|
|
216
|
+
server_key: string | null;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
export interface EnsureProjectResult {
|
|
220
|
+
credentials: ProjectCredentials;
|
|
221
|
+
/** True when we minted a new project this run. */
|
|
222
|
+
newlyCreated: boolean;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Ensure the current working directory is attached to an Amba project.
|
|
226
|
+
*
|
|
227
|
+
* Decision tree:
|
|
228
|
+
* 1. Load existing `<cwd>/.amba/project.json`.
|
|
229
|
+
* - Present → return (no API call; we trust the file's metadata
|
|
230
|
+
* until something downstream fails, at which point the caller
|
|
231
|
+
* re-keys).
|
|
232
|
+
* 2. Missing + `signupFirstProject` provided → use those keys, write
|
|
233
|
+
* `<cwd>/.amba/project.json`, return (newlyCreated=true).
|
|
234
|
+
* 3. Missing + no signup payload + `attachToProjectId` provided →
|
|
235
|
+
* mint a new client+server key under that project, write the
|
|
236
|
+
* file, return.
|
|
237
|
+
* 4. Missing + no signup payload + no attach → call
|
|
238
|
+
* `createProject({ name, environment })` under the dev's PAT,
|
|
239
|
+
* mint both keys, write the file, return.
|
|
240
|
+
*/
|
|
241
|
+
export declare function ensureProjectForCwd(cwd: string, options: EnsureProjectOptions): Promise<EnsureProjectResult>;
|
|
242
|
+
/**
|
|
243
|
+
* Sanitize a candidate project name. The control-plane enforces
|
|
244
|
+
* `^[a-zA-Z0-9-_]{1,64}$` (see `apps/api/src/routes/projects.ts`); the
|
|
245
|
+
* basename of a project folder often contains spaces or dots. We
|
|
246
|
+
* collapse runs of non-allowed chars to `-`, trim outer dashes, and
|
|
247
|
+
* truncate to 64.
|
|
248
|
+
*/
|
|
249
|
+
export declare function sanitizeProjectName(input: string): string;
|
|
250
|
+
/**
|
|
251
|
+
* Update an existing `<cwd>/.amba/project.json` to record additional
|
|
252
|
+
* surfaces the skill has wired up. Used by the Amba skill after each
|
|
253
|
+
* `amba_<surface>_create` call lands so re-runs can skip already-done
|
|
254
|
+
* work. Bumps `updated_at`. Silently no-ops if the file is missing
|
|
255
|
+
* (skill should always run after `amba init`).
|
|
256
|
+
*/
|
|
257
|
+
export declare function recordWiredSurface(cwd: string, surface: string): Promise<void>;
|
|
258
|
+
/** True iff a `<cwd>/.amba/project.json` exists and parses. */
|
|
259
|
+
export declare function projectIsLinked(cwd: string): Promise<boolean>;
|