aranea-sdk-cli 0.3.1 → 0.3.3

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,65 @@
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
+
43
+ 以下の情報は一般ドキュメントでは得られない**実践的知見**です。
44
+ 発見次第、CLIでナレッジベースに追加してください:
45
+
46
+ | カテゴリ | 追加すべき情報 | 例 |
47
+ |---------|--------------|-----|
48
+ | `incident` | ハードウェア固有の問題・解決策 | メモリ不足でクラッシュ、タイムアウトエラー |
49
+ | `tip` | テスト・デバッグで追い込んだパラメータ | HTTPSタイムアウト15秒必要 |
50
+ | `tip` | ESP32メモリ関連設定 | SSL接続に50KB必要 |
51
+ | `tip` | SBC (OrangePi等) のサービス起動・権限問題 | systemd設定、sudoers設定 |
52
+ | `incident` | ハードウェア相性問題 | 特定WiFiモジュールとの非互換 |
53
+
54
+ ```bash
55
+ # 例: インシデント対応で発見した設定値を追加
56
+ aranea-sdk knowledge add \
57
+ --title "ESP32 HTTPSタイムアウト 15秒必要" \
58
+ --category tip \
59
+ --content "ESP32でHTTPS接続する場合、最低15秒のタイムアウトが必要。初回SSL handshakeは特に時間がかかる。-11 READ_TIMEOUTエラーの原因。" \
60
+ --keywords "esp32,https,timeout,ssl,handshake" \
61
+ --device-types "aranea_ar-is04a,aranea_ar-is05a"
62
+ ```
63
+
64
+ ---
65
+
7
66
  ## 概要
8
67
 
9
68
  AraneaSDK CLIは、AraneaSDK対応ESP32デバイスの開発・テスト・登録を支援するコマンドラインツールです。
@@ -39,12 +98,13 @@ aranea-sdk metatron ask "State Reportの送信方法は?"
39
98
  |---------|------|------|
40
99
  | `test` | 接続・認証テスト | 不要 |
41
100
  | `register` | デバイス登録 | 不要(テストテナント) |
42
- | `schema` | スキーマ取得・State Report検証 | 不要 |
101
+ | `schema` | スキーマ取得・検証・プッシュ | push/promote時必要 |
43
102
  | `validate` | Type名検証 | 不要 |
44
103
  | `simulate` | 状態レポートシミュレーション | 不要 |
45
104
  | `mqtt` | コマンド送信・ACKモニタリング | **必要** |
46
105
  | `knowledge` | ナレッジベース管理 | **必要** |
47
106
  | `metatron` | AI対話アシスタント | **必要** |
107
+ | `auth` | 認証トークン管理 | - |
48
108
 
49
109
  ---
50
110
 
@@ -166,11 +226,27 @@ aranea-sdk schema validate --file state.json --type aranea_ar-is04a
166
226
  | `list` | ✅ 実装済み | 登録済みスキーマ一覧 |
167
227
  | `get` | ✅ 実装済み | スキーマ詳細取得 |
168
228
  | `validate` | ✅ 実装済み | State Report 検証 |
169
- | `create` | 🔜 計画中 | スキーマ新規作成 |
170
- | `push` | 🔜 計画中 | 開発環境へプッシュ |
171
- | `promote` | 🔜 計画中 | 本番環境へ昇格 |
229
+ | `validate-schema` | 実装済み | スキーマ定義の静的検証 |
230
+ | `push` | 実装済み | 開発環境へプッシュ (認証必要) |
231
+ | `promote` | 実装済み | 本番環境へ昇格 (認証必要、確認ステップあり) |
232
+ | `info` | ✅ 実装済み | スキーマ詳細情報・リビジョン履歴 |
172
233
  | `rollback` | 🔜 計画中 | バージョンロールバック |
173
234
 
235
+ ### 環境切替 (v0.3.1)
236
+
237
+ すべてのschemaサブコマンドで `--endpoint` オプションが使用可能です:
238
+
239
+ ```bash
240
+ # デフォルト: staging
241
+ aranea-sdk schema list
242
+
243
+ # 明示的にproduction指定
244
+ aranea-sdk schema list --endpoint production
245
+
246
+ # 環境変数でも指定可能
247
+ ARANEA_ENV=production aranea-sdk schema list
248
+ ```
249
+
174
250
  ---
175
251
 
176
252
  ## validate - Type名検証
@@ -339,6 +415,45 @@ aranea-sdk metatron examples
339
415
 
340
416
  ---
341
417
 
