pilotswarm 0.5.42 → 0.5.44
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/mcp/README.md +25 -1
- package/mcp/dist/src/auth.d.ts.map +1 -1
- package/mcp/dist/src/auth.js +5 -3
- package/mcp/dist/src/auth.js.map +1 -1
- package/mcp/dist/src/resources/models.d.ts.map +1 -1
- package/mcp/dist/src/resources/models.js +21 -14
- package/mcp/dist/src/resources/models.js.map +1 -1
- package/mcp/dist/src/server.d.ts.map +1 -1
- package/mcp/dist/src/server.js +2 -0
- package/mcp/dist/src/server.js.map +1 -1
- package/mcp/dist/src/tools/agent-packages.d.ts.map +1 -1
- package/mcp/dist/src/tools/agent-packages.js +28 -16
- package/mcp/dist/src/tools/agent-packages.js.map +1 -1
- package/mcp/dist/src/tools/models.d.ts.map +1 -1
- package/mcp/dist/src/tools/models.js +55 -47
- package/mcp/dist/src/tools/models.js.map +1 -1
- package/mcp/dist/src/tools/providers.d.ts +18 -0
- package/mcp/dist/src/tools/providers.d.ts.map +1 -0
- package/mcp/dist/src/tools/providers.js +284 -0
- package/mcp/dist/src/tools/providers.js.map +1 -0
- package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
- package/mcp/dist/src/tools/sessions.js +10 -1
- package/mcp/dist/src/tools/sessions.js.map +1 -1
- package/mcp/dist/src/tools/system.js +2 -2
- package/mcp/dist/src/tools/system.js.map +1 -1
- package/mcp/dist/src/util/respond.d.ts.map +1 -1
- package/mcp/dist/src/util/respond.js +6 -0
- package/mcp/dist/src/util/respond.js.map +1 -1
- package/package.json +3 -3
- package/tui/README.md +8 -5
- package/tui/src/agents-cli.js +80 -78
- package/tui/src/app.js +119 -17
- package/tui/src/node-sdk-transport.js +150 -347
- package/ui/core/src/controller.js +1079 -23
- package/ui/core/src/reducer.js +649 -1
- package/ui/core/src/selectors.js +891 -6
- package/ui/core/src/state.js +163 -3
- package/ui/react/src/components.js +146 -4
- package/ui/react/src/web-app.js +1732 -50
- package/web/README.md +4 -4
- package/web/api/router.js +33 -0
- package/web/dist/assets/{abnfDiagram-VRR7QNED-Jh9nLlRI.js → abnfDiagram-VRR7QNED-67Q0WWge.js} +1 -1
- package/web/dist/assets/{arc-CmN4jFMW.js → arc-BvcYFngS.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-DgUSVwl7.js → architectureDiagram-ZJ3FMSHR-CPBN0rk8.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-CCJEXNgp.js → blockDiagram-677ZJIJ3-D_hp1Oah.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-DG11zUre.js → c4Diagram-LMCZKHZV-DAOVGMIW.js} +1 -1
- package/web/dist/assets/channel-DiW7lUT8.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-Cl8MUWGh.js → chunk-2Q5K7J3B-DajZuaot.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-BaLutEQY.js → chunk-32BRIVSS-C6pXBsgt.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-BOPcnMeW.js → chunk-5VM5RSS4-780edrmi.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-bY2tdfJ2.js → chunk-EX3LRPZG-C0e4NVuz.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-CASBfQW6.js → chunk-JWPE2WC7-uRe83I6C.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-WrEHfiAj.js → chunk-MOJQB5TN-B0WPoPjh.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-XQoZii_K.js → chunk-RYQCIY6F-eRFuHHyG.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-BvA5V7VF.js → chunk-V7JOEXUC-C8FDXprk.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-SK_jCKYo.js → chunk-VR4S4FIN-DPFpLQdB.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-CtZZImS8.js → chunk-XXDRQBXY-CoGQOPKW.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-CpAhBd5x.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-CpAhBd5x.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-PRXhsdiX.js → cose-bilkent-JH36ORCC-BTBSfO5v.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-CzUocqvb.js → cynefin-VYW2F7L2-DgTkQEoK.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-DYGEqQ23.js → cynefinDiagram-TSTJHNR4-DiBMlKoP.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-CAyb_zBo.js → dagre-VKFMJZFB-Qv-4dcbk.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-CvpXMmL-.js → diagram-FQU43EPY-CgyAb7yx.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-DBQRZJS0.js → diagram-G47NLZAW-BxN-KcGp.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-BGzD61gL.js → diagram-NH7WQ7WH-BiellpWz.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-DqQf4oMW.js → diagram-OA4YK3LP-C8Ktgrwv.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-CYHoWtg7.js → diagram-WEI45ONY-Bj5K1X91.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-oMOMgcs8.js → ebnfDiagram-CCIWWBDH-DNQI2XT9.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-DaZaseAH.js → erDiagram-Q63AITRT-D5Xkllu6.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-BIe9TtAL.js → flowDiagram-23GEKE2U-DJpTtMuj.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-DitrY3hM.js → ganttDiagram-NO4QXBWP-C-EQlCJf.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-DRjIH_99.js → gitGraphDiagram-IHSO6WYX-C8vpSbvW.js} +1 -1
- package/web/dist/assets/index-C2ioXNJJ.js +24 -0
- package/web/dist/assets/index-CVYm02UI.css +1 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-BJCx4g9_.js → infoDiagram-FWYZ7A6U-CKNzsR3r.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-CLxmaTWp.js → ishikawaDiagram-FXEZZL3T-CjyQq3lf.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-D2_VI8CC.js → journeyDiagram-5HDEW3XC-CK3EEkJt.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-DnUq9E7I.js → kanban-definition-HUTT4EX6-CHQ8YkPx.js} +1 -1
- package/web/dist/assets/{linear-mKMwWrAB.js → linear-CUYirs1h.js} +1 -1
- package/web/dist/assets/{mermaid.core-CApAWULn.js → mermaid.core-Di8sQC4g.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-D2twxIMO.js → mindmap-definition-LN4V7U3C-D38dmHP5.js} +1 -1
- package/web/dist/assets/{papaparse.min-BhDLFNak.js → papaparse.min-DWBU_pXS.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-D2RtIeDP.js → pegDiagram-2B236MQR-BU759QCo.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-vonumKaj.js → pieDiagram-ENE6RG2P-BbpfHbsj.js} +1 -1
- package/web/dist/assets/pilotswarm-DrM3pXOV.js +97 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CAZL1kJH.js → quadrantDiagram-ABIIQ3AL-BYZ3XHZn.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-CgpDomFp.js → railroadDiagram-RFXS5EU6-D18gkZBJ.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-9B6yfsXV.js → requirementDiagram-TGXJPOKE-D6vo26Ib.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-B_FAnwxi.js → sankeyDiagram-HTMAVEWB-CxQwXnRE.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-BbL6OCms.js → sequenceDiagram-DBY2YBRQ-CfGisw4A.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-DIRKFU8M.js → sizeCapture-X5ZJPWSS-BDK7-yA-.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-pUX5NF32.js → stateDiagram-2N3HPSRC-8IyidYSV.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-F7qYkvpr.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-DO7BjQ4-.js → swimlanes-5IMT3BWC-CgNqXCvM.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-CUKrHLkY.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-BcbYRQ7s.js → timeline-definition-FHXFAJF6-DAJsGj6d.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-CUt_orN5.js → vennDiagram-L72KCM5P-DDVdvG5k.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-BlUPWQdi.js → wardleyDiagram-EHGQE667-CiAs_m72.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-CDW7A5_U.js → xychartDiagram-FW5EYKEG-D6OLJtsD.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/runtime.js +220 -2
- package/web/server.js +35 -7
- package/web/dist/assets/channel-BQBGhjIw.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-BIr20mVO.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-BIr20mVO.js +0 -1
- package/web/dist/assets/index-Cl6-pI9g.js +0 -24
- package/web/dist/assets/index-DRLA5aNR.css +0 -1
- package/web/dist/assets/pilotswarm-DETFHWYc.js +0 -97
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-J_okbpZN.js +0 -1
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-gTxQyRZa.js +0 -8
package/tui/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PilotSwarm TUI
|
|
2
2
|
|
|
3
3
|
Terminal UI for PilotSwarm.
|
|
4
4
|
|
|
5
5
|
Install:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install pilotswarm
|
|
8
|
+
npm install pilotswarm
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
For app-specific worker modules or direct SDK imports, also add:
|
|
@@ -20,12 +20,15 @@ Run locally against a plugin directory:
|
|
|
20
20
|
npx pilotswarm local --env .env --plugin ./plugin --worker ./worker-module.js
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
`pilotswarm
|
|
23
|
+
The `pilotswarm` package provides the shipped TUI (`pilotswarm-cli` remains a
|
|
24
|
+
bin alias). Your app customizes it with `plugin/plugin.json`,
|
|
25
|
+
`plugin/agents/*.agent.md`, `plugin/skills/*/SKILL.md`, and optional worker-side
|
|
26
|
+
tools.
|
|
24
27
|
|
|
25
28
|
The shipped files inspector supports shared artifact browsing, download, local open, and delete flows. Binary artifacts download intact rather than being coerced through UTF-8 text previews.
|
|
26
29
|
|
|
27
|
-
Portal/runtime helpers
|
|
28
|
-
are exported from `pilotswarm-
|
|
30
|
+
Portal/runtime helpers are exported from `pilotswarm/host`; shared UI layers
|
|
31
|
+
are exported from `pilotswarm/ui-core` and `pilotswarm/ui-react`.
|
|
29
32
|
|
|
30
33
|
Common docs:
|
|
31
34
|
|
package/tui/src/agents-cli.js
CHANGED
|
@@ -26,19 +26,17 @@ import * as fs from "node:fs";
|
|
|
26
26
|
import * as os from "node:os";
|
|
27
27
|
import * as path from "node:path";
|
|
28
28
|
import {
|
|
29
|
-
PgSessionCatalog,
|
|
30
29
|
PilotSwarmManagementClient,
|
|
31
30
|
createSessionBlobStore,
|
|
32
31
|
FilesystemArtifactStore,
|
|
33
32
|
validateAgentPackageDir,
|
|
34
33
|
stageAgentPackageDir,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
readAgentPackageTarGz,
|
|
38
|
-
fetchAgentPackageTarGz,
|
|
34
|
+
listBundledAgentNames,
|
|
35
|
+
loadAgentFiles,
|
|
39
36
|
AgentPackageValidationError,
|
|
40
37
|
} from "pilotswarm-sdk";
|
|
41
38
|
import { bootstrapApiAuth } from "./auth/cli.js";
|
|
39
|
+
import { getPluginDirsFromEnv } from "./plugin-config.js";
|
|
42
40
|
|
|
43
41
|
/** The server's inline-upload envelope (node-sdk-transport uploadAgentPackage). */
|
|
44
42
|
const UPLOAD_MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -60,6 +58,7 @@ function parseArgs(argv) {
|
|
|
60
58
|
else if (arg === "--schema") flags.schema = argv[++i];
|
|
61
59
|
else if (arg === "--api-url") flags.apiUrl = argv[++i];
|
|
62
60
|
else if (arg === "--semver") flags.semver = argv[++i];
|
|
61
|
+
else if (arg === "--output" || arg === "-o") flags.output = argv[++i];
|
|
63
62
|
else if (arg === "--help" || arg === "-h") flags.help = true;
|
|
64
63
|
else positional.push(arg);
|
|
65
64
|
}
|
|
@@ -78,6 +77,7 @@ Usage:
|
|
|
78
77
|
pilotswarm agents enable <name> | disable <name>
|
|
79
78
|
pilotswarm agents tree <name> [--semver <v>] [--json]
|
|
80
79
|
pilotswarm agents cat <name> <file> [--semver <v>]
|
|
80
|
+
pilotswarm agents download <name> [--semver <v>] [--output <file>]
|
|
81
81
|
pilotswarm agents rm <name> --yes
|
|
82
82
|
|
|
83
83
|
Connection (web API — the default):
|
|
@@ -90,7 +90,10 @@ Connection (direct store — break-glass; no authn/authz):
|
|
|
90
90
|
|
|
91
91
|
Scope:
|
|
92
92
|
--user (default) only you see the package's agents
|
|
93
|
-
|
|
93
|
+
--shared every user can create sessions from them
|
|
94
|
+
|
|
95
|
+
For show/pin/promote/demote/enable/disable/tree/cat/download/rm, --user or
|
|
96
|
+
--shared selects which same-named package copy to target.`;
|
|
94
97
|
|
|
95
98
|
/**
|
|
96
99
|
* Web unless direct is explicitly asked for. `--store` always wins; otherwise
|
|
@@ -116,18 +119,20 @@ async function makeWebContext({ apiUrl }) {
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
async function makeDirectContext({ store }, flags) {
|
|
119
|
-
const
|
|
122
|
+
const sessionStateDir = process.env.SESSION_STATE_DIR
|
|
123
|
+
|| path.join(os.homedir(), ".copilot", "session-state");
|
|
124
|
+
const artifactStore = createSessionBlobStore(process.env, { sessionStateDir })
|
|
125
|
+
?? new FilesystemArtifactStore(path.join(path.dirname(sessionStateDir), "artifacts"));
|
|
126
|
+
const client = new PilotSwarmManagementClient({
|
|
127
|
+
store,
|
|
128
|
+
cmsSchema: flags.schema || process.env.PILOTSWARM_CMS_SCHEMA || undefined,
|
|
129
|
+
artifactStore,
|
|
130
|
+
});
|
|
120
131
|
try {
|
|
121
|
-
await
|
|
122
|
-
|
|
123
|
-
|| path.join(os.homedir(), ".copilot", "session-state");
|
|
124
|
-
const artifactStore = createSessionBlobStore(process.env, { sessionStateDir })
|
|
125
|
-
?? new FilesystemArtifactStore(path.join(path.dirname(sessionStateDir), "artifacts"));
|
|
126
|
-
return { mode: "direct", catalog, artifactStore, close: () => catalog.close() };
|
|
132
|
+
await client.start();
|
|
133
|
+
return { mode: "direct", client, close: () => client.stop() };
|
|
127
134
|
} catch (error) {
|
|
128
|
-
|
|
129
|
-
// instead of exiting non-zero.
|
|
130
|
-
await catalog.close().catch(() => {});
|
|
135
|
+
await client.stop().catch(() => {});
|
|
131
136
|
throw error;
|
|
132
137
|
}
|
|
133
138
|
}
|
|
@@ -221,6 +226,28 @@ function asDay(value) {
|
|
|
221
226
|
return Number.isNaN(date.getTime()) ? "" : date.toISOString().slice(0, 10);
|
|
222
227
|
}
|
|
223
228
|
|
|
229
|
+
export function reservedAgentNamesForCli() {
|
|
230
|
+
const names = new Set(listBundledAgentNames());
|
|
231
|
+
for (const pluginDir of getPluginDirsFromEnv()) {
|
|
232
|
+
for (const agent of loadAgentFiles(pluginDir)) {
|
|
233
|
+
if (agent?.name) names.add(agent.name);
|
|
234
|
+
if (agent?.id) names.add(agent.id);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return [...names];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function packageFileForCli(file) {
|
|
241
|
+
if (file?.encoding === "base64" || file?.binary === true) {
|
|
242
|
+
return { binary: true, size: file?.size ?? 0, text: "" };
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
binary: false,
|
|
246
|
+
size: file?.size ?? 0,
|
|
247
|
+
text: typeof file === "string" ? file : (file?.content ?? file?.text ?? ""),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
224
251
|
export async function runAgentsCommand(argv) {
|
|
225
252
|
const { flags, positional } = parseArgs(argv);
|
|
226
253
|
const [command, ...rest] = positional;
|
|
@@ -257,6 +284,7 @@ export async function runAgentsCommand(argv) {
|
|
|
257
284
|
const actor = null; // direct store mode = operator = admin
|
|
258
285
|
const isAdmin = true;
|
|
259
286
|
const createdBy = `${os.userInfo().username}@cli`;
|
|
287
|
+
const selector = flags.scope ? { scope: flags.scope } : null;
|
|
260
288
|
try {
|
|
261
289
|
switch (command) {
|
|
262
290
|
case "push": {
|
|
@@ -267,18 +295,16 @@ export async function runAgentsCommand(argv) {
|
|
|
267
295
|
let outcome;
|
|
268
296
|
try {
|
|
269
297
|
if (web) {
|
|
270
|
-
outcome = await ctx.client.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
});
|
|
298
|
+
outcome = await ctx.client.uploadAgentPackage(
|
|
299
|
+
await buildUploadPayload(resolvedDir), scope, actor, isAdmin,
|
|
300
|
+
);
|
|
274
301
|
} else {
|
|
275
|
-
outcome = await
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
});
|
|
302
|
+
outcome = await ctx.client.publishAgentPackageDirectory(
|
|
303
|
+
resolvedDir, scope, actor, isAdmin, {
|
|
304
|
+
createdBy,
|
|
305
|
+
reservedAgentNames: reservedAgentNamesForCli(),
|
|
306
|
+
},
|
|
307
|
+
);
|
|
282
308
|
}
|
|
283
309
|
} catch (error) {
|
|
284
310
|
if (error instanceof AgentPackageValidationError) {
|
|
@@ -299,9 +325,7 @@ export async function runAgentsCommand(argv) {
|
|
|
299
325
|
return 0;
|
|
300
326
|
}
|
|
301
327
|
case "list": {
|
|
302
|
-
const packages =
|
|
303
|
-
? await ctx.client.ops.listAgentPackages()
|
|
304
|
-
: await ctx.catalog.listAgentPackages(actor, isAdmin);
|
|
328
|
+
const packages = await ctx.client.listAgentPackages(actor, isAdmin);
|
|
305
329
|
if (flags.json) { console.log(JSON.stringify(packages, null, 2)); return 0; }
|
|
306
330
|
if (packages.length === 0) { console.log("no agent packages registered"); return 0; }
|
|
307
331
|
for (const pkg of packages) console.log(formatPackageLine(pkg));
|
|
@@ -310,9 +334,7 @@ export async function runAgentsCommand(argv) {
|
|
|
310
334
|
case "show": {
|
|
311
335
|
const name = rest[0];
|
|
312
336
|
if (!name) { console.error("usage: pilotswarm agents show <name>"); return 1; }
|
|
313
|
-
const detail =
|
|
314
|
-
? await ctx.client.ops.getAgentPackage({ name })
|
|
315
|
-
: await ctx.catalog.getAgentPackage(name, actor, isAdmin);
|
|
337
|
+
const detail = await ctx.client.getAgentPackage(name, actor, isAdmin, selector);
|
|
316
338
|
if (!detail) { console.error(`package "${name}" not found`); return 1; }
|
|
317
339
|
if (flags.json) { console.log(JSON.stringify(detail, null, 2)); return 0; }
|
|
318
340
|
console.log(`${detail.name} · ${detail.scope} · ${detail.enabled ? "enabled" : "disabled"}`);
|
|
@@ -331,8 +353,7 @@ export async function runAgentsCommand(argv) {
|
|
|
331
353
|
let semver = rest[1];
|
|
332
354
|
if (name?.includes("@")) [name, semver] = name.split("@");
|
|
333
355
|
if (!name || !semver) { console.error("usage: pilotswarm agents pin <name>@<semver>"); return 1; }
|
|
334
|
-
|
|
335
|
-
else await ctx.catalog.pinAgentPackageVersion(name, semver, actor, isAdmin);
|
|
356
|
+
await ctx.client.pinAgentPackageVersion(name, semver, actor, isAdmin, selector);
|
|
336
357
|
console.log(`✓ ${name} active version pinned to ${semver} — fleet converges on the next epoch poll`);
|
|
337
358
|
return 0;
|
|
338
359
|
}
|
|
@@ -341,8 +362,7 @@ export async function runAgentsCommand(argv) {
|
|
|
341
362
|
const name = rest[0];
|
|
342
363
|
if (!name) { console.error(`usage: pilotswarm agents ${command} <name>`); return 1; }
|
|
343
364
|
const scope = command === "promote" ? "shared" : "user";
|
|
344
|
-
|
|
345
|
-
else await ctx.catalog.setAgentPackageScope(name, scope, actor, isAdmin);
|
|
365
|
+
await ctx.client.setAgentPackageScope(name, scope, actor, isAdmin, selector);
|
|
346
366
|
console.log(`✓ ${name} is now ${scope}${scope === "shared" ? " — visible to every user" : " — visible only to its owner"} (running agents unaffected)`);
|
|
347
367
|
return 0;
|
|
348
368
|
}
|
|
@@ -351,17 +371,14 @@ export async function runAgentsCommand(argv) {
|
|
|
351
371
|
const name = rest[0];
|
|
352
372
|
if (!name) { console.error(`usage: pilotswarm agents ${command} <name>`); return 1; }
|
|
353
373
|
const enabled = command === "enable";
|
|
354
|
-
|
|
355
|
-
else await ctx.catalog.setAgentPackageEnabled(name, enabled, actor, isAdmin);
|
|
374
|
+
await ctx.client.setAgentPackageEnabled(name, enabled, actor, isAdmin, selector);
|
|
356
375
|
console.log(`✓ ${name} ${enabled ? "enabled" : "disabled"} fleet-wide — workers converge on the next epoch poll`);
|
|
357
376
|
return 0;
|
|
358
377
|
}
|
|
359
378
|
case "tree": {
|
|
360
379
|
const name = rest[0];
|
|
361
380
|
if (!name) { console.error("usage: pilotswarm agents tree <name> [--semver <v>]"); return 1; }
|
|
362
|
-
const tree =
|
|
363
|
-
? await ctx.client.ops.getAgentPackageTree({ name, semver: flags.semver })
|
|
364
|
-
: await directTree(ctx, name, flags.semver, actor, isAdmin);
|
|
381
|
+
const tree = await ctx.client.getAgentPackageTree(name, flags.semver ?? null, actor, isAdmin, selector);
|
|
365
382
|
if (flags.json) { console.log(JSON.stringify(tree, null, 2)); return 0; }
|
|
366
383
|
const entries = Array.isArray(tree) ? tree : (tree?.files ?? tree?.entries ?? []);
|
|
367
384
|
if (entries.length === 0) { console.log("(empty package)"); return 0; }
|
|
@@ -376,13 +393,20 @@ export async function runAgentsCommand(argv) {
|
|
|
376
393
|
const name = rest[0];
|
|
377
394
|
const filePath = rest[1];
|
|
378
395
|
if (!name || !filePath) { console.error("usage: pilotswarm agents cat <name> <file> [--semver <v>]"); return 1; }
|
|
379
|
-
const file =
|
|
380
|
-
? await ctx.client.ops.getAgentPackageFile({ name, semver: flags.semver, filePath })
|
|
381
|
-
: await directFile(ctx, name, flags.semver, filePath, actor, isAdmin);
|
|
396
|
+
const file = await ctx.client.getAgentPackageFile(name, flags.semver ?? null, filePath, actor, isAdmin, selector);
|
|
382
397
|
if (flags.json) { console.log(JSON.stringify(file, null, 2)); return 0; }
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
process.stdout.write(text.endsWith("\n") ? text : `${text}\n`);
|
|
398
|
+
const formatted = packageFileForCli(file);
|
|
399
|
+
if (formatted.binary) { console.error(`${filePath} is binary (${formatted.size || "?"} bytes)`); return 1; }
|
|
400
|
+
process.stdout.write(formatted.text.endsWith("\n") ? formatted.text : `${formatted.text}\n`);
|
|
401
|
+
return 0;
|
|
402
|
+
}
|
|
403
|
+
case "download": {
|
|
404
|
+
const name = rest[0];
|
|
405
|
+
if (!name) { console.error("usage: pilotswarm agents download <name> [--semver <v>] [--output <file>]"); return 1; }
|
|
406
|
+
const pkg = await ctx.client.downloadAgentPackage(name, flags.semver ?? null, actor, isAdmin, selector);
|
|
407
|
+
const output = path.resolve(flags.output || pkg.filename || `${name}.tgz`);
|
|
408
|
+
fs.writeFileSync(output, Buffer.from(pkg.body));
|
|
409
|
+
console.log(`✓ ${name}@${pkg.semver} downloaded to ${output} (sha ${pkg.sha256.slice(0, 12)})`);
|
|
386
410
|
return 0;
|
|
387
411
|
}
|
|
388
412
|
case "rm": {
|
|
@@ -392,8 +416,7 @@ export async function runAgentsCommand(argv) {
|
|
|
392
416
|
console.error(`refusing to delete "${name}" without --yes (removes every version and its artifacts; live sessions using its agents will fail resolution on their next turn)`);
|
|
393
417
|
return 1;
|
|
394
418
|
}
|
|
395
|
-
|
|
396
|
-
else await deleteAgentPackageEverywhere(ctx, name, actor, isAdmin);
|
|
419
|
+
await ctx.client.deleteAgentPackage(name, actor, isAdmin, selector);
|
|
397
420
|
console.log(`✓ ${name} deleted (registry rows and artifacts)`);
|
|
398
421
|
return 0;
|
|
399
422
|
}
|
|
@@ -407,36 +430,15 @@ export async function runAgentsCommand(argv) {
|
|
|
407
430
|
}
|
|
408
431
|
}
|
|
409
432
|
|
|
410
|
-
/** Direct-mode tree/cat read the tarball the same way the portal ops do. */
|
|
411
|
-
async function loadDirectPackageEntries(ctx, name, semver, actor, isAdmin) {
|
|
412
|
-
const detail = await ctx.catalog.getAgentPackage(name, actor, isAdmin);
|
|
413
|
-
if (!detail) throw Object.assign(new Error(`package "${name}" not found`), { code: "NOT_FOUND" });
|
|
414
|
-
const version = semver
|
|
415
|
-
? detail.versions.find((v) => v.semver === semver)
|
|
416
|
-
: detail.versions.find((v) => v.versionId === detail.activeVersionId) ?? detail.versions[0];
|
|
417
|
-
if (!version) {
|
|
418
|
-
throw Object.assign(new Error(`package "${name}" has no ${semver ? `version ${semver}` : "versions"}`), { code: "NOT_FOUND" });
|
|
419
|
-
}
|
|
420
|
-
const targz = await fetchAgentPackageTarGz(ctx.artifactStore, version.artifactFilename, version.sha256);
|
|
421
|
-
return readAgentPackageTarGz(targz);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// readAgentPackageTarGz yields { name, body } — NOT { path, body }. Reading
|
|
425
|
-
// `entry.path` silently produced undefined for every entry, so `tree` printed
|
|
426
|
-
// a column of "undefined" and `cat` could never match a file.
|
|
427
433
|
export async function directTree(ctx, name, semver, actor, isAdmin) {
|
|
428
|
-
const
|
|
429
|
-
return
|
|
434
|
+
const tree = await ctx.client.getAgentPackageTree(name, semver ?? null, actor, isAdmin);
|
|
435
|
+
return tree?.files ?? tree ?? [];
|
|
430
436
|
}
|
|
431
437
|
|
|
432
438
|
export async function directFile(ctx, name, semver, filePath, actor, isAdmin) {
|
|
433
|
-
const
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (entry.body.subarray(0, 4096).includes(0)) {
|
|
439
|
-
return { binary: true, size: entry.body.length };
|
|
440
|
-
}
|
|
441
|
-
return { content: entry.body.toString("utf8"), size: entry.body.length };
|
|
439
|
+
const file = await ctx.client.getAgentPackageFile(name, semver ?? null, filePath, actor, isAdmin);
|
|
440
|
+
const formatted = packageFileForCli(file);
|
|
441
|
+
return formatted.binary
|
|
442
|
+
? { binary: true, size: formatted.size }
|
|
443
|
+
: { content: formatted.text, size: formatted.size };
|
|
442
444
|
}
|
package/tui/src/app.js
CHANGED
|
@@ -291,15 +291,39 @@ export function PilotSwarmTuiApp({ controller, platform, onRequestExit }) {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
// ── Admin Console keybindings ─────────────────────────
|
|
294
|
-
// The Admin Console replaces the workspace, so its input
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
//
|
|
298
|
-
// controller mutators, and only Esc / Enter exit composition.
|
|
294
|
+
// The Admin Console replaces the workspace, so its input handling
|
|
295
|
+
// runs before the modal/normal path. Provider creation is a shared
|
|
296
|
+
// two-step name/credential wizard; the credential field is masked
|
|
297
|
+
// and ui-core clears it before awaiting the create call.
|
|
299
298
|
const adminState = controller.getState().admin;
|
|
300
299
|
const adminVisible = Boolean(adminState?.visible);
|
|
300
|
+
const adminProviderCreating = Boolean(adminState?.modelProviders?.create?.editing);
|
|
301
301
|
const adminEditing = Boolean(adminState?.ghcpKey?.editing);
|
|
302
302
|
const adminSaving = Boolean(adminState?.ghcpKey?.saving);
|
|
303
|
+
if (adminProviderCreating) {
|
|
304
|
+
const create = adminState.modelProviders.create;
|
|
305
|
+
if (key.escape) {
|
|
306
|
+
controller.cancelAdminProviderCreate();
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
if (create.saving) return;
|
|
310
|
+
if (key.tab && create.stage === "name") {
|
|
311
|
+
controller.cycleAdminProviderCreateType();
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (key.return) {
|
|
315
|
+
if (create.stage === "credential") controller.saveAdminProviderCreate().catch(() => {});
|
|
316
|
+
else controller.advanceAdminProviderCreate();
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (key.leftArrow) { controller.moveAdminProviderCreateCursor(-1); return; }
|
|
320
|
+
if (key.rightArrow) { controller.moveAdminProviderCreateCursor(1); return; }
|
|
321
|
+
if (key.home) { controller.moveAdminProviderCreateCursorToBoundary("start"); return; }
|
|
322
|
+
if (key.end) { controller.moveAdminProviderCreateCursorToBoundary("end"); return; }
|
|
323
|
+
if (key.backspace || key.delete) { controller.deleteAdminProviderCreateChar(); return; }
|
|
324
|
+
if (!key.ctrl && !key.meta && input) controller.insertAdminProviderCreateText(input);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
303
327
|
if (adminEditing) {
|
|
304
328
|
// Block all input while saving so we don't enqueue mutations
|
|
305
329
|
// against a stale draft. Esc still cancels in case the
|
|
@@ -325,18 +349,37 @@ export function PilotSwarmTuiApp({ controller, platform, onRequestExit }) {
|
|
|
325
349
|
return;
|
|
326
350
|
}
|
|
327
351
|
if (adminVisible) {
|
|
328
|
-
const adminSection = ["packages", "workers"].includes(adminState?.section)
|
|
352
|
+
const adminSection = ["providers", "packages", "workers"].includes(adminState?.section)
|
|
353
|
+
? adminState.section
|
|
354
|
+
: "providers";
|
|
355
|
+
if (modal?.type === "confirm") {
|
|
356
|
+
if (key.escape || input === "n") {
|
|
357
|
+
controller.handleCommand(UI_COMMANDS.CLOSE_MODAL).catch(() => {});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (key.return || input === "y") {
|
|
361
|
+
controller.handleCommand(UI_COMMANDS.MODAL_CONFIRM).catch(() => {});
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
329
366
|
if (key.escape) {
|
|
330
367
|
controller.handleCommand(UI_COMMANDS.CLOSE_ADMIN_CONSOLE).catch(() => {});
|
|
331
368
|
return;
|
|
332
369
|
}
|
|
333
|
-
// Settings-tree section toggles (
|
|
370
|
+
// Settings-tree section toggles (Model Providers ⟷ Agents ⟷ Workers).
|
|
334
371
|
if (plainShortcut && input === "a" && adminSection !== "packages") {
|
|
335
372
|
controller.handleCommand(UI_COMMANDS.ADMIN_SHOW_PACKAGES).catch(() => {});
|
|
336
373
|
return;
|
|
337
374
|
}
|
|
338
|
-
if (plainShortcut && input === "
|
|
339
|
-
controller.
|
|
375
|
+
if (plainShortcut && input === "m") {
|
|
376
|
+
controller.setAdminSection("providers");
|
|
377
|
+
controller.setAdminModelProviderPage("mine");
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (plainShortcut && input === "M" && adminState?.profile?.isAdmin) {
|
|
381
|
+
controller.setAdminSection("providers");
|
|
382
|
+
controller.setAdminModelProviderPage("shared");
|
|
340
383
|
return;
|
|
341
384
|
}
|
|
342
385
|
if (plainShortcut && input === "w" && adminSection !== "workers"
|
|
@@ -351,6 +394,73 @@ export function PilotSwarmTuiApp({ controller, platform, onRequestExit }) {
|
|
|
351
394
|
}
|
|
352
395
|
return;
|
|
353
396
|
}
|
|
397
|
+
if (adminSection === "providers") {
|
|
398
|
+
const selection = adminState.modelProviders?.selection || {};
|
|
399
|
+
const providerPage = adminState.modelProviders?.page === "shared" ? "shared" : "mine";
|
|
400
|
+
if (key.tab && providerPage === "shared") {
|
|
401
|
+
controller.setAdminModelProviderSelection({
|
|
402
|
+
focus: selection.focus === "agents" ? "providers" : "agents",
|
|
403
|
+
});
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (plainShortcut && (input === "j" || key.downArrow)) {
|
|
407
|
+
controller.stepAdminModelProviderSelection(1);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (plainShortcut && (input === "k" || key.upArrow)) {
|
|
411
|
+
controller.stepAdminModelProviderSelection(-1);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (plainShortcut && input === "e" && providerPage === "mine") {
|
|
415
|
+
controller.beginAdminCreateGithubProvider();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (plainShortcut && input === "E" && providerPage === "shared" && adminState?.profile?.isAdmin) {
|
|
419
|
+
controller.beginAdminCreateProvider({ shared: true });
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (plainShortcut && input === "d") {
|
|
423
|
+
controller.requestDeleteSelectedAdminProvider();
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (plainShortcut && input === "r") {
|
|
427
|
+
controller.refreshAdminModelProviders().catch(() => {});
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (plainShortcut && input === "u" && providerPage === "mine") {
|
|
431
|
+
controller.cycleAdminModelDefault("user").catch(() => {});
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
if (plainShortcut && input === "l" && providerPage === "shared" && adminState?.profile?.isAdmin) {
|
|
435
|
+
controller.cycleAdminModelDefault("cluster").catch(() => {});
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (plainShortcut && input === "s" && providerPage === "shared" && adminState?.profile?.isAdmin) {
|
|
439
|
+
controller.cycleAdminModelDefault("system").catch(() => {});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (plainShortcut && input === "C" && adminState?.profile?.isAdmin) {
|
|
443
|
+
controller.cycleAdminModelDefault("system", { restartDisposition: "complete" }).catch(() => {});
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (plainShortcut && input === "T" && adminState?.profile?.isAdmin) {
|
|
447
|
+
controller.cycleAdminModelDefault("system", { restartDisposition: "terminate" }).catch(() => {});
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (plainShortcut && input === "H" && adminState?.profile?.isAdmin) {
|
|
451
|
+
controller.cycleAdminModelDefault("system", { restartDisposition: "hard_delete" }).catch(() => {});
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (plainShortcut && input === "t" && providerPage === "mine" && adminState?.profile?.isAdmin) {
|
|
455
|
+
controller.toggleSelectedAdminProviderSystemUse().catch(() => {});
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (plainShortcut && input === "o" && providerPage === "shared" && adminState?.profile?.isAdmin) {
|
|
459
|
+
controller.cycleSelectedAdminSystemAgentOverride().catch(() => {});
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
354
464
|
if (adminSection === "packages") {
|
|
355
465
|
if (plainShortcut && (input === "j" || key.downArrow)) {
|
|
356
466
|
controller.handleCommand(UI_COMMANDS.ADMIN_PACKAGES_NEXT).catch(() => {});
|
|
@@ -366,14 +476,6 @@ export function PilotSwarmTuiApp({ controller, platform, onRequestExit }) {
|
|
|
366
476
|
}
|
|
367
477
|
return;
|
|
368
478
|
}
|
|
369
|
-
if (plainShortcut && input === "e") {
|
|
370
|
-
controller.handleCommand(UI_COMMANDS.ADMIN_BEGIN_EDIT_GHCP_KEY).catch(() => {});
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
if (plainShortcut && input === "c" && adminState?.profile?.githubCopilotKeySet) {
|
|
374
|
-
controller.handleCommand(UI_COMMANDS.ADMIN_CLEAR_GHCP_KEY).catch(() => {});
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
479
|
if (plainShortcut && input === "r") {
|
|
378
480
|
controller.handleCommand(UI_COMMANDS.ADMIN_REFRESH_PROFILE).catch(() => {});
|
|
379
481
|
return;
|