aranea-sdk-cli 0.3.0 → 0.3.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 CHANGED
@@ -4,6 +4,42 @@
4
4
 
5
5
  AraneaSDK CLI - ESP32 IoTデバイス開発支援ツール
6
6
 
7
+ ---
8
+
9
+ ## 🤖 AIエージェント向けガイド
10
+
11
+ > **AIエージェント (Claude, Codex, etc.) がAraneaSDK関連タスクを実行する際は、このCLIを使用してください。**
12
+
13
+ ### ナレッジ追加 (ローカルファイルではなくCLI経由で)
14
+
15
+ ```bash
16
+ # ❌ ローカルファイル作成ではなく
17
+ # ✅ CLIでナレッジベースに追加
18
+ aranea-sdk knowledge add \
19
+ --title "ESP32 HTTPSタイムアウト設定" \
20
+ --category tip \
21
+ --content "ESP32でHTTPS接続する場合、最低15秒のタイムアウトが必要。初回SSL handshakeは特に時間がかかる。" \
22
+ --keywords "esp32,https,timeout,ssl"
23
+ ```
24
+
25
+ ### Metatronへの質問 (AIアシスタント連携)
26
+
27
+ ```bash
28
+ # AraneaSDK専門AIに質問
29
+ aranea-sdk metatron ask "ESP32のHTTPSタイムアウトのベストプラクティスは?"
30
+
31
+ # 対話モード
32
+ aranea-sdk metatron chat
33
+ ```
34
+
35
+ ### 典型的なワークフロー
36
+
37
+ 1. **問題解決時**: `metatron ask "問題の説明"` で既存ナレッジを確認
38
+ 2. **新知見発見時**: `knowledge add` でナレッジベースに追加
39
+ 3. **デバイス登録時**: `register --dry-run` で検証後、実登録
40
+
41
+ ---
42
+
7
43
  ## 概要
8
44
 
9
45
  AraneaSDK CLIは、AraneaSDK対応ESP32デバイスの開発・テスト・登録を支援するコマンドラインツールです。
@@ -39,12 +75,13 @@ aranea-sdk metatron ask "State Reportの送信方法は?"
39
75
  |---------|------|------|
40
76
  | `test` | 接続・認証テスト | 不要 |
41
77
  | `register` | デバイス登録 | 不要(テストテナント) |
42
- | `schema` | スキーマ取得・State Report検証 | 不要 |
78
+ | `schema` | スキーマ取得・検証・プッシュ | push/promote時必要 |
43
79
  | `validate` | Type名検証 | 不要 |
44
80
  | `simulate` | 状態レポートシミュレーション | 不要 |
45
81
  | `mqtt` | コマンド送信・ACKモニタリング | **必要** |
46
82
  | `knowledge` | ナレッジベース管理 | **必要** |
47
83
  | `metatron` | AI対話アシスタント | **必要** |
84
+ | `auth` | 認証トークン管理 | - |
48
85
 
49
86
  ---
50
87
 
@@ -166,11 +203,27 @@ aranea-sdk schema validate --file state.json --type aranea_ar-is04a
166
203
  | `list` | ✅ 実装済み | 登録済みスキーマ一覧 |
167
204
  | `get` | ✅ 実装済み | スキーマ詳細取得 |
168
205
  | `validate` | ✅ 実装済み | State Report 検証 |
169
- | `create` | 🔜 計画中 | スキーマ新規作成 |
170
- | `push` | 🔜 計画中 | 開発環境へプッシュ |
171
- | `promote` | 🔜 計画中 | 本番環境へ昇格 |
206
+ | `validate-schema` | 実装済み | スキーマ定義の静的検証 |
207
+ | `push` | 実装済み | 開発環境へプッシュ (認証必要) |
208
+ | `promote` | 実装済み | 本番環境へ昇格 (認証必要、確認ステップあり) |
209
+ | `info` | ✅ 実装済み | スキーマ詳細情報・リビジョン履歴 |
172
210
  | `rollback` | 🔜 計画中 | バージョンロールバック |
173
211
 