418
+ ## auth - 認証管理 (v0.3.1)
419
+
420
+ Firebase Auth IDトークンを管理します。トークンは `~/.aranea-sdk/credentials.json` に保存されます。
421
+
422
+ ### 使用例
423
+
424
+ ```bash
425
+ # ログイン (対話式)
426
+ aranea-sdk auth login
427
+
428
+ # メールアドレス指定でログイン
429
+ aranea-sdk auth login --email dev@example.com
430
+
431
+ # トークン情報表示
432
+ aranea-sdk auth token
433
+
434
+ # トークンのみ出力 (スクリプト用)
435
+ aranea-sdk auth token --raw
436
+
437
+ # トークン更新 (1時間で期限切れ)
438
+ aranea-sdk auth refresh
439
+
440
+ # ログアウト
441
+ aranea-sdk auth logout
442
+ ```
443
+
444
+ ### トークンライフサイクル
445
+
446
+ - IDトークンは **1時間** で期限切れ
447
+ - `auth refresh` で新しいトークンを取得
448
+ - `auth token --raw` でスクリプトからトークン取得可能
449
+
450
+ ```bash
451
+ # 他コマンドでトークンを使用
452
+ aranea-sdk metatron ask "質問" --token "$(aranea-sdk auth token --raw)"
453
+ ```
454
+
455
+ ---
456
+
342
457
  ## 対応デバイスType
343
458
 
344
459
  ### 新規 (aranea_ar-*)
@@ -54,10 +54,17 @@ const ora_1 = __importDefault(require("ora"));
54
54
  const axios_1 = __importDefault(require("axios"));
55
55
  const fs = __importStar(require("fs"));
56
56
  const path = __importStar(require("path"));
57
+ const config_1 = require("../config");
57
58
  // ============================================================================
58
59
  // Config
59
60
  // ============================================================================
60
- const KNOWLEDGE_API_BASE = 'https://asia-northeast1-mobesorder.cloudfunctions.net/araneaSDK_knowledgeManagement';
61
+ const KNOWLEDGE_API_ENDPOINTS = {
62
+ production: 'https://asia-northeast1-mobesorder.cloudfunctions.net/araneaKnowledgeManagement',
63
+ staging: 'https://asia-northeast1-mobesorder-staging.cloudfunctions.net/araneaKnowledgeManagement',
64
+ };
65
+ function getKnowledgeApiBase(env) {
66
+ return KNOWLEDGE_API_ENDPOINTS[env];
67
+ }
61
68
  // カテゴリ定義
62
69
  const CATEGORIES = ['api', 'guide', 'code', 'reference', 'incident', 'tip'];
63
70
  // ============================================================================
