agentic-workflow-manager 3.1.0 → 3.2.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/commands/add.js +84 -0
- package/dist/src/commands/agent.js +95 -0
- package/dist/src/commands/backup.js +46 -0
- package/dist/src/commands/doctor.js +80 -4
- package/dist/src/commands/hooks/claude.js +192 -0
- package/dist/src/commands/hooks/codex.js +191 -0
- package/dist/src/commands/hooks/index.js +23 -8
- package/dist/src/commands/hooks/install.js +11 -107
- package/dist/src/commands/hooks/resync.js +28 -18
- package/dist/src/commands/hooks/shared.js +94 -0
- package/dist/src/commands/hooks/status.js +13 -64
- package/dist/src/commands/hooks/uninstall.js +11 -47
- package/dist/src/commands/init.js +90 -28
- package/dist/src/commands/registry/index.js +1 -1
- package/dist/src/commands/sync.js +113 -0
- package/dist/src/commands/update.js +107 -0
- package/dist/src/core/agent-targets.js +50 -0
- package/dist/src/core/artifact-state.js +65 -0
- package/dist/src/core/atomic-file.js +72 -0
- package/dist/src/core/bundle-install.js +60 -38
- package/dist/src/core/bundles.js +21 -0
- package/dist/src/core/context/managed-block.js +190 -0
- package/dist/src/core/context/orchestrator.js +3 -1
- package/dist/src/core/context/project-constitution-inject.js +1 -1
- package/dist/src/core/context/regenerate.js +3 -3
- package/dist/src/core/context/strategies/codex-agents.js +100 -0
- package/dist/src/core/diagnostics/checks.js +16 -0
- package/dist/src/core/diagnostics/context.js +37 -8
- package/dist/src/core/diagnostics/provider-checks.js +219 -0
- package/dist/src/core/executor.js +30 -9
- package/dist/src/core/init/mutation-targets.js +139 -0
- package/dist/src/core/init/provider-facts.js +164 -0
- package/dist/src/core/init/steps.js +65 -9
- package/dist/src/core/install-planner.js +206 -0
- package/dist/src/core/install-transaction.js +405 -0
- package/dist/src/core/profile.js +1 -1
- package/dist/src/core/provider-artifacts.js +54 -0
- package/dist/src/core/provider-version.js +36 -0
- package/dist/src/core/reconciliation.js +61 -0
- package/dist/src/core/registries.js +10 -0
- package/dist/src/core/renderers/canonical-agent.js +27 -0
- package/dist/src/core/renderers/codex-agent.js +60 -0
- package/dist/src/core/skill-integrity.js +4 -3
- package/dist/src/index.js +97 -289
- package/dist/src/providers/index.js +143 -39
- package/dist/src/ui/provider-preflight.js +26 -0
- package/dist/src/utils/config.js +101 -9
- package/dist/tests/commands/agent.test.js +103 -0
- package/dist/tests/commands/backup.test.js +109 -0
- package/dist/tests/commands/doctor.test.js +65 -4
- package/dist/tests/commands/hooks/codex.test.js +230 -0
- package/dist/tests/commands/hooks/install.test.js +20 -1
- package/dist/tests/commands/hooks/resync.test.js +53 -6
- package/dist/tests/commands/hooks/status.test.js +10 -0
- package/dist/tests/commands/hooks/uninstall.test.js +12 -0
- package/dist/tests/commands/init.test.js +195 -8
- package/dist/tests/commands/multi-agent-targeting.test.js +231 -0
- package/dist/tests/core/agent-targets.test.js +45 -0
- package/dist/tests/core/artifact-state.test.js +144 -0
- package/dist/tests/core/atomic-file.test.js +96 -0
- package/dist/tests/core/bundle-install.test.js +208 -17
- package/dist/tests/core/bundles.test.js +12 -0
- package/dist/tests/core/context/managed-block.test.js +90 -0
- package/dist/tests/core/context/orchestrator.test.js +48 -3
- package/dist/tests/core/context/regenerate.test.js +1 -1
- package/dist/tests/core/context/strategies/codex-agents.test.js +185 -0
- package/dist/tests/core/context/strategies/config-instructions.test.js +1 -1
- package/dist/tests/core/diagnostics/checks.test.js +19 -0
- package/dist/tests/core/diagnostics/context.test.js +74 -0
- package/dist/tests/core/diagnostics/provider-checks.test.js +252 -0
- package/dist/tests/core/executor.test.js +20 -0
- package/dist/tests/core/export/engine.test.js +3 -2
- package/dist/tests/core/init/mutation-targets.test.js +235 -0
- package/dist/tests/core/init/orchestrator.test.js +1 -1
- package/dist/tests/core/init/provider-facts.test.js +129 -0
- package/dist/tests/core/init/steps.test.js +106 -2
- package/dist/tests/core/install-planner.test.js +224 -0
- package/dist/tests/core/install-transaction.test.js +257 -0
- package/dist/tests/core/provider-artifacts.test.js +64 -0
- package/dist/tests/core/provider-version.test.js +53 -0
- package/dist/tests/core/reconciliation.test.js +165 -0
- package/dist/tests/core/registries-sync.test.js +4 -4
- package/dist/tests/core/renderers/canonical-agent.test.js +58 -0
- package/dist/tests/core/renderers/codex-agent.test.js +128 -0
- package/dist/tests/core/versioning.test.js +1 -1
- package/dist/tests/integration/codex-provider-isolated.test.js +206 -0
- package/dist/tests/providers/hooks-config.test.js +43 -25
- package/dist/tests/providers/index.test.js +144 -39
- package/dist/tests/structural/codex-agent-escaping-completeness.test.js +77 -0
- package/dist/tests/ui/provider-preflight.test.js +25 -0
- package/dist/tests/utils/config.test.js +178 -18
- package/package.json +1 -1
|
@@ -88,10 +88,11 @@ function repairGlobalSkills(skillsDir, registryContentDirs) {
|
|
|
88
88
|
* único agente target. Cada provider en su propio path; un dir ausente se omite. */
|
|
89
89
|
function reconcileAllSkillLinks(registryContentDirs) {
|
|
90
90
|
const out = [];
|
|
91
|
-
for (const agent of
|
|
92
|
-
|
|
91
|
+
for (const agent of providers_1.AGENT_TARGETS) {
|
|
92
|
+
const skillsDir = (0, providers_1.providerFor)(agent).skill.global;
|
|
93
|
+
if (!fs_1.default.existsSync(skillsDir))
|
|
93
94
|
continue;
|
|
94
|
-
out.push({ agent, result: repairGlobalSkills(
|
|
95
|
+
out.push({ agent, result: repairGlobalSkills(skillsDir, registryContentDirs) });
|
|
95
96
|
}
|
|
96
97
|
return out;
|
|
97
98
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -13,31 +13,33 @@ const tty_1 = require("./ui/tty");
|
|
|
13
13
|
const picker_1 = require("./ui/picker");
|
|
14
14
|
const providers_1 = require("./providers");
|
|
15
15
|
const executor_1 = require("./core/executor");
|
|
16
|
-
const
|
|
16
|
+
const provider_artifacts_1 = require("./core/provider-artifacts");
|
|
17
|
+
const provider_preflight_1 = require("./ui/provider-preflight");
|
|
17
18
|
const discovery_1 = require("./core/discovery");
|
|
18
19
|
const bundles_1 = require("./core/bundles");
|
|
19
|
-
const skill_integrity_1 = require("./core/skill-integrity");
|
|
20
20
|
const registries_1 = require("./core/registries");
|
|
21
|
-
const cli_version_1 = require("./core/cli-version");
|
|
22
|
-
const bundle_install_1 = require("./core/bundle-install");
|
|
23
|
-
const profile_1 = require("./core/profile");
|
|
24
21
|
const path_1 = __importDefault(require("path"));
|
|
25
22
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
26
23
|
const fs_1 = __importDefault(require("fs"));
|
|
27
24
|
const story_map_parser_1 = require("./core/story-map-parser");
|
|
28
25
|
const miro_1 = require("./core/miro");
|
|
29
26
|
const hooks_1 = require("./commands/hooks");
|
|
30
|
-
const resync_1 = require("./commands/hooks/resync");
|
|
31
27
|
const sensors_1 = require("./commands/sensors");
|
|
32
28
|
const ledger_1 = require("./commands/ledger");
|
|
33
29
|
const doctor_1 = require("./commands/doctor");
|
|
30
|
+
const backup_1 = require("./commands/backup");
|
|
34
31
|
const init_1 = require("./commands/init");
|
|
35
32
|
const registry_1 = require("./commands/registry");
|
|
36
33
|
const pin_1 = require("./commands/pin");
|
|
37
34
|
const export_1 = require("./commands/export");
|
|
38
|
-
const
|
|
35
|
+
const agent_1 = require("./commands/agent");
|
|
36
|
+
const add_1 = require("./commands/add");
|
|
37
|
+
const sync_1 = require("./commands/sync");
|
|
38
|
+
const update_1 = require("./commands/update");
|
|
39
|
+
const agent_targets_1 = require("./core/agent-targets");
|
|
39
40
|
const update_check_1 = require("./core/update-check");
|
|
40
41
|
const paths_1 = require("./core/paths");
|
|
42
|
+
const cli_version_1 = require("./core/cli-version");
|
|
41
43
|
const program = new commander_1.Command();
|
|
42
44
|
program.name('awm').description('Agentic Workflow Manager').version((0, cli_version_1.cliVersion)());
|
|
43
45
|
program.hook('postAction', () => {
|
|
@@ -46,6 +48,17 @@ program.hook('postAction', () => {
|
|
|
46
48
|
}
|
|
47
49
|
catch { /* el aviso nunca rompe un comando */ }
|
|
48
50
|
});
|
|
51
|
+
/** Shared resolve-or-exit for the 3 index.ts call sites that need `--agent` targeting
|
|
52
|
+
* outside an already-testable `run*Core` function (which returns `{ code: 1, ... }`
|
|
53
|
+
* instead — see `core/agent-targets.ts`'s `resolveAgentTargetsOrError`). */
|
|
54
|
+
function resolveTargetsOrExit(prefs, explicit) {
|
|
55
|
+
const resolved = (0, agent_targets_1.resolveAgentTargetsOrError)({ prefs, explicit });
|
|
56
|
+
if (!resolved.ok) {
|
|
57
|
+
console.error(picocolors_1.default.red(resolved.error));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
return resolved.targets;
|
|
61
|
+
}
|
|
49
62
|
function handleCancel(value) {
|
|
50
63
|
if ((0, prompts_1.isCancel)(value)) {
|
|
51
64
|
(0, prompts_1.outro)('Operation cancelled.');
|
|
@@ -72,7 +85,7 @@ function resolveSelectedArtifacts(selections) {
|
|
|
72
85
|
program.command('add [name]')
|
|
73
86
|
.description('Add a skill, workflow, or process interactively (or non-interactively with flags)')
|
|
74
87
|
.option('-t, --type <type>', 'Artifact type: skill, workflow, or process')
|
|
75
|
-
.option('-a, --agent <agent>', `Target agent: ${
|
|
88
|
+
.option('-a, --agent <agent>', `Target agent: ${providers_1.AGENT_TARGETS.join(', ')}`)
|
|
76
89
|
.option('-s, --scope <scope>', 'Scope: local or global')
|
|
77
90
|
.option('-m, --method <method>', 'Install method: symlink or copy')
|
|
78
91
|
.option('-y, --yes', 'Skip confirmation prompts')
|
|
@@ -91,65 +104,12 @@ program.command('add [name]')
|
|
|
91
104
|
// 1b. If `name` matches a bundle, run the bundle-activation flow and exit.
|
|
92
105
|
if (name) {
|
|
93
106
|
const allBundles = (0, bundles_1.discoverAllBundles)();
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const parsed = options.agent.split(',').map((a) => a.trim());
|
|
101
|
-
for (const a of parsed) {
|
|
102
|
-
if (!valid.includes(a)) {
|
|
103
|
-
console.error(picocolors_1.default.red(`Invalid agent "${a}". Use: ${valid.join(', ')}.`));
|
|
104
|
-
process.exit(1);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
bundleAgents = parsed;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
bundleAgents = [prefs.defaultAgent];
|
|
111
|
-
}
|
|
112
|
-
let scopeOverride;
|
|
113
|
-
if (options.scope) {
|
|
114
|
-
if (!['local', 'global'].includes(options.scope)) {
|
|
115
|
-
console.error(picocolors_1.default.red(`Invalid scope "${options.scope}". Use: local or global.`));
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
scopeOverride = options.scope;
|
|
119
|
-
}
|
|
120
|
-
const effective = scopeOverride ?? (0, bundles_1.defaultScopeForBundle)(matchedBundle.scope);
|
|
121
|
-
const projectRoot = (0, profile_1.findProjectRoot)(process.cwd());
|
|
122
|
-
if (effective === 'local' && !projectRoot) {
|
|
123
|
-
console.error(picocolors_1.default.red('No project root found (need a .git/, package.json, or .awm/profile.json here). Run inside a project, or pass --global.'));
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
const result = (0, bundle_install_1.addBundle)({
|
|
127
|
-
bundleName: matchedBundle.name,
|
|
128
|
-
bundles: allBundles,
|
|
129
|
-
agents: bundleAgents,
|
|
130
|
-
method: 'symlink',
|
|
131
|
-
projectRoot: projectRoot ?? process.cwd(),
|
|
132
|
-
scopeOverride,
|
|
133
|
-
});
|
|
134
|
-
if (result.skipped.length > 0) {
|
|
135
|
-
for (const s of result.skipped)
|
|
136
|
-
console.log(picocolors_1.default.yellow(` ⚠ Skipped: ${s}`));
|
|
137
|
-
}
|
|
138
|
-
if (result.installed.length === 0) {
|
|
139
|
-
(0, prompts_1.outro)(picocolors_1.default.yellow(`Nothing installed for bundle "${matchedBundle.name}".`));
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const lines = result.installed.map((n) => picocolors_1.default.green(n)).join('\n ');
|
|
143
|
-
const recordNote = result.recordedExtension
|
|
144
|
-
? `\n\n${picocolors_1.default.dim('Recorded as a project extension in .awm/profile.json (commit it; symlinks are gitignored).')}`
|
|
145
|
-
: '';
|
|
146
|
-
(0, prompts_1.outro)(`✅ Installed bundle ${picocolors_1.default.cyan(matchedBundle.name)}:\n ${lines}${recordNote}`);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
// name given but no matching bundle found — report clearly regardless of TTY
|
|
150
|
-
console.error(picocolors_1.default.red(`Bundle "${name}" not found in registry.`));
|
|
151
|
-
console.error(picocolors_1.default.dim('Run `awm list` to see available packages.'));
|
|
152
|
-
process.exit(1);
|
|
107
|
+
const prefs = (0, config_1.getPreferences)();
|
|
108
|
+
const outcome = (0, add_1.runAddBundleCore)({ name, agent: options.agent, scope: options.scope }, prefs, allBundles);
|
|
109
|
+
if (outcome.code !== 0)
|
|
110
|
+
process.exit(outcome.code);
|
|
111
|
+
(0, prompts_1.outro)('Done.');
|
|
112
|
+
return;
|
|
153
113
|
}
|
|
154
114
|
// 2. Discover artifacts
|
|
155
115
|
const skills = (0, discovery_1.discoverSkills)();
|
|
@@ -162,21 +122,7 @@ program.command('add [name]')
|
|
|
162
122
|
const prefs = (0, config_1.getPreferences)();
|
|
163
123
|
// --all: install everything from every package headlessly
|
|
164
124
|
if (options.all) {
|
|
165
|
-
|
|
166
|
-
if (options.agent) {
|
|
167
|
-
const validAgents = Object.keys(providers_1.PROVIDERS);
|
|
168
|
-
const parsed = options.agent.split(',').map((a) => a.trim());
|
|
169
|
-
for (const a of parsed) {
|
|
170
|
-
if (!validAgents.includes(a)) {
|
|
171
|
-
console.error(picocolors_1.default.red(`Invalid agent "${a}". Use: ${validAgents.join(', ')}.`));
|
|
172
|
-
process.exit(1);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
targetAgents = parsed;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
targetAgents = [prefs.defaultAgent];
|
|
179
|
-
}
|
|
125
|
+
const targetAgents = resolveTargetsOrExit(prefs, options.agent);
|
|
180
126
|
let scopeVal;
|
|
181
127
|
if (options.scope) {
|
|
182
128
|
if (!['local', 'global'].includes(options.scope)) {
|
|
@@ -199,8 +145,8 @@ program.command('add [name]')
|
|
|
199
145
|
else {
|
|
200
146
|
methodVal = scopeVal === 'local' ? 'copy' : 'symlink';
|
|
201
147
|
}
|
|
202
|
-
const includeWorkflows = targetAgents.some((a) => providers_1.
|
|
203
|
-
const includeAgents = targetAgents.some((a) => providers_1.
|
|
148
|
+
const includeWorkflows = targetAgents.some((a) => (0, providers_1.providerFor)(a).workflow !== null);
|
|
149
|
+
const includeAgents = targetAgents.some((a) => (0, providers_1.providerFor)(a).agent !== null);
|
|
204
150
|
const allView = (0, registry_view_1.buildPackageView)(skills, includeWorkflows ? workflows : [], includeAgents ? agents : [], (0, bundles_1.discoverAllBundles)());
|
|
205
151
|
const allDedup = new Map();
|
|
206
152
|
for (const pkg of allView) {
|
|
@@ -217,6 +163,9 @@ program.command('add [name]')
|
|
|
217
163
|
(0, prompts_1.outro)(picocolors_1.default.yellow('No artifacts available.'));
|
|
218
164
|
return;
|
|
219
165
|
}
|
|
166
|
+
const preflightOk = (0, provider_preflight_1.preflightLinkArtifactsForCli)(targetAgents.flatMap((agent) => artifactsToInstall.map((artifact) => ({ agent, artifact }))));
|
|
167
|
+
if (!preflightOk)
|
|
168
|
+
return;
|
|
220
169
|
const installSpinner = (0, prompts_1.spinner)();
|
|
221
170
|
installSpinner.start('Installing artifacts...');
|
|
222
171
|
try {
|
|
@@ -224,17 +173,24 @@ program.command('add [name]')
|
|
|
224
173
|
const skipped = [];
|
|
225
174
|
for (const currentAgent of targetAgents) {
|
|
226
175
|
for (const artifact of artifactsToInstall) {
|
|
227
|
-
|
|
176
|
+
const config = (0, providers_1.assertLinkRenderer)(artifact.type, currentAgent);
|
|
177
|
+
if (config === null) {
|
|
228
178
|
skipped.push(`${artifact.name} (${currentAgent})`);
|
|
229
179
|
continue;
|
|
230
180
|
}
|
|
231
|
-
const targetDir =
|
|
181
|
+
const targetDir = config[scopeVal];
|
|
232
182
|
const finalDest = path_1.default.join(targetDir, artifact.name);
|
|
233
183
|
(0, executor_1.installArtifact)(artifact.sourcePath, finalDest, methodVal);
|
|
234
184
|
installed.push(`${artifact.name} → ${currentAgent} (${scopeVal})`);
|
|
235
185
|
}
|
|
236
186
|
}
|
|
237
|
-
(0, config_1.
|
|
187
|
+
const updatedPrefs = targetAgents.reduce((current, agent) => (0, config_1.enableAgent)(current, agent), prefs);
|
|
188
|
+
(0, config_1.savePreferences)({
|
|
189
|
+
...updatedPrefs,
|
|
190
|
+
defaultAgent: targetAgents[0],
|
|
191
|
+
defaultScope: scopeVal,
|
|
192
|
+
installMethod: methodVal,
|
|
193
|
+
});
|
|
238
194
|
installSpinner.stop('Installation complete!');
|
|
239
195
|
if (skipped.length > 0) {
|
|
240
196
|
for (const sk of skipped) {
|
|
@@ -260,24 +216,16 @@ program.command('add [name]')
|
|
|
260
216
|
// 3. Agent & Scope Prompts (Moved up)
|
|
261
217
|
let targetAgents;
|
|
262
218
|
if (options.agent) {
|
|
263
|
-
|
|
264
|
-
const parsed = options.agent.split(',').map(a => a.trim());
|
|
265
|
-
for (const a of parsed) {
|
|
266
|
-
if (!validAgents.includes(a)) {
|
|
267
|
-
console.error(picocolors_1.default.red(`Invalid agent "${a}". Use: ${validAgents.join(', ')}.`));
|
|
268
|
-
process.exit(1);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
targetAgents = parsed;
|
|
219
|
+
targetAgents = resolveTargetsOrExit(prefs, options.agent);
|
|
272
220
|
}
|
|
273
221
|
else {
|
|
274
222
|
const agentChoice = await (0, prompts_1.multiselect)({
|
|
275
223
|
message: 'Which agent(s) do you want to install to?',
|
|
276
|
-
options:
|
|
224
|
+
options: providers_1.AGENT_TARGETS.map((key) => ({
|
|
277
225
|
value: key,
|
|
278
|
-
label:
|
|
226
|
+
label: (0, providers_1.providerFor)(key).label
|
|
279
227
|
})),
|
|
280
|
-
initialValues: [prefs.
|
|
228
|
+
initialValues: [...prefs.enabledAgents],
|
|
281
229
|
required: true
|
|
282
230
|
});
|
|
283
231
|
handleCancel(agentChoice);
|
|
@@ -304,8 +252,8 @@ program.command('add [name]')
|
|
|
304
252
|
scopeVal = scopeChoice;
|
|
305
253
|
}
|
|
306
254
|
// 4. Build the package view, filtered to artifact types the target agent(s) support
|
|
307
|
-
const includeWorkflows = targetAgents.some(a => providers_1.
|
|
308
|
-
const includeAgents = targetAgents.some(a => providers_1.
|
|
255
|
+
const includeWorkflows = targetAgents.some(a => (0, providers_1.providerFor)(a).workflow !== null);
|
|
256
|
+
const includeAgents = targetAgents.some(a => (0, providers_1.providerFor)(a).agent !== null);
|
|
309
257
|
const view = (0, registry_view_1.buildPackageView)(skills, includeWorkflows ? workflows : [], includeAgents ? agents : [], (0, bundles_1.discoverAllBundles)());
|
|
310
258
|
if (view.length === 0) {
|
|
311
259
|
(0, prompts_1.outro)(picocolors_1.default.yellow('No artifacts available for the selected agent(s).'));
|
|
@@ -349,6 +297,9 @@ program.command('add [name]')
|
|
|
349
297
|
(0, prompts_1.outro)(picocolors_1.default.yellow('No artifacts selected.'));
|
|
350
298
|
return;
|
|
351
299
|
}
|
|
300
|
+
const preflightOk = (0, provider_preflight_1.preflightLinkArtifactsForCli)(targetAgents.flatMap((agent) => artifactsToInstall.map((artifact) => ({ agent, artifact }))));
|
|
301
|
+
if (!preflightOk)
|
|
302
|
+
return;
|
|
352
303
|
// 6. Installation Method
|
|
353
304
|
let methodVal;
|
|
354
305
|
if (options.method) {
|
|
@@ -389,17 +340,24 @@ program.command('add [name]')
|
|
|
389
340
|
for (const currentAgent of targetAgents) {
|
|
390
341
|
for (const artifact of artifactsToInstall) {
|
|
391
342
|
// Skip artifacts not supported by this agent
|
|
392
|
-
|
|
343
|
+
const config = (0, providers_1.assertLinkRenderer)(artifact.type, currentAgent);
|
|
344
|
+
if (config === null) {
|
|
393
345
|
skipped.push(`${artifact.name} (${currentAgent})`);
|
|
394
346
|
continue;
|
|
395
347
|
}
|
|
396
|
-
const targetDir =
|
|
348
|
+
const targetDir = config[scopeVal];
|
|
397
349
|
const finalDest = path_1.default.join(targetDir, artifact.name);
|
|
398
350
|
(0, executor_1.installArtifact)(artifact.sourcePath, finalDest, methodVal);
|
|
399
351
|
installed.push(`${artifact.name} → ${currentAgent} (${scopeVal})`);
|
|
400
352
|
}
|
|
401
353
|
}
|
|
402
|
-
(0, config_1.
|
|
354
|
+
const updatedPrefs = targetAgents.reduce((current, agent) => (0, config_1.enableAgent)(current, agent), prefs);
|
|
355
|
+
(0, config_1.savePreferences)({
|
|
356
|
+
...updatedPrefs,
|
|
357
|
+
defaultAgent: targetAgents[0],
|
|
358
|
+
defaultScope: scopeVal,
|
|
359
|
+
installMethod: methodVal,
|
|
360
|
+
});
|
|
403
361
|
installSpinner.stop('Installation complete!');
|
|
404
362
|
if (skipped.length > 0) {
|
|
405
363
|
for (const s of skipped) {
|
|
@@ -416,149 +374,25 @@ program.command('add [name]')
|
|
|
416
374
|
}
|
|
417
375
|
});
|
|
418
376
|
program.command('update')
|
|
419
|
-
.description('Sync all configured registries
|
|
420
|
-
.
|
|
377
|
+
.description('Sync all configured registries, reconcile artifacts and re-sync hooks')
|
|
378
|
+
.option('-a, --agent <agent>', `Target agent(s), comma-separated: ${providers_1.AGENT_TARGETS.join(', ')} (defaults to every enabled agent)`)
|
|
379
|
+
.action(async (options) => {
|
|
421
380
|
(0, prompts_1.intro)(picocolors_1.default.bgCyan(picocolors_1.default.black(' AWM - Update Registries ')));
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
if (results.length === 0) {
|
|
427
|
-
console.log(picocolors_1.default.yellow(' No registries configured — run `awm init` (seeds baseline) or `awm registry add <remote>`.'));
|
|
428
|
-
}
|
|
429
|
-
for (const r of results) {
|
|
430
|
-
if (r.action === 'error') {
|
|
431
|
-
console.warn(picocolors_1.default.yellow(` ⚠ registry ${r.name}: ${r.error}`));
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
console.log(picocolors_1.default.green(` ✓ Registry ${r.name} ${r.action === 'pulled' ? 'updated' : 're-cloned'} @ ${r.version}`));
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
for (const f of (0, registries_1.verifyMinCliVersions)()) {
|
|
438
|
-
console.warn(picocolors_1.default.yellow(` ⚠ Registry ${f.name} requires CLI ≥ ${f.min} (you have ${(0, cli_version_1.cliVersion)()}) — run: npm i -g agentic-workflow-manager`));
|
|
439
|
-
}
|
|
440
|
-
try {
|
|
441
|
-
const regen = (0, regenerate_1.regenerateGlobalContext)();
|
|
442
|
-
const refreshed = regen.filter((r) => r.action === 'refreshed').map((r) => r.agent);
|
|
443
|
-
if (refreshed.length > 0)
|
|
444
|
-
console.log(picocolors_1.default.green(` ✓ Regenerated AWM context for: ${refreshed.join(', ')}`));
|
|
445
|
-
}
|
|
446
|
-
catch { /* no aborta */ }
|
|
447
|
-
try {
|
|
448
|
-
for (const { agent, result } of (0, skill_integrity_1.reconcileAllSkillLinks)((0, registries_1.contentRoots)())) {
|
|
449
|
-
const touched = result.relinked.length + result.pruned.length;
|
|
450
|
-
if (touched > 0)
|
|
451
|
-
console.log(picocolors_1.default.green(` ✓ Reconciled ${agent} skill links: re-linked ${result.relinked.length}, pruned ${result.pruned.length}`));
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
catch { /* no aborta */ }
|
|
455
|
-
try {
|
|
456
|
-
const hooksRoot = (0, registries_1.capabilityRoot)('hooks');
|
|
457
|
-
if (hooksRoot) {
|
|
458
|
-
for (const r of (0, resync_1.resyncInstalledHooks)(hooksRoot)) {
|
|
459
|
-
if (r.action === 'resynced')
|
|
460
|
-
console.log(picocolors_1.default.green(` ✓ Re-synced ${r.agent} hook scripts`));
|
|
461
|
-
else if (r.action === 'registry-missing')
|
|
462
|
-
console.warn(picocolors_1.default.yellow(` ⚠ ${r.agent} hook installed but registry hooks missing — run 'awm hooks install'`));
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
catch { /* no aborta */ }
|
|
467
|
-
await (0, update_check_1.offerSelfUpdate)(); // capa 2 — Task 13
|
|
468
|
-
(0, prompts_1.outro)('✅ Registries, skills and hooks updated.');
|
|
381
|
+
(0, paths_1.warnIfUnsupportedPlatform)((m) => console.warn(picocolors_1.default.yellow(`⚠ ${m}`)));
|
|
382
|
+
const result = await (0, update_1.runUpdateCore)(options);
|
|
383
|
+
(0, prompts_1.outro)(result.code === 0 ? '✅ Registries, skills and hooks updated.' : picocolors_1.default.red('Update failed — see errors above.'));
|
|
384
|
+
process.exitCode = result.code;
|
|
469
385
|
});
|
|
470
386
|
program.command('sync')
|
|
471
387
|
.description('Rebuild local skill symlinks from .awm/profile.json (e.g. after cloning on a new machine)')
|
|
472
|
-
.option('-a, --agent <agent>', `Target agent: ${
|
|
388
|
+
.option('-a, --agent <agent>', `Target agent(s), comma-separated: ${providers_1.AGENT_TARGETS.join(', ')} (defaults to every enabled agent)`)
|
|
473
389
|
.option('-m, --method <method>', 'Install method: symlink or copy', 'symlink')
|
|
474
390
|
.action(async (options) => {
|
|
475
391
|
(0, prompts_1.intro)(picocolors_1.default.bgCyan(picocolors_1.default.black(' AWM - Sync Project Profile ')));
|
|
476
392
|
(0, paths_1.warnIfUnsupportedPlatform)((m) => console.warn(picocolors_1.default.yellow(`⚠ ${m}`)));
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
process.exit(1);
|
|
481
|
-
}
|
|
482
|
-
let profile;
|
|
483
|
-
try {
|
|
484
|
-
profile = (0, profile_1.readProfile)(projectRoot);
|
|
485
|
-
}
|
|
486
|
-
catch (e) {
|
|
487
|
-
console.error(picocolors_1.default.red(e.message));
|
|
488
|
-
process.exit(1);
|
|
489
|
-
}
|
|
490
|
-
const s = (0, prompts_1.spinner)();
|
|
491
|
-
s.start('Syncing registries...');
|
|
492
|
-
const syncResults = await (0, registries_1.syncRegistries)();
|
|
493
|
-
s.stop('Registries synced.');
|
|
494
|
-
for (const r of syncResults) {
|
|
495
|
-
if (r.action === 'error')
|
|
496
|
-
console.warn(picocolors_1.default.yellow(` ⚠ registry ${r.name}: ${r.error}`));
|
|
497
|
-
}
|
|
498
|
-
// Gate minCliVersion (WS-4): un registry puede exigir una versión mínima del CLI.
|
|
499
|
-
// Corre ANTES del gate de pins — gates de contrato primero (CONSTITUTION).
|
|
500
|
-
const cliFailures = (0, registries_1.verifyMinCliVersions)();
|
|
501
|
-
if (cliFailures.length > 0) {
|
|
502
|
-
for (const f of cliFailures) {
|
|
503
|
-
console.error(picocolors_1.default.red(`Registry ${f.name} requires CLI ≥ ${f.min} (you have ${(0, cli_version_1.cliVersion)()}).`));
|
|
504
|
-
console.error(picocolors_1.default.red(' Run: npm i -g agentic-workflow-manager'));
|
|
505
|
-
}
|
|
506
|
-
process.exit(1);
|
|
507
|
-
}
|
|
508
|
-
// Gate de versión (WS-3): el pin del profile es el lock del proyecto.
|
|
509
|
-
// Runs before the empty-extensions early-exit so pinned projects always fail fast.
|
|
510
|
-
const pins = profile.registries ?? {};
|
|
511
|
-
if (Object.keys(pins).length > 0) {
|
|
512
|
-
const failures = await (0, profile_pins_1.verifyProjectPins)(pins);
|
|
513
|
-
if (failures.length > 0) {
|
|
514
|
-
for (const f of failures) {
|
|
515
|
-
if (f.reason === 'missing-registry') {
|
|
516
|
-
const registriesConfig = (0, registries_1.readRegistriesConfig)();
|
|
517
|
-
const isConfigured = registriesConfig.some((r) => r.name === f.name);
|
|
518
|
-
if (isConfigured) {
|
|
519
|
-
console.error(picocolors_1.default.red(`The registry "${f.name}" is configured but not yet synced on this machine. Run: awm update`));
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
console.error(picocolors_1.default.red(`The registry "${f.name}" is not configured on this machine. Run: awm registry add <remote>`));
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
console.error(picocolors_1.default.red(`This machine has ${f.name} @ ${f.actual ? `v${f.actual}` : 'HEAD (no tag)'} but the project requires v${f.required}.`));
|
|
527
|
-
console.error(picocolors_1.default.red(` Run: awm pin ${f.name} ${f.required} && awm update`));
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
process.exit(1);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
if (profile.extensions.length === 0) {
|
|
534
|
-
(0, prompts_1.outro)(picocolors_1.default.yellow('No extensions in .awm/profile.json — nothing to sync. Use `awm add <bundle>` first.'));
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
const prefs = (0, config_1.getPreferences)();
|
|
538
|
-
let agents;
|
|
539
|
-
if (options.agent) {
|
|
540
|
-
const valid = Object.keys(providers_1.PROVIDERS);
|
|
541
|
-
const parsed = options.agent.split(',').map((a) => a.trim());
|
|
542
|
-
for (const a of parsed) {
|
|
543
|
-
if (!valid.includes(a)) {
|
|
544
|
-
console.error(picocolors_1.default.red(`Invalid agent "${a}". Use: ${valid.join(', ')}.`));
|
|
545
|
-
process.exit(1);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
agents = parsed;
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
agents = [prefs.defaultAgent];
|
|
552
|
-
}
|
|
553
|
-
const method = options.method === 'copy' ? 'copy' : 'symlink';
|
|
554
|
-
const result = (0, bundle_install_1.syncProfile)({ projectRoot, bundles: (0, bundles_1.discoverAllBundles)(), agents, method });
|
|
555
|
-
if (result.skipped.length > 0) {
|
|
556
|
-
for (const sk of result.skipped)
|
|
557
|
-
console.log(picocolors_1.default.yellow(` ⚠ Skipped: ${sk}`));
|
|
558
|
-
}
|
|
559
|
-
const lines = result.installed.map((n) => picocolors_1.default.green(n)).join('\n ');
|
|
560
|
-
const installedNote = lines ? `\n ${lines}` : picocolors_1.default.dim(' (all up to date)');
|
|
561
|
-
(0, prompts_1.outro)(`✅ Synced extensions [${result.extensions.join(', ')}]:${installedNote}`);
|
|
393
|
+
const { code } = await (0, sync_1.runSyncCore)(options);
|
|
394
|
+
(0, prompts_1.outro)(code === 0 ? 'Done.' : picocolors_1.default.red('Sync failed — see errors above.'));
|
|
395
|
+
process.exitCode = code;
|
|
562
396
|
});
|
|
563
397
|
program.command('list [package]')
|
|
564
398
|
.description('List available artifacts. With no argument shows a package summary; pass a package name or --all for detail.')
|
|
@@ -621,21 +455,29 @@ program.command('list [package]')
|
|
|
621
455
|
});
|
|
622
456
|
program.command('remove')
|
|
623
457
|
.description('Remove an installed skill or workflow')
|
|
624
|
-
.
|
|
458
|
+
.option('-a, --agent <agent>', `Target agent(s), comma-separated: ${providers_1.AGENT_TARGETS.join(', ')} (defaults to every enabled agent)`)
|
|
459
|
+
.action(async (options) => {
|
|
625
460
|
(0, prompts_1.intro)(picocolors_1.default.bgCyan(picocolors_1.default.black(' AWM - Remove Artifact ')));
|
|
626
461
|
const prefs = (0, config_1.getPreferences)();
|
|
627
|
-
// Multi-agent selection (matching the add command flow)
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
462
|
+
// Multi-agent selection (matching the add command flow). --agent skips
|
|
463
|
+
// the interactive prompt and resolves the same way as add/sync/update/doctor (R12/R13).
|
|
464
|
+
let targetAgents;
|
|
465
|
+
if (options.agent) {
|
|
466
|
+
targetAgents = resolveTargetsOrExit(prefs, options.agent);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
const agentChoice = await (0, prompts_1.multiselect)({
|
|
470
|
+
message: 'From which agent(s)?',
|
|
471
|
+
options: providers_1.AGENT_TARGETS.map((key) => ({
|
|
472
|
+
value: key,
|
|
473
|
+
label: (0, providers_1.providerFor)(key).label
|
|
474
|
+
})),
|
|
475
|
+
initialValues: [...prefs.enabledAgents],
|
|
476
|
+
required: true
|
|
477
|
+
});
|
|
478
|
+
handleCancel(agentChoice);
|
|
479
|
+
targetAgents = agentChoice;
|
|
480
|
+
}
|
|
639
481
|
const scopeChoice = await (0, prompts_1.select)({
|
|
640
482
|
message: 'Scope?',
|
|
641
483
|
options: [
|
|
@@ -646,43 +488,7 @@ program.command('remove')
|
|
|
646
488
|
});
|
|
647
489
|
handleCancel(scopeChoice);
|
|
648
490
|
const scopeVal = scopeChoice;
|
|
649
|
-
|
|
650
|
-
const artifactMap = new Map();
|
|
651
|
-
const scanDir = (dir, type, agent) => {
|
|
652
|
-
if (!fs_1.default.existsSync(dir))
|
|
653
|
-
return;
|
|
654
|
-
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
655
|
-
for (const entry of entries) {
|
|
656
|
-
const existing = artifactMap.get(entry.name);
|
|
657
|
-
if (existing) {
|
|
658
|
-
existing.installedIn.push(agent);
|
|
659
|
-
existing.fullPaths.push(path_1.default.join(dir, entry.name));
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
artifactMap.set(entry.name, {
|
|
663
|
-
name: entry.name,
|
|
664
|
-
type,
|
|
665
|
-
installedIn: [agent],
|
|
666
|
-
fullPaths: [path_1.default.join(dir, entry.name)]
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
for (const targetAgent of targetAgents) {
|
|
672
|
-
try {
|
|
673
|
-
scanDir((0, providers_1.getTargetPath)('skill', targetAgent, scopeVal), 'skill', targetAgent);
|
|
674
|
-
}
|
|
675
|
-
catch { /* ok */ }
|
|
676
|
-
try {
|
|
677
|
-
scanDir((0, providers_1.getTargetPath)('workflow', targetAgent, scopeVal), 'workflow', targetAgent);
|
|
678
|
-
}
|
|
679
|
-
catch { /* ok */ }
|
|
680
|
-
try {
|
|
681
|
-
scanDir((0, providers_1.getTargetPath)('agent', targetAgent, scopeVal), 'agent', targetAgent);
|
|
682
|
-
}
|
|
683
|
-
catch { /* ok */ }
|
|
684
|
-
}
|
|
685
|
-
const installed = Array.from(artifactMap.values());
|
|
491
|
+
const installed = (0, provider_artifacts_1.scanLegacyArtifacts)(targetAgents, scopeVal);
|
|
686
492
|
if (installed.length === 0) {
|
|
687
493
|
(0, prompts_1.outro)(picocolors_1.default.yellow('No installed artifacts found for the selected agents/scope.'));
|
|
688
494
|
process.exit(0);
|
|
@@ -799,8 +605,10 @@ miroCmd.command('sync <storyMapPath>')
|
|
|
799
605
|
(0, sensors_1.registerSensorsCommand)(program);
|
|
800
606
|
(0, ledger_1.registerLedgerCommand)(program);
|
|
801
607
|
(0, doctor_1.registerDoctorCommand)(program);
|
|
608
|
+
(0, backup_1.registerBackupCommand)(program);
|
|
802
609
|
(0, init_1.registerInitCommand)(program);
|
|
803
610
|
(0, registry_1.registerRegistryCommand)(program);
|
|
804
611
|
(0, pin_1.registerPinCommands)(program);
|
|
805
612
|
(0, export_1.registerExportCommand)(program);
|
|
613
|
+
(0, agent_1.registerAgentCommand)(program);
|
|
806
614
|
program.parse();
|