@gaia-ai/gaia 0.6.0 → 0.6.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 +17 -0
- package/dist/src/host.js +20 -10
- package/dist/src/plugins-barrel.d.ts +4 -1
- package/dist/src/plugins-barrel.js +16 -1
- package/dist/src/upgrade.d.ts +47 -2
- package/dist/src/upgrade.js +108 -11
- package/package.json +18 -13
package/README.md
CHANGED
|
@@ -26,6 +26,23 @@ spawn plugins (Claude, Codex, herdr, and a deterministic fake for tests). Point
|
|
|
26
26
|
it at a control plane with a `conductor.config.js` (scaffold one with
|
|
27
27
|
`gaia init`).
|
|
28
28
|
|
|
29
|
+
## `gaia ui` deep links
|
|
30
|
+
|
|
31
|
+
`gaia ui` is the interactive terminal cockpit, and it takes an optional target so you open
|
|
32
|
+
the thing you are working on directly:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gaia ui GAIA-221 # a ticket by identifier (case-insensitive)
|
|
36
|
+
gaia ui project:gaia # a project; also ticket:<uuid> · run:<uuid>
|
|
37
|
+
gaia ui --here # this branch's ticket, else this repo's project
|
|
38
|
+
gaia ui GAIA-221 --view teaser # a compact block instead of the tabbed detail
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
At most **one** target source (the positional, `--ticket`, `--project`, `--run`, `--here`);
|
|
42
|
+
two exit non-zero naming both. `--here` reads the current branch for a ticket identifier and
|
|
43
|
+
otherwise resolves this repo's git remote against the projects that claim it — several
|
|
44
|
+
claimants open a picker. `gaia ui --help` lists every form.
|
|
45
|
+
|
|
29
46
|
## Plugins
|
|
30
47
|
|
|
31
48
|
The four spawn plugins ship **inside** this package — nothing extra to install.
|
package/dist/src/host.js
CHANGED
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
+
import { commands as deploymentCommands } from '@gaia-ai/addon-deployment/preset';
|
|
5
|
+
import { commands as dropshCommands } from '@gaia-ai/addon-dropsh/preset';
|
|
4
6
|
import { commands as conductorCommands } from '@gaia-ai/conductor/preset';
|
|
5
7
|
import { resolveModuleEslintStyle, } from '@gaia-ai/core';
|
|
6
|
-
import { commands as dropshCommands } from '@gaia-ai/plugin-dropsh/preset';
|
|
7
8
|
import { commands as uiCommands } from '@gaia-ai/ui/preset';
|
|
8
9
|
import { Command } from 'commander';
|
|
9
10
|
import { registerUpgrade } from './upgrade.js';
|
|
10
11
|
// GAIA-201: the `gaia` plugin HOST. The meta package `@gaia-ai/gaia` owns the
|
|
11
|
-
// CLI entrypoint (AC-1); ui / conductor / dropsh are declared,
|
|
12
|
-
// resolved, LAZILY mounted command plugins (AC-2). The host
|
|
13
|
-
// it hard-wires nothing. Only the invoked subcommand's module
|
|
14
|
-
// `gaia --help` lists all
|
|
15
|
-
// `gaia conductor …` imports only the conductor module.
|
|
12
|
+
// CLI entrypoint (AC-1); ui / conductor / dropsh / deployment are declared,
|
|
13
|
+
// ESLint-style resolved, LAZILY mounted command plugins (AC-2). The host
|
|
14
|
+
// discovers + mounts; it hard-wires nothing. Only the invoked subcommand's module
|
|
15
|
+
// is imported — `gaia --help` lists all four via describe-only stubs and imports
|
|
16
|
+
// none; `gaia conductor …` imports only the conductor module.
|
|
16
17
|
//
|
|
17
|
-
// GAIA-215: the registry is DERIVED from the command surface — the
|
|
18
|
+
// GAIA-215: the registry is DERIVED from the command surface — the command
|
|
18
19
|
// addons' preset `commands` accumulators — rather than a hand-written list.
|
|
19
20
|
// Those presets are LIGHT (they import no runtime, only return descriptors), so
|
|
20
21
|
// composing them at boot keeps `gaia --help` import-light. `$GAIA_COMMANDS`
|
|
21
|
-
// still overrides the whole registry.
|
|
22
|
+
// still overrides the whole registry. GAIA-224 (Finding 7) added the fourth
|
|
23
|
+
// command surface, `@gaia-ai/addon-deployment` (`gaia deployment …`), which the
|
|
24
|
+
// `conductor` command plugin used to register as a side effect.
|
|
22
25
|
/** Compose the built-in command registry from the command addons' presets. The
|
|
23
26
|
* accumulators are synchronous descriptor builders (light presets), threaded in
|
|
24
|
-
* the conductor → ui → dropsh order. */
|
|
27
|
+
* the conductor → ui → dropsh → deployment order. */
|
|
25
28
|
function composeCommandSurface() {
|
|
26
|
-
const accumulators = [
|
|
29
|
+
const accumulators = [
|
|
30
|
+
conductorCommands,
|
|
31
|
+
uiCommands,
|
|
32
|
+
dropshCommands,
|
|
33
|
+
deploymentCommands,
|
|
34
|
+
];
|
|
27
35
|
let acc = [];
|
|
28
36
|
for (const fn of accumulators) {
|
|
29
37
|
if (typeof fn === 'function')
|
|
@@ -141,6 +149,8 @@ function pluginDescribe(entry) {
|
|
|
141
149
|
return 'interactive terminal UI: project dashboard, ticket list, ticket detail';
|
|
142
150
|
case 'dropsh':
|
|
143
151
|
return 'JSON:API shell (dropsh) bound to the GAIA connection config';
|
|
152
|
+
case 'deployment':
|
|
153
|
+
return 'release / deployment helpers';
|
|
144
154
|
default:
|
|
145
155
|
return `${entry.name} command`;
|
|
146
156
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { basicAuthProvider } from '@gaia-ai/addon-auth-basic';
|
|
2
|
+
export { DrupalGaiaRemote, drupalRemote } from '@gaia-ai/addon-remote-drupal';
|
|
3
|
+
export { GitWorkspace, gitWorkspace, loadInstructions, } from '@gaia-ai/addon-workspace-git';
|
|
4
|
+
export { type AgentCandidate, type ResolvedAgent, selectAgent, selectAgents, selectExecutor, selectRemote, selectWorkspace, } from '@gaia-ai/conductor/contract';
|
|
@@ -1 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
// GAIA-224 (Finding 6, decision 11): the `@gaia-ai/gaia/plugins` BACK-COMPAT
|
|
2
|
+
// barrel. It used to be a single `export * from '@gaia-ai/core/plugins'`; that
|
|
3
|
+
// core barrel is deleted, because core no longer ships plugin implementations.
|
|
4
|
+
// The barrel itself stays (published configs may still name
|
|
5
|
+
// `{ plugin: '@gaia-ai/gaia/plugins', export: 'drupalRemote' }`), but it now
|
|
6
|
+
// aggregates the CONTRIBUTIONS from where they actually live: the impl addons +
|
|
7
|
+
// the conductor-surface selectors. "plugins" is the right word for a
|
|
8
|
+
// contribution barrel (decision 16) — only the *package* prefix became `addon-`.
|
|
9
|
+
//
|
|
10
|
+
// The fakes (`fakeRemote`/`fakeWorkspace`) are deliberately NOT re-exported:
|
|
11
|
+
// they moved into `@gaia-ai/addon-fake`, a workspace-only test fixture that is
|
|
12
|
+
// never published, so the published meta package must not depend on it.
|
|
13
|
+
export { basicAuthProvider } from '@gaia-ai/addon-auth-basic';
|
|
14
|
+
export { DrupalGaiaRemote, drupalRemote } from '@gaia-ai/addon-remote-drupal';
|
|
15
|
+
export { GitWorkspace, gitWorkspace, loadInstructions, } from '@gaia-ai/addon-workspace-git';
|
|
16
|
+
export { selectAgent, selectAgents, selectExecutor, selectRemote, selectWorkspace, } from '@gaia-ai/conductor/contract';
|
package/dist/src/upgrade.d.ts
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
import { type ProjectConnectionChoice } from '@gaia-ai/conductor';
|
|
1
2
|
import type { Command } from 'commander';
|
|
2
|
-
/**
|
|
3
|
-
export
|
|
3
|
+
/** Where the running `gaia` resolved from and what it calls itself. */
|
|
4
|
+
export interface GaiaInstallInfo {
|
|
5
|
+
/** The meta package version (`0.0.0` when the manifest is unreadable). */
|
|
6
|
+
version: string;
|
|
7
|
+
/** Absolute path of the package root this module was loaded from. */
|
|
8
|
+
root: string;
|
|
9
|
+
/** `global install` when that root sits inside `node_modules`, else `dev clone`. */
|
|
10
|
+
kind: 'dev clone' | 'global install';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Identify the running install from THIS module's own URL — walking up to the
|
|
14
|
+
* nearest `package.json` — rather than from `$PATH` or `process.argv`, so a shim
|
|
15
|
+
* that execs a checkout's build reports the checkout, not the shim.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveInstallInfo(): GaiaInstallInfo;
|
|
18
|
+
/**
|
|
19
|
+
* GAIA-218 (AC-3, AC-4): resolve what to do with the PROJECT connection override.
|
|
20
|
+
* Default no in every branch — only an explicit yes opts in. Non-interactive
|
|
21
|
+
* (no TTY) ⇒ always `skip`. The prompt is injected so the host test can stub it.
|
|
22
|
+
*
|
|
23
|
+
* - existing project `gaia.config.js` → "remove this override? [y/N]" → `remove`|`skip`
|
|
24
|
+
* - none → "create an override? [y/N]" → `create`|`skip`
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveProjectConnectionChoice(opts: {
|
|
27
|
+
existing: string | undefined;
|
|
28
|
+
isTTY: boolean;
|
|
29
|
+
prompt: (question: string) => Promise<boolean>;
|
|
30
|
+
}): Promise<ProjectConnectionChoice>;
|
|
31
|
+
/**
|
|
32
|
+
* GAIA-230 (AC-9): the intro lines printed BEFORE the first migration step, on
|
|
33
|
+
* `--dry-run` too. `home` is where the schema `from` is read (the home connection
|
|
34
|
+
* config `~/.gaia/gaia.config.js`, the one every repo inherits); `to` is the
|
|
35
|
+
* version this gaia ships. Pure — returns the lines rather than printing them.
|
|
36
|
+
*/
|
|
37
|
+
export declare function renderUpgradeIntro(opts: {
|
|
38
|
+
cwd: string;
|
|
39
|
+
home: string;
|
|
40
|
+
install?: GaiaInstallInfo;
|
|
41
|
+
}): string[];
|
|
42
|
+
/** Register `gaia upgrade` on the host program. `deps` is injectable for tests. */
|
|
43
|
+
export declare function registerUpgrade(program: Command, deps?: {
|
|
44
|
+
prompt?: (question: string) => Promise<boolean>;
|
|
45
|
+
isTTY?: boolean;
|
|
46
|
+
cwd?: string;
|
|
47
|
+
home?: string;
|
|
48
|
+
}): void;
|
package/dist/src/upgrade.js
CHANGED
|
@@ -1,17 +1,114 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join, sep } from 'node:path';
|
|
4
|
+
import { createInterface } from 'node:readline';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { GAIA_CONFIG_SCHEMA_VERSION, hasProjectConnection, readConfigSchemaVersion, runUpgrade, } from '@gaia-ai/conductor';
|
|
7
|
+
/**
|
|
8
|
+
* Identify the running install from THIS module's own URL — walking up to the
|
|
9
|
+
* nearest `package.json` — rather than from `$PATH` or `process.argv`, so a shim
|
|
10
|
+
* that execs a checkout's build reports the checkout, not the shim.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveInstallInfo() {
|
|
13
|
+
let root = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
let version = '0.0.0';
|
|
15
|
+
for (;;) {
|
|
16
|
+
try {
|
|
17
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
18
|
+
version = pkg.version ?? '0.0.0';
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
const parent = dirname(root);
|
|
23
|
+
if (parent === root)
|
|
24
|
+
break;
|
|
25
|
+
root = parent;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
version,
|
|
30
|
+
root,
|
|
31
|
+
kind: root.includes(`${sep}node_modules${sep}`)
|
|
32
|
+
? 'global install'
|
|
33
|
+
: 'dev clone',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Ask a yes/no question on the terminal; anything but an explicit yes is no. */
|
|
37
|
+
async function promptYesNo(question) {
|
|
38
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
39
|
+
try {
|
|
40
|
+
const answer = await new Promise((resolve) => rl.question(question, resolve));
|
|
41
|
+
const a = answer.trim().toLowerCase();
|
|
42
|
+
return a === 'y' || a === 'yes';
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
rl.close();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* GAIA-218 (AC-3, AC-4): resolve what to do with the PROJECT connection override.
|
|
50
|
+
* Default no in every branch — only an explicit yes opts in. Non-interactive
|
|
51
|
+
* (no TTY) ⇒ always `skip`. The prompt is injected so the host test can stub it.
|
|
52
|
+
*
|
|
53
|
+
* - existing project `gaia.config.js` → "remove this override? [y/N]" → `remove`|`skip`
|
|
54
|
+
* - none → "create an override? [y/N]" → `create`|`skip`
|
|
55
|
+
*/
|
|
56
|
+
export async function resolveProjectConnectionChoice(opts) {
|
|
57
|
+
if (!opts.isTTY)
|
|
58
|
+
return 'skip';
|
|
59
|
+
if (opts.existing !== undefined) {
|
|
60
|
+
const yes = await opts.prompt(`remove this project connection override (${opts.existing})? [y/N] `);
|
|
61
|
+
return yes ? 'remove' : 'skip';
|
|
62
|
+
}
|
|
63
|
+
const yes = await opts.prompt('create a project connection override for this repo? [y/N] ');
|
|
64
|
+
return yes ? 'create' : 'skip';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* GAIA-230 (AC-9): the intro lines printed BEFORE the first migration step, on
|
|
68
|
+
* `--dry-run` too. `home` is where the schema `from` is read (the home connection
|
|
69
|
+
* config `~/.gaia/gaia.config.js`, the one every repo inherits); `to` is the
|
|
70
|
+
* version this gaia ships. Pure — returns the lines rather than printing them.
|
|
71
|
+
*/
|
|
72
|
+
export function renderUpgradeIntro(opts) {
|
|
73
|
+
const info = opts.install ?? resolveInstallInfo();
|
|
74
|
+
const homeConnection = join(opts.home, '.gaia', 'gaia.config.js');
|
|
75
|
+
const from = readConfigSchemaVersion(homeConnection);
|
|
76
|
+
return [
|
|
77
|
+
`gaia upgrade — gaia v${info.version} (${info.kind})`,
|
|
78
|
+
` resolved from: ${info.root}`,
|
|
79
|
+
` config schema: v${from} → v${GAIA_CONFIG_SCHEMA_VERSION} (${homeConnection})`,
|
|
80
|
+
` the .gaia/ configs of ${opts.cwd} and of ${join(opts.home, '.gaia')} get migrated`,
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
/** Register `gaia upgrade` on the host program. `deps` is injectable for tests. */
|
|
84
|
+
export function registerUpgrade(program, deps = {}) {
|
|
9
85
|
program
|
|
10
86
|
.command('upgrade')
|
|
11
|
-
.description('migrate this install
|
|
87
|
+
.description('migrate this install: the split config model (gaia.config.js connection + conductor.config.js engine; ~/.gaia/machine.config.js) and the GAIA-224 addon package names (@gaia-ai/plugin-*, @gaia-ai/core/builtins and the @gaia-ai/core/plugins + @gaia-ai/gaia/plugins host barrels → @gaia-ai/addon-*). Prompts before creating/removing a project connection override.')
|
|
12
88
|
.option('--dry-run', 'print the migration plan without writing anything', false)
|
|
13
|
-
.action((opts) => {
|
|
14
|
-
const
|
|
89
|
+
.action(async (opts) => {
|
|
90
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
91
|
+
const home = deps.home ?? homedir();
|
|
92
|
+
const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
|
|
93
|
+
const prompt = deps.prompt ?? promptYesNo;
|
|
94
|
+
// GAIA-230 (AC-9): the intro comes first — before the connection prompt and
|
|
95
|
+
// before the first migration step, so it is on the record either way.
|
|
96
|
+
for (const line of renderUpgradeIntro({ cwd, home }))
|
|
97
|
+
console.log(line);
|
|
98
|
+
const projectConnection = await resolveProjectConnectionChoice({
|
|
99
|
+
existing: hasProjectConnection(cwd),
|
|
100
|
+
isTTY,
|
|
101
|
+
prompt,
|
|
102
|
+
});
|
|
103
|
+
// `cwd`/`home` are forwarded so an injected pair really scopes the run —
|
|
104
|
+
// without them `runUpgrade` reached for `process.cwd()`/`homedir()` and
|
|
105
|
+
// rewrote the developer's own `.gaia/` from a test.
|
|
106
|
+
const report = runUpgrade({
|
|
107
|
+
cwd,
|
|
108
|
+
home,
|
|
109
|
+
dryRun: opts.dryRun,
|
|
110
|
+
projectConnection,
|
|
111
|
+
});
|
|
15
112
|
for (const line of report.actions)
|
|
16
113
|
console.log(line);
|
|
17
114
|
if (report.alreadyCurrent)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaia-ai/gaia",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "GAIA meta package: the `gaia` plugin-host CLI + all runtime plugins. Global install target.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
29
|
"url": "git+https://git.key-tec.de/keytec/gaia.git",
|
|
30
|
-
"directory": "
|
|
30
|
+
"directory": "gaia-cli/host"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"gaia",
|
|
@@ -38,17 +38,22 @@
|
|
|
38
38
|
"jsonapi"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@gaia-ai/
|
|
42
|
-
"@gaia-ai/
|
|
43
|
-
"@gaia-ai/
|
|
44
|
-
"@gaia-ai/
|
|
45
|
-
"@gaia-ai/
|
|
46
|
-
"@gaia-ai/
|
|
47
|
-
"@gaia-ai/
|
|
48
|
-
"@gaia-ai/
|
|
49
|
-
"@gaia-ai/
|
|
50
|
-
"@gaia-ai/
|
|
51
|
-
"@gaia-ai/
|
|
41
|
+
"@gaia-ai/addon-auth-basic": "^0.6.2",
|
|
42
|
+
"@gaia-ai/addon-claude": "^0.6.2",
|
|
43
|
+
"@gaia-ai/addon-codex": "^0.6.2",
|
|
44
|
+
"@gaia-ai/addon-deployment": "^0.6.2",
|
|
45
|
+
"@gaia-ai/addon-dropsh": "^0.6.2",
|
|
46
|
+
"@gaia-ai/addon-essentials": "^0.6.2",
|
|
47
|
+
"@gaia-ai/addon-gaia-ui": "^0.6.2",
|
|
48
|
+
"@gaia-ai/addon-herdr": "^0.6.2",
|
|
49
|
+
"@gaia-ai/addon-kimi": "^0.6.2",
|
|
50
|
+
"@gaia-ai/addon-opencode": "^0.6.2",
|
|
51
|
+
"@gaia-ai/addon-pi": "^0.6.2",
|
|
52
|
+
"@gaia-ai/addon-remote-drupal": "^0.6.2",
|
|
53
|
+
"@gaia-ai/addon-workspace-git": "^0.6.2",
|
|
54
|
+
"@gaia-ai/conductor": "^0.6.2",
|
|
55
|
+
"@gaia-ai/core": "^0.6.2",
|
|
56
|
+
"@gaia-ai/ui": "^0.6.2",
|
|
52
57
|
"commander": "^12.1.0"
|
|
53
58
|
}
|
|
54
59
|
}
|