@gaia-ai/gaia 0.13.1 → 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 +29 -3
- package/package.json +24 -24
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
|
@@ -5,7 +5,7 @@ import { commands as dropshCommands } from '@gaia-ai/addon-dropsh/preset';
|
|
|
5
5
|
import { commands as infoCommands } from '@gaia-ai/addon-info/preset';
|
|
6
6
|
import { commands as portsCommands } from '@gaia-ai/addon-ports/preset';
|
|
7
7
|
import { commands as conductorCommands } from '@gaia-ai/conductor/preset';
|
|
8
|
-
import { resolveCliVersion, resolveModuleEslintStyle, } from '@gaia-ai/core';
|
|
8
|
+
import { resolveCliVersion, resolveConfigPath, resolveModuleEslintStyle, } from '@gaia-ai/core';
|
|
9
9
|
import { commands as uiCommands } from '@gaia-ai/ui/preset';
|
|
10
10
|
import { Command } from 'commander';
|
|
11
11
|
import { registerConfig } from './config.js';
|
|
@@ -140,9 +140,36 @@ function pluginDescribe(entry) {
|
|
|
140
140
|
* are describe-only stubs). */
|
|
141
141
|
export async function buildHostProgram(argv, opts = {}) {
|
|
142
142
|
const bases = opts.bases ?? hostBases();
|
|
143
|
-
const host = { resolveBases: bases };
|
|
144
143
|
const commands = resolveCommands();
|
|
145
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
|
+
};
|
|
146
173
|
const program = new Command();
|
|
147
174
|
// exitOverride so commander surfaces help/version/unknown-command as thrown
|
|
148
175
|
// CommanderErrors (mapped in runHost) instead of calling process.exit —
|
|
@@ -171,7 +198,6 @@ export async function buildHostProgram(argv, opts = {}) {
|
|
|
171
198
|
registerConfig(program, { host });
|
|
172
199
|
registerUpdate(program);
|
|
173
200
|
registerValidate(program);
|
|
174
|
-
const target = opts.forceTarget ?? scanTarget(argv, names);
|
|
175
201
|
for (const entry of commands) {
|
|
176
202
|
if (entry.name === target) {
|
|
177
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,29 +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-info": "^0.
|
|
53
|
-
"@gaia-ai/addon-kimi": "^0.
|
|
54
|
-
"@gaia-ai/addon-opencode": "^0.
|
|
55
|
-
"@gaia-ai/addon-pi": "^0.
|
|
56
|
-
"@gaia-ai/addon-ports": "^0.
|
|
57
|
-
"@gaia-ai/addon-ports-ui": "^0.
|
|
58
|
-
"@gaia-ai/addon-remote-drupal": "^0.
|
|
59
|
-
"@gaia-ai/addon-workspace": "^0.
|
|
60
|
-
"@gaia-ai/addon-workspace-git": "^0.
|
|
61
|
-
"@gaia-ai/conductor": "^0.
|
|
62
|
-
"@gaia-ai/core": "^0.
|
|
63
|
-
"@gaia-ai/ui": "^0.
|
|
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",
|
|
64
64
|
"commander": "^12.1.0"
|
|
65
65
|
}
|
|
66
66
|
}
|