@aiwg/cli 2026.8.0 → 2026.8.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 +33 -0
- package/agentic/code/providers/capability-matrix.yaml +511 -0
- package/agentic/code/providers/model-capabilities.v1.json +120 -0
- package/agentic/code/providers/model-catalog.v1.json +96 -0
- package/agentic/code/providers/model-policy-evaluations.v1.json +50 -0
- package/agentic/code/providers/premium-model-allowlist.v1.json +36 -0
- package/bin/aiwg.mjs +14 -10
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.js +1 -0
- package/dist/src/artifacts/cli.js +2 -0
- package/dist/src/artifacts/types.js +4 -0
- package/dist/src/auth/client.js +209 -0
- package/dist/src/auth/config.js +38 -0
- package/dist/src/auth/credential-store.js +141 -0
- package/dist/src/auth/resource-credentials.js +25 -0
- package/dist/src/auth/types.js +2 -0
- package/dist/src/channel/manager.mjs +5 -5
- package/dist/src/cli/handlers/auth.js +125 -0
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/install.js +42 -4
- package/dist/src/cli/handlers/marketplace.js +375 -122
- package/dist/src/cli/handlers/resource-versions.js +2 -0
- package/dist/src/cli/handlers/sessions.js +23 -5
- package/dist/src/cli/handlers/subcommands.js +10 -1
- package/dist/src/cli/handlers/use.js +342 -43
- package/dist/src/config/gitignore.js +1 -0
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/marketplace/exchange.js +602 -0
- package/dist/src/marketplace/provenance-types.js +19 -0
- package/dist/src/marketplace/provenance.js +834 -0
- package/dist/src/memory/canonical-context.js +342 -0
- package/dist/src/memory/context-pack.js +282 -0
- package/dist/src/memory/index.js +4 -0
- package/dist/src/memory/intake.js +118 -0
- package/dist/src/packages/adapters/git.js +79 -29
- package/dist/src/packages/package-discovery.js +81 -0
- package/dist/src/packages/package-registry.js +2 -0
- package/dist/src/packages/registry.js +119 -20
- package/dist/src/resources/resolver.js +1 -0
- package/dist/src/resources/web-release.d.ts +3 -1
- package/dist/src/resources/web-release.js +14 -6
- package/dist/src/serve/agentic-sandbox-fleet-client.js +213 -0
- package/dist/src/serve/fleet-mission-conductor.js +293 -0
- package/dist/src/sessions/index.js +1 -0
- package/dist/src/sessions/output-registration.js +338 -0
- package/dist/src/sessions/promotion.js +73 -2
- package/dist/src/sessions/repository.js +2 -1
- package/dist/src/update/notifier.mjs +13 -2
- package/package.json +8 -1
- package/tools/_resolve-impl.mjs +74 -0
- package/tools/agents/deploy-agents.mjs +962 -0
- package/tools/agents/providers/base.mjs +2954 -0
- package/tools/agents/providers/claude.mjs +711 -0
- package/tools/agents/providers/codex.mjs +699 -0
- package/tools/agents/providers/copilot.mjs +659 -0
- package/tools/agents/providers/cursor.mjs +714 -0
- package/tools/agents/providers/factory.mjs +1130 -0
- package/tools/agents/providers/hermes.mjs +663 -0
- package/tools/agents/providers/hook-capabilities.mjs +85 -0
- package/tools/agents/providers/model-role.mjs +56 -0
- package/tools/agents/providers/openclaw-translator.mjs +348 -0
- package/tools/agents/providers/openclaw.mjs +680 -0
- package/tools/agents/providers/opencode.mjs +675 -0
- package/tools/agents/providers/openhuman.mjs +292 -0
- package/tools/agents/providers/warp.mjs +413 -0
- package/tools/agents/providers/windsurf.mjs +748 -0
- package/tools/commands/deploy-prompts-codex.mjs +336 -0
- package/tools/plugin/package-plugins.mjs +1013 -0
- package/tools/skills/deploy-skills-codex.mjs +571 -0
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Git-native Fortemi marketplace command handler.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* OpenClaw, etc.).
|
|
7
|
-
*
|
|
8
|
-
* Subcommands:
|
|
9
|
-
* search <query> Fan-out search to all adapters, display with source attribution
|
|
10
|
-
* list List installed marketplace packages
|
|
11
|
-
*
|
|
12
|
-
* Flags:
|
|
13
|
-
* --source <id> Limit to a single adapter (e.g. clawhub, openclaw, local)
|
|
14
|
-
* --json Emit structured JSON for programmatic use
|
|
4
|
+
* Catalog results are observations, never endorsements. Direct Git and catalog
|
|
5
|
+
* installs share the same immutable lock and local receipt pipeline.
|
|
15
6
|
*
|
|
16
7
|
* @implements #805
|
|
8
|
+
* @implements #2009
|
|
17
9
|
*/
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
18
12
|
import { searchSkills } from '../../skills/registry.js';
|
|
19
|
-
import { listInstalledPackages } from '../../packages/registry.js';
|
|
13
|
+
import { installPackage, listInstalledPackages } from '../../packages/registry.js';
|
|
14
|
+
import { GitAdapter } from '../../packages/adapters/git.js';
|
|
15
|
+
import { inspectGitCheckout } from '../../marketplace/provenance.js';
|
|
16
|
+
import { exportPortablePackage, findIndexedPackage, importPortablePackage, marketplaceConfigDir, publishLocalPackage, readCatalogEnvelope, readTrustStore, registerCatalog, removeCatalog, resolveCatalogEntry, resolveVerificationPolicy, searchCatalogs, verifyIndexedPackage, } from '../../marketplace/exchange.js';
|
|
20
17
|
import * as ui from '../ui.js';
|
|
21
|
-
// ── Usage string ───────────────────────────────────────────────────────────
|
|
22
18
|
const USAGE = [
|
|
23
19
|
'Usage:',
|
|
24
|
-
' aiwg marketplace
|
|
20
|
+
' aiwg marketplace add <catalog-git-url> [--ref <tag-or-sha>]',
|
|
21
|
+
' aiwg marketplace search <query> Search packages and signed catalogs',
|
|
22
|
+
' aiwg marketplace info <package> Show provenance and catalog observations',
|
|
23
|
+
' aiwg marketplace install <url|package> Install and lock direct Git or catalog package',
|
|
24
|
+
' aiwg marketplace verify <package|lock> Verify cached content and receipts offline',
|
|
25
|
+
' aiwg marketplace export <package> --output <archive.json>',
|
|
26
|
+
' aiwg marketplace import <archive.json> [--project-local]',
|
|
27
|
+
' aiwg marketplace publish <source> --key <pem> --publisher <id>',
|
|
28
|
+
' aiwg marketplace remove <catalog-id>',
|
|
25
29
|
' aiwg marketplace list List installed marketplace packages',
|
|
26
30
|
'',
|
|
27
|
-
'
|
|
28
|
-
' --
|
|
29
|
-
' --
|
|
30
|
-
'',
|
|
31
|
-
'
|
|
32
|
-
' aiwg marketplace search parallel-dispatch',
|
|
33
|
-
' aiwg marketplace search auth --source clawhub',
|
|
34
|
-
' aiwg marketplace search auth --json',
|
|
35
|
-
' aiwg marketplace list',
|
|
36
|
-
' aiwg marketplace list --json',
|
|
31
|
+
'Common flags:',
|
|
32
|
+
' --json Output structured JSON',
|
|
33
|
+
' --project-local Store/read state below the target project .aiwg directory',
|
|
34
|
+
' --global Store/read state in the user AIWG directory (default)',
|
|
35
|
+
' --policy <name> Named trust policy or JSON policy path',
|
|
37
36
|
].join('\n');
|
|
38
|
-
// ── Flag helpers ───────────────────────────────────────────────────────────
|
|
39
37
|
function parseFlag(args, flag) {
|
|
40
38
|
const idx = args.indexOf(flag);
|
|
41
39
|
if (idx === -1 || idx + 1 >= args.length)
|
|
@@ -45,124 +43,379 @@ function parseFlag(args, flag) {
|
|
|
45
43
|
function hasFlag(args, flag) {
|
|
46
44
|
return args.includes(flag);
|
|
47
45
|
}
|
|
48
|
-
|
|
46
|
+
function scopeFromContext(ctx) {
|
|
47
|
+
const projectLocal = hasFlag(ctx.args, '--project-local');
|
|
48
|
+
if (projectLocal && hasFlag(ctx.args, '--global'))
|
|
49
|
+
throw new Error('Choose either --project-local or --global, not both');
|
|
50
|
+
return { projectLocal, projectDir: parseFlag(ctx.args, '--target') ?? ctx.cwd };
|
|
51
|
+
}
|
|
52
|
+
function jsonOrMessage(jsonMode, value, message) {
|
|
53
|
+
if (jsonMode) {
|
|
54
|
+
console.log(JSON.stringify(value, null, 2));
|
|
55
|
+
return { exitCode: 0 };
|
|
56
|
+
}
|
|
57
|
+
return { exitCode: 0, message };
|
|
58
|
+
}
|
|
59
|
+
function failure(error) {
|
|
60
|
+
return { exitCode: 1, message: `Error: ${error instanceof Error ? error.message : String(error)}` };
|
|
61
|
+
}
|
|
62
|
+
function requiredArg(ctx, usage) {
|
|
63
|
+
const value = ctx.args[1];
|
|
64
|
+
return !value || value.startsWith('--') ? { exitCode: 1, message: `Error: ${usage}` } : value;
|
|
65
|
+
}
|
|
49
66
|
export const marketplaceHandler = {
|
|
50
67
|
id: 'marketplace',
|
|
51
68
|
name: 'Marketplace',
|
|
52
|
-
description: '
|
|
69
|
+
description: 'Federated Git marketplace with Fortemi provenance and offline verification',
|
|
53
70
|
category: 'framework',
|
|
54
71
|
aliases: ['market'],
|
|
55
72
|
async execute(ctx) {
|
|
56
73
|
const subcommand = ctx.args[0];
|
|
57
|
-
if (!subcommand)
|
|
74
|
+
if (!subcommand)
|
|
58
75
|
return { exitCode: 0, message: USAGE };
|
|
59
|
-
|
|
60
|
-
|
|
76
|
+
if (subcommand === 'add')
|
|
77
|
+
return handleAdd(ctx);
|
|
78
|
+
if (subcommand === 'search')
|
|
61
79
|
return handleSearch(ctx);
|
|
62
|
-
|
|
63
|
-
|
|
80
|
+
if (subcommand === 'info')
|
|
81
|
+
return handleInfo(ctx);
|
|
82
|
+
if (subcommand === 'install')
|
|
83
|
+
return handleInstall(ctx);
|
|
84
|
+
if (subcommand === 'verify')
|
|
85
|
+
return handleVerify(ctx);
|
|
86
|
+
if (subcommand === 'export')
|
|
87
|
+
return handleExport(ctx);
|
|
88
|
+
if (subcommand === 'import')
|
|
89
|
+
return handleImport(ctx);
|
|
90
|
+
if (subcommand === 'publish')
|
|
91
|
+
return handlePublish(ctx);
|
|
92
|
+
if (subcommand === 'remove')
|
|
93
|
+
return handleRemove(ctx);
|
|
94
|
+
if (subcommand === 'list')
|
|
64
95
|
return handleList(ctx);
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
exitCode: 1,
|
|
68
|
-
message: `Error: Unknown subcommand '${subcommand}'\n\n${USAGE}`,
|
|
69
|
-
};
|
|
96
|
+
return { exitCode: 1, message: `Error: Unknown subcommand '${subcommand}'\n\n${USAGE}` };
|
|
70
97
|
},
|
|
71
98
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
async function handleAdd(ctx) {
|
|
100
|
+
const argument = requiredArg(ctx, 'Catalog Git URL required');
|
|
101
|
+
if (typeof argument !== 'string')
|
|
102
|
+
return argument;
|
|
103
|
+
try {
|
|
104
|
+
const scope = scopeFromContext(ctx);
|
|
105
|
+
const requestedRef = parseFlag(ctx.args, '--ref') ?? 'HEAD';
|
|
106
|
+
const adapter = new GitAdapter();
|
|
107
|
+
const source = { gitUrl: argument, ref: requestedRef, label: argument };
|
|
108
|
+
const cachePath = await adapter.fetch(source, { refresh: hasFlag(ctx.args, '--refresh') });
|
|
109
|
+
const identity = await inspectGitCheckout(cachePath);
|
|
110
|
+
const candidates = [
|
|
111
|
+
path.join(cachePath, 'aiwg-marketplace-catalog.json'),
|
|
112
|
+
path.join(cachePath, '.aiwg', 'marketplace', 'catalog.json'),
|
|
113
|
+
];
|
|
114
|
+
const catalogPath = candidates.find((candidate) => fs.existsSync(candidate));
|
|
115
|
+
if (!catalogPath)
|
|
116
|
+
throw new Error('Catalog repository has no aiwg-marketplace-catalog.json or .aiwg/marketplace/catalog.json');
|
|
117
|
+
const trustStore = await readTrustStore({ ...scope, path: parseFlag(ctx.args, '--trust-store') });
|
|
118
|
+
const record = await registerCatalog({
|
|
119
|
+
...scope,
|
|
120
|
+
catalogPath,
|
|
121
|
+
source: identity.canonicalRemote,
|
|
122
|
+
requestedRef: source.ref ?? requestedRef,
|
|
123
|
+
resolvedCommit: identity.resolvedCommit,
|
|
124
|
+
cachePath,
|
|
125
|
+
trustStore,
|
|
126
|
+
});
|
|
127
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), record, `Added verified catalog ${record.catalogId} at ${record.resolvedCommit}`);
|
|
88
128
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (source) {
|
|
92
|
-
ui.dim(` Source: ${source}`);
|
|
129
|
+
catch (error) {
|
|
130
|
+
return failure(error);
|
|
93
131
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
132
|
+
}
|
|
133
|
+
async function handleSearch(ctx) {
|
|
134
|
+
const argument = requiredArg(ctx, 'Query required\n\nUsage: aiwg marketplace search <query>');
|
|
135
|
+
if (typeof argument !== 'string')
|
|
136
|
+
return argument;
|
|
137
|
+
try {
|
|
138
|
+
const source = parseFlag(ctx.args, '--source');
|
|
139
|
+
const scope = scopeFromContext(ctx);
|
|
140
|
+
const [skillResults, catalogResults] = await Promise.all([
|
|
141
|
+
!source || !source.startsWith('catalog:') ? searchSkills(argument, source) : Promise.resolve([]),
|
|
142
|
+
searchCatalogs(argument, scope),
|
|
143
|
+
]);
|
|
144
|
+
const filteredCatalogs = source?.startsWith('catalog:')
|
|
145
|
+
? catalogResults.filter((result) => result.catalogId === source.slice('catalog:'.length))
|
|
146
|
+
: source ? [] : catalogResults;
|
|
147
|
+
const results = [
|
|
148
|
+
...skillResults,
|
|
149
|
+
...filteredCatalogs.map((entry) => ({
|
|
150
|
+
name: `${entry.identity}@${entry.version}`,
|
|
151
|
+
description: entry.description,
|
|
152
|
+
source: `catalog:${entry.catalogId}`,
|
|
153
|
+
package: entry.identity,
|
|
154
|
+
provenanceCompleteness: entry.provenanceCompleteness,
|
|
155
|
+
verificationStatus: entry.verificationStatus,
|
|
156
|
+
observation: entry.observation,
|
|
157
|
+
})),
|
|
158
|
+
];
|
|
159
|
+
if (hasFlag(ctx.args, '--json')) {
|
|
160
|
+
console.log(JSON.stringify(results, null, 2));
|
|
161
|
+
return { exitCode: 0 };
|
|
162
|
+
}
|
|
97
163
|
ui.blank();
|
|
98
|
-
ui.
|
|
164
|
+
console.log(` ${ui.brandMark()} ${ui.bold(`Marketplace Search: "${argument}"`)}`);
|
|
165
|
+
if (source)
|
|
166
|
+
ui.dim(` Source: ${source}`);
|
|
167
|
+
ui.rule();
|
|
168
|
+
if (results.length === 0) {
|
|
169
|
+
ui.dim(' No results found.');
|
|
170
|
+
ui.blank();
|
|
171
|
+
return { exitCode: 0 };
|
|
172
|
+
}
|
|
173
|
+
const nameWidth = Math.max(12, ...results.map((result) => result.name.length));
|
|
174
|
+
const sourceWidth = Math.max(8, ...results.map((result) => result.source.length));
|
|
175
|
+
const pkgWidth = Math.max(10, ...results.map((result) => (result.package ?? '').length));
|
|
176
|
+
const header = ['Name'.padEnd(nameWidth), 'Source'.padEnd(sourceWidth), 'Package'.padEnd(pkgWidth), 'Description'].join(' ');
|
|
177
|
+
ui.dim(` ${header}`);
|
|
178
|
+
ui.dim(` ${'─'.repeat(header.length)}`);
|
|
179
|
+
for (const result of results) {
|
|
180
|
+
console.log(` ${[
|
|
181
|
+
result.name.padEnd(nameWidth),
|
|
182
|
+
result.source.padEnd(sourceWidth),
|
|
183
|
+
(result.package ?? '').padEnd(pkgWidth),
|
|
184
|
+
result.description.length > 60 ? `${result.description.slice(0, 57)}...` : result.description,
|
|
185
|
+
].join(' ')}`);
|
|
186
|
+
}
|
|
99
187
|
ui.blank();
|
|
188
|
+
ui.dim(` ${results.length} result${results.length === 1 ? '' : 's'}; catalog inclusion is not an endorsement`);
|
|
100
189
|
return { exitCode: 0 };
|
|
101
190
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return { exitCode: 0 };
|
|
191
|
+
catch (error) {
|
|
192
|
+
return failure(error);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function handleInfo(ctx) {
|
|
196
|
+
const argument = requiredArg(ctx, 'Package query required');
|
|
197
|
+
if (typeof argument !== 'string')
|
|
198
|
+
return argument;
|
|
199
|
+
try {
|
|
200
|
+
const scope = scopeFromContext(ctx);
|
|
201
|
+
const installed = await findIndexedPackage(argument, scope);
|
|
202
|
+
const catalogs = (await searchCatalogs(argument, scope)).filter((entry) => entry.identity === argument || `${entry.identity}@${entry.version}` === argument || entry.lockId === argument);
|
|
203
|
+
if (!installed && catalogs.length === 0)
|
|
204
|
+
return { exitCode: 1, message: `Error: Marketplace package '${argument}' was not found` };
|
|
205
|
+
const result = {
|
|
206
|
+
query: argument,
|
|
207
|
+
installed: installed ? {
|
|
208
|
+
lock: installed.lock,
|
|
209
|
+
verificationStatus: installed.verificationStatus,
|
|
210
|
+
installedAt: installed.installedAt,
|
|
211
|
+
catalogs: installed.catalogs,
|
|
212
|
+
} : null,
|
|
213
|
+
catalogObservations: catalogs,
|
|
214
|
+
endorsement: false,
|
|
215
|
+
};
|
|
216
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), result, [
|
|
217
|
+
`Package: ${argument}`,
|
|
218
|
+
`Installed: ${installed ? 'yes' : 'no'}`,
|
|
219
|
+
...(installed ? [`Lock: ${installed.lock.lockId}`, `Verification: ${installed.verificationStatus}`] : []),
|
|
220
|
+
`Catalog observations: ${catalogs.length} (not endorsements)`,
|
|
221
|
+
...catalogs.map((entry) => ` ${entry.catalogId}: ${entry.provenanceCompleteness}% provenance, ${entry.verificationStatus}`),
|
|
222
|
+
].join('\n'));
|
|
135
223
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
224
|
+
catch (error) {
|
|
225
|
+
return failure(error);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function looksLikeGitUrl(value) {
|
|
229
|
+
return /^(?:https?:\/\/|ssh:\/\/|git@)/.test(value);
|
|
230
|
+
}
|
|
231
|
+
async function handleInstall(ctx) {
|
|
232
|
+
const argument = requiredArg(ctx, 'Git URL or catalog package required');
|
|
233
|
+
if (typeof argument !== 'string')
|
|
234
|
+
return argument;
|
|
235
|
+
try {
|
|
236
|
+
const scope = scopeFromContext(ctx);
|
|
237
|
+
const configDir = marketplaceConfigDir(scope);
|
|
238
|
+
const resolvedPolicy = await resolveVerificationPolicy(parseFlag(ctx.args, '--policy'), scope);
|
|
239
|
+
let rawRef = argument;
|
|
240
|
+
let expectedEnvelope;
|
|
241
|
+
let expectedLockId;
|
|
242
|
+
let catalogId;
|
|
243
|
+
let ref = parseFlag(ctx.args, '--ref');
|
|
244
|
+
if (!looksLikeGitUrl(argument)) {
|
|
245
|
+
const catalog = await resolveCatalogEntry(argument, scope);
|
|
246
|
+
expectedEnvelope = await readCatalogEnvelope(catalog, scope);
|
|
247
|
+
rawRef = catalog.canonicalRemote;
|
|
248
|
+
expectedLockId = catalog.lockId;
|
|
249
|
+
catalogId = catalog.catalogId;
|
|
250
|
+
ref = catalog.resolvedCommit;
|
|
251
|
+
}
|
|
252
|
+
const installed = await installPackage(rawRef, {
|
|
253
|
+
configDir,
|
|
254
|
+
ref,
|
|
255
|
+
packageSelector: parseFlag(ctx.args, '--package'),
|
|
256
|
+
refresh: hasFlag(ctx.args, '--refresh'),
|
|
257
|
+
verify: hasFlag(ctx.args, '--verify'),
|
|
258
|
+
verificationPolicy: resolvedPolicy.policy,
|
|
259
|
+
trustStore: resolvedPolicy.trustStore,
|
|
260
|
+
expectedEnvelope,
|
|
261
|
+
expectedLockId,
|
|
262
|
+
catalogId,
|
|
263
|
+
actor: 'local-user',
|
|
264
|
+
});
|
|
265
|
+
const result = {
|
|
266
|
+
package: installed.key,
|
|
267
|
+
version: installed.envelope.package.version,
|
|
268
|
+
lockId: installed.lock.lockId,
|
|
269
|
+
resolvedCommit: installed.lock.resolvedCommit,
|
|
270
|
+
verificationStatus: installed.verification.status,
|
|
271
|
+
scope: scope.projectLocal ? 'project-local' : 'global',
|
|
272
|
+
catalog: catalogId ?? null,
|
|
273
|
+
};
|
|
274
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), result, `Installed ${result.package}@${result.version}\nLock: ${result.lockId}\nVerification: ${result.verificationStatus}`);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
return failure(error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async function handleVerify(ctx) {
|
|
281
|
+
const argument = requiredArg(ctx, 'Package or lock query required');
|
|
282
|
+
if (typeof argument !== 'string')
|
|
283
|
+
return argument;
|
|
284
|
+
try {
|
|
285
|
+
const scope = scopeFromContext(ctx);
|
|
286
|
+
const resolved = await resolveVerificationPolicy(parseFlag(ctx.args, '--policy'), scope);
|
|
287
|
+
const result = await verifyIndexedPackage({
|
|
288
|
+
...scope,
|
|
289
|
+
query: argument,
|
|
290
|
+
policy: resolved.policy,
|
|
291
|
+
trustStore: resolved.trustStore,
|
|
292
|
+
requireSignature: hasFlag(ctx.args, '--require-signature'),
|
|
293
|
+
actor: 'local-user',
|
|
294
|
+
});
|
|
295
|
+
if (!result.verification.ok)
|
|
296
|
+
return { exitCode: 1, message: `Verification failed: ${result.verification.errors.join('; ')}` };
|
|
297
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), result.verification, `Verified ${result.entry.lock.identity}@${result.entry.lock.version} offline\nStatus: ${result.verification.status}\nLock: ${result.entry.lock.lockId}`);
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
return failure(error);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function handleExport(ctx) {
|
|
304
|
+
const argument = requiredArg(ctx, 'Package query required');
|
|
305
|
+
if (typeof argument !== 'string')
|
|
306
|
+
return argument;
|
|
307
|
+
const output = parseFlag(ctx.args, '--output');
|
|
308
|
+
if (!output)
|
|
309
|
+
return { exitCode: 1, message: 'Error: Usage: aiwg marketplace export <package> --output <archive.json>' };
|
|
310
|
+
try {
|
|
311
|
+
const result = await exportPortablePackage({ ...scopeFromContext(ctx), query: argument, output, actor: 'local-user' });
|
|
312
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), { output: result.output, lockId: result.bundle.lock.lockId, receiptId: result.receipt.receiptId }, `Exported ${result.bundle.lock.identity}@${result.bundle.lock.version} to ${result.output}`);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
return failure(error);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function handleImport(ctx) {
|
|
319
|
+
const argument = requiredArg(ctx, 'Portable archive path required');
|
|
320
|
+
if (typeof argument !== 'string')
|
|
321
|
+
return argument;
|
|
322
|
+
try {
|
|
323
|
+
const scope = scopeFromContext(ctx);
|
|
324
|
+
const resolved = await resolveVerificationPolicy(parseFlag(ctx.args, '--policy'), scope);
|
|
325
|
+
const result = await importPortablePackage({
|
|
326
|
+
...scope,
|
|
327
|
+
input: argument,
|
|
328
|
+
verify: hasFlag(ctx.args, '--verify'),
|
|
329
|
+
policy: resolved.policy,
|
|
330
|
+
trustStore: resolved.trustStore,
|
|
331
|
+
actor: 'local-user',
|
|
332
|
+
});
|
|
333
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), { lock: result.entry.lock, verification: result.verification, receipt: result.receipt }, `Imported ${result.entry.lock.identity}@${result.entry.lock.version}\nLock: ${result.entry.lock.lockId}\nVerification: ${result.verification.status}`);
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
return failure(error);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
async function handlePublish(ctx) {
|
|
340
|
+
const argument = requiredArg(ctx, 'Package source directory required');
|
|
341
|
+
if (typeof argument !== 'string')
|
|
342
|
+
return argument;
|
|
343
|
+
const privateKeyPath = parseFlag(ctx.args, '--key');
|
|
344
|
+
const publisher = parseFlag(ctx.args, '--publisher');
|
|
345
|
+
if (!privateKeyPath || !publisher) {
|
|
346
|
+
return { exitCode: 1, message: 'Error: Usage: aiwg marketplace publish <source> --key <ed25519.pem> --publisher <id> [--output <dir>]' };
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const outputDir = parseFlag(ctx.args, '--output') ?? path.join(path.resolve(argument), '.aiwg', 'marketplace');
|
|
350
|
+
const sequenceText = parseFlag(ctx.args, '--sequence');
|
|
351
|
+
const sequence = sequenceText === undefined ? undefined : Number(sequenceText);
|
|
352
|
+
if (sequence !== undefined && (!Number.isSafeInteger(sequence) || sequence < 1))
|
|
353
|
+
throw new Error('--sequence must be a positive integer');
|
|
354
|
+
const published = await publishLocalPackage({
|
|
355
|
+
sourceDir: argument,
|
|
356
|
+
outputDir,
|
|
357
|
+
privateKeyPath,
|
|
358
|
+
publicKeyPath: parseFlag(ctx.args, '--public-key'),
|
|
359
|
+
keyId: parseFlag(ctx.args, '--key-id'),
|
|
360
|
+
publisher,
|
|
361
|
+
requestedRef: parseFlag(ctx.args, '--ref'),
|
|
362
|
+
packageSelector: parseFlag(ctx.args, '--package'),
|
|
363
|
+
sequence,
|
|
364
|
+
actor: publisher,
|
|
365
|
+
});
|
|
366
|
+
return jsonOrMessage(hasFlag(ctx.args, '--json'), published, `Published signed envelope ${published.lock.lockId}\nEnvelope: ${published.envelopePath}\nFortemi: ${published.shardPath}`);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
return failure(error);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async function handleRemove(ctx) {
|
|
373
|
+
const argument = requiredArg(ctx, 'Catalog ID required');
|
|
374
|
+
if (typeof argument !== 'string')
|
|
375
|
+
return argument;
|
|
376
|
+
try {
|
|
377
|
+
const removed = await removeCatalog(argument, scopeFromContext(ctx));
|
|
378
|
+
return {
|
|
379
|
+
exitCode: removed ? 0 : 1,
|
|
380
|
+
message: removed
|
|
381
|
+
? `Removed catalog ${argument}; existing immutable package locks remain valid`
|
|
382
|
+
: `Catalog '${argument}' was not registered`,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
return failure(error);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
async function handleList(ctx) {
|
|
390
|
+
try {
|
|
391
|
+
const scope = scopeFromContext(ctx);
|
|
392
|
+
const packages = await listInstalledPackages(marketplaceConfigDir(scope));
|
|
393
|
+
if (hasFlag(ctx.args, '--json')) {
|
|
394
|
+
console.log(JSON.stringify(packages, null, 2));
|
|
395
|
+
return { exitCode: 0 };
|
|
396
|
+
}
|
|
141
397
|
ui.blank();
|
|
142
|
-
ui.
|
|
398
|
+
console.log(` ${ui.brandMark()} ${ui.bold('Installed Marketplace Packages')}`);
|
|
399
|
+
ui.rule();
|
|
400
|
+
if (packages.length === 0) {
|
|
401
|
+
ui.dim(' No packages installed.');
|
|
402
|
+
ui.blank();
|
|
403
|
+
return { exitCode: 0 };
|
|
404
|
+
}
|
|
405
|
+
const keyWidth = Math.max(12, ...packages.map((pkg) => pkg.key.length));
|
|
406
|
+
const versionWidth = Math.max(7, ...packages.map((pkg) => pkg.version.length));
|
|
407
|
+
const header = ['Package'.padEnd(keyWidth), 'Version'.padEnd(versionWidth), 'Type', 'Verification'].join(' ');
|
|
408
|
+
ui.dim(` ${header}`);
|
|
409
|
+
ui.dim(` ${'─'.repeat(header.length)}`);
|
|
410
|
+
for (const pkg of packages) {
|
|
411
|
+
console.log(` ${[pkg.key.padEnd(keyWidth), pkg.version.padEnd(versionWidth), pkg.type, pkg.verificationStatus ?? 'legacy'].join(' ')}`);
|
|
412
|
+
}
|
|
143
413
|
ui.blank();
|
|
414
|
+
ui.dim(` ${packages.length} package${packages.length === 1 ? '' : 's'} installed`);
|
|
144
415
|
return { exitCode: 0 };
|
|
145
416
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
'Package'.padEnd(keyWidth),
|
|
150
|
-
'Version'.padEnd(versionWidth),
|
|
151
|
-
'Type',
|
|
152
|
-
].join(' ');
|
|
153
|
-
ui.dim(` ${header}`);
|
|
154
|
-
ui.dim(` ${'─'.repeat(header.length)}`);
|
|
155
|
-
for (const pkg of packages) {
|
|
156
|
-
const row = [
|
|
157
|
-
pkg.key.padEnd(keyWidth),
|
|
158
|
-
pkg.version.padEnd(versionWidth),
|
|
159
|
-
pkg.type,
|
|
160
|
-
].join(' ');
|
|
161
|
-
console.log(` ${row}`);
|
|
162
|
-
}
|
|
163
|
-
ui.blank();
|
|
164
|
-
ui.dim(` ${packages.length} package${packages.length !== 1 ? 's' : ''} installed`);
|
|
165
|
-
ui.blank();
|
|
166
|
-
return { exitCode: 0 };
|
|
417
|
+
catch (error) {
|
|
418
|
+
return failure(error);
|
|
419
|
+
}
|
|
167
420
|
}
|
|
168
421
|
//# sourceMappingURL=marketplace.js.map
|
|
@@ -3,6 +3,7 @@ import { loadResourceTrustRootFile, readVerifiedRegularFile, resolveWebRelease,
|
|
|
3
3
|
import { getProjectDir } from "../../config/aiwg-config.js";
|
|
4
4
|
import { cleanWebResourceCache } from "../../resources/cache-cleanup.js";
|
|
5
5
|
import { writeWebResourceLock } from "../../resources/lockfile.js";
|
|
6
|
+
import { createResourceCredentialProvider } from "../../auth/resource-credentials.js";
|
|
6
7
|
const MAX_RESOURCE_MANIFEST_BYTES = 4 * 1024 * 1024;
|
|
7
8
|
const DEFAULT_CHANNELS = ["stable", "latest", "canary", "main"];
|
|
8
9
|
function usage() {
|
|
@@ -82,6 +83,7 @@ function webReleaseOptionsFromEnvironment() {
|
|
|
82
83
|
? undefined
|
|
83
84
|
: loadResourceTrustRootFile(path.resolve(trustRootFile));
|
|
84
85
|
return {
|
|
86
|
+
credentialProvider: createResourceCredentialProvider(process.env),
|
|
85
87
|
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
86
88
|
...(cacheRoot === undefined ? {} : { cacheRoot }),
|
|
87
89
|
...(publicKeyPem === undefined ? {} : { publicKeyPem }),
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, realpathSync, statSync, } from 'node:fs';
|
|
2
2
|
import { dirname, isAbsolute, resolve, } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
3
4
|
import { CLAUDE_ADAPTER_VERSION, ClaudeSessionAdapter, CODEX_ADAPTER_VERSION, CodexSessionAdapter, COPILOT_ADAPTER_VERSION, CopilotSessionAdapter, CURSOR_ADAPTER_VERSION, CursorSessionAdapter, FACTORY_ADAPTER_VERSION, FactorySessionAdapter, HERMES_ADAPTER_VERSION, HermesSessionAdapter, OPENCODE_ADAPTER_VERSION, OpenCodeSessionAdapter, OPENCLAW_ADAPTER_VERSION, OpenClawSessionAdapter, OPENHUMAN_ADAPTER_VERSION, OpenHumanSessionAdapter, WARP_ADAPTER_VERSION, WarpSessionAdapter, DEVIN_DESKTOP_ADAPTER_VERSION, DevinDesktopSessionAdapter, CandidateExtractionService, GENERIC_ADAPTER_VERSION, GenericSessionInterchangeAdapter, IncrementalSessionImporter, ImportLeaseContentionError, FilesystemMemoryDestination, FilesystemPromotionDispositionCoordinator, MemoryPromotionGateway, SESSION_CONTRACT_VERSION, SESSION_PROVIDER_IDS, SessionContractError, SessionRepository, SessionSourceSchema, StructuralCandidateExtractor, resolveMemoryConsumerManifest, assertSessionProviderId, acquireImportLease, defaultDiscoveryManifestPath, discoverWorkspaceHistories, deriveSessionTimeline, importDiscoveryManifest, previewDiscoveryImport, publicDiscoveryManifest, readDiscoveryManifest, redactSourceLocator, sha256, parseTimelineGap, writeDiscoveryManifest, } from '../../sessions/index.js';
|
|
4
5
|
const JSON_CONTRACT_VERSION = '1.0.0';
|
|
6
|
+
async function createLineMemoryPromotionDestination(projectRoot, manifestPath) {
|
|
7
|
+
const modulePath = resolve(dirname(manifestPath), 'commands', 'line-memory.mjs');
|
|
8
|
+
if (!existsSync(modulePath)) {
|
|
9
|
+
throw new SessionContractError('UNSUPPORTED_OPERATION', 'line-memory promotion adapter is missing from the installed addon');
|
|
10
|
+
}
|
|
11
|
+
const loaded = await import(pathToFileURL(modulePath).href);
|
|
12
|
+
if (!loaded.LineMemoryPromotionDestination) {
|
|
13
|
+
throw new SessionContractError('UNSUPPORTED_OPERATION', 'line-memory addon does not export its promotion adapter');
|
|
14
|
+
}
|
|
15
|
+
return new loaded.LineMemoryPromotionDestination({
|
|
16
|
+
projectRoot,
|
|
17
|
+
consumer: 'line-memory',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
5
20
|
const EXIT = {
|
|
6
21
|
ok: 0, usage: 2, unsupported: 3, unavailable: 4, contract: 5, storage: 6,
|
|
7
22
|
locked: 7, coverage: 8,
|
|
@@ -406,11 +421,14 @@ async function executeCommand(ctx, args) {
|
|
|
406
421
|
const candidateId = requiredPositional(args, 0, 'candidate-id');
|
|
407
422
|
const version = boundedInteger(requiredPositional(args, 1, 'version'), 1, 1, Number.MAX_SAFE_INTEGER, 'version');
|
|
408
423
|
const consumer = requiredValue(args, '--consumer');
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
424
|
+
const manifestPath = resolveMemoryConsumerManifest(ctx.cwd, consumer);
|
|
425
|
+
const destination = consumer === 'line-memory'
|
|
426
|
+
? await createLineMemoryPromotionDestination(ctx.cwd, manifestPath)
|
|
427
|
+
: new FilesystemMemoryDestination({
|
|
428
|
+
projectRoot: ctx.cwd,
|
|
429
|
+
consumer,
|
|
430
|
+
manifestPath,
|
|
431
|
+
});
|
|
414
432
|
const scopedPromotionStore = {
|
|
415
433
|
getCandidate: (id, candidateVersion) => repository.getCandidate(id, candidateVersion, workspaceId),
|
|
416
434
|
getPromotionReceipt: (id, candidateVersion, namedConsumer) => repository.getCandidate(id, candidateVersion, workspaceId)
|
|
@@ -1147,9 +1147,18 @@ export const packagePluginHandler = {
|
|
|
1147
1147
|
message: "Error: plugin name is required.\n\nRun `aiwg package-plugin --help` for usage.",
|
|
1148
1148
|
};
|
|
1149
1149
|
}
|
|
1150
|
+
const positionalSource = positional && (positional.includes('/') || positional.includes('\\'))
|
|
1151
|
+
? positional
|
|
1152
|
+
: undefined;
|
|
1150
1153
|
const normalizedArgs = hasExplicitPlugin
|
|
1151
1154
|
? ctx.args
|
|
1152
|
-
:
|
|
1155
|
+
: positionalSource
|
|
1156
|
+
? [
|
|
1157
|
+
"--plugin", path.basename(path.resolve(ctx.cwd, positionalSource)),
|
|
1158
|
+
"--source", positionalSource,
|
|
1159
|
+
...ctx.args.slice(1),
|
|
1160
|
+
]
|
|
1161
|
+
: ["--plugin", positional, ...ctx.args.slice(1)];
|
|
1153
1162
|
const frameworkRoot = await getFrameworkRoot();
|
|
1154
1163
|
const runner = createScriptRunner(frameworkRoot);
|
|
1155
1164
|
return runner.run("tools/plugin/package-plugins.mjs", normalizedArgs, {
|