212
+ ### 環境切替 (v0.3.1)
213
+
214
+ すべてのschemaサブコマンドで `--endpoint` オプションが使用可能です:
215
+
216
+ ```bash
217
+ # デフォルト: staging
218
+ aranea-sdk schema list
219
+
220
+ # 明示的にproduction指定
221
+ aranea-sdk schema list --endpoint production
222
+
223
+ # 環境変数でも指定可能
224
+ ARANEA_ENV=production aranea-sdk schema list
225
+ ```
226
+
174
227
  ---
175
228
 
176
229
  ## validate - Type名検証
@@ -339,6 +392,45 @@ aranea-sdk metatron examples
339
392
 
340
393
  ---
341
394
 
395
+ ## auth - 認証管理 (v0.3.1)
396
+
397
+ Firebase Auth IDトークンを管理します。トークンは `~/.aranea-sdk/credentials.json` に保存されます。
398
+
399
+ ### 使用例
400
+
401
+ ```bash
402
+ # ログイン (対話式)
403
+ aranea-sdk auth login
404
+
405
+ # メールアドレス指定でログイン
406
+ aranea-sdk auth login --email dev@example.com
407
+
408
+ # トークン情報表示
409
+ aranea-sdk auth token
410
+
411
+ # トークンのみ出力 (スクリプト用)
412
+ aranea-sdk auth token --raw
413
+
414
+ # トークン更新 (1時間で期限切れ)
415
+ aranea-sdk auth refresh
416
+
417
+ # ログアウト
418
+ aranea-sdk auth logout
419
+ ```
420
+
421
+ ### トークンライフサイクル
422
+
423
+ - IDトークンは **1時間** で期限切れ
424
+ - `auth refresh` で新しいトークンを取得
425
+ - `auth token --raw` でスクリプトからトークン取得可能
426
+
427
+ ```bash
428
+ # 他コマンドでトークンを使用
429
+ aranea-sdk metatron ask "質問" --token "$(aranea-sdk auth token --raw)"
430
+ ```
431
+
432
+ ---
433
+
342
434
  ## 対応デバイスType
343
435
 
344
436
  ### 新規 (aranea_ar-*)
