@superzerodev/cli 0.1.0

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/args.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * CLI の引数解析(P0設計 §6.1 / AG-05)
3
+ *
4
+ * 規律: すべてのコマンドが --json と --yes に対応し、TTY を前提とする処理を持たない。
5
+ * 対話プロンプトを一切書かない。エージェントが叩けなくなるため。
6
+ *
7
+ * 依存を足さない。Node 24 の util.parseArgs で足りる。
8
+ */
9
+ export declare const COMMANDS: readonly ["projects", "keys", "billing", "usage", "plan", "apply", "verify", "status", "secrets", "logs"];
10
+ export type Command = (typeof COMMANDS)[number];
11
+ export interface ParsedArgs {
12
+ command: Command;
13
+ positionals: string[];
14
+ json: boolean;
15
+ yes: boolean;
16
+ allowDestructive: boolean;
17
+ config: string;
18
+ env: string | undefined;
19
+ }
20
+ export declare class UsageError extends Error {
21
+ readonly usage: string;
22
+ constructor(message: string, usage: string);
23
+ }
24
+ export declare const USAGE = "superzero <command> [options]\n\nCommands:\n projects create <name> Create a project and its production environment.\n Prints the environment id. Safe to run twice.\n projects keep <name>... After moving back to Free, choose which projects stay\n active. The others are paused, not deleted.\n keys list|create|revoke Manage this organization's API keys.\n usage Show this month's recorded usage for the organization.\n billing Show the plan (Free or Pro) and what it unlocks.\n billing setup Print the card-registration URL that upgrades to Pro.\n Hand it to a person; card entry is never automated.\n plan Show what would change. Has no side effects.\n apply Provision resources, then run self-verification.\n verify Run health checks against the current environment.\n status List the resources in the environment.\n secrets set|list|rm Manage secrets.\n logs Tail logs.\n\nOptions:\n --json Emit machine-readable JSON. Every command supports it.\n --yes Assume yes. Never prompts either way; kept for scripts.\n --allow-destructive Permit changes that delete data.\n --config <path> Path to the config file (default: superzero.config.ts).\n --env <id> Environment id.\n";
25
+ export declare function parseCliArgs(argv: string[]): ParsedArgs;
26
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,QAAQ,2GAWX,CAAA;AAEV,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CACxB;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;gBACV,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAK3C;AAED,eAAO,MAAM,KAAK,g6CAyBjB,CAAA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA+BvD"}
package/dist/args.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * CLI の引数解析(P0設計 §6.1 / AG-05)
3
+ *
4
+ * 規律: すべてのコマンドが --json と --yes に対応し、TTY を前提とする処理を持たない。
5
+ * 対話プロンプトを一切書かない。エージェントが叩けなくなるため。
6
+ *
7
+ * 依存を足さない。Node 24 の util.parseArgs で足りる。
8
+ */
9
+ import { parseArgs } from 'node:util';
10
+ export const COMMANDS = [
11
+ 'projects',
12
+ 'keys',
13
+ 'billing',
14
+ 'usage',
15
+ 'plan',
16
+ 'apply',
17
+ 'verify',
18
+ 'status',
19
+ 'secrets',
20
+ 'logs',
21
+ ];
22
+ export class UsageError extends Error {
23
+ usage;
24
+ constructor(message, usage) {
25
+ super(message);
26
+ this.name = 'UsageError';
27
+ this.usage = usage;
28
+ }
29
+ }
30
+ export const USAGE = `superzero <command> [options]
31
+
32
+ Commands:
33
+ projects create <name> Create a project and its production environment.
34
+ Prints the environment id. Safe to run twice.
35
+ projects keep <name>... After moving back to Free, choose which projects stay
36
+ active. The others are paused, not deleted.
37
+ keys list|create|revoke Manage this organization's API keys.
38
+ usage Show this month's recorded usage for the organization.
39
+ billing Show the plan (Free or Pro) and what it unlocks.
40
+ billing setup Print the card-registration URL that upgrades to Pro.
41
+ Hand it to a person; card entry is never automated.
42
+ plan Show what would change. Has no side effects.
43
+ apply Provision resources, then run self-verification.
44
+ verify Run health checks against the current environment.
45
+ status List the resources in the environment.
46
+ secrets set|list|rm Manage secrets.
47
+ logs Tail logs.
48
+
49
+ Options:
50
+ --json Emit machine-readable JSON. Every command supports it.
51
+ --yes Assume yes. Never prompts either way; kept for scripts.
52
+ --allow-destructive Permit changes that delete data.
53
+ --config <path> Path to the config file (default: superzero.config.ts).
54
+ --env <id> Environment id.
55
+ `;
56
+ export function parseCliArgs(argv) {
57
+ const { values, positionals } = parseArgs({
58
+ args: argv,
59
+ allowPositionals: true,
60
+ strict: true,
61
+ options: {
62
+ json: { type: 'boolean', default: false },
63
+ yes: { type: 'boolean', short: 'y', default: false },
64
+ 'allow-destructive': { type: 'boolean', default: false },
65
+ config: { type: 'string', default: 'superzero.config.ts' },
66
+ env: { type: 'string' },
67
+ },
68
+ });
69
+ const [command, ...rest] = positionals;
70
+ if (command === undefined) {
71
+ throw new UsageError('No command given.', USAGE);
72
+ }
73
+ if (!COMMANDS.includes(command)) {
74
+ throw new UsageError(`Unknown command "${command}".`, USAGE);
75
+ }
76
+ return {
77
+ command: command,
78
+ positionals: rest,
79
+ json: values.json === true,
80
+ yes: values.yes === true,
81
+ allowDestructive: values['allow-destructive'] === true,
82
+ config: values.config ?? 'superzero.config.ts',
83
+ env: values.env,
84
+ };
85
+ }
86
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,UAAU;IACV,MAAM;IACN,SAAS;IACT,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,MAAM;CACE,CAAA;AAcV,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,KAAK,CAAQ;IACtB,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBpB,CAAA;AAED,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YACzC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;YACpD,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YACxD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE;YAC1D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACxB;KACF,CAAC,CAAA;IAEF,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CAAA;IACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,CAAE,QAA8B,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,UAAU,CAAC,oBAAoB,OAAO,IAAI,EAAE,KAAK,CAAC,CAAA;IAC9D,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAkB;QAC3B,WAAW,EAAE,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,IAAI;QAC1B,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,IAAI;QACxB,gBAAgB,EAAE,MAAM,CAAC,mBAAmB,CAAC,KAAK,IAAI;QACtD,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,qBAAqB;QAC9C,GAAG,EAAE,MAAM,CAAC,GAAG;KAChB,CAAA;AACH,CAAC"}
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { run } from './main.js';
3
+ process.exitCode = await run({ argv: process.argv.slice(2) });
4
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAE/B,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Control Plane の REST クライアント(P0設計 §6.3)
3
+ *
4
+ * CLI と MCP はどちらもこの薄いクライアント越しに同じ API を呼ぶ。
5
+ * 3つの実装を持たない。
6
+ *
7
+ * ★ サーバーが返す正規化エラーをそのまま SuperzeroError に戻す。
8
+ * ここで握り潰すと suggestedFix が消え、エージェントが自力で直せなくなる。
9
+ */
10
+ import { type Plan, type VerifyResult } from '@superzerodev/core';
11
+ export interface ControlPlaneClientOptions {
12
+ baseUrl: string;
13
+ token?: string | undefined;
14
+ timeoutMs?: number;
15
+ /** テスト用の差し替え口 */
16
+ fetchImpl?: typeof fetch;
17
+ }
18
+ export interface ApplyResponse {
19
+ deploymentId: string;
20
+ ok: boolean;
21
+ applied: string[];
22
+ skipped: string[];
23
+ failure?: {
24
+ key: string;
25
+ error: unknown;
26
+ };
27
+ verify?: VerifyResult;
28
+ }
29
+ export interface StatusResponse {
30
+ resources: {
31
+ kind: string;
32
+ logicalName: string;
33
+ provider: string;
34
+ status: string;
35
+ }[];
36
+ }
37
+ /** アップロードしたソースの控え。sourceId を plan / apply に添える */
38
+ export interface SourceUpload {
39
+ sourceId: string;
40
+ fileCount: number;
41
+ bytes: number;
42
+ }
43
+ export declare class ControlPlaneClient {
44
+ #private;
45
+ constructor(options: ControlPlaneClientOptions);
46
+ /**
47
+ * デプロイするソースを送る。
48
+ *
49
+ * ★ ここが無いと、CLI とサーバーが同じホストに居るときしか動かない。
50
+ * 以前はローカルの絶対パスを文字列で送っていて、遠隔からの apply は
51
+ * サーバー側で ENOENT になっていた。
52
+ *
53
+ * ★ 本文は gzip 済みの tar そのもの。JSON に包まない。
54
+ * base64 にすると 4/3 に膨らみ、メモリにも二重に載る。
55
+ */
56
+ uploadSource(environmentId: string, archive: Uint8Array): Promise<SourceUpload>;
57
+ plan(environmentId: string, config: unknown, options?: {
58
+ allowDestructive?: boolean;
59
+ sourceId?: string;
60
+ }): Promise<Plan>;
61
+ apply(environmentId: string, config: unknown, options?: {
62
+ allowDestructive?: boolean;
63
+ sourceId?: string;
64
+ }): Promise<ApplyResponse>;
65
+ verify(environmentId: string): Promise<VerifyResult>;
66
+ /**
67
+ * ★ 人の介在なしにここへ到達できることが検証仮説 H3 の前提。
68
+ * 以前は運用者がスクリプトを叩く必要があり、顧客を受け入れられなかった。
69
+ */
70
+ createProject(name: string, region: string | undefined): Promise<{
71
+ projectId: string;
72
+ environmentId: string;
73
+ created: boolean;
74
+ }>;
75
+ listKeys(): Promise<{
76
+ keys: KeySummary[];
77
+ }>;
78
+ /** 今月の使用量。呼び出し元の組織の分だけ返る */
79
+ usage(): Promise<UsageSummary>;
80
+ /** プランと上限。Free で閉じているものは locked に入る */
81
+ billing(): Promise<BillingStatus>;
82
+ /**
83
+ * カード登録(Free → Pro)のページを作る。
84
+ * ★ 返るのは URL だけ。カード入力は人がブラウザでやる。
85
+ */
86
+ billingCheckout(): Promise<{
87
+ checkoutUrl: string;
88
+ }>;
89
+ /** Free に戻ったあと、残すプロジェクトを選ぶ。他は休止 */
90
+ keepProjects(names: string[]): Promise<{
91
+ kept: string[];
92
+ paused: string[];
93
+ }>;
94
+ createKey(name: string | undefined): Promise<{
95
+ key: {
96
+ id: string;
97
+ token: string;
98
+ };
99
+ }>;
100
+ revokeKey(keyId: string): Promise<{
101
+ id: string;
102
+ revoked: boolean;
103
+ }>;
104
+ status(environmentId: string): Promise<StatusResponse>;
105
+ }
106
+ export interface UsageSummary {
107
+ /** 集計の開始時刻(今月の初日)。計測の口が無い環境では null */
108
+ periodStart: string | null;
109
+ metrics: {
110
+ metric: string;
111
+ quantity: string;
112
+ }[];
113
+ /**
114
+ * まだ記録していないメトリクス。
115
+ * ★ 「0 だった」と「測っていない」を区別するために要る。区別しないと表示が嘘になる。
116
+ */
117
+ notRecorded: string[];
118
+ available: boolean;
119
+ }
120
+ export interface BillingStatus {
121
+ plan: 'free' | 'pro';
122
+ /** 決済事業者が無い Control Plane では false。Free のまま動く */
123
+ billingAvailable: boolean;
124
+ projectLimit?: number;
125
+ projectsUsed?: number;
126
+ spendLimitUsd?: number;
127
+ selectionRequired?: boolean;
128
+ locked?: string[];
129
+ }
130
+ export interface KeySummary {
131
+ id: string;
132
+ prefix: string;
133
+ name: string | null;
134
+ createdAt: string;
135
+ lastUsedAt: string | null;
136
+ revokedAt: string | null;
137
+ }
138
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Control Plane の REST クライアント(P0設計 §6.3)
3
+ *
4
+ * CLI と MCP はどちらもこの薄いクライアント越しに同じ API を呼ぶ。
5
+ * 3つの実装を持たない。
6
+ *
7
+ * ★ サーバーが返す正規化エラーをそのまま SuperzeroError に戻す。
8
+ * ここで握り潰すと suggestedFix が消え、エージェントが自力で直せなくなる。
9
+ */
10
+ import { SuperzeroError } from '@superzerodev/core';
11
+ export class ControlPlaneClient {
12
+ #baseUrl;
13
+ #token;
14
+ #timeoutMs;
15
+ #fetch;
16
+ constructor(options) {
17
+ this.#baseUrl = options.baseUrl.replace(/\/$/, '');
18
+ this.#token = options.token;
19
+ this.#timeoutMs = options.timeoutMs ?? 15 * 60 * 1000;
20
+ this.#fetch = options.fetchImpl ?? fetch;
21
+ }
22
+ async #call(method, path, body) {
23
+ let res;
24
+ try {
25
+ res = await this.#fetch(`${this.#baseUrl}${path}`, {
26
+ method,
27
+ headers: {
28
+ accept: 'application/json',
29
+ ...(this.#token ? { authorization: `Bearer ${this.#token}` } : {}),
30
+ ...(body === undefined ? {} : { 'content-type': 'application/json' }),
31
+ },
32
+ ...(body === undefined ? {} : { body: JSON.stringify(body) }),
33
+ signal: AbortSignal.timeout(this.#timeoutMs),
34
+ });
35
+ }
36
+ catch (err) {
37
+ throw unreachable(this.#baseUrl, err);
38
+ }
39
+ if (!res.ok)
40
+ throw await fromResponse(res);
41
+ return (await res.json());
42
+ }
43
+ /**
44
+ * デプロイするソースを送る。
45
+ *
46
+ * ★ ここが無いと、CLI とサーバーが同じホストに居るときしか動かない。
47
+ * 以前はローカルの絶対パスを文字列で送っていて、遠隔からの apply は
48
+ * サーバー側で ENOENT になっていた。
49
+ *
50
+ * ★ 本文は gzip 済みの tar そのもの。JSON に包まない。
51
+ * base64 にすると 4/3 に膨らみ、メモリにも二重に載る。
52
+ */
53
+ async uploadSource(environmentId, archive) {
54
+ let res;
55
+ try {
56
+ res = await this.#fetch(`${this.#baseUrl}/v1/environments/${encodeURIComponent(environmentId)}/sources`, {
57
+ method: 'POST',
58
+ headers: {
59
+ accept: 'application/json',
60
+ ...(this.#token ? { authorization: `Bearer ${this.#token}` } : {}),
61
+ 'content-type': 'application/gzip',
62
+ 'content-length': String(archive.byteLength),
63
+ },
64
+ body: archive,
65
+ signal: AbortSignal.timeout(this.#timeoutMs),
66
+ });
67
+ }
68
+ catch (err) {
69
+ throw unreachable(this.#baseUrl, err);
70
+ }
71
+ if (!res.ok)
72
+ throw await fromResponse(res);
73
+ return (await res.json());
74
+ }
75
+ async plan(environmentId, config, options = {}) {
76
+ const body = await this.#call('POST', `/v1/environments/${encodeURIComponent(environmentId)}/plan`, {
77
+ config,
78
+ allowDestructive: options.allowDestructive === true,
79
+ // ★ plan にも添える。無いとサーバーがソースを読めず、
80
+ // コードだけ変えた場合に「変更なし」と答えてしまう。
81
+ ...(options.sourceId ? { sourceId: options.sourceId } : {}),
82
+ });
83
+ return { changes: body.changes, destructiveKeys: body.destructiveKeys, ordered: true };
84
+ }
85
+ async apply(environmentId, config, options = {}) {
86
+ return this.#call('POST', `/v1/environments/${encodeURIComponent(environmentId)}/apply`, {
87
+ config,
88
+ allowDestructive: options.allowDestructive === true,
89
+ ...(options.sourceId ? { sourceId: options.sourceId } : {}),
90
+ });
91
+ }
92
+ async verify(environmentId) {
93
+ return this.#call('POST', `/v1/environments/${encodeURIComponent(environmentId)}/verify`);
94
+ }
95
+ /**
96
+ * ★ 人の介在なしにここへ到達できることが検証仮説 H3 の前提。
97
+ * 以前は運用者がスクリプトを叩く必要があり、顧客を受け入れられなかった。
98
+ */
99
+ async createProject(name, region) {
100
+ return this.#call('POST', '/v1/projects', {
101
+ name,
102
+ ...(region ? { region } : {}),
103
+ });
104
+ }
105
+ async listKeys() {
106
+ return this.#call('GET', '/v1/keys');
107
+ }
108
+ /** 今月の使用量。呼び出し元の組織の分だけ返る */
109
+ async usage() {
110
+ return this.#call('GET', '/v1/usage');
111
+ }
112
+ /** プランと上限。Free で閉じているものは locked に入る */
113
+ async billing() {
114
+ return this.#call('GET', '/v1/billing');
115
+ }
116
+ /**
117
+ * カード登録(Free → Pro)のページを作る。
118
+ * ★ 返るのは URL だけ。カード入力は人がブラウザでやる。
119
+ */
120
+ async billingCheckout() {
121
+ return this.#call('POST', '/v1/billing/checkout', {});
122
+ }
123
+ /** Free に戻ったあと、残すプロジェクトを選ぶ。他は休止 */
124
+ async keepProjects(names) {
125
+ return this.#call('POST', '/v1/projects/keep', { names });
126
+ }
127
+ async createKey(name) {
128
+ return this.#call('POST', '/v1/keys', name ? { name } : {});
129
+ }
130
+ async revokeKey(keyId) {
131
+ return this.#call('DELETE', `/v1/keys/${encodeURIComponent(keyId)}`);
132
+ }
133
+ async status(environmentId) {
134
+ return this.#call('GET', `/v1/environments/${encodeURIComponent(environmentId)}/status`);
135
+ }
136
+ }
137
+ /** サーバーの正規化エラーを復元する。suggestedFix を落とさない */
138
+ async function fromResponse(res) {
139
+ let body = {};
140
+ try {
141
+ body = (await res.json());
142
+ }
143
+ catch {
144
+ // JSON でない応答(プロキシのエラーページなど)
145
+ }
146
+ return new SuperzeroError({
147
+ code: body.code ?? 'PROVIDER_UNEXPECTED_ERROR',
148
+ message: body.message ?? `Control plane returned ${res.status} ${res.statusText}.`,
149
+ ...(body.cause ? { cause: body.cause } : {}),
150
+ ...(body.suggestedFix ? { suggestedFix: body.suggestedFix } : {}),
151
+ ...(body.docsUrl ? { docsUrl: body.docsUrl } : {}),
152
+ });
153
+ }
154
+ /** 接続できない。設定ミスか、サーバーが起動していないかのどちらか */
155
+ function unreachable(baseUrl, err) {
156
+ return new SuperzeroError({
157
+ code: 'CONTROL_PLANE_UNREACHABLE',
158
+ message: `Could not reach the Superzero API at ${baseUrl}: ${err instanceof Error ? err.message : String(err)}`,
159
+ suggestedFix: {
160
+ description: 'Check that SUPERZERO_URL points at a running control plane. ' +
161
+ 'For local development, start it first.',
162
+ command: 'pnpm --filter @superzerodev/control-plane dev',
163
+ },
164
+ });
165
+ }
166
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 各コマンドの実装(P0設計 §6.1)
3
+ *
4
+ * 規律:
5
+ * - 対話プロンプトを書かない(AG-05)。--yes は互換のために受けるだけ。
6
+ * - --json のとき stdout は JSON のみ。人間向けは stderr。
7
+ * - 戻り値は終了コード。0 = 成功、1 = 失敗。
8
+ */
9
+ import type { ParsedArgs } from './args.js';
10
+ import type { ControlPlaneClient } from './client.js';
11
+ import { type Writer } from './output.js';
12
+ export interface CommandDeps {
13
+ client: ControlPlaneClient;
14
+ writer: Writer;
15
+ cwd: string;
16
+ /** --env 未指定時のフォールバック(SUPERZERO_ENV) */
17
+ defaultEnvironmentId?: string | undefined;
18
+ }
19
+ /**
20
+ * projects create <name>
21
+ *
22
+ * ★ 環境IDを標準出力へ、それ以外を標準エラーへ出す。
23
+ * エージェントが `superzero projects create app` の出力を
24
+ * そのまま SUPERZERO_ENV に渡せる形にしておく。
25
+ */
26
+ export declare function runProjects(args: ParsedArgs, deps: CommandDeps): Promise<number>;
27
+ /** keys list | create [name] | revoke <id> */
28
+ export declare function runKeys(args: ParsedArgs, deps: CommandDeps): Promise<number>;
29
+ /**
30
+ * usage
31
+ *
32
+ * ★ 測っていないものを 0 と書かない。
33
+ * 「SMS 0 通」と出せば、実際に送っている顧客に嘘をつくことになる。
34
+ * 記録していないメトリクスは、そう明示する。
35
+ */
36
+ export declare function runUsage(args: ParsedArgs, deps: CommandDeps): Promise<number>;
37
+ /**
38
+ * billing / billing setup
39
+ *
40
+ * ★ カード入力は人がやる。CLI は URL を出すところまで。
41
+ * エージェントはこの URL を人に渡す。それ以上は自動化しない(AG-05 とは別の理由:
42
+ * 決済は本人の意思表示であり、代理で通してはいけない)。
43
+ */
44
+ export declare function runBilling(args: ParsedArgs, deps: CommandDeps): Promise<number>;
45
+ export declare function runPlan(args: ParsedArgs, deps: CommandDeps): Promise<number>;
46
+ export declare function runApply(args: ParsedArgs, deps: CommandDeps): Promise<number>;
47
+ export declare function runVerify(args: ParsedArgs, deps: CommandDeps): Promise<number>;
48
+ export declare function runStatus(args: ParsedArgs, deps: CommandDeps): Promise<number>;
49
+ export declare function runNotImplemented(command: string, deps: CommandDeps): number;
50
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,aAAa,CAAA;AAErE,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAGrD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C;AAiBD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA6CtF;AAED,8CAA8C;AAC9C,wBAAsB,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClF;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BnF;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA2CrF;AAeD,wBAAsB,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAalF;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BnF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAY5E"}