@gaia-ai/ui 0.10.0 → 0.11.1

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.
@@ -10,15 +10,6 @@ export interface HomeConnection {
10
10
  jsonapiPrefix?: string | undefined;
11
11
  authPlugins: unknown[];
12
12
  configPath?: string | undefined;
13
- /** The dropsh auth profile the cockpit READS as (`gaia_run` is session-only). */
14
- authProfile?: string | undefined;
15
- /**
16
- * GAIA-233: the dropsh auth profile the cockpit WRITES as, named beside the
17
- * read profile so both scopes are declared in one place. `session` holds no
18
- * `update gaia_ticket`, and `conductor_id` is additionally field-gated on
19
- * `assign gaia conductor`.
20
- */
21
- writeProfile?: string | undefined;
22
13
  }
23
14
  /**
24
15
  * Resolve the agent-launch command builder from the home config. Turns a TUI
@@ -5,6 +5,12 @@
5
5
  // holds no connection-precedence rule of its own (AC-6).
6
6
  import { dirname, resolve } from 'node:path';
7
7
  import { findProjectGaiaDir, homeGaiaDir, shellQuote, } from '@gaia-ai/core';
8
+ // GAIA-391: the two read/write auth-profile members are gone. A connection used
9
+ // to declare two dropsh auth profiles that differed only by OAuth scope, and the
10
+ // cockpit had to name one for reads and one for writes; GAIA-359 moved capability
11
+ // onto OG ranks, so both resolved to the same role. The connection now declares
12
+ // ONE default provider and nothing has to choose. AC2's grep over
13
+ // `gaia-cli/*/src` is the guard, so the retired names are not spelled here.
8
14
  /**
9
15
  * Resolve the agent-launch command builder from the home config. Turns a TUI
10
16
  * prompt into the shell command herdr runs. Defaults to `claude` (an empty
package/dist/src/ui.d.ts CHANGED
@@ -67,7 +67,6 @@ export interface BuildWriteClientOptions {
67
67
  baseUrl: string;
68
68
  jsonapiPrefix: string;
69
69
  plugins: GaiaConnectionConfig['plugins'];
70
- profile: string;
71
70
  }
72
71
  /** Test/composition seams for `gaia ui`. */
73
72
  export interface UiDeps {
package/dist/src/ui.js CHANGED
@@ -8,17 +8,24 @@ import { createHttpClient, createJsonApiClient } from 'dropsh/plugin';
8
8
  import { applyOpentuiLibc, reExecUnderBun, resolveBunBinary, shouldReExecUnderBun, } from './bun-runtime.js';
9
9
  import { parseTarget, resolveHere, UI_VIEW_MODES, } from './route.js';
10
10
  import { resolveAgentCommand, resolveProjectRooting, } from './ui-home.js';
11
- /** The auth profile `gaia ui` writes as. Reads stay on `session`. */
12
- const WRITE_PROFILE = 'pm';
13
11
  /**
14
- * Build a second JSON:API client under a different auth profile, from the
15
- * plugins core already constructed. `@dropsh/plugin-oauth2@0.5.7` derives its
16
- * plugin id from the profile id, so `session` and `pm` are distinct plugins and
17
- * BOTH resolve in one process — the old profile-dedupe that collapsed them is
18
- * fixed (measured: `providers: … session, pm`).
12
+ * Build the write-side JSON:API client from the plugins core already
13
+ * constructed, resolving the connection's DEFAULT auth provider.
19
14
  *
20
- * Throws a catchable error when the connection declares no such profile; the
21
- * caller degrades explicitly rather than aborting the cockpit.
15
+ * GAIA-391: no profile is named any more. This used to resolve a second,
16
+ * differently-SCOPED provider (`pm`) beside the reads' `session`, because at
17
+ * granularity `role` the requested scope alone decided which role a token
18
+ * carried. GAIA-359 moved capability onto OG ranks, so both scopes resolved to
19
+ * the same role and the split was ceremony.
20
+ *
21
+ * It is still a second CLIENT, and that is not an oversight (spec D6): the READ
22
+ * client lives inside dropsh — the TUI renders within the dropsh program, which
23
+ * resolves auth itself — and is unreachable from here. Two client objects, ONE
24
+ * identity.
25
+ *
26
+ * Throws when the connection declares no usable provider — the caller catches
27
+ * it and runs the cockpit read-only rather than aborting, because a connection
28
+ * with no resolvable provider still reads.
22
29
  */
23
30
  async function buildWriteClientDefault(o) {
24
31
  const http = createHttpClient();
@@ -27,7 +34,6 @@ async function buildWriteClientDefault(o) {
27
34
  plugins: o.plugins,
28
35
  http,
29
36
  now: () => Date.now(),
30
- profile: o.profile,
31
37
  });
32
38
  return createJsonApiClient({
33
39
  baseUrl: o.baseUrl,
@@ -252,8 +258,16 @@ export async function cmdUi(deps = {}) {
252
258
  });
253
259
  }
254
260
  catch (err) {
255
- logger.error({}, err instanceof Error ? err.message : String(err));
256
- process.exitCode = 1;
261
+ // `fail`, not `logger.error`: a connection config that will not resolve is
262
+ // the most user-facing error this command has, and the logger writes to
263
+ // `$HOME/log.txt` whenever stdout is not a TTY. Sent to the log sink it
264
+ // came out as `exit 1` and NOT ONE LINE of output — which is exactly how
265
+ // CI reported it, with the actual cause (a missing top-level
266
+ // `workspace_id`) sitting in a file nobody on that runner would think to
267
+ // read. The log keeps its copy; stderr gets the one a human reads.
268
+ const message = err instanceof Error ? err.message : String(err);
269
+ logger.error({}, message);
270
+ fail(`gaia ui: ${message}`);
257
271
  return;
258
272
  }
259
273
  const notice = deps.updateCheck
@@ -269,33 +283,37 @@ export async function cmdUi(deps = {}) {
269
283
  jsonapiPrefix: resolved.site.jsonapi_prefix,
270
284
  authPlugins: resolved.plugins,
271
285
  configPath: resolved.config_path,
272
- authProfile: 'session',
273
- writeProfile: WRITE_PROFILE,
274
286
  };
275
287
  // GAIA-233: the write client, built here because this package already holds
276
288
  // the constructed plugins and imports dropsh — the renderer stays
277
289
  // dropsh-decoupled and receives a finished object.
278
290
  //
279
- // A connection declaring only `session` is a supported configuration, not an
280
- // error: the cockpit still reads everything. So the failure is EXPLICIT
281
- // rather than fatal no write client is injected, `writeProfile` names the
282
- // profile the write will really use, and the popup says so. The server's own
283
- // 403 then surfaces verbatim; there is one failure path for "wrong scope" and
284
- // "no scope" alike.
291
+ // GAIA-391 emptied this fallback of the PROFILE concept but kept the fallback
292
+ // itself, and the difference is the point. It used to point the write profile
293
+ // at the read one, because a connection declaring the reads' provider and not
294
+ // the writes' was an ordinary configuration; that rename is gone along with
295
+ // both fields, and there is no profile left to name.
296
+ //
297
+ // What remains is why it was a `catch` and not a `fail`: a connection with NO
298
+ // resolvable auth provider still READS. `resolveAuth` throws
299
+ // `Multiple auth profiles configured (); none active` for a plugins[] that
300
+ // yields none, and a `@gaia-ai/addon-auth-basic` connection reaches this line
301
+ // the same way. Aborting there would take the whole cockpit down over a write
302
+ // seam it may never use. So no write client is injected, the renderer falls
303
+ // back to the read client, and the server's own 403 is the operator's answer —
304
+ // Decision 1's single failure path, minus the profile it used to name.
285
305
  let writeClient;
286
306
  try {
287
307
  writeClient = await (deps.buildWriteClient ?? buildWriteClientDefault)({
288
308
  baseUrl: resolved.site.base_url,
289
309
  jsonapiPrefix: resolved.site.jsonapi_prefix ?? '/jsonapi',
290
310
  plugins: resolved.plugins,
291
- profile: WRITE_PROFILE,
292
311
  });
293
312
  }
294
313
  catch (err) {
295
- connection.writeProfile = connection.authProfile;
296
- logger.warn({ profile: WRITE_PROFILE }, `gaia ui: no '${WRITE_PROFILE}'-scoped write client ` +
314
+ logger.warn({}, 'gaia ui: no write client could be built ' +
297
315
  `(${err instanceof Error ? err.message : String(err)}); ` +
298
- `edits will be attempted as '${connection.authProfile}'.`);
316
+ 'edits will be attempted through the read client.');
299
317
  }
300
318
  const rooting = resolveProjectRooting(cwd, homedir());
301
319
  const project = deps.project;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gaia-ai/ui",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "GAIA project-first cockpit: the `gaia ui` command plugin (renderer resolved dynamically).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,9 +26,9 @@
26
26
  "directory": "gaia-cli/ui"
27
27
  },
28
28
  "dependencies": {
29
- "@gaia-ai/core": "^0.10.0",
30
- "@gaia-ai/addon-herdr": "^0.10.0",
29
+ "@gaia-ai/core": "^0.11.1",
30
+ "@gaia-ai/addon-herdr": "^0.11.1",
31
31
  "commander": "^12.1.0",
32
- "dropsh": "^0.5.8"
32
+ "dropsh": "^0.6.1"
33
33
  }
34
34
  }