@@ -0,0 +1,26 @@
1
+ /**
2
+ * AraneaSDK CLI - Auth Command
3
+ *
4
+ * Firebase Auth token management for CLI operations
5
+ *
6
+ * Usage:
7
+ * aranea-sdk auth login # Interactive login
8
+ * aranea-sdk auth token # Show current token info
9
+ * aranea-sdk auth refresh # Refresh token
10
+ * aranea-sdk auth logout # Clear saved credentials
11
+ *
12
+ * Token Storage:
13
+ * ~/.aranea-sdk/credentials.json
14
+ *
15
+ * Note: ID tokens expire after 1 hour. Use `auth refresh` to get a new token.
16
+ */
17
+ import { Command } from 'commander';
18
+ /**
19
+ * Get valid token, refreshing if necessary
20
+ * Exported for use by other commands
21
+ */
22
+ export declare function getValidToken(): Promise<string | null>;
23
+ /**
24
+ * Auth command
25
+ */
26
+ export declare const authCommand: Command;
@@ -0,0 +1,427 @@
1
+ "use strict";
2
+ /**
3
+ * AraneaSDK CLI - Auth Command
4
+ *
5
+ * Firebase Auth token management for CLI operations
6
+ *
7
+ * Usage:
8
+ * aranea-sdk auth login # Interactive login
9
+ * aranea-sdk auth token # Show current token info
10
+ * aranea-sdk auth refresh # Refresh token
11
+ * aranea-sdk auth logout # Clear saved credentials
12
+ *
13
+ * Token Storage:
14
+ * ~/.aranea-sdk/credentials.json
15
+ *
16
+ * Note: ID tokens expire after 1 hour. Use `auth refresh` to get a new token.
17
+ */
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || (function () {
35
+ var ownKeys = function(o) {
36
+ ownKeys = Object.getOwnPropertyNames || function (o) {
37
+ var ar = [];
38
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
+ return ar;
40
+ };
41
+ return ownKeys(o);
42
+ };
43
+ return function (mod) {
44
+ if (mod && mod.__esModule) return mod;
45
+ var result = {};
46
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
+ __setModuleDefault(result, mod);
48
+ return result;
49
+ };
50
+ })();
51
+ var __importDefault = (this && this.__importDefault) || function (mod) {
52
+ return (mod && mod.__esModule) ? mod : { "default": mod };
53
+ };
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.authCommand = void 0;
56
+ exports.getValidToken = getValidToken;
57
+ const commander_1 = require("commander");
58
+ const fs = __importStar(require("fs"));
59
+ const path = __importStar(require("path"));
60
+ const os = __importStar(require("os"));
61
+ const readline = __importStar(require("readline"));
62
+ const chalk_1 = __importDefault(require("chalk"));
63
+ // Firebase Auth REST API configuration
64
+ const FIREBASE_API_KEY = 'AIzaSyChVMfLPZ9fL_LQBK2TtLbM2iONPhyU1NY'; // mobesorder project
65
+ const AUTH_ENDPOINT = 'https://identitytoolkit.googleapis.com/v1';
66
+ // Credentials storage
67
+ const CONFIG_DIR = path.join(os.homedir(), '.aranea-sdk');
68
+ const CREDENTIALS_FILE = path.join(CONFIG_DIR, 'credentials.json');
69
+ /**
70
+ * Ensure config directory exists
71
+ */
72
+ function ensureConfigDir() {
73
+ if (!fs.existsSync(CONFIG_DIR)) {
74
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
75
+ }
76
+ }
77
+ /**
78
+ * Load saved credentials
79
+ */
80
+ function loadCredentials() {
81
+ try {
82
+ if (fs.existsSync(CREDENTIALS_FILE)) {
83
+ const data = fs.readFileSync(CREDENTIALS_FILE, 'utf8');
84
+ return JSON.parse(data);
85
+ }
86
+ }
87
+ catch (error) {
88
+ // Ignore parse errors
89
+ }
90
+ return null;
91
+ }
92
+ /**
93
+ * Save credentials to disk
94
+ */
95
+ function saveCredentials(credentials) {
96
+ ensureConfigDir();
97
+ fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), {
98
+ mode: 0o600,
99
+ });
100
+ }
101
+ /**
102
+ * Clear saved credentials
103
+ */
104
+ function clearCredentials() {
105
+ if (fs.existsSync(CREDENTIALS_FILE)) {
106
+ fs.unlinkSync(CREDENTIALS_FILE);
107
+ }
108
+ }
109
+ /**
110
+ * Check if token is expired or about to expire (within 5 minutes)
111
+ */
112
+ function isTokenExpired(credentials) {
113
+ const bufferMs = 5 * 60 * 1000; // 5 minutes buffer
114
+ return Date.now() >= credentials.expiresAt - bufferMs;
115
+ }
116
+ /**
117
+ * Format remaining time
118
+ */
119
+ function formatRemainingTime(expiresAt) {
120
+ const remaining = expiresAt - Date.now();
121
+ if (remaining <= 0) {
122
+ return chalk_1.default.red('Expired');
123
+ }
124
+ const minutes = Math.floor(remaining / 60000);
125
+ const seconds = Math.floor((remaining % 60000) / 1000);
126
+ if (minutes > 30) {
127
+ return chalk_1.default.green(`${minutes}m ${seconds}s`);
128
+ }
129
+ else if (minutes > 5) {
130
+ return chalk_1.default.yellow(`${minutes}m ${seconds}s`);
131
+ }
132
+ else {
133
+ return chalk_1.default.red(`${minutes}m ${seconds}s`);
134
+ }
135
+ }
136
+ /**
137
+ * Prompt for password (hidden input)
138
+ */
139
+ async function promptPassword(prompt) {
140
+ return new Promise((resolve) => {
141
+ const rl = readline.createInterface({
142
+ input: process.stdin,
143
+ output: process.stdout,
144
+ });
145
+ // Hide password input
146
+ const stdin = process.stdin;
147
+ const wasRaw = stdin.isRaw || false;
148
+ process.stdout.write(prompt);
149
+ if (stdin.isTTY) {
150
+ stdin.setRawMode(true);
151
+ }
152
+ let password = '';
153
+ const onData = (char) => {
154
+ const c = char.toString();
155
+ switch (c) {
156
+ case '\n':
157
+ case '\r':
158
+ case '\u0004': // Ctrl+D
159
+ if (stdin.isTTY) {
160
+ stdin.setRawMode(wasRaw);
161
+ }
162
+ stdin.removeListener('data', onData);
163
+ rl.close();
164
+ process.stdout.write('\n');
165
+ resolve(password);
166
+ break;
167
+ case '\u0003': // Ctrl+C
168
+ process.exit();
169
+ break;
170
+ case '\u007F': // Backspace
171
+ if (password.length > 0) {
172
+ password = password.slice(0, -1);
173
+ process.stdout.write('\b \b');
174
+ }
175
+ break;
176
+ default:
177
+ password += c;
178
+ process.stdout.write('*');
179
+ break;
180
+ }
181
+ };
182
+ stdin.on('data', onData);
183
+ });
184
+ }
185
+ /**
186
+ * Prompt for email
187
+ */
188
+ async function promptEmail() {
189
+ return new Promise((resolve) => {
190
+ const rl = readline.createInterface({
191
+ input: process.stdin,
192
+ output: process.stdout,
193
+ });
194
+ rl.question('Email: ', (answer) => {
195
+ rl.close();
196
+ resolve(answer.trim());
197
+ });
198
+ });
199
+ }
200
+ /**
201
+ * Login with email and password
202
+ */
203
+ async function loginWithEmailPassword(email, password) {
204
+ const response = await fetch(`${AUTH_ENDPOINT}/accounts:signInWithPassword?key=${FIREBASE_API_KEY}`, {
205
+ method: 'POST',
206
+ headers: { 'Content-Type': 'application/json' },
207
+ body: JSON.stringify({
208
+ email,
209
+ password,
210
+ returnSecureToken: true,
211
+ }),
212
+ });
213
+ if (!response.ok) {
214
+ const errorBody = await response.json();
215
+ const errorMessage = errorBody.error?.message || 'Login failed';
216
+ throw new Error(translateFirebaseError(errorMessage));
217
+ }
218
+ const data = (await response.json());
219
+ const expiresIn = parseInt(data.expiresIn, 10) * 1000; // Convert to ms
220
+ return {
221
+ idToken: data.idToken,
222
+ refreshToken: data.refreshToken,
223
+ email: data.email,
224
+ expiresAt: Date.now() + expiresIn,
225
+ localId: data.localId,
226
+ };
227
+ }
228
+ /**
229
+ * Refresh ID token
230
+ */
231
+ async function refreshIdToken(refreshToken) {
232
+ const response = await fetch(`https://securetoken.googleapis.com/v1/token?key=${FIREBASE_API_KEY}`, {
233
+ method: 'POST',
234
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
235
+ body: `grant_type=refresh_token&refresh_token=${encodeURIComponent(refreshToken)}`,
236
+ });
237
+ if (!response.ok) {
238
+ const errorBody = await response.json();
239
+ throw new Error(errorBody.error?.message || 'Token refresh failed');
240
+ }
241
+ const data = (await response.json());
242
+ const expiresIn = parseInt(data.expires_in, 10) * 1000;
243
+ // Load existing credentials to preserve email
244
+ const existing = loadCredentials();
245
+ return {
246
+ idToken: data.id_token,
247
+ refreshToken: data.refresh_token,
248
+ email: existing?.email || '',
249
+ expiresAt: Date.now() + expiresIn,
250
+ localId: data.user_id,
251
+ };
252
+ }
253
+ /**
254
+ * Translate Firebase error messages to user-friendly Japanese
255
+ */
256
+ function translateFirebaseError(errorCode) {
257
+ const translations = {
258
+ EMAIL_NOT_FOUND: 'メールアドレスが見つかりません',
259
+ INVALID_PASSWORD: 'パスワードが正しくありません',
260
+ INVALID_EMAIL: 'メールアドレスの形式が正しくありません',
261
+ USER_DISABLED: 'このアカウントは無効化されています',
262
+ TOO_MANY_ATTEMPTS_TRY_LATER: 'ログイン試行回数が多すぎます。しばらく待ってから再試行してください',
263
+ INVALID_LOGIN_CREDENTIALS: 'メールアドレスまたはパスワードが正しくありません',
264
+ TOKEN_EXPIRED: 'トークンの有効期限が切れています。再度ログインしてください',
265
+ INVALID_REFRESH_TOKEN: 'リフレッシュトークンが無効です。再度ログインしてください',
266
+ };
267
+ return translations[errorCode] || errorCode;
268
+ }
269
+ /**
270
+ * Get valid token, refreshing if necessary
271
+ * Exported for use by other commands
272
+ */
273
+ async function getValidToken() {
274
+ const credentials = loadCredentials();
275
+ if (!credentials) {
276
+ return null;
277
+ }
278
+ if (isTokenExpired(credentials)) {
279
+ try {
280
+ const newCredentials = await refreshIdToken(credentials.refreshToken);
281
+ saveCredentials(newCredentials);
282
+ return newCredentials.idToken;
283
+ }
284
+ catch {
285
+ return null;
286
+ }
287
+ }
288
+ return credentials.idToken;
289
+ }
290
+ /**
291
+ * Auth command
292
+ */
293
+ exports.authCommand = new commander_1.Command('auth')
294
+ .description('Firebase Auth token management')
295
+ .addHelpText('after', `
296
+ Token Lifecycle:
297
+ - ID tokens expire after 1 hour
298
+ - Use 'auth refresh' to get a new token
299
+ - Tokens are auto-saved to ~/.aranea-sdk/credentials.json
300
+
301
+ Examples:
302
+ aranea-sdk auth login # Interactive login
303
+ aranea-sdk auth token # Show current token info
304
+ aranea-sdk auth refresh # Refresh expired token
305
+ aranea-sdk auth logout # Clear saved credentials
306
+ `);
307
+ // auth login
308
+ exports.authCommand
309
+ .command('login')
310
+ .description('Login with email and password')
311
+ .option('-e, --email <email>', 'Email address')
312
+ .action(async (options) => {
313
+ console.log(chalk_1.default.cyan('\n=== AraneaSDK CLI Login ===\n'));
314
+ try {
315
+ // Get email
316
+ const email = options.email || (await promptEmail());
317
+ if (!email) {
318
+ console.error(chalk_1.default.red('Email is required'));
319
+ process.exit(1);
320
+ }
321
+ // Get password
322
+ const password = await promptPassword('Password: ');
323
+ if (!password) {
324
+ console.error(chalk_1.default.red('Password is required'));
325
+ process.exit(1);
326
+ }
327
+ console.log('\nLogging in...');
328
+ const credentials = await loginWithEmailPassword(email, password);
329
+ saveCredentials(credentials);
330
+ console.log(chalk_1.default.green('\n✓ Login successful!'));
331
+ console.log(` Email: ${credentials.email}`);
332
+ console.log(` User ID: ${credentials.localId}`);
333
+ console.log(` Token expires: ${formatRemainingTime(credentials.expiresAt)}`);
334
+ console.log(`\nCredentials saved to: ${CREDENTIALS_FILE}`);
335
+ console.log(chalk_1.default.yellow('\nNote: ID tokens expire after 1 hour. Use "aranea-sdk auth refresh" to renew.'));
336
+ }
337
+ catch (error) {
338
+ console.error(chalk_1.default.red(`\n✖ Login failed: ${error.message}`));
339
+ process.exit(1);
340
+ }
341
+ });
342
+ // auth token
343
+ exports.authCommand
344
+ .command('token')
345
+ .description('Show current token information')
346
+ .option('--raw', 'Output raw token value only')
347
+ .action(async (options) => {
348
+ const credentials = loadCredentials();
349
+ if (!credentials) {
350
+ if (options.raw) {
351
+ process.exit(1);
352
+ }
353
+ console.log(chalk_1.default.yellow('\nNo saved credentials found.'));
354
+ console.log('Run "aranea-sdk auth login" to authenticate.');
355
+ process.exit(1);
356
+ }
357
+ if (options.raw) {
358
+ // Output just the token for scripting
359
+ if (isTokenExpired(credentials)) {
360
+ try {
361
+ const newCredentials = await refreshIdToken(credentials.refreshToken);
362
+ saveCredentials(newCredentials);
363
+ console.log(newCredentials.idToken);
364
+ }
365
+ catch {
366
+ process.exit(1);
367
+ }
368
+ }
369
+ else {
370
+ console.log(credentials.idToken);
371
+ }
372
+ return;
373
+ }
374
+ console.log(chalk_1.default.cyan('\n=== AraneaSDK CLI Token Info ===\n'));
375
+ console.log(` Email: ${credentials.email}`);
376
+ console.log(` User ID: ${credentials.localId}`);
377
+ console.log(` Expires in: ${formatRemainingTime(credentials.expiresAt)}`);
378
+ console.log(` Expires at: ${new Date(credentials.expiresAt).toLocaleString('ja-JP')}`);
379
+ if (isTokenExpired(credentials)) {
380
+ console.log(chalk_1.default.red('\n⚠ Token is expired or about to expire.'));
381
+ console.log('Run "aranea-sdk auth refresh" to get a new token.');
382
+ }
383
+ else {
384
+ console.log(chalk_1.default.green('\n✓ Token is valid'));
385
+ }
386
+ console.log(`\nToken (first 50 chars): ${credentials.idToken.substring(0, 50)}...`);
387
+ });
388
+ // auth refresh
389
+ exports.authCommand
390
+ .command('refresh')
391
+ .description('Refresh the ID token')
392
+ .action(async () => {
393
+ const credentials = loadCredentials();
394
+ if (!credentials) {
395
+ console.log(chalk_1.default.yellow('\nNo saved credentials found.'));
396
+ console.log('Run "aranea-sdk auth login" to authenticate.');
397
+ process.exit(1);
398
+ }
399
+ console.log('Refreshing token...');
400
+ try {
401
+ const newCredentials = await refreshIdToken(credentials.refreshToken);
402
+ saveCredentials(newCredentials);
403
+ console.log(chalk_1.default.green('\n✓ Token refreshed successfully!'));
404
+ console.log(` Email: ${newCredentials.email}`);
405
+ console.log(` Expires in: ${formatRemainingTime(newCredentials.expiresAt)}`);
406
+ console.log(` Expires at: ${new Date(newCredentials.expiresAt).toLocaleString('ja-JP')}`);
407
+ }
408
+ catch (error) {
409
+ console.error(chalk_1.default.red(`\n✖ Token refresh failed: ${error.message}`));
410
+ console.log('You may need to run "aranea-sdk auth login" again.');
411
+ process.exit(1);
412
+ }
413
+ });
414
+ // auth logout
415
+ exports.authCommand
416
+ .command('logout')
417
+ .description('Clear saved credentials')
418
+ .action(() => {
419
+ const credentials = loadCredentials();
420
+ if (!credentials) {
421
+ console.log(chalk_1.default.yellow('\nNo saved credentials found.'));
422
+ return;
423
+ }
424
+ clearCredentials();
425
+ console.log(chalk_1.default.green('\n✓ Credentials cleared.'));
426
+ console.log(` Removed: ${CREDENTIALS_FILE}`);
427
+ });
@@ -2,13 +2,17 @@
2
2
  * schema command
