agent-conveyor 0.1.18 → 0.1.20
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 +21 -3
- package/dist/cli/typescript-runtime.d.ts +9 -0
- package/dist/cli/typescript-runtime.js +246 -7
- package/dist/cli/typescript-runtime.js.map +1 -1
- package/dist/runtime/campaigns.d.ts +19 -0
- package/dist/runtime/campaigns.js +61 -0
- package/dist/runtime/campaigns.js.map +1 -1
- package/package.json +2 -1
- package/plugin/agent-conveyor/plugin.json +15 -0
- package/plugin/agent-conveyor/skills/conveyor-check-status/SKILL.md +38 -0
- package/plugin/agent-conveyor/skills/conveyor-create-pair/SKILL.md +43 -0
- package/plugin/agent-conveyor/skills/conveyor-create-worker-set/SKILL.md +55 -0
package/README.md
CHANGED
|
@@ -154,18 +154,36 @@ The GitHub Pages version lives at
|
|
|
154
154
|
Use `node scripts/check-landing-page.mjs` for a docs-only desktop/mobile
|
|
155
155
|
screenshot gate; this does not run the full package release smoke.
|
|
156
156
|
|
|
157
|
+
### Codex Operator Plugin
|
|
158
|
+
|
|
159
|
+
Agent Conveyor also ships Codex-app-only operator scaffolding for visible
|
|
160
|
+
manager/worker sessions from any project. Install the package, then install
|
|
161
|
+
and inspect the plugin:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npm install -g agent-conveyor
|
|
165
|
+
conveyor install-plugin
|
|
166
|
+
conveyor plugin-status
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The per-project default ledger for operator sessions is
|
|
170
|
+
`.codex-workers/workerctl.db`. The initial included skills are
|
|
171
|
+
`conveyor-create-pair`, `conveyor-create-worker-set`, and
|
|
172
|
+
`conveyor-check-status`.
|
|
173
|
+
|
|
157
174
|
After install, the intended Codex app entry point is natural language. Open a
|
|
158
175
|
new Codex app session in the target repo and say:
|
|
159
176
|
|
|
160
177
|
```text
|
|
161
|
-
Use the
|
|
178
|
+
Use the conveyor-create-pair skill.
|
|
162
179
|
|
|
163
180
|
Set up a Codex app Ralph loop for issue CTL.
|
|
164
181
|
Require adversarial proof before another worker iteration.
|
|
165
182
|
```
|
|
166
183
|
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
For multiple workers, start with `Use the conveyor-create-worker-set skill`.
|
|
185
|
+
The installed plugin skill should call the `conveyor` CLI, choose names, create
|
|
186
|
+
the no-tmux binding with `create-disposable-binding`, point the worker at
|
|
169
187
|
`worker-inbox`, and use `loop-status` plus telemetry receipts before reporting
|
|
170
188
|
that the loop is ready. When the manager is itself running in the Codex app and
|
|
171
189
|
thread tools are available, the skill should first call `create_thread` for a
|
|
@@ -25,6 +25,15 @@ interface SpawnedCodexSessionDiscoveryOptions {
|
|
|
25
25
|
}
|
|
26
26
|
type TypescriptRuntimeOptions = {
|
|
27
27
|
args: readonly string[];
|
|
28
|
+
campaignReadbackBeforeVerify?: (context: {
|
|
29
|
+
databasePath: string;
|
|
30
|
+
readback: {
|
|
31
|
+
assignment?: string;
|
|
32
|
+
campaign: string;
|
|
33
|
+
channel?: string;
|
|
34
|
+
slot?: string;
|
|
35
|
+
};
|
|
36
|
+
}) => void;
|
|
28
37
|
codexCommandResolver?: (name: string) => string | null;
|
|
29
38
|
cwd?: string;
|
|
30
39
|
discoverSpawnedCodexSession?: (options: SpawnedCodexSessionDiscoveryOptions) => SpawnedCodexSessionDiscovery;
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { taskAuditSync } from "../runtime/audit.js";
|
|
8
8
|
import { appAutopilotPlanSync, appLoopStatusSync, appWakeupDispatchPlanSync, appWakeupPlanSync, directInboxPollCommand, visibleSessionProtocolLines, } from "../runtime/app-autonomy.js";
|
|
9
9
|
import { classifyBusyWait, classifyStartupOutput } from "../runtime/classify.js";
|
|
10
|
-
import { addCampaignWorkerSlotSync, campaignDashboardSync, campaignStatusSync, createCampaignAssignmentSync, createCampaignSync, recordCampaignAssetReceiptSync, updateCampaignWorkerSlotLifecycleSync, upsertCampaignChannelBriefSync, } from "../runtime/campaigns.js";
|
|
10
|
+
import { addCampaignWorkerSlotSync, campaignDashboardSync, campaignSetupReadbackProofSync, campaignStatusSync, createCampaignAssignmentSync, createCampaignSync, recordCampaignAssetReceiptSync, updateCampaignWorkerSlotLifecycleSync, upsertCampaignChannelBriefSync, } from "../runtime/campaigns.js";
|
|
11
11
|
import { exportTaskSync } from "../runtime/export.js";
|
|
12
12
|
import { ingestSessionSync } from "../runtime/ingest.js";
|
|
13
13
|
import { acceptanceCriteriaForTaskSync, loopEvidenceCriterion, recordAdversarialLoopEvidenceSync, recordLoopEvidenceSync, recordVisualDiffLoopEvidenceSync, } from "../runtime/loop-evidence.js";
|
|
@@ -171,6 +171,15 @@ export function runTypescriptRuntimeCommand(options) {
|
|
|
171
171
|
if (parsed.command === "install-skills") {
|
|
172
172
|
return runInstallSkillsCommand(parsed, options);
|
|
173
173
|
}
|
|
174
|
+
if (parsed.command === "plugin-path") {
|
|
175
|
+
return runPluginPathCommand(parsed, options);
|
|
176
|
+
}
|
|
177
|
+
if (parsed.command === "plugin-status") {
|
|
178
|
+
return runPluginStatusCommand(parsed, options);
|
|
179
|
+
}
|
|
180
|
+
if (parsed.command === "install-plugin") {
|
|
181
|
+
return runInstallPluginCommand(parsed, options);
|
|
182
|
+
}
|
|
174
183
|
if (parsed.command === "bind") {
|
|
175
184
|
return runBindCommand(parsed, options);
|
|
176
185
|
}
|
|
@@ -1086,7 +1095,7 @@ function parseRuntimeArgs(args, env) {
|
|
|
1086
1095
|
index += 1;
|
|
1087
1096
|
}
|
|
1088
1097
|
else if (arg === "--codex-home") {
|
|
1089
|
-
if (command !== "install-skills") {
|
|
1098
|
+
if (command !== "install-skills" && command !== "install-plugin" && command !== "plugin-status" && command !== "plugin-path") {
|
|
1090
1099
|
return { command, enabled, error: "Unsupported TypeScript runtime option: --codex-home", explicit, flags, task };
|
|
1091
1100
|
}
|
|
1092
1101
|
const value = valueAfter(queue, index, arg);
|
|
@@ -6096,12 +6105,16 @@ function runCampaignCommand(parsed, options) {
|
|
|
6096
6105
|
name: campaign,
|
|
6097
6106
|
objective,
|
|
6098
6107
|
});
|
|
6108
|
+
const readback = campaignSetupReadbackProofFromConfiguredDatabase(parsed, options, {
|
|
6109
|
+
campaign: campaignId,
|
|
6110
|
+
});
|
|
6099
6111
|
return campaignResult(parsed, {
|
|
6100
6112
|
action,
|
|
6101
6113
|
campaign,
|
|
6102
6114
|
campaign_id: campaignId,
|
|
6103
6115
|
created: true,
|
|
6104
|
-
|
|
6116
|
+
ledger_readback: readback,
|
|
6117
|
+
}, [`campaign ${campaign} created ${campaignId}`, campaignLedgerReadbackText(readback)]);
|
|
6105
6118
|
}
|
|
6106
6119
|
if (action === "add-slot") {
|
|
6107
6120
|
const slotKey = requiredStringFlag(parsed.flags.slotKey, "--slot-key");
|
|
@@ -6119,13 +6132,18 @@ function runCampaignCommand(parsed, options) {
|
|
|
6119
6132
|
slotKey,
|
|
6120
6133
|
...(state ? { state } : {}),
|
|
6121
6134
|
});
|
|
6135
|
+
const readback = campaignSetupReadbackProofFromConfiguredDatabase(parsed, options, {
|
|
6136
|
+
campaign,
|
|
6137
|
+
slot: slotId,
|
|
6138
|
+
});
|
|
6122
6139
|
return campaignResult(parsed, {
|
|
6123
6140
|
action,
|
|
6124
6141
|
campaign,
|
|
6125
6142
|
created: true,
|
|
6143
|
+
ledger_readback: readback,
|
|
6126
6144
|
slot_id: slotId,
|
|
6127
6145
|
slot_key: slotKey,
|
|
6128
|
-
}, [`campaign ${campaign} slot ${slotKey} created ${slotId}
|
|
6146
|
+
}, [`campaign ${campaign} slot ${slotKey} created ${slotId}`, campaignLedgerReadbackText(readback)]);
|
|
6129
6147
|
}
|
|
6130
6148
|
if (action === "attach-slot") {
|
|
6131
6149
|
const slot = requiredStringFlag(parsed.flags.slot, "--slot");
|
|
@@ -6194,13 +6212,18 @@ function runCampaignCommand(parsed, options) {
|
|
|
6194
6212
|
campaign,
|
|
6195
6213
|
channel,
|
|
6196
6214
|
});
|
|
6215
|
+
const readback = campaignSetupReadbackProofFromConfiguredDatabase(parsed, options, {
|
|
6216
|
+
campaign,
|
|
6217
|
+
channel,
|
|
6218
|
+
});
|
|
6197
6219
|
return campaignResult(parsed, {
|
|
6198
6220
|
action,
|
|
6199
6221
|
brief_id: briefId,
|
|
6200
6222
|
campaign,
|
|
6201
6223
|
channel,
|
|
6224
|
+
ledger_readback: readback,
|
|
6202
6225
|
upserted: true,
|
|
6203
|
-
}, [`campaign ${campaign} brief ${channel} upserted ${briefId}
|
|
6226
|
+
}, [`campaign ${campaign} brief ${channel} upserted ${briefId}`, campaignLedgerReadbackText(readback)]);
|
|
6204
6227
|
}
|
|
6205
6228
|
if (action === "assign") {
|
|
6206
6229
|
const slot = requiredStringFlag(parsed.flags.slot, "--slot");
|
|
@@ -6216,13 +6239,19 @@ function runCampaignCommand(parsed, options) {
|
|
|
6216
6239
|
title,
|
|
6217
6240
|
...(status ? { status } : {}),
|
|
6218
6241
|
});
|
|
6242
|
+
const readback = campaignSetupReadbackProofFromConfiguredDatabase(parsed, options, {
|
|
6243
|
+
assignment: assignmentId,
|
|
6244
|
+
campaign,
|
|
6245
|
+
slot,
|
|
6246
|
+
});
|
|
6219
6247
|
return campaignResult(parsed, {
|
|
6220
6248
|
action,
|
|
6221
6249
|
assignment_id: assignmentId,
|
|
6222
6250
|
campaign,
|
|
6223
6251
|
created: true,
|
|
6252
|
+
ledger_readback: readback,
|
|
6224
6253
|
slot_id: slot,
|
|
6225
|
-
}, [`campaign ${campaign} assignment created ${assignmentId}
|
|
6254
|
+
}, [`campaign ${campaign} assignment created ${assignmentId}`, campaignLedgerReadbackText(readback)]);
|
|
6226
6255
|
}
|
|
6227
6256
|
if (action === "asset") {
|
|
6228
6257
|
const slot = requiredStringFlag(parsed.flags.slot, "--slot");
|
|
@@ -6276,6 +6305,25 @@ function runCampaignCommand(parsed, options) {
|
|
|
6276
6305
|
function campaignActionsUsage() {
|
|
6277
6306
|
return CAMPAIGN_ACTION_NAMES.join("|");
|
|
6278
6307
|
}
|
|
6308
|
+
function campaignSetupReadbackProofFromConfiguredDatabase(parsed, options, readbackOptions) {
|
|
6309
|
+
const databasePath = runtimeDbPath(parsed, options);
|
|
6310
|
+
options.campaignReadbackBeforeVerify?.({ databasePath, readback: readbackOptions });
|
|
6311
|
+
const database = openDatabaseSync(databasePath);
|
|
6312
|
+
initializeDatabaseSync(database);
|
|
6313
|
+
try {
|
|
6314
|
+
return campaignSetupReadbackProofSync(database, readbackOptions);
|
|
6315
|
+
}
|
|
6316
|
+
catch (error) {
|
|
6317
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6318
|
+
throw new Error(`campaign ledger readback failed after setup write: ${message}`, { cause: error });
|
|
6319
|
+
}
|
|
6320
|
+
finally {
|
|
6321
|
+
database.close();
|
|
6322
|
+
}
|
|
6323
|
+
}
|
|
6324
|
+
function campaignLedgerReadbackText(proof) {
|
|
6325
|
+
return `ledger_readback ok campaign=${proof.campaign_id} checks=${proof.checks.map((check) => check.entity).join(",")}`;
|
|
6326
|
+
}
|
|
6279
6327
|
function unsupportedCampaignActionMessage(action) {
|
|
6280
6328
|
return `Unsupported campaign action: ${action ?? "<missing>"}; expected one of: ${CAMPAIGN_ACTION_NAMES.join(", ")}. Use \`conveyor campaign dashboard --name <campaign> --json\` to list assets and receipt counts.`;
|
|
6281
6329
|
}
|
|
@@ -6616,7 +6664,7 @@ function runInstallSkillsCommand(parsed, options) {
|
|
|
6616
6664
|
if (unsupported) {
|
|
6617
6665
|
return unsupportedRuntimeResult(parsed, unsupported);
|
|
6618
6666
|
}
|
|
6619
|
-
const codexHome =
|
|
6667
|
+
const codexHome = resolveCodexHome(parsed, options);
|
|
6620
6668
|
const skills = installableSkillSources();
|
|
6621
6669
|
const targets = skills.map((skill) => ({
|
|
6622
6670
|
name: skill.name,
|
|
@@ -6648,6 +6696,194 @@ function runInstallSkillsCommand(parsed, options) {
|
|
|
6648
6696
|
const lines = targets.map((target) => `${parsed.flags.dryRun ? "would install" : "installed"} ${target.name} skill in ${target.target}`);
|
|
6649
6697
|
return { exitCode: 0, handled: true, stdout: `${lines.join("\n")}\n` };
|
|
6650
6698
|
}
|
|
6699
|
+
const AGENT_CONVEYOR_PLUGIN_NAME = "agent-conveyor";
|
|
6700
|
+
const AGENT_CONVEYOR_PLUGIN_SKILLS = ["conveyor-create-pair", "conveyor-create-worker-set", "conveyor-check-status"];
|
|
6701
|
+
function resolveCodexHome(parsed, options) {
|
|
6702
|
+
return resolve(expandUserPath(parsed.flags.codexHome ?? options.env?.CODEX_HOME ?? join(homedir(), ".codex")));
|
|
6703
|
+
}
|
|
6704
|
+
function packageVersionFromRoot(packageRoot) {
|
|
6705
|
+
const packageJsonPath = join(packageRoot, "package.json");
|
|
6706
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
6707
|
+
if (!isPlainRecord(parsed) || typeof parsed.version !== "string" || parsed.version.length === 0) {
|
|
6708
|
+
throw new Error(`Package version not found in ${packageJsonPath}.`);
|
|
6709
|
+
}
|
|
6710
|
+
return parsed.version;
|
|
6711
|
+
}
|
|
6712
|
+
function pluginPaths(parsed, options) {
|
|
6713
|
+
const codexHome = resolveCodexHome(parsed, options);
|
|
6714
|
+
const packageRoot = packageRootFromRuntimeModule();
|
|
6715
|
+
const packageVersion = packageVersionFromRoot(packageRoot);
|
|
6716
|
+
const pluginCacheRoot = join(codexHome, "plugins", "cache", AGENT_CONVEYOR_PLUGIN_NAME, AGENT_CONVEYOR_PLUGIN_NAME);
|
|
6717
|
+
return {
|
|
6718
|
+
codex_home: codexHome,
|
|
6719
|
+
package_root: packageRoot,
|
|
6720
|
+
plugin_cache_root: pluginCacheRoot,
|
|
6721
|
+
plugin_install_root: join(pluginCacheRoot, packageVersion),
|
|
6722
|
+
plugin_source: join(packageRoot, "plugin", AGENT_CONVEYOR_PLUGIN_NAME),
|
|
6723
|
+
skills_install_root: join(codexHome, "skills"),
|
|
6724
|
+
};
|
|
6725
|
+
}
|
|
6726
|
+
function readAgentConveyorPluginManifest(source) {
|
|
6727
|
+
const manifestPath = join(source, "plugin.json");
|
|
6728
|
+
const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
6729
|
+
if (!isPlainRecord(parsed)) {
|
|
6730
|
+
throw new Error(`Agent Conveyor plugin manifest must be a JSON object: ${manifestPath}`);
|
|
6731
|
+
}
|
|
6732
|
+
if (parsed.name !== AGENT_CONVEYOR_PLUGIN_NAME) {
|
|
6733
|
+
throw new Error(`Agent Conveyor plugin manifest name must be "${AGENT_CONVEYOR_PLUGIN_NAME}": ${manifestPath}`);
|
|
6734
|
+
}
|
|
6735
|
+
if (typeof parsed.version !== "string") {
|
|
6736
|
+
throw new Error(`Agent Conveyor plugin manifest is missing a string version: ${manifestPath}`);
|
|
6737
|
+
}
|
|
6738
|
+
return {
|
|
6739
|
+
name: parsed.name,
|
|
6740
|
+
version: parsed.version,
|
|
6741
|
+
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((skill) => typeof skill === "string") : undefined,
|
|
6742
|
+
};
|
|
6743
|
+
}
|
|
6744
|
+
function assertPluginVersionMatchesPackage(manifest, packageVersion) {
|
|
6745
|
+
if (manifest.version !== packageVersion) {
|
|
6746
|
+
throw new Error(`Agent Conveyor plugin version ${manifest.version} does not match package version ${packageVersion}.`);
|
|
6747
|
+
}
|
|
6748
|
+
}
|
|
6749
|
+
function pluginSkillTargets(paths) {
|
|
6750
|
+
return AGENT_CONVEYOR_PLUGIN_SKILLS.map((name) => {
|
|
6751
|
+
const target = join(paths.skills_install_root, name);
|
|
6752
|
+
return {
|
|
6753
|
+
installed: existsSync(join(target, "SKILL.md")),
|
|
6754
|
+
name,
|
|
6755
|
+
source: join(paths.plugin_source, "skills", name),
|
|
6756
|
+
target,
|
|
6757
|
+
};
|
|
6758
|
+
});
|
|
6759
|
+
}
|
|
6760
|
+
function installedAgentConveyorPluginManifest(paths) {
|
|
6761
|
+
const manifestPath = join(paths.plugin_install_root, "plugin.json");
|
|
6762
|
+
if (!existsSync(manifestPath)) {
|
|
6763
|
+
return null;
|
|
6764
|
+
}
|
|
6765
|
+
const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
6766
|
+
if (!isPlainRecord(parsed) || parsed.name !== AGENT_CONVEYOR_PLUGIN_NAME || typeof parsed.version !== "string") {
|
|
6767
|
+
return null;
|
|
6768
|
+
}
|
|
6769
|
+
return {
|
|
6770
|
+
name: parsed.name,
|
|
6771
|
+
version: parsed.version,
|
|
6772
|
+
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((skill) => typeof skill === "string") : undefined,
|
|
6773
|
+
};
|
|
6774
|
+
}
|
|
6775
|
+
function agentConveyorPluginStatus(parsed, options) {
|
|
6776
|
+
const paths = pluginPaths(parsed, options);
|
|
6777
|
+
const packageVersion = packageVersionFromRoot(paths.package_root);
|
|
6778
|
+
const manifest = readAgentConveyorPluginManifest(paths.plugin_source);
|
|
6779
|
+
const installedManifest = installedAgentConveyorPluginManifest(paths);
|
|
6780
|
+
const installedVersion = installedManifest?.version ?? null;
|
|
6781
|
+
const skills = pluginSkillTargets(paths);
|
|
6782
|
+
const installed = installedManifest !== null && skills.every((skill) => skill.installed);
|
|
6783
|
+
return {
|
|
6784
|
+
installed,
|
|
6785
|
+
installed_version: installedVersion,
|
|
6786
|
+
package_version: packageVersion,
|
|
6787
|
+
paths,
|
|
6788
|
+
plugin_version: manifest.version,
|
|
6789
|
+
skills,
|
|
6790
|
+
version_matches: installed && installedVersion === packageVersion && manifest.version === packageVersion,
|
|
6791
|
+
};
|
|
6792
|
+
}
|
|
6793
|
+
function unsupportedPluginOptions(parsed) {
|
|
6794
|
+
if (parsed.task !== null) {
|
|
6795
|
+
return `Unexpected argument: ${parsed.task}`;
|
|
6796
|
+
}
|
|
6797
|
+
return null;
|
|
6798
|
+
}
|
|
6799
|
+
function runPluginPathCommand(parsed, options) {
|
|
6800
|
+
const unsupported = unsupportedPluginOptions(parsed);
|
|
6801
|
+
if (unsupported) {
|
|
6802
|
+
return unsupportedRuntimeResult(parsed, unsupported);
|
|
6803
|
+
}
|
|
6804
|
+
const paths = pluginPaths(parsed, options);
|
|
6805
|
+
if (parsed.flags.json) {
|
|
6806
|
+
return jsonResult(paths);
|
|
6807
|
+
}
|
|
6808
|
+
return {
|
|
6809
|
+
exitCode: 0,
|
|
6810
|
+
handled: true,
|
|
6811
|
+
stdout: [
|
|
6812
|
+
`codex_home: ${paths.codex_home}`,
|
|
6813
|
+
`package_root: ${paths.package_root}`,
|
|
6814
|
+
`plugin_cache_root: ${paths.plugin_cache_root}`,
|
|
6815
|
+
`plugin_install_root: ${paths.plugin_install_root}`,
|
|
6816
|
+
`plugin_source: ${paths.plugin_source}`,
|
|
6817
|
+
`skills_install_root: ${paths.skills_install_root}`,
|
|
6818
|
+
"",
|
|
6819
|
+
].join("\n"),
|
|
6820
|
+
};
|
|
6821
|
+
}
|
|
6822
|
+
function runPluginStatusCommand(parsed, options) {
|
|
6823
|
+
const unsupported = unsupportedPluginOptions(parsed);
|
|
6824
|
+
if (unsupported) {
|
|
6825
|
+
return unsupportedRuntimeResult(parsed, unsupported);
|
|
6826
|
+
}
|
|
6827
|
+
const status = agentConveyorPluginStatus(parsed, options);
|
|
6828
|
+
if (parsed.flags.json) {
|
|
6829
|
+
return jsonResult(status);
|
|
6830
|
+
}
|
|
6831
|
+
const skillLines = status.skills.map((skill) => `skill ${skill.name}: ${skill.installed ? "installed" : "missing"}`);
|
|
6832
|
+
return {
|
|
6833
|
+
exitCode: 0,
|
|
6834
|
+
handled: true,
|
|
6835
|
+
stdout: [
|
|
6836
|
+
`installed: ${status.installed}`,
|
|
6837
|
+
`installed_version: ${status.installed_version ?? "none"}`,
|
|
6838
|
+
`package_version: ${status.package_version}`,
|
|
6839
|
+
`plugin_version: ${status.plugin_version}`,
|
|
6840
|
+
`version_matches: ${status.version_matches}`,
|
|
6841
|
+
...skillLines,
|
|
6842
|
+
"",
|
|
6843
|
+
].join("\n"),
|
|
6844
|
+
};
|
|
6845
|
+
}
|
|
6846
|
+
function runInstallPluginCommand(parsed, options) {
|
|
6847
|
+
const unsupported = unsupportedPluginOptions(parsed);
|
|
6848
|
+
if (unsupported) {
|
|
6849
|
+
return unsupportedRuntimeResult(parsed, unsupported);
|
|
6850
|
+
}
|
|
6851
|
+
const paths = pluginPaths(parsed, options);
|
|
6852
|
+
const packageVersion = packageVersionFromRoot(paths.package_root);
|
|
6853
|
+
const manifest = readAgentConveyorPluginManifest(paths.plugin_source);
|
|
6854
|
+
assertPluginVersionMatchesPackage(manifest, packageVersion);
|
|
6855
|
+
const skillTargets = pluginSkillTargets(paths);
|
|
6856
|
+
for (const target of skillTargets) {
|
|
6857
|
+
if (!existsSync(join(target.source, "SKILL.md"))) {
|
|
6858
|
+
throw new Error(`Agent Conveyor plugin skill not found: ${target.source}`);
|
|
6859
|
+
}
|
|
6860
|
+
}
|
|
6861
|
+
if (!parsed.flags.dryRun) {
|
|
6862
|
+
rmSync(paths.plugin_install_root, { force: true, recursive: true });
|
|
6863
|
+
mkdirSync(dirname(paths.plugin_install_root), { recursive: true });
|
|
6864
|
+
cpSync(paths.plugin_source, paths.plugin_install_root, { recursive: true });
|
|
6865
|
+
for (const target of skillTargets) {
|
|
6866
|
+
rmSync(target.target, { force: true, recursive: true });
|
|
6867
|
+
mkdirSync(dirname(target.target), { recursive: true });
|
|
6868
|
+
cpSync(target.source, target.target, { recursive: true });
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
const status = agentConveyorPluginStatus(parsed, options);
|
|
6872
|
+
const payload = {
|
|
6873
|
+
...status,
|
|
6874
|
+
dry_run: parsed.flags.dryRun,
|
|
6875
|
+
installed: status.installed,
|
|
6876
|
+
installed_skills: parsed.flags.dryRun ? [] : skillTargets.map((target) => target.name),
|
|
6877
|
+
};
|
|
6878
|
+
if (parsed.flags.json) {
|
|
6879
|
+
return jsonResult(payload);
|
|
6880
|
+
}
|
|
6881
|
+
const lines = [
|
|
6882
|
+
`${parsed.flags.dryRun ? "would install" : "installed"} ${AGENT_CONVEYOR_PLUGIN_NAME} plugin in ${paths.plugin_install_root}`,
|
|
6883
|
+
...skillTargets.map((target) => `${parsed.flags.dryRun ? "would install" : "installed"} ${target.name} skill in ${target.target}`),
|
|
6884
|
+
];
|
|
6885
|
+
return { exitCode: 0, handled: true, stdout: `${lines.join("\n")}\n` };
|
|
6886
|
+
}
|
|
6651
6887
|
function dashboardLaunchPayload(parsed) {
|
|
6652
6888
|
const queryParams = new URLSearchParams();
|
|
6653
6889
|
if (parsed.flags.taskName) {
|
|
@@ -15447,6 +15683,9 @@ function isDefaultRuntimeCommand(command) {
|
|
|
15447
15683
|
|| command === "start-test"
|
|
15448
15684
|
|| command === "dashboard"
|
|
15449
15685
|
|| command === "install-skills"
|
|
15686
|
+
|| command === "install-plugin"
|
|
15687
|
+
|| command === "plugin-status"
|
|
15688
|
+
|| command === "plugin-path"
|
|
15450
15689
|
|| command === "replay"
|
|
15451
15690
|
|| command === "export-task"
|
|
15452
15691
|
|| command === "tasks"
|