@gaia-ai/gaia 0.13.0 → 0.14.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.
- package/dist/src/config.js +61 -6
- package/dist/src/host.js +33 -3
- package/package.json +24 -21
package/dist/src/config.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { homedir, hostname } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
2
3
|
import { createInterface } from 'node:readline';
|
|
3
4
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
import {
|
|
5
|
+
import { reportLoadedGaiaConfigFields, resolveGaiaConnectionSelection, } from '@gaia-ai/core';
|
|
5
6
|
import { Option } from 'commander';
|
|
6
7
|
/** Terminal-only input. Secret characters are never echoed. */
|
|
7
8
|
async function promptInput(label, secret = false) {
|
|
@@ -41,6 +42,12 @@ export function renderConfigReport(report, dryRun = false) {
|
|
|
41
42
|
];
|
|
42
43
|
for (const file of report.files.filter((file) => file.selected))
|
|
43
44
|
lines.push(`${file.layer}: ${file.path} (${file.state}; schema ${file.version.effective ?? 'unversioned'} → ${file.version.current ?? 'unversioned'}; ${file.fingerprint ?? 'absent'})`);
|
|
45
|
+
if (report.connection_resolution) {
|
|
46
|
+
const selected = report.connection_resolution;
|
|
47
|
+
lines.push(`Connection: ${selected.id} (${selected.selected_by}) — ${selected.path}`);
|
|
48
|
+
for (const field of selected.fields)
|
|
49
|
+
lines.push(` ${field.key}: ${String(field.value)} (from ${field.source})`);
|
|
50
|
+
}
|
|
44
51
|
for (const change of report.changes)
|
|
45
52
|
lines.push(`${change.path}: schema ${change.before_version ?? 'absent/unversioned'} → ${change.after_version ?? 'unversioned'}\n${change.diff}`);
|
|
46
53
|
for (const finding of report.findings)
|
|
@@ -73,22 +80,25 @@ export function registerConfig(program, deps = {}) {
|
|
|
73
80
|
.option('--project <name>', 'explicit project name for initialization')
|
|
74
81
|
.option('--machine-path <file>', 'override machine configuration path')
|
|
75
82
|
.option('--config <file>', 'override global connection configuration path')
|
|
83
|
+
.option('--connection <id>', 'named connection from ~/.gaia/connections')
|
|
76
84
|
.option('--yes', 'disable prompts and automatic selections')
|
|
77
85
|
.option('--online', 'authenticate and verify each selected workspace (not applicable for machine scope)');
|
|
78
86
|
if (operation !== 'check')
|
|
79
87
|
command
|
|
80
88
|
.option('--dry-run', 'report planned changes without imports, network or writes')
|
|
81
|
-
.addOption(new Option('--project-connection <choice>', '
|
|
82
|
-
.choices(['keep', 'create'])
|
|
83
|
-
.default('keep'))
|
|
89
|
+
.addOption(new Option('--project-connection <choice>', 'retired; use --connection'))
|
|
84
90
|
.option('--machine-id <id>', 'explicit host identity')
|
|
85
91
|
.option('--user-id <id>', 'local operator identifier')
|
|
86
92
|
.option('--max-parallel <number>', 'positive integer host capacity')
|
|
87
93
|
.option('--base-url <url>', 'connection server URL')
|
|
88
94
|
.option('--client-id <id>', 'OAuth client identifier')
|
|
89
95
|
.option('--workspace-id <uuid>', 'explicit workspace UUID')
|
|
96
|
+
.option('--workspace <name>', 'committed project workspace name')
|
|
90
97
|
.option('--secret-env <name>', 'environment variable containing the OAuth secret');
|
|
91
98
|
command.action(async (options) => {
|
|
99
|
+
const { applyConfigPlan, planConfig } = await import('@gaia-ai/conductor/config');
|
|
100
|
+
if (options.projectConnection !== undefined)
|
|
101
|
+
throw new Error('--project-connection is retired; use --connection <id> and .gaia/connection.config.local.js.');
|
|
92
102
|
const cwd = deps.cwd ?? process.cwd();
|
|
93
103
|
const env = deps.env ?? process.env;
|
|
94
104
|
const interactive = (deps.isTTY ?? Boolean(process.stdin.isTTY && process.stdout.isTTY)) &&
|
|
@@ -113,6 +123,7 @@ export function registerConfig(program, deps = {}) {
|
|
|
113
123
|
'baseUrl',
|
|
114
124
|
'clientId',
|
|
115
125
|
'workspaceId',
|
|
126
|
+
'workspace',
|
|
116
127
|
]) {
|
|
117
128
|
const value = options[key];
|
|
118
129
|
if (value !== undefined)
|
|
@@ -127,7 +138,6 @@ export function registerConfig(program, deps = {}) {
|
|
|
127
138
|
operation,
|
|
128
139
|
cwd,
|
|
129
140
|
home: deps.home ?? homedir(),
|
|
130
|
-
projectConnection: options.projectConnection === 'create' ? 'create' : 'inherit',
|
|
131
141
|
inputs,
|
|
132
142
|
};
|
|
133
143
|
for (const key of ['scope', 'path', 'project', 'machinePath']) {
|
|
@@ -137,6 +147,25 @@ export function registerConfig(program, deps = {}) {
|
|
|
137
147
|
}
|
|
138
148
|
if (options.config !== undefined)
|
|
139
149
|
planning.connectionPath = options.config;
|
|
150
|
+
else if (options.connection !== undefined) {
|
|
151
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(options.connection))
|
|
152
|
+
throw new Error('--connection must be an identifier containing letters, numbers, dot, underscore or hyphen.');
|
|
153
|
+
planning.connectionPath = join(deps.home ?? homedir(), '.gaia', 'connections', `${options.connection}.js`);
|
|
154
|
+
}
|
|
155
|
+
let selectedConnection;
|
|
156
|
+
const initializesNamedConnection = operation === 'init' &&
|
|
157
|
+
options.connection !== undefined &&
|
|
158
|
+
['connection', 'all'].includes(options.scope ?? '');
|
|
159
|
+
if (!initializesNamedConnection && options.scope !== 'machine') {
|
|
160
|
+
selectedConnection = await resolveGaiaConnectionSelection({
|
|
161
|
+
cwd,
|
|
162
|
+
home: deps.home ?? homedir(),
|
|
163
|
+
env,
|
|
164
|
+
...(options.config ? { explicit: options.config } : {}),
|
|
165
|
+
...(options.connection ? { connection: options.connection } : {}),
|
|
166
|
+
});
|
|
167
|
+
planning.connectionPath = selectedConnection.path;
|
|
168
|
+
}
|
|
140
169
|
let plan = planConfig(planning);
|
|
141
170
|
if (operation === 'init' &&
|
|
142
171
|
options.project &&
|
|
@@ -162,10 +191,11 @@ export function registerConfig(program, deps = {}) {
|
|
|
162
191
|
['clientId', 'client_id', 'OAuth client identifier'],
|
|
163
192
|
['secret', 'client_secret', 'OAuth client secret'],
|
|
164
193
|
['workspaceId', 'workspace_id', 'Workspace UUID'],
|
|
194
|
+
['workspace', 'gaia.workspace', 'Workspace name'],
|
|
165
195
|
];
|
|
166
196
|
for (const [input, key, label] of fields) {
|
|
167
197
|
const requiredForFreshConnection = freshConnection &&
|
|
168
|
-
['baseUrl', 'clientId', 'secret'
|
|
198
|
+
['baseUrl', 'clientId', 'secret'].includes(input);
|
|
169
199
|
if (inputs[input] !== undefined ||
|
|
170
200
|
(!requiredForFreshConnection &&
|
|
171
201
|
!plan.report.findings.some((f) => plan.report.resolved_scopes.includes(f.owner) &&
|
|
@@ -241,6 +271,31 @@ export function registerConfig(program, deps = {}) {
|
|
|
241
271
|
reason,
|
|
242
272
|
});
|
|
243
273
|
}
|
|
274
|
+
const resolution = selectedConnection ??
|
|
275
|
+
(planning.connectionPath
|
|
276
|
+
? {
|
|
277
|
+
path: planning.connectionPath,
|
|
278
|
+
connectionId: options.connection ?? 'default',
|
|
279
|
+
selectionSource: options.connection
|
|
280
|
+
? 'flag-connection'
|
|
281
|
+
: 'flag-config',
|
|
282
|
+
}
|
|
283
|
+
: undefined);
|
|
284
|
+
if (resolution) {
|
|
285
|
+
let fields = [];
|
|
286
|
+
try {
|
|
287
|
+
fields = await reportLoadedGaiaConfigFields(resolution.path);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
// Inventory findings already describe an unreadable or malformed file.
|
|
291
|
+
}
|
|
292
|
+
report.connection_resolution = {
|
|
293
|
+
id: resolution.connectionId ?? 'default',
|
|
294
|
+
selected_by: resolution.selectionSource,
|
|
295
|
+
path: resolution.path,
|
|
296
|
+
fields,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
244
299
|
(deps.stdout ?? ((text) => process.stdout.write(text)))(options.format === 'json'
|
|
245
300
|
? `${JSON.stringify(report)}\n`
|
|
246
301
|
: renderConfigReport(report, options.dryRun));
|
package/dist/src/host.js
CHANGED
|
@@ -2,8 +2,10 @@ import { pathToFileURL } from 'node:url';
|
|
|
2
2
|
import { commands as agentsCommands } from '@gaia-ai/addon-agents/preset';
|
|
3
3
|
import { commands as deploymentCommands } from '@gaia-ai/addon-deployment/preset';
|
|
4
4
|
import { commands as dropshCommands } from '@gaia-ai/addon-dropsh/preset';
|
|
5
|
+
import { commands as infoCommands } from '@gaia-ai/addon-info/preset';
|
|
6
|
+
import { commands as portsCommands } from '@gaia-ai/addon-ports/preset';
|
|
5
7
|
import { commands as conductorCommands } from '@gaia-ai/conductor/preset';
|
|
6
|
-
import { resolveCliVersion, resolveModuleEslintStyle, } from '@gaia-ai/core';
|
|
8
|
+
import { resolveCliVersion, resolveConfigPath, resolveModuleEslintStyle, } from '@gaia-ai/core';
|
|
7
9
|
import { commands as uiCommands } from '@gaia-ai/ui/preset';
|
|
8
10
|
import { Command } from 'commander';
|
|
9
11
|
import { registerConfig } from './config.js';
|
|
@@ -33,6 +35,8 @@ function composeCommandSurface() {
|
|
|
33
35
|
dropshCommands,
|
|
34
36
|
deploymentCommands,
|
|
35
37
|
agentsCommands,
|
|
38
|
+
infoCommands,
|
|
39
|
+
portsCommands,
|
|
36
40
|
];
|
|
37
41
|
let acc = [];
|
|
38
42
|
for (const fn of accumulators) {
|
|
@@ -136,9 +140,36 @@ function pluginDescribe(entry) {
|
|
|
136
140
|
* are describe-only stubs). */
|
|
137
141
|
export async function buildHostProgram(argv, opts = {}) {
|
|
138
142
|
const bases = opts.bases ?? hostBases();
|
|
139
|
-
const host = { resolveBases: bases };
|
|
140
143
|
const commands = resolveCommands();
|
|
141
144
|
const names = commands.map((c) => c.name);
|
|
145
|
+
const target = opts.forceTarget ?? scanTarget(argv, names);
|
|
146
|
+
const projectContext = target === 'ui'
|
|
147
|
+
? await import('@gaia-ai/conductor/project-context')
|
|
148
|
+
: undefined;
|
|
149
|
+
const host = {
|
|
150
|
+
resolveBases: bases,
|
|
151
|
+
workspacePlugin: async (workspaceId) => {
|
|
152
|
+
const { workspacePlugin } = await import('@gaia-ai/addon-workspace');
|
|
153
|
+
return workspacePlugin({ workspace_id: workspaceId });
|
|
154
|
+
},
|
|
155
|
+
...(projectContext
|
|
156
|
+
? {
|
|
157
|
+
projectContext: {
|
|
158
|
+
resolveConfigPath: (cwd) => resolveConfigPath(undefined, cwd),
|
|
159
|
+
readWorkspace: (configPath) => projectContext.readGaiaProjectSelection(configPath).workspace,
|
|
160
|
+
resolveContext: async (configPath, connection) => {
|
|
161
|
+
const { createGaiaConnectionClient } = await import('@gaia-ai/core');
|
|
162
|
+
const { resolveGaiaProjectContext } = await import('@gaia-ai/conductor/contract');
|
|
163
|
+
const selection = projectContext.readGaiaProjectSelection(configPath);
|
|
164
|
+
return resolveGaiaProjectContext(await createGaiaConnectionClient(connection), selection);
|
|
165
|
+
},
|
|
166
|
+
writeWorkspace: async (configPath, name) => {
|
|
167
|
+
await projectContext.writeGaiaWorkspaceSelection(projectContext.gaiaProjectOwner(configPath), name, `Set gaia.workspace in ${configPath} to switch manually.`);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
: {}),
|
|
172
|
+
};
|
|
142
173
|
const program = new Command();
|
|
143
174
|
// exitOverride so commander surfaces help/version/unknown-command as thrown
|
|
144
175
|
// CommanderErrors (mapped in runHost) instead of calling process.exit —
|
|
@@ -167,7 +198,6 @@ export async function buildHostProgram(argv, opts = {}) {
|
|
|
167
198
|
registerConfig(program, { host });
|
|
168
199
|
registerUpdate(program);
|
|
169
200
|
registerValidate(program);
|
|
170
|
-
const target = opts.forceTarget ?? scanTarget(argv, names);
|
|
171
201
|
for (const entry of commands) {
|
|
172
202
|
if (entry.name === target) {
|
|
173
203
|
const plugin = await loadCommandPlugin(entry, bases);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaia-ai/gaia",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
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",
|
|
@@ -38,26 +38,29 @@
|
|
|
38
38
|
"jsonapi"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@gaia-ai/addon-agents": "^0.
|
|
42
|
-
"@gaia-ai/addon-auth-basic": "^0.
|
|
43
|
-
"@gaia-ai/addon-claude": "^0.
|
|
44
|
-
"@gaia-ai/addon-codex": "^0.
|
|
45
|
-
"@gaia-ai/addon-deployment": "^0.
|
|
46
|
-
"@gaia-ai/addon-dropsh": "^0.
|
|
47
|
-
"@gaia-ai/addon-essentials": "^0.
|
|
48
|
-
"@gaia-ai/addon-gaia-ui": "^0.
|
|
49
|
-
"@gaia-ai/addon-gaia-ui-artifacts": "^0.
|
|
50
|
-
"@gaia-ai/addon-grok": "^0.
|
|
51
|
-
"@gaia-ai/addon-herdr": "^0.
|
|
52
|
-
"@gaia-ai/addon-
|
|
53
|
-
"@gaia-ai/addon-
|
|
54
|
-
"@gaia-ai/addon-
|
|
55
|
-
"@gaia-ai/addon-
|
|
56
|
-
"@gaia-ai/addon-
|
|
57
|
-
"@gaia-ai/addon-
|
|
58
|
-
"@gaia-ai/
|
|
59
|
-
"@gaia-ai/
|
|
60
|
-
"@gaia-ai/
|
|
41
|
+
"@gaia-ai/addon-agents": "^0.14.0",
|
|
42
|
+
"@gaia-ai/addon-auth-basic": "^0.14.0",
|
|
43
|
+
"@gaia-ai/addon-claude": "^0.14.0",
|
|
44
|
+
"@gaia-ai/addon-codex": "^0.14.0",
|
|
45
|
+
"@gaia-ai/addon-deployment": "^0.14.0",
|
|
46
|
+
"@gaia-ai/addon-dropsh": "^0.14.0",
|
|
47
|
+
"@gaia-ai/addon-essentials": "^0.14.0",
|
|
48
|
+
"@gaia-ai/addon-gaia-ui": "^0.14.0",
|
|
49
|
+
"@gaia-ai/addon-gaia-ui-artifacts": "^0.14.0",
|
|
50
|
+
"@gaia-ai/addon-grok": "^0.14.0",
|
|
51
|
+
"@gaia-ai/addon-herdr": "^0.14.0",
|
|
52
|
+
"@gaia-ai/addon-info": "^0.14.0",
|
|
53
|
+
"@gaia-ai/addon-kimi": "^0.14.0",
|
|
54
|
+
"@gaia-ai/addon-opencode": "^0.14.0",
|
|
55
|
+
"@gaia-ai/addon-pi": "^0.14.0",
|
|
56
|
+
"@gaia-ai/addon-ports": "^0.14.0",
|
|
57
|
+
"@gaia-ai/addon-ports-ui": "^0.14.0",
|
|
58
|
+
"@gaia-ai/addon-remote-drupal": "^0.14.0",
|
|
59
|
+
"@gaia-ai/addon-workspace": "^0.14.0",
|
|
60
|
+
"@gaia-ai/addon-workspace-git": "^0.14.0",
|
|
61
|
+
"@gaia-ai/conductor": "^0.14.0",
|
|
62
|
+
"@gaia-ai/core": "^0.14.0",
|
|
63
|
+
"@gaia-ai/ui": "^0.14.0",
|
|
61
64
|
"commander": "^12.1.0"
|
|
62
65
|
}
|
|
63
66
|
}
|