3
3
  *
4
4
  * Usage:
5
- * aranea-sdk schema get --type "aranea_ar-is04a"
6
- * aranea-sdk schema list
5
+ * aranea-sdk schema list [--endpoint staging|production]
6
+ * aranea-sdk schema get --type "aranea_ar-is04a" [--endpoint staging|production]
7
7
  * aranea-sdk schema validate --type "aranea_ar-is04a" --file state.json
8
8
  * aranea-sdk schema validate-schema --file schema.json
9
- * aranea-sdk schema push --file schema.json [--token TOKEN]
10
- * aranea-sdk schema promote --type "aranea_ar-is04a" [--token TOKEN]
11
- * aranea-sdk schema info --type "aranea_ar-is04a"
9
+ * aranea-sdk schema push --file schema.json [--token TOKEN] [--endpoint staging|production]
10
+ * aranea-sdk schema promote --type "aranea_ar-is04a" [--token TOKEN] [--endpoint staging|production] [--confirm]
11
+ * aranea-sdk schema info --type "aranea_ar-is04a" [--endpoint staging|production]
12
+ *
13
+ * Environment:
14
+ * - Default: staging (for safety)
15
+ * - Override: ARANEA_ENV=production or --endpoint production
12
16
  */
13
17
  import { Command } from 'commander';
14
18
  export declare const schemaCommand: Command;