@openagents-org/agent-launcher 0.2.192 → 0.2.194

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
@@ -10,6 +10,24 @@ npm install -g @openagents-org/agent-connector
10
10
 
11
11
  ## CLI Usage
12
12
 
13
+ ### Shared thread context
14
+
15
+ Before each triggered agent turn in a workspace thread, the connector reads
16
+ recent messages from all participants, including human-to-human discussion.
17
+ It includes up to 30 chat messages from the latest 100 events before the
18
+ trigger, in chronological order with speaker names. The transcript is bounded
19
+ to 16,000 characters, with long messages shortened to 2,000 characters each.
20
+ Status updates and the triggering message are excluded from the transcript;
21
+ the current request remains separate. Older messages remain available through
22
+ the workspace history tool.
23
+
24
+ This does not change mention or response-mode rules. Direct messages keep
25
+ their existing conversation handling. If history cannot be fetched within
26
+ five seconds, the connector logs the failure and continues with the request.
27
+ Existing installations need the updated connector and an agent restart.
28
+
29
+ ### Commands
30
+
13
31
  ```bash
14
32
  # Browse available agents
15
33
  agent-connector search
@@ -32,8 +50,14 @@ agent-connector status
32
50
  # View logs
33
51
  agent-connector logs
34
52
 
35
- # Connect to a workspace
36
- agent-connector connect my-agent <token>
53
+ # Connect this device (formerly "node") to a workspace with a pairing code
54
+ # from Workspace → Devices → Connect a device. Pair once; agents created on
55
+ # this device can then join without a token. `agn node ...` still works.
56
+ agent-connector device connect XXXX-XXXX
57
+ agent-connector device status
58
+
59
+ # Connect an agent to a paired workspace
60
+ agent-connector connect my-agent --workspace <slug>
37
61
 
38
62
  # Stop
39
63
  agent-connector down
@@ -41,6 +65,12 @@ agent-connector down
41
65
 
42
66
  Run `agent-connector help` for the full command list.
43
67
 
68
+ Only the person who connected a device controls it from the workspace
69
+ (remote add/start/stop of its agents); a workspace admin can only unpair it.
70
+ Every request the connector makes for an agent carries `X-Agent-Name`, so the
71
+ workspace applies that agent's permissions rather than treating the call as an
72
+ anonymous machine.
73
+
44
74
  ## Library Usage
45
75
 
46
76
  ```js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-launcher",
3
- "version": "0.2.192",
3
+ "version": "0.2.194",
4
4
  "description": "OpenAgents Launcher \u2014 install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/registry.json CHANGED
@@ -329,7 +329,7 @@
329
329
  },
330
330
  "check_ready": {
331
331
  "binary": "agent",
332
- "not_ready_message": "Cursor is installed but not signed in — run `cursor-agent login` on the device, or set a CURSOR_API_KEY from cursor.com/settings. Third-party or relay API keys do not work with Cursor.",
332
+ "not_ready_message": "Cursor is installed but not signed in — run `cursor-agent login` on the device (this is separate from signing in to the Cursor editor), or set a CURSOR_API_KEY from cursor.com/settings. Third-party or relay API keys do not work with Cursor.",
333
333
  "env_vars": [
334
334
  "CURSOR_API_KEY"
335
335
  ],
@@ -337,7 +337,11 @@
337
337
  "creds_key": "authInfo",
338
338
  "creds_no_parse": true,
339
339
  "unverifiable": true,
340
- "login_command": "cursor-agent login"
340
+ "login_command": "cursor-agent login",
341
+ "status_args": [
342
+ "status"
343
+ ],
344
+ "logged_out_pattern": "not logged in|not signed in|not authenticated|unauthenticated|logged out|signed out|login required|partially authenticated"
341
345
  },