@@ -72,8 +79,9 @@ function getAuthToken() {
72
79
  /**
73
80
  * API呼び出し(Callable形式)
74
81
  */
75
- async function callKnowledgeAPI(action, params, token) {
76
- const response = await axios_1.default.post(KNOWLEDGE_API_BASE, { data: { action, ...params } }, {
82
+ async function callKnowledgeAPI(action, params, token, env) {
83
+ const apiBase = getKnowledgeApiBase(env);
84
+ const response = await axios_1.default.post(apiBase, { data: { action, ...params } }, {
77
85
  headers: {
78
86
  'Content-Type': 'application/json',
79
87
  Authorization: `Bearer ${token}`,
@@ -131,9 +139,12 @@ exports.knowledgeCommand
131
139
  .option('--device-types <types>', '関連デバイスタイプ (カンマ区切り)')
132
140
  .option('--status <status>', 'ステータス (draft|published)', 'draft')
133
141
  .option('--token <token>', '認証トークン')
142
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
134
143
  .action(async (options) => {
135
144
  try {
136
- console.log(chalk_1.default.bold('\n=== Knowledge Add ===\n'));
145
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
146
+ (0, config_1.warnIfProduction)(env, 'knowledge add');
147
+ console.log(chalk_1.default.bold(`\n=== Knowledge Add (${env}) ===\n`));
137
148
  // 認証トークン
138
149
  const token = options.token || getAuthToken();
139
150
  if (!token) {
@@ -186,7 +197,7 @@ exports.knowledgeCommand
186
197
  relatedDeviceTypes: deviceTypes,
187
198
  status: options.status,
188
199
  },
189
- }, token);
200
+ }, token, env);
190
201
  spinner.stop();
191
202
  if (result.success) {
192
203
  console.log(chalk_1.default.green('✓ ナレッジエントリを追加しました'));
@@ -194,6 +205,7 @@ exports.knowledgeCommand
194
205
  console.log(` Title: ${options.title}`);
195
206
  console.log(` Category: ${options.category}`);
196
207
  console.log(` Status: ${options.status}`);
208
+ console.log(` Environment: ${env}`);
197
209
  }
198
210
  else {
199
211
  console.log(chalk_1.default.red(`✗ 追加失敗: ${result.error}`));
@@ -212,9 +224,11 @@ exports.knowledgeCommand
212
224
  .option('-c, --category <category>', 'カテゴリフィルタ')
213
225
  .option('-l, --limit <limit>', '結果数', '10')
214
226
  .option('--token <token>', '認証トークン')
227
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
215
228
  .action(async (options) => {
216
229
  try {
217
- console.log(chalk_1.default.bold('\n=== Knowledge Search ===\n'));
230
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
231
+ console.log(chalk_1.default.bold(`\n=== Knowledge Search (${env}) ===\n`));
218
232
  const token = options.token || getAuthToken();
219
233
  if (!token) {
220
234
  console.error(chalk_1.default.red('❌ 認証トークンが必要です'));
@@ -225,7 +239,7 @@ exports.knowledgeCommand
225
239
  query: options.query,
226
240
  category: options.category,
227
241
  limit: parseInt(options.limit, 10),
228
- }, token);
242
+ }, token, env);
229
243
  spinner.stop();
230
244
  if (result.success && result.data) {
231
245
  const entries = Array.isArray(result.data) ? result.data : [];
@@ -254,9 +268,11 @@ exports.knowledgeCommand
254
268
  .option('-s, --status <status>', 'ステータスフィルタ (draft|published|archived)')
255
269
  .option('-l, --limit <limit>', '表示数', '20')
256
270
  .option('--token <token>', '認証トークン')
271
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
257
272
  .action(async (options) => {
258
273
  try {
259
- console.log(chalk_1.default.bold('\n=== Knowledge List ===\n'));
274
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
275
+ console.log(chalk_1.default.bold(`\n=== Knowledge List (${env}) ===\n`));
260
276
  const token = options.token || getAuthToken();
261
277
  if (!token) {
262
278
  console.error(chalk_1.default.red('❌ 認証トークンが必要です'));
@@ -267,7 +283,7 @@ exports.knowledgeCommand
267
283
  category: options.category,
268
284
  status: options.status,
269
285
  limit: parseInt(options.limit, 10),
270
- }, token);
286
+ }, token, env);
271
287
  spinner.stop();
272
288
  if (result.success && result.data) {
273
289
  const entries = Array.isArray(result.data) ? result.data : [];
@@ -294,16 +310,18 @@ exports.knowledgeCommand
294
310
  .description('ナレッジエントリを取得')
295
311
  .requiredOption('-i, --id <id>', 'エントリID')
296
312
  .option('--token <token>', '認証トークン')
313
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
297
314
  .action(async (options) => {
298
315
  try {
299
- console.log(chalk_1.default.bold('\n=== Knowledge Get ===\n'));
316
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
317
+ console.log(chalk_1.default.bold(`\n=== Knowledge Get (${env}) ===\n`));
300
318
  const token = options.token || getAuthToken();
301
319
  if (!token) {
302
320
  console.error(chalk_1.default.red('❌ 認証トークンが必要です'));
303
321
  process.exit(1);
304
322
  }
305
323
  const spinner = (0, ora_1.default)('ナレッジを取得中...').start();
306
- const result = await callKnowledgeAPI('get', { id: options.id }, token);
324
+ const result = await callKnowledgeAPI('get', { id: options.id }, token, env);
307
325
  spinner.stop();
308
326
  if (result.success && result.data) {
309
327
  formatEntry(result.data, true);
@@ -323,10 +341,13 @@ exports.knowledgeCommand
323
341
  .description('ナレッジエントリを削除 (アーカイブ)')
324
342
  .requiredOption('-i, --id <id>', 'エントリID')
325
343
  .option('--token <token>', '認証トークン')
344
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
326
345
  .option('-y, --yes', '確認をスキップ')
327
346
  .action(async (options) => {
328
347
  try {
329
- console.log(chalk_1.default.bold('\n=== Knowledge Delete ===\n'));
348
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
349
+ (0, config_1.warnIfProduction)(env, 'knowledge delete');
350
+ console.log(chalk_1.default.bold(`\n=== Knowledge Delete (${env}) ===\n`));
330
351
  const token = options.token || getAuthToken();
331
352
  if (!token) {
332
353
  console.error(chalk_1.default.red('❌ 認証トークンが必要です'));
@@ -338,7 +359,7 @@ exports.knowledgeCommand
338
359
  // Note: In a real CLI, would use inquirer for confirmation
339
360
  }
340
361
  const spinner = (0, ora_1.default)('削除中...').start();
341
- const result = await callKnowledgeAPI('delete', { id: options.id }, token);
362
+ const result = await callKnowledgeAPI('delete', { id: options.id }, token, env);
342
363
  spinner.stop();
343
364
  if (result.success) {
344
365
  console.log(chalk_1.default.green('✓ ナレッジエントリをアーカイブしました'));
@@ -355,20 +376,74 @@ exports.knowledgeCommand
355
376
  // knowledge categories
356
377
  exports.knowledgeCommand
357
378
  .command('categories')
358
- .description('利用可能なカテゴリ一覧')
379
+ .description('利用可能なカテゴリ一覧と追加すべきナレッジの例')
359
380
  .action(() => {
360
381
  console.log(chalk_1.default.bold('\n=== Knowledge Categories ===\n'));
361
- const categoryDescriptions = {
362
- api: 'API仕様・エンドポイント',
363
- guide: '実装ガイド・チュートリアル',
364
- code: 'コードサンプル・スニペット',
365
- reference: 'リファレンス・仕様書',
366
- incident: 'インシデント・トラブルシューティング',
367
- tip: 'Tips・ノウハウ',
382
+ const categoryInfo = {
383
+ api: {
384
+ desc: 'API仕様・エンドポイント',
385
+ examples: [
386
+ 'State Report API の仕様変更',
387
+ 'エンドポイントURL・認証方式',
388
+ ],
389
+ },
390
+ guide: {
391
+ desc: '実装ガイド・チュートリアル',
392
+ examples: [
393
+ 'ESP32 State Report実装手順',
394
+ 'OrangePi サービス設定ガイド',
395
+ ],
396
+ },
397
+ code: {
398
+ desc: 'コードサンプル・スニペット',
399
+ examples: [
400
+ 'Arduino HTTPS接続コード',
401
+ 'Python MQTT受信サンプル',
402
+ ],
403
+ },
404
+ reference: {
405
+ desc: 'リファレンス・仕様書',
406
+ examples: [
407
+ 'スキーマ定義一覧',
408
+ 'エラーコード一覧',
409
+ ],
410
+ },
411
+ incident: {
412
+ desc: 'インシデント・トラブルシューティング',
413
+ examples: [
414
+ '⚠️ ハードウェア固有の問題・解決策',
415
+ '⚠️ メモリ不足・タイムアウト事例',
416
+ '⚠️ 相性問題・回避策',
417
+ ],
418
+ },
419
+ tip: {
420
+ desc: 'Tips・ノウハウ(一般情報では得られない実践知見)',
421
+ examples: [
422
+ '⚠️ ESP32 HTTPSタイムアウト 15秒必要',
423
+ '⚠️ OrangePi サービス起動順序',
424
+ '⚠️ メモリ設定・バッファサイズの追い込み値',
425
+ '⚠️ ハードウェア相性・非互換情報',
426
+ ],
427
+ },
368
428
  };
369
429
  for (const cat of CATEGORIES) {
370
- console.log(` ${chalk_1.default.cyan(cat.padEnd(12))} ${categoryDescriptions[cat]}`);
430
+ const info = categoryInfo[cat];
431
+ console.log(` ${chalk_1.default.cyan(cat.padEnd(12))} ${info.desc}`);
432
+ for (const ex of info.examples) {
433
+ if (ex.startsWith('⚠️')) {
434
+ console.log(` ${chalk_1.default.yellow(ex)}`);
435
+ }
436
+ else {
437
+ console.log(` ${chalk_1.default.gray('- ' + ex)}`);
438
+ }
439
+ }
440
+ console.log('');
371
441
  }
372
- console.log('');
442
+ console.log(chalk_1.default.bold('📝 AIエージェント向け: 以下のナレッジは特に貴重です\n'));
443
+ console.log(chalk_1.default.yellow(' • インシデント対応で発見したハードウェア固有の設定値'));
444
+ console.log(chalk_1.default.yellow(' • テスト・デバッグで追い込んだパラメータ(タイムアウト、バッファサイズ等)'));
445
+ console.log(chalk_1.default.yellow(' • ESP32のメモリ関連、SBCのサービス起動・権限問題'));
446
+ console.log(chalk_1.default.yellow(' • ハードウェア相性問題と回避策'));
447
+ console.log(chalk_1.default.yellow(' • 一般的なドキュメントには載っていない実践的知見\n'));
373
448
  });
374
449
  exports.default = exports.knowledgeCommand;
@@ -51,10 +51,17 @@ const chalk_1 = __importDefault(require("chalk"));
51
51
  const ora_1 = __importDefault(require("ora"));
52
52
  const axios_1 = __importDefault(require("axios"));
53
53
  const readline = __importStar(require("readline"));
54
+ const config_1 = require("../config");
54
55
  // ============================================================================
55
56
  // Config
56
57
  // ============================================================================
57
- const METATRON_API_BASE = 'https://asia-northeast1-mobesorder.cloudfunctions.net/araneaSDK_metatronQuery';
58
+ const METATRON_API_ENDPOINTS = {
59
+ production: 'https://asia-northeast1-mobesorder.cloudfunctions.net/araneaMetatronQuery',
60
+ staging: 'https://asia-northeast1-mobesorder-staging.cloudfunctions.net/araneaMetatronQuery',
61
+ };
62
+ function getMetatronApiBase(env) {
63
+ return METATRON_API_ENDPOINTS[env];
64
+ }
58
65
  // ============================================================================
59
66
  // Helper Functions
60
67
  // ============================================================================
@@ -67,8 +74,9 @@ function getAuthToken() {
67
74
  /**
68
75
  * Metatron API呼び出し
69
76
  */
70
- async function queryMetatron(query, context, token) {
71
- const response = await axios_1.default.post(METATRON_API_BASE, { data: { query, context } }, {
77
+ async function queryMetatron(query, context, token, env) {
78
+ const apiBase = getMetatronApiBase(env);
79
+ const response = await axios_1.default.post(apiBase, { data: { query, context } }, {
72
80
  headers: {
73
81
  'Content-Type': 'application/json',
74
82
  Authorization: `Bearer ${token}`,
@@ -110,11 +118,13 @@ exports.metatronCommand
110
118
  .description('単発質問')
111
119
  .option('--context <context>', 'コンテキスト', 'aranea_sdk_cli')
112
120
  .option('--token <token>', '認証トークン')
121
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
113
122
  .option('--raw', 'JSON出力')
114
123
  .action(async (question, options) => {
115
124
  try {
125
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
116
126
  if (!options.raw) {
117
- console.log(chalk_1.default.bold('\n=== AraneaMetatron ===\n'));
127
+ console.log(chalk_1.default.bold(`\n=== AraneaMetatron (${env}) ===\n`));
118
128
  console.log(chalk_1.default.gray(`Q: ${question}`));
119
129
  }
120
130
  const token = options.token || getAuthToken();
@@ -123,7 +133,7 @@ exports.metatronCommand
123
133
  process.exit(1);
124
134
  }
125
135
  const spinner = options.raw ? null : (0, ora_1.default)('回答生成中...').start();
126
- const result = await queryMetatron(question, options.context, token);
136
+ const result = await queryMetatron(question, options.context, token, env);
127
137
  spinner?.stop();
128
138
  if (options.raw) {
129
139
  console.log(JSON.stringify(result, null, 2));
@@ -143,8 +153,10 @@ exports.metatronCommand
143
153
  .description('対話モード (REPL)')
144
154
  .option('--context <context>', 'コンテキスト', 'aranea_sdk_cli')
145
155
  .option('--token <token>', '認証トークン')
156
+ .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
146
157
  .action(async (options) => {
147
- console.log(chalk_1.default.bold('\n=== AraneaMetatron Chat ===\n'));
158
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
159
+ console.log(chalk_1.default.bold(`\n=== AraneaMetatron Chat (${env}) ===\n`));
148
160
  console.log(chalk_1.default.gray('AraneaSDKについて質問してください。'));
149
161
  console.log(chalk_1.default.gray('終了するには "exit" または Ctrl+C を入力\n'));
150
162
  const token = options.token || getAuthToken();
@@ -171,7 +183,7 @@ exports.metatronCommand
171
183
  const spinner = (0, ora_1.default)('').start();
172
184
  spinner.text = '';
173
185
  try {
174
- const result = await queryMetatron(query, options.context, token);
186
+ const result = await queryMetatron(query, options.context, token, env);
175
187
  spinner.stop();
176
188
  console.log('');
177
189
  console.log(chalk_1.default.green('Metatron:'), result.answer);
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ const program = new commander_1.Command();
28
28
  program
29
29
  .name('aranea-sdk')
30
30
  .description('AraneaSDK CLI - デバイス開発支援ツール')
31
- .version('0.3.1');
31
+ .version('0.3.3');
32
32
  // test コマンド
33
33
  program.addCommand(test_1.testCommand);
34
34
  // simulate コマンド
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aranea-sdk-cli",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "AraneaSDK CLI - ESP32 IoTデバイス開発支援ツール",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",