@gopherhole/cli 0.2.0 → 0.3.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.
Files changed (3) hide show
  1. package/dist/index.js +20 -10
  2. package/package.json +2 -2
  3. package/src/index.ts +22 -10
package/dist/index.js CHANGED
@@ -62,6 +62,14 @@ async function resolveAgentId(flagValue) {
62
62
  catch { /* ignore */ }
63
63
  return null;
64
64
  }
65
+ function resolveTransport(flagValue) {
66
+ const value = flagValue || process.env.GOPHERHOLE_TRANSPORT || 'http';
67
+ if (!['http', 'ws', 'auto'].includes(value)) {
68
+ console.error(chalk_1.default.red(`Invalid transport: ${value}. Must be http, ws, or auto`));
69
+ process.exit(1);
70
+ }
71
+ return value;
72
+ }
65
73
  function makeAgentClient(apiKey) {
66
74
  return new sdk_1.A2AClient({
67
75
  apiKey,
@@ -69,10 +77,10 @@ function makeAgentClient(apiKey) {
69
77
  });
70
78
  }
71
79
  /** Hub client for workspace/discovery operations (does not connect WebSocket) */
72
- function makeHubClient(apiKey) {
80
+ function makeHubClient(apiKey, transport) {
73
81
  const apiUrl = process.env.GOPHERHOLE_API_URL || 'https://hub.gopherhole.ai';
74
82
  const hubUrl = apiUrl.replace('https://', 'wss://').replace('http://', 'ws://') + '/ws';
75
- return new sdk_1.GopherHole({ apiKey, hubUrl, autoReconnect: false });
83
+ return new sdk_1.GopherHole({ apiKey, hubUrl, autoReconnect: false, transport: transport || 'http' });
76
84
  }
77
85
  /** Send a message and poll until terminal state, return response text.
78
86
  * Matches the MCP client pattern: sendText → poll getTask. */
@@ -166,6 +174,7 @@ ${chalk_1.default.bold('Documentation:')}
166
174
  `)
167
175
  .version(VERSION)
168
176
  .option('-v, --verbose', 'Enable verbose output for debugging')
177
+ .option('-t, --transport <mode>', 'Transport mode: http | ws | auto (default: http)')
169
178
  .hook('preAction', (thisCommand) => {
170
179
  verbose = thisCommand.opts().verbose || false;
171
180
  if (verbose) {
@@ -2316,6 +2325,7 @@ ${chalk_1.default.bold('Examples:')}
2316
2325
  console.error(chalk_1.default.gray('Set GOPHERHOLE_API_KEY, pass --api-key, or run gopher init to create a .env'));
2317
2326
  process.exit(1);
2318
2327
  }
2328
+ log(`Transport: http (A2AClient is HTTP-only)`);
2319
2329
  const spinner = (0, ora_1.default)(`Messaging ${agentId}...`).start();
2320
2330
  try {
2321
2331
  const client = makeAgentClient(apiKey);
@@ -2465,7 +2475,7 @@ ws
2465
2475
  }
2466
2476
  const spinner = (0, ora_1.default)('Loading workspaces...').start();
2467
2477
  try {
2468
- const client = makeHubClient(apiKey);
2478
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2469
2479
  const result = await client.workspaceList();
2470
2480
  spinner.stop();
2471
2481
  if (!result.workspaces.length) {
@@ -2499,7 +2509,7 @@ ws
2499
2509
  }
2500
2510
  const spinner = (0, ora_1.default)('Creating workspace...').start();
2501
2511
  try {
2502
- const client = makeHubClient(apiKey);
2512
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2503
2513
  const result = await client.workspaceCreate(name, options.description);
2504
2514
  spinner.succeed(`Workspace created: ${chalk_1.default.bold(result.workspace.name)}`);
2505
2515
  console.log(chalk_1.default.gray(` ID: ${result.workspace.id}`));
@@ -2524,7 +2534,7 @@ ws
2524
2534
  }
2525
2535
  const spinner = (0, ora_1.default)('Searching...').start();
2526
2536
  try {
2527
- const client = makeHubClient(apiKey);
2537
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2528
2538
  const result = await client.workspaceQuery({
2529
2539
  workspace_id: workspaceId,
2530
2540
  query,
@@ -2565,7 +2575,7 @@ ws
2565
2575
  }
2566
2576
  const spinner = (0, ora_1.default)('Storing...').start();
2567
2577
  try {
2568
- const client = makeHubClient(apiKey);
2578
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2569
2579
  const result = await client.workspaceStore({
2570
2580
  workspace_id: workspaceId,
2571
2581
  content,
@@ -2594,7 +2604,7 @@ ws
2594
2604
  }
2595
2605
  const spinner = (0, ora_1.default)('Loading memories...').start();
2596
2606
  try {
2597
- const client = makeHubClient(apiKey);
2607
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2598
2608
  const result = await client.workspaceMemories({
2599
2609
  workspace_id: workspaceId,
2600
2610
  limit: parseInt(options.limit),
@@ -2637,7 +2647,7 @@ ws
2637
2647
  }
2638
2648
  const spinner = (0, ora_1.default)('Deleting...').start();
2639
2649
  try {
2640
- const client = makeHubClient(apiKey);
2650
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2641
2651
  const result = await client.workspaceForget({
2642
2652
  workspace_id: workspaceId,
2643
2653
  id: options.id,
@@ -2666,7 +2676,7 @@ wsMembers
2666
2676
  }
2667
2677
  const spinner = (0, ora_1.default)('Loading members...').start();
2668
2678
  try {
2669
- const client = makeHubClient(apiKey);
2679
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2670
2680
  const result = await client.workspaceMembersList(workspaceId);
2671
2681
  spinner.stop();
2672
2682
  result.members.forEach(m => {
@@ -2692,7 +2702,7 @@ wsMembers
2692
2702
  }
2693
2703
  const spinner = (0, ora_1.default)('Adding member...').start();
2694
2704
  try {
2695
- const client = makeHubClient(apiKey);
2705
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2696
2706
  await client.workspaceMembersAdd(workspaceId, agentId, options.role);
2697
2707
  spinner.succeed(`Added ${agentId} with role: ${options.role}`);
2698
2708
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gopherhole/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "GopherHole CLI - Connect AI agents to the world",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
  "author": "GopherHole",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@gopherhole/sdk": "^0.5.4",
25
+ "@gopherhole/sdk": "^0.6.0",
26
26
  "chalk": "^5.3.0",
27
27
  "commander": "^12.0.0",
28
28
  "conf": "^12.0.0",
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import inquirer from 'inquirer';
6
6
  import ora from 'ora';
7
7
  import open from 'open';
8
8
  import { A2AClient, GopherHole } from '@gopherhole/sdk';
9
+ import type { TransportMode } from '@gopherhole/sdk';
9
10
 
10
11
  const config = new Conf({ projectName: 'gopherhole' });
11
12
  const API_URL = 'https://gopherhole.ai/api';
@@ -61,6 +62,15 @@ async function resolveAgentId(flagValue?: string): Promise<string | null> {
61
62
  return null;
62
63
  }
63
64
 
65
+ function resolveTransport(flagValue?: string): TransportMode {
66
+ const value = flagValue || process.env.GOPHERHOLE_TRANSPORT || 'http';
67
+ if (!['http', 'ws', 'auto'].includes(value)) {
68
+ console.error(chalk.red(`Invalid transport: ${value}. Must be http, ws, or auto`));
69
+ process.exit(1);
70
+ }
71
+ return value as TransportMode;
72
+ }
73
+
64
74
  function makeAgentClient(apiKey: string): A2AClient {
65
75
  return new A2AClient({
66
76
  apiKey,
@@ -69,10 +79,10 @@ function makeAgentClient(apiKey: string): A2AClient {
69
79
  }
70
80
 
71
81
  /** Hub client for workspace/discovery operations (does not connect WebSocket) */
72
- function makeHubClient(apiKey: string): GopherHole {
82
+ function makeHubClient(apiKey: string, transport?: TransportMode): GopherHole {
73
83
  const apiUrl = process.env.GOPHERHOLE_API_URL || 'https://hub.gopherhole.ai';
74
84
  const hubUrl = apiUrl.replace('https://', 'wss://').replace('http://', 'ws://') + '/ws';
75
- return new GopherHole({ apiKey, hubUrl, autoReconnect: false });
85
+ return new GopherHole({ apiKey, hubUrl, autoReconnect: false, transport: transport || 'http' });
76
86
  }
77
87
 
78
88
  /** Send a message and poll until terminal state, return response text.
@@ -176,6 +186,7 @@ ${chalk.bold('Documentation:')}
176
186
  `)
177
187
  .version(VERSION)
178
188
  .option('-v, --verbose', 'Enable verbose output for debugging')
189
+ .option('-t, --transport <mode>', 'Transport mode: http | ws | auto (default: http)')
179
190
  .hook('preAction', (thisCommand) => {
180
191
  verbose = thisCommand.opts().verbose || false;
181
192
  if (verbose) {
@@ -2550,6 +2561,7 @@ ${chalk.bold('Examples:')}
2550
2561
  process.exit(1);
2551
2562
  }
2552
2563
 
2564
+ log(`Transport: http (A2AClient is HTTP-only)`);
2553
2565
  const spinner = ora(`Messaging ${agentId}...`).start();
2554
2566
  try {
2555
2567
  const client = makeAgentClient(apiKey);
@@ -2695,7 +2707,7 @@ ws
2695
2707
  }
2696
2708
  const spinner = ora('Loading workspaces...').start();
2697
2709
  try {
2698
- const client = makeHubClient(apiKey);
2710
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2699
2711
  const result = await client.workspaceList();
2700
2712
  spinner.stop();
2701
2713
  if (!result.workspaces.length) {
@@ -2726,7 +2738,7 @@ ws
2726
2738
  }
2727
2739
  const spinner = ora('Creating workspace...').start();
2728
2740
  try {
2729
- const client = makeHubClient(apiKey);
2741
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2730
2742
  const result = await client.workspaceCreate(name, options.description);
2731
2743
  spinner.succeed(`Workspace created: ${chalk.bold(result.workspace.name)}`);
2732
2744
  console.log(chalk.gray(` ID: ${result.workspace.id}`));
@@ -2749,7 +2761,7 @@ ws
2749
2761
  }
2750
2762
  const spinner = ora('Searching...').start();
2751
2763
  try {
2752
- const client = makeHubClient(apiKey);
2764
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2753
2765
  const result = await client.workspaceQuery({
2754
2766
  workspace_id: workspaceId,
2755
2767
  query,
@@ -2787,7 +2799,7 @@ ws
2787
2799
  }
2788
2800
  const spinner = ora('Storing...').start();
2789
2801
  try {
2790
- const client = makeHubClient(apiKey);
2802
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2791
2803
  const result = await client.workspaceStore({
2792
2804
  workspace_id: workspaceId,
2793
2805
  content,
@@ -2814,7 +2826,7 @@ ws
2814
2826
  }
2815
2827
  const spinner = ora('Loading memories...').start();
2816
2828
  try {
2817
- const client = makeHubClient(apiKey);
2829
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2818
2830
  const result = await client.workspaceMemories({
2819
2831
  workspace_id: workspaceId,
2820
2832
  limit: parseInt(options.limit),
@@ -2854,7 +2866,7 @@ ws
2854
2866
  }
2855
2867
  const spinner = ora('Deleting...').start();
2856
2868
  try {
2857
- const client = makeHubClient(apiKey);
2869
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2858
2870
  const result = await client.workspaceForget({
2859
2871
  workspace_id: workspaceId,
2860
2872
  id: options.id,
@@ -2882,7 +2894,7 @@ wsMembers
2882
2894
  }
2883
2895
  const spinner = ora('Loading members...').start();
2884
2896
  try {
2885
- const client = makeHubClient(apiKey);
2897
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2886
2898
  const result = await client.workspaceMembersList(workspaceId);
2887
2899
  spinner.stop();
2888
2900
  result.members.forEach(m => {
@@ -2906,7 +2918,7 @@ wsMembers
2906
2918
  }
2907
2919
  const spinner = ora('Adding member...').start();
2908
2920
  try {
2909
- const client = makeHubClient(apiKey);
2921
+ const client = makeHubClient(apiKey, resolveTransport(program.opts().transport));
2910
2922
  await client.workspaceMembersAdd(workspaceId, agentId, options.role);
2911
2923
  spinner.succeed(`Added ${agentId} with role: ${options.role}`);
2912
2924
  } catch (err) {