342
346
  "env_config": [
343
347
  {
@@ -1323,9 +1327,11 @@
1323
1327
  "env_vars": [
1324
1328
  "GEMINI_API_KEY"
1325
1329
  ],
1330
+ "credential_target": "gemini:antigravity",
1331
+ "unverifiable": true,
1326
1332
  "saved_env_key": "GEMINI_API_KEY",
1327
1333
  "login_command": "agy",
1328
- "not_ready_message": "Needs sign-in — run `agy` to sign in with Google, or set GEMINI_API_KEY.",
1334
+ "not_ready_message": "Sign-in not confirmed. Run `agy` in a terminal to sign in with Google, or set GEMINI_API_KEY. On Windows the sign-in is detected once it lands in Credential Manager; elsewhere agy keeps it out of reach, so it is confirmed when you run a task.",
1329
1335
  "auth_detected_labels": {
1330
1336
  "cli_login": "Google account sign-in detected",
1331
1337
  "api_key": "API key detected"
@@ -158,7 +158,21 @@ class AgyRunState {
158
158
  }
159
159
  }
160
160
 
161
- const AUTH_RE = /authentication (required|failed)|not authenticated|sign[ -]?in|log[ -]?in required|no valid credentials|GEMINI_API_KEY/i;
161
+ // Auth phrasings agy and the Gemini API behind it actually produce. The
162
+ // underscored API status codes are spelled out rather than matched as plain
163
+ // English ("permission denied" alone is just as likely to be a file a tool
164
+ // couldn't read), and an expired/missing token counts as auth because the fix
165
+ // is the same sign-in either way.
166
+ const AUTH_RE =
167
+ /authentication (required|failed)|not authenticated|unauthenticated|sign[ -]?in|log[ -]?in required|no valid credentials|credentials? (not found|missing|expired|invalid)|(access|auth|refresh|id) token (expired|invalid|missing)|permission_denied|GEMINI_API_KEY/i;
168
+ // agy 1.2.2, verbatim, on an account Antigravity will not serve:
169
+ // Eligibility check failed: Your current account is not eligible for
170
+ // Antigravity, because it is not currently available in your location.
171
+ // It is checked BEFORE the auth patterns because it is the one failure a
172
+ // sign-in cannot fix — the account is signed in, which is exactly why telling
173
+ // the user to sign in again is the wrong answer.
174
+ const ELIGIBILITY_RE =
175
+ /eligibility check failed|not (currently )?available in your (location|country|region)/i;
162
176
  const PROVIDER_RE = /modelProvider|model provider/i;
163
177
  const MODEL_RE = /unknown model|invalid model/i;
164
178
  const TIMEOUT_RE = /print-timeout|timed? ?out/i;
@@ -177,6 +191,17 @@ function classifyAgyFailure({ code, stderr, error } = {}) {
177
191
  typeof error === 'string' ? error : [err.type, err.message].filter(Boolean).join(' ');
178
192
  const text = [errText, stderr].filter(Boolean).join('\n');
179
193
 
194
+ if (ELIGIBILITY_RE.test(text)) {
195
+ return {
196
+ kind: 'eligibility',
197
+ message:
198
+ 'Antigravity CLI refused the run because this Google account is not ' +
199
+ 'eligible for Antigravity — agy reports it is not available in your ' +
200
+ 'location. Signing in again will not change that. The other path this ' +
201
+ 'agent supports is GEMINI_API_KEY, which runs it against the Gemini API ' +
202
+ 'instead.',
203
+ };
204
+ }
180
205
  if (AUTH_RE.test(text)) {
181
206
  return {
182
207
  kind: 'auth',
@@ -206,15 +231,50 @@ function classifyAgyFailure({ code, stderr, error } = {}) {
206
231
  if (TIMEOUT_RE.test(text)) {
207
232
  return { kind: 'timeout', message: 'Antigravity CLI timed out before producing a response.' };
208
233
  }
209
- const detail = (errText || (stderr || '').trim().split('\n').pop() || '').slice(0, 200);
234
+ const detail = errText || stderrTail(stderr);
235
+ if (!detail) {
236
+ return {
237
+ kind: 'unknown',
238
+ message: `Antigravity CLI exited with code ${code ?? '?'} without a response.`,
239
+ };
240
+ }
241
+ // Unclassified, so the CLI's own words lead — but they are often a bare
242
+ // "Agent execution terminated due to error.", which tells the user nothing
243
+ // they can act on. Name the first thing worth checking without claiming to
244
+ // know it is the cause; agy says nothing more specific when it has no usable
245
+ // credentials, and that is far and away the most common way a run reaches
246
+ // here.
210
247
  return {
211
248
  kind: 'unknown',
212
- message: detail
213
- ? `Antigravity CLI failed (exit ${code ?? '?'}): ${detail}`
214
- : `Antigravity CLI exited with code ${code ?? '?'} without a response.`,
249
+ message:
250
+ `Antigravity CLI failed (exit ${code ?? '?'}):\n${detail}\n\n` +
251
+ 'If that does not say why, check the sign-in first — run `agy` once in a ' +
252
+ 'terminal to sign in with Google, or set GEMINI_API_KEY for this agent.',
215
253
  };
216
254
  }
217
255
 
256
+ /**
257
+ * The tail of a CLI's stderr, as a short quotable block.
258
+ *
259
+ * The last line alone used to be it, which threw away the informative half of
260
+ * every multi-line failure: agy prints its detail above a generic closing line,
261
+ * so what survived was exactly the part that says nothing. Colour codes are
262
+ * stripped — agy writes them even into a pipe, and they arrive as mojibake in a
263
+ * chat message.
264
+ */
265
+ function stderrTail(stderr, { lines = 3, limit = 600 } = {}) {
266
+ // eslint-disable-next-line no-control-regex
267
+ const plain = String(stderr || '').replace(/\u001B\[[0-9;?]*[ -\/]*[@-~]/g, '');
268
+ const kept = plain
269
+ .split('\n')
270
+ .map((l) => l.trimEnd())
271
+ .filter((l) => l.trim())
272
+ .slice(-lines)
273
+ .join('\n')
274
+ .trim();
275
+ return kept.length > limit ? kept.slice(-limit) : kept;
276
+ }
277
+
218
278
  /**
219
279
  * Filesystem candidates for the agy binary, beyond a PATH lookup. The install
220
280
  * script targets ~/.local/bin on macOS/Linux and %LOCALAPPDATA%\agy\bin on