pilotswarm 0.5.38 → 0.5.39

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.
Files changed (77) hide show
  1. package/mcp/dist/src/tools/agent-packages.d.ts.map +1 -1
  2. package/mcp/dist/src/tools/agent-packages.js +34 -14
  3. package/mcp/dist/src/tools/agent-packages.js.map +1 -1
  4. package/package.json +2 -2
  5. package/tui/src/node-sdk-transport.js +113 -18
  6. package/ui/core/src/controller.js +99 -29
  7. package/ui/core/src/layout.js +10 -0
  8. package/ui/core/src/reducer.js +52 -5
  9. package/ui/core/src/selectors.js +49 -7
  10. package/ui/react/src/web-app.js +76 -19
  11. package/web/dist/assets/{abnfDiagram-VRR7QNED-DrJhXhSQ.js → abnfDiagram-VRR7QNED-Hsly1fgf.js} +1 -1
  12. package/web/dist/assets/{arc-BEaG9DWd.js → arc-DiQLL9vM.js} +1 -1
  13. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-D9fc1Imx.js → architectureDiagram-ZJ3FMSHR-B8ry8WNZ.js} +1 -1
  14. package/web/dist/assets/{blockDiagram-677ZJIJ3-rS5Eikvt.js → blockDiagram-677ZJIJ3-Z4PcukIo.js} +1 -1
  15. package/web/dist/assets/{c4Diagram-LMCZKHZV-HKLlX5cR.js → c4Diagram-LMCZKHZV-Cahkc0gc.js} +1 -1
  16. package/web/dist/assets/channel-BHLBPE50.js +1 -0
  17. package/web/dist/assets/{chunk-2Q5K7J3B-kq0TyLSB.js → chunk-2Q5K7J3B-CtZuWH4J.js} +1 -1
  18. package/web/dist/assets/{chunk-32BRIVSS-O-LMarT5.js → chunk-32BRIVSS-C0M390-k.js} +1 -1
  19. package/web/dist/assets/{chunk-5VM5RSS4-Di4h0CAu.js → chunk-5VM5RSS4-ClvX9u5j.js} +1 -1
  20. package/web/dist/assets/{chunk-EX3LRPZG-C8rgqUOt.js → chunk-EX3LRPZG-BVAet5KG.js} +1 -1
  21. package/web/dist/assets/{chunk-JWPE2WC7-BSH41q4T.js → chunk-JWPE2WC7-BccmZmrr.js} +1 -1
  22. package/web/dist/assets/{chunk-MOJQB5TN-BAFuQHAC.js → chunk-MOJQB5TN-BN5MKe94.js} +1 -1
  23. package/web/dist/assets/{chunk-RYQCIY6F-DAg6JOs7.js → chunk-RYQCIY6F-DfWw-ACP.js} +1 -1
  24. package/web/dist/assets/{chunk-V7JOEXUC-DbVrT8BG.js → chunk-V7JOEXUC-BgUEoLnN.js} +1 -1
  25. package/web/dist/assets/{chunk-VR4S4FIN-C6f5_Grp.js → chunk-VR4S4FIN-k1eKfFNA.js} +1 -1
  26. package/web/dist/assets/{chunk-XXDRQBXY-CqcCYpqA.js → chunk-XXDRQBXY-DPyV10yR.js} +1 -1
  27. package/web/dist/assets/classDiagram-OUVF2IWQ-rj9D2TSL.js +1 -0
  28. package/web/dist/assets/classDiagram-v2-EOCWNBFH-rj9D2TSL.js +1 -0
  29. package/web/dist/assets/{cose-bilkent-JH36ORCC-DJw04eFh.js → cose-bilkent-JH36ORCC-Bt_rpukK.js} +1 -1
  30. package/web/dist/assets/{cynefin-VYW2F7L2-CpjwdEIU.js → cynefin-VYW2F7L2-Z8eMzFMv.js} +1 -1
  31. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-RqEIWoT0.js → cynefinDiagram-TSTJHNR4-BJSNawFi.js} +1 -1
  32. package/web/dist/assets/{dagre-VKFMJZFB-C1eGQNK2.js → dagre-VKFMJZFB-D6dNl8jc.js} +1 -1
  33. package/web/dist/assets/{diagram-FQU43EPY-BODLQ7dz.js → diagram-FQU43EPY-Cy1nbGsU.js} +1 -1
  34. package/web/dist/assets/{diagram-G47NLZAW-DlhmukMC.js → diagram-G47NLZAW-CmrbuA_d.js} +1 -1
  35. package/web/dist/assets/{diagram-NH7WQ7WH-Ba_jZoCN.js → diagram-NH7WQ7WH-PoLNQE2j.js} +1 -1
  36. package/web/dist/assets/{diagram-OA4YK3LP-DnSiAJBG.js → diagram-OA4YK3LP-BZwNFcSV.js} +1 -1
  37. package/web/dist/assets/{diagram-WEI45ONY-B3KoQ7_W.js → diagram-WEI45ONY-pKw0b_fN.js} +1 -1
  38. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-ChnFc5gf.js → ebnfDiagram-CCIWWBDH-UNctuQCV.js} +1 -1
  39. package/web/dist/assets/{erDiagram-Q63AITRT-D2KkJXLZ.js → erDiagram-Q63AITRT-DxIETMif.js} +1 -1
  40. package/web/dist/assets/{flowDiagram-23GEKE2U-CmybZufj.js → flowDiagram-23GEKE2U-C06IdNKV.js} +1 -1
  41. package/web/dist/assets/{ganttDiagram-NO4QXBWP-BzPurW_v.js → ganttDiagram-NO4QXBWP-fU7aGyP1.js} +1 -1
  42. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-DAbXl4gO.js → gitGraphDiagram-IHSO6WYX-9UKkPJm6.js} +1 -1
  43. package/web/dist/assets/index-B8nGlHwb.js +24 -0
  44. package/web/dist/assets/{infoDiagram-FWYZ7A6U-C6qGjNA1.js → infoDiagram-FWYZ7A6U-C6F06SQJ.js} +1 -1
  45. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-D2d1tO-9.js → ishikawaDiagram-FXEZZL3T-CB-O9NfO.js} +1 -1
  46. package/web/dist/assets/{journeyDiagram-5HDEW3XC-fP13w1b7.js → journeyDiagram-5HDEW3XC-B-8MOf-H.js} +1 -1
  47. package/web/dist/assets/{kanban-definition-HUTT4EX6-BJfWAXZ0.js → kanban-definition-HUTT4EX6-DX0XA3hI.js} +1 -1
  48. package/web/dist/assets/{linear-CltApkHf.js → linear-D60PrjTW.js} +1 -1
  49. package/web/dist/assets/{mermaid.core-B1Dwetk3.js → mermaid.core-bonzwapf.js} +4 -4
  50. package/web/dist/assets/{mindmap-definition-LN4V7U3C-CdRUD7LF.js → mindmap-definition-LN4V7U3C-Y-6Dum33.js} +1 -1
  51. package/web/dist/assets/{papaparse.min-C1y3wBH1.js → papaparse.min-Cas1JfRG.js} +1 -1
  52. package/web/dist/assets/{pegDiagram-2B236MQR-CeQkqN6Q.js → pegDiagram-2B236MQR-_paO0yDw.js} +1 -1
  53. package/web/dist/assets/{pieDiagram-ENE6RG2P-Dqgc87jA.js → pieDiagram-ENE6RG2P-xT1_Gpn4.js} +1 -1
  54. package/web/dist/assets/pilotswarm-BT6tOknQ.js +96 -0
  55. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CD7f-w6m.js → quadrantDiagram-ABIIQ3AL-1usdLFOF.js} +1 -1
  56. package/web/dist/assets/{railroadDiagram-RFXS5EU6-CcsAijSC.js → railroadDiagram-RFXS5EU6-R3lwHOz9.js} +1 -1
  57. package/web/dist/assets/{requirementDiagram-TGXJPOKE-BkzF80pL.js → requirementDiagram-TGXJPOKE-BL8J1__Z.js} +1 -1
  58. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-D9XOFw7Y.js → sankeyDiagram-HTMAVEWB-Dz6--0pl.js} +1 -1
  59. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-BFfaS_Sz.js → sequenceDiagram-DBY2YBRQ-CG2Xpkct.js} +1 -1
  60. package/web/dist/assets/{sizeCapture-X5ZJPWSS-CDJV16tP.js → sizeCapture-X5ZJPWSS-BPbYfjxj.js} +1 -1
  61. package/web/dist/assets/{stateDiagram-2N3HPSRC-C0E-MPXO.js → stateDiagram-2N3HPSRC-46x_y_aA.js} +1 -1
  62. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-C2tnolSo.js +1 -0
  63. package/web/dist/assets/{swimlanes-5IMT3BWC-n5Vsv7n9.js → swimlanes-5IMT3BWC-SXdMo4zJ.js} +2 -2
  64. package/web/dist/assets/swimlanesDiagram-G3AALYLV-Dh6Sn__t.js +8 -0
  65. package/web/dist/assets/{timeline-definition-FHXFAJF6-DW2gV8-n.js → timeline-definition-FHXFAJF6-CGgT-b38.js} +1 -1
  66. package/web/dist/assets/{vennDiagram-L72KCM5P-D9dbDm08.js → vennDiagram-L72KCM5P-BGS3xBa_.js} +1 -1
  67. package/web/dist/assets/{wardleyDiagram-EHGQE667-CIcG7fiC.js → wardleyDiagram-EHGQE667-m2U3wEZJ.js} +1 -1
  68. package/web/dist/assets/{xychartDiagram-FW5EYKEG-elEIFsc9.js → xychartDiagram-FW5EYKEG-DI6tQysg.js} +1 -1
  69. package/web/dist/index.html +2 -2
  70. package/web/runtime.js +30 -7
  71. package/web/dist/assets/channel-DRy7FvyF.js +0 -1
  72. package/web/dist/assets/classDiagram-OUVF2IWQ-C35RhB8X.js +0 -1
  73. package/web/dist/assets/classDiagram-v2-EOCWNBFH-C35RhB8X.js +0 -1
  74. package/web/dist/assets/index-CRY94nFp.js +0 -24
  75. package/web/dist/assets/pilotswarm-DayYdi39.js +0 -96
  76. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-BMqXeMJu.js +0 -1
  77. package/web/dist/assets/swimlanesDiagram-G3AALYLV-CGl4gRnH.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"agent-packages.d.ts","sourceRoot":"","sources":["../../../src/tools/agent-packages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QAwJ9E"}
1
+ {"version":3,"file":"agent-packages.d.ts","sourceRoot":"","sources":["../../../src/tools/agent-packages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QAkL9E"}
@@ -32,14 +32,16 @@ export function registerAgentPackageTools(server, ctx) {
32
32
  name: z.string().min(1).describe("Package name"),
33
33
  include_tree: z.boolean().optional().describe("Also return the file tree of the active (or given) version"),
34
34
  semver: z.string().optional().describe("Version for the tree (default: active)"),
35
+ scope: z.enum(["shared", "user"]).optional().describe("Which same-named copy (scope shadowing): default walks your copy, then shared"),
35
36
  },
36
- }, withToolErrors(async ({ name, include_tree, semver }) => {
37
- const detail = await ops.getAgentPackage({ name });
37
+ }, withToolErrors(async ({ name, include_tree, semver, scope }) => {
38
+ const sel = scope ? { scope } : {};
39
+ const detail = await ops.getAgentPackage({ name, ...sel });
38
40
  if (!detail)
39
41
  return errorResult(`package "${name}" not found or not visible to you`, { name });
40
42
  const result = { package: detail };
41
43
  if (include_tree) {
42
- result.tree = await ops.getAgentPackageTree({ name, ...(semver ? { semver } : {}) });
44
+ result.tree = await ops.getAgentPackageTree({ name, ...(semver ? { semver } : {}), ...sel });
43
45
  }
44
46
  return jsonResult(result);
45
47
  }));
@@ -50,9 +52,10 @@ export function registerAgentPackageTools(server, ctx) {
50
52
  name: z.string().min(1).describe("Package name"),
51
53
  file_path: z.string().min(1).describe("File path inside the package (e.g. agents/triager.agent.md)"),
52
54
  semver: z.string().optional().describe("Version (default: active)"),
55
+ scope: z.enum(["shared", "user"]).optional().describe("Which same-named copy (scope shadowing)"),
53
56
  },
54
- }, withToolErrors(async ({ name, file_path, semver }) => {
55
- const file = await ops.getAgentPackageFile({ name, filePath: file_path, ...(semver ? { semver } : {}) });
57
+ }, withToolErrors(async ({ name, file_path, semver, scope }) => {
58
+ const file = await ops.getAgentPackageFile({ name, filePath: file_path, ...(semver ? { semver } : {}), ...(scope ? { scope } : {}) });
56
59
  return jsonResult(file);
57
60
  }));
58
61
  if (ctx.agentMgmt !== "full")
@@ -89,16 +92,31 @@ export function registerAgentPackageTools(server, ctx) {
89
92
  await ops.setAgentPackageScope({ name, scope });
90
93
  return jsonResult({ ok: true, name, scope });
91
94
  }));
95
+ server.registerTool("republish_agent_package_version", {
96
+ title: "Republish Agent Package Version Across Scopes",
97
+ description: "Publish an existing version's exact bytes into the same-named package in the other scope. "
98
+ + "THE update path for an already-published shared package: promote can only move a row to an "
99
+ + "unused name, this adds a version to the existing one. Creator or admin.",
100
+ inputSchema: {
101
+ name: z.string().min(1),
102
+ semver: z.string().optional().describe("Source version (default: the source copy's active version)"),
103
+ target_scope: z.enum(["shared", "user"]).describe("Destination scope; the source is the same-named package in the other scope"),
104
+ },
105
+ }, withToolErrors(async ({ name, semver, target_scope }) => {
106
+ const outcome = await ops.republishAgentPackageVersion({ name, ...(semver ? { semver } : {}), targetScope: target_scope });
107
+ return jsonResult(outcome);
108
+ }));
92
109
  server.registerTool("pin_agent_package_version", {
93
110
  title: "Pin Agent Package Version",
94
111
  description: "Point the package at a published version (rollback/roll-forward). The fleet converges on the next epoch poll. Creator or admin.",
95
112
  inputSchema: {
96
113
  name: z.string().min(1),
97
114
  semver: z.string().min(1),
115
+ scope: z.enum(["shared", "user"]).optional().describe("Which same-named copy to pin (scope shadowing): default walks your copy, then shared"),
98
116
  },
99
- }, withToolErrors(async ({ name, semver }) => {
100
- await ops.pinAgentPackageVersion({ name, semver });
101
- return jsonResult({ ok: true, name, active: semver });
117
+ }, withToolErrors(async ({ name, semver, scope }) => {
118
+ await ops.pinAgentPackageVersion({ name, semver, ...(scope ? { scope } : {}) });
119
+ return jsonResult({ ok: true, name, active: semver, ...(scope ? { scope } : {}) });
102
120
  }));
103
121
  server.registerTool("set_agent_package_enabled", {
104
122
  title: "Enable / Disable Agent Package",
@@ -106,10 +124,11 @@ export function registerAgentPackageTools(server, ctx) {
106
124
  inputSchema: {
107
125
  name: z.string().min(1),
108
126
  enabled: z.boolean(),
127
+ scope: z.enum(["shared", "user"]).optional().describe("Which same-named copy (scope shadowing): default walks your copy, then shared"),
109
128
  },
110
- }, withToolErrors(async ({ name, enabled }) => {
111
- await ops.setAgentPackageEnabled({ name, enabled });
112
- return jsonResult({ ok: true, name, enabled });
129
+ }, withToolErrors(async ({ name, enabled, scope }) => {
130
+ await ops.setAgentPackageEnabled({ name, enabled, ...(scope ? { scope } : {}) });
131
+ return jsonResult({ ok: true, name, enabled, ...(scope ? { scope } : {}) });
113
132
  }));
114
133
  server.registerTool("delete_agent_package", {
115
134
  title: "Delete Agent Package",
@@ -117,10 +136,11 @@ export function registerAgentPackageTools(server, ctx) {
117
136
  inputSchema: {
118
137
  name: z.string().min(1),
119
138
  confirm: z.literal(true).describe("Must be true — acknowledges the deletion is permanent"),
139
+ scope: z.enum(["shared", "user"]).optional().describe("Which same-named copy to delete (scope shadowing). Strongly recommended when both copies exist."),
120
140
  },
121
- }, withToolErrors(async ({ name }) => {
122
- await ops.deleteAgentPackage({ name });
123
- return jsonResult({ ok: true, deleted: name });
141
+ }, withToolErrors(async ({ name, scope }) => {
142
+ await ops.deleteAgentPackage({ name, ...(scope ? { scope } : {}) });
143
+ return jsonResult({ ok: true, deleted: name, ...(scope ? { scope } : {}) });
124
144
  }));
125
145
  }
126
146
  //# sourceMappingURL=agent-packages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-packages.js","sourceRoot":"","sources":["../../../src/tools/agent-packages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-packages.js","sourceRoot":"","sources":["../../../src/tools/agent-packages.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pilotswarm",
3
- "version": "0.5.38",
3
+ "version": "0.5.39",
4
4
  "description": "PilotSwarm application package: terminal UI, browser portal + Web API server, and MCP server — one install, three bins.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -81,7 +81,7 @@
81
81
  "ink": "^6.8.0",
82
82
  "jose": "^6.2.2",
83
83
  "mermaid": "^11.16.0",
84
- "pilotswarm-sdk": "0.5.38",
84
+ "pilotswarm-sdk": "0.5.39",
85
85
  "react": "^19.2.4",
86
86
  "react-dom": "^19.2.4",
87
87
  "ws": "^8.18.2"
@@ -19,6 +19,7 @@ import {
19
19
  ATTACHMENTS_MAX_TOTAL_BYTES,
20
20
  PgSessionCatalog,
21
21
  publishAgentPackageDir,
22
+ publishPackedAgentPackage,
22
23
  deleteAgentPackageEverywhere,
23
24
  fetchAgentPackageTarGz,
24
25
  readAgentPackageTarGz,
@@ -780,7 +781,13 @@ export class NodeSdkTransport {
780
781
  }
781
782
 
782
783
  _requirePrincipal(owner, isAdmin) {
783
- if (owner) return { provider: owner.provider, subject: owner.subject };
784
+ // Shape-checked, not just truthy: the portal runtime always passes a
785
+ // real principal here, but a caller that skips the owner/isAdmin args
786
+ // (direct-mode TUI) must fail closed with this clear error — never
787
+ // flow a garbage object into the registry as an identity.
788
+ if (owner && typeof owner.provider === "string" && typeof owner.subject === "string") {
789
+ return { provider: owner.provider, subject: owner.subject };
790
+ }
784
791
  if (isAdmin) return null; // anonymous deployments: admin-equivalent
785
792
  const err = new Error("agent-package operations require an authenticated principal");
786
793
  err.code = "FORBIDDEN";
@@ -821,10 +828,36 @@ export class NodeSdkTransport {
821
828
  return ctx.catalog.listAgentPackages(this._requirePrincipal(owner, isAdmin), Boolean(isAdmin));
822
829
  }
823
830
 
824
- async getAgentPackage(name, owner, isAdmin) {
831
+ /**
832
+ * Normalize wire selector params ({scope, ownerProvider, ownerSubject})
833
+ * into the catalog's AgentPackageSelector — which same-named copy an op
834
+ * means. Authorization is NOT decided here: the registry procs re-check
835
+ * ownership against the RESOLVED row, so a non-admin naming someone
836
+ * else's copy still gets FORBIDDEN/invisible from the database.
837
+ */
838
+ _packageSelector(selector, isAdmin = false) {
839
+ if (!selector || typeof selector !== "object") return null;
840
+ const scope = selector.scope === "shared" || selector.scope === "user" ? selector.scope : null;
841
+ const provider = typeof selector.ownerProvider === "string" && selector.ownerProvider.trim() ? selector.ownerProvider.trim() : null;
842
+ const subject = typeof selector.ownerSubject === "string" && selector.ownerSubject.trim() ? selector.ownerSubject.trim() : null;
843
+ // The owner override targets ANOTHER user's copy, which only an admin
844
+ // may do. For a non-admin it is dropped, NOT honored-then-denied:
845
+ // resolving a foreign package and letting the proc answer FORBIDDEN vs
846
+ // NOT_FOUND would be an existence oracle. Dropped, a non-admin's
847
+ // selector falls back to own-then-shared resolution, which can only
848
+ // ever reach their own or shared packages.
849
+ const owner = isAdmin && provider && subject ? { provider, subject } : null;
850
+ if (!scope && !owner) return null;
851
+ return {
852
+ ...(scope ? { scope } : {}),
853
+ ...(owner ? { owner } : {}),
854
+ };
855
+ }
856
+
857
+ async getAgentPackage(name, owner, isAdmin, selector = null) {
825
858
  const ctx = await this._agentPackagesContext();
826
859
  if (!ctx) return null;
827
- return ctx.catalog.getAgentPackage(name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin));
860
+ return ctx.catalog.getAgentPackage(name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), this._packageSelector(selector, Boolean(isAdmin)));
828
861
  }
829
862
 
830
863
 
@@ -843,38 +876,100 @@ export class NodeSdkTransport {
843
876
  return ctx.catalog.listWorkers();
844
877
  }
845
878
 
846
- async setAgentPackageScope(name, scope, owner, isAdmin) {
879
+ async setAgentPackageScope(name, scope, owner, isAdmin, selector = null) {
847
880
  const ctx = await this._agentPackagesContext();
848
881
  if (!ctx) throw new Error("agent packages are not available on this deployment");
849
- await this._mapAgentPackageErrors(() => ctx.catalog.setAgentPackageScope(name, scope === "shared" ? "shared" : "user",
850
- this._requirePrincipal(owner, isAdmin), Boolean(isAdmin)));
882
+ const targetScope = scope === "shared" ? "shared" : "user";
883
+ const ownerOverride = this._packageSelector(selector, Boolean(isAdmin))?.owner ?? null;
884
+ // The SOURCE copy is implied by the direction, but the two directions
885
+ // need different selectors — and passing an explicit scope selector
886
+ // DISABLES the SQL admin/NULL-owner fallback (it fires only when the
887
+ // selector scope is NULL), so name-only is used wherever it resolves
888
+ // correctly:
889
+ // demote (target user): must move the globally-unique SHARED copy,
890
+ // so select scope 'shared' explicitly — the shared row is unique,
891
+ // no owner fallback is needed to find it.
892
+ // promote (target shared): ordinary own-copy-then-shared resolution
893
+ // already lands on the caller's own USER copy, and keeping the
894
+ // selector NULL preserves the admin/NULL-owner fallback for
895
+ // packages minted without an owner. An admin acting on ANOTHER
896
+ // user's copy passes that owner explicitly.
897
+ let sourceSelector = null;
898
+ if (targetScope === "user") {
899
+ sourceSelector = { scope: "shared", ...(ownerOverride ? { owner: ownerOverride } : {}) };
900
+ } else if (ownerOverride) {
901
+ sourceSelector = { scope: "user", owner: ownerOverride };
902
+ }
903
+ await this._mapAgentPackageErrors(() => ctx.catalog.setAgentPackageScope(name, targetScope,
904
+ this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), sourceSelector));
851
905
  return { ok: true };
852
906
  }
853
907
 
854
- async setAgentPackageEnabled(name, enabled, owner, isAdmin) {
908
+ async setAgentPackageEnabled(name, enabled, owner, isAdmin, selector = null) {
855
909
  const ctx = await this._agentPackagesContext();
856
910
  if (!ctx) throw new Error("agent packages are not available on this deployment");
857
911
  await this._mapAgentPackageErrors(() => ctx.catalog.setAgentPackageEnabled(name, Boolean(enabled),
858
- this._requirePrincipal(owner, isAdmin), Boolean(isAdmin)));
912
+ this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), this._packageSelector(selector, Boolean(isAdmin))));
859
913
  return { ok: true };
860
914
  }
861
915
 
862
- async pinAgentPackageVersion(name, semver, owner, isAdmin) {
916
+ async pinAgentPackageVersion(name, semver, owner, isAdmin, selector = null) {
863
917
  const ctx = await this._agentPackagesContext();
864
918
  if (!ctx) throw new Error("agent packages are not available on this deployment");
865
919
  await this._mapAgentPackageErrors(() => ctx.catalog.pinAgentPackageVersion(name, String(semver || ""),
866
- this._requirePrincipal(owner, isAdmin), Boolean(isAdmin)));
920
+ this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), this._packageSelector(selector, Boolean(isAdmin))));
867
921
  return { ok: true };
868
922
  }
869
923
 
870
- async deleteAgentPackage(name, owner, isAdmin) {
924
+ async deleteAgentPackage(name, owner, isAdmin, selector = null) {
871
925
  const ctx = await this._agentPackagesContext();
872
926
  if (!ctx) throw new Error("agent packages are not available on this deployment");
873
- await this._mapAgentPackageErrors(() => deleteAgentPackageEverywhere(ctx, name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin)));
927
+ await this._mapAgentPackageErrors(() => deleteAgentPackageEverywhere(ctx, name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), this._packageSelector(selector, Boolean(isAdmin))));
874
928
  this._agentPkgTarCache?.clear?.();
875
929
  return { ok: true };
876
930
  }
877
931
 
932
+ /**
933
+ * Publish an existing version's exact bytes into the same-named package
934
+ * in the OTHER scope. This is the "update the shared package from my
935
+ * tested user copy" path the console's promote button cannot express —
936
+ * promote MOVES a row and refuses when the shared name already exists;
937
+ * this adds a version to it instead.
938
+ */
939
+ async republishAgentPackageVersion(name, semver, targetScope, owner, isAdmin) {
940
+ const ctx = await this._agentPackagesContext();
941
+ if (!ctx) throw new Error("agent packages are not available on this deployment");
942
+ const principal = this._requirePrincipal(owner, isAdmin);
943
+ const target = targetScope === "shared" ? "shared" : "user";
944
+ const sourceScope = target === "shared" ? "user" : "shared";
945
+ return await this._mapAgentPackageErrors(async () => {
946
+ const detail = await ctx.catalog.getAgentPackage(name, principal, Boolean(isAdmin), { scope: sourceScope });
947
+ if (!detail) {
948
+ const err = new Error(`AGENT_PACKAGE_NOT_FOUND: no ${sourceScope}-scope package named "${name}" to republish from`);
949
+ throw err;
950
+ }
951
+ const wanted = String(semver || "").trim();
952
+ const version = wanted
953
+ ? detail.versions.find((v) => v.semver === wanted)
954
+ : detail.versions.find((v) => v.versionId === detail.activeVersionId) ?? detail.versions[0];
955
+ if (!version) {
956
+ throw new Error(`AGENT_PACKAGE_VERSION_NOT_FOUND: ${name}@${wanted || "(active)"} is not a published ${sourceScope} version`);
957
+ }
958
+ const targz = await fetchAgentPackageTarGz(ctx.artifactStore, version.artifactFilename, version.sha256);
959
+ const outcome = await publishPackedAgentPackage(ctx, {
960
+ manifest: version.manifest,
961
+ targz,
962
+ sha256: version.sha256,
963
+ scope: target,
964
+ owner: principal,
965
+ createdBy: `${this._createdByLabel(owner)} (republish of ${sourceScope} ${name}@${version.semver})`,
966
+ isAdmin: Boolean(isAdmin),
967
+ });
968
+ const { manifest: _m, ...summary } = outcome;
969
+ return summary;
970
+ });
971
+ }
972
+
878
973
  /** Inline-files upload → the one publish pipeline. ≤ 2 MB decoded. */
879
974
  async uploadAgentPackage(files, scope, owner, isAdmin) {
880
975
  const ctx = await this._agentPackagesContext();
@@ -943,10 +1038,10 @@ export class NodeSdkTransport {
943
1038
 
944
1039
  // ── Agent packages: workspace viewer (tree + file preview) ──
945
1040
 
946
- async _agentPackageEntries(name, semver, owner, isAdmin) {
1041
+ async _agentPackageEntries(name, semver, owner, isAdmin, selector = null) {
947
1042
  const ctx = await this._agentPackagesContext();
948
1043
  if (!ctx) throw new Error("agent packages are not available on this deployment");
949
- const detail = await ctx.catalog.getAgentPackage(name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin));
1044
+ const detail = await ctx.catalog.getAgentPackage(name, this._requirePrincipal(owner, isAdmin), Boolean(isAdmin), this._packageSelector(selector, Boolean(isAdmin)));
950
1045
  if (!detail) throw Object.assign(new Error(`package "${name}" not found`), { code: "NOT_FOUND" });
951
1046
  const version = semver
952
1047
  ? detail.versions.find((v) => v.semver === semver)
@@ -975,8 +1070,8 @@ export class NodeSdkTransport {
975
1070
  return { entries, version };
976
1071
  }
977
1072
 
978
- async getAgentPackageTree(name, semver, owner, isAdmin) {
979
- const { entries, version } = await this._agentPackageEntries(name, semver, owner, isAdmin);
1073
+ async getAgentPackageTree(name, semver, owner, isAdmin, selector = null) {
1074
+ const { entries, version } = await this._agentPackageEntries(name, semver, owner, isAdmin, selector);
980
1075
  const dirs = new Set();
981
1076
  const files = [];
982
1077
  for (const entry of entries) {
@@ -994,8 +1089,8 @@ export class NodeSdkTransport {
994
1089
  };
995
1090
  }
996
1091
 
997
- async getAgentPackageFile(name, semver, filePath, owner, isAdmin) {
998
- const { entries, version } = await this._agentPackageEntries(name, semver, owner, isAdmin);
1092
+ async getAgentPackageFile(name, semver, filePath, owner, isAdmin, selector = null) {
1093
+ const { entries, version } = await this._agentPackageEntries(name, semver, owner, isAdmin, selector);
999
1094
  const rel = String(filePath || "");
1000
1095
  const entry = entries.find((candidate) => candidate.name === rel);
1001
1096
  if (!entry) throw Object.assign(new Error(`"${rel}" is not in ${name}@${version.semver}`), { code: "NOT_FOUND" });
@@ -51,6 +51,22 @@ import {
51
51
  import { findArtifactEntry } from "./state.js";
52
52
  import { getTheme, listThemes } from "./themes/index.js";
53
53
 
54
+ /**
55
+ * The copy selector for a package LIST row: which same-named copy it is.
56
+ * Scope shadowing means one name can be a shared package AND a user copy at
57
+ * once; the row's scope (+ owner, for admins looking at someone else's user
58
+ * copy) is what disambiguates every read and action on it.
59
+ */
60
+ export function packageRowSelector(row) {
61
+ if (!row) return null;
62
+ return {
63
+ ...(row.scope === "shared" || row.scope === "user" ? { scope: row.scope } : {}),
64
+ ...(row.scope === "user" && row.owner?.provider && row.owner?.subject
65
+ ? { owner: { provider: row.owner.provider, subject: row.owner.subject } }
66
+ : {}),
67
+ };
68
+ }
69
+
54
70
  const ORCHESTRATION_STATS_REFRESH_MS = 20_000;
55
71
  const SESSION_STATS_REFRESH_MS = 20_000;
56
72
  const FLEET_STATS_REFRESH_MS = 30_000;
@@ -3062,27 +3078,39 @@ export class PilotSwarmUiController {
3062
3078
  }
3063
3079
  }
3064
3080
 
3065
- /** Select a package: loads its detail and workspace tree. */
3066
- async selectAdminPackage(name) {
3067
- this.dispatch({ type: "admin/packages/select", name });
3081
+ /**
3082
+ * Select a package: loads its detail and workspace tree.
3083
+ *
3084
+ * `selector` = { scope, owner? } from the clicked ROW. One name can be
3085
+ * two packages at once (scope shadowing: a shared copy plus a user
3086
+ * copy), and without the selector every read here resolved "own copy
3087
+ * first" — both rows showed the same history, and actions could land on
3088
+ * the copy the user was not looking at.
3089
+ */
3090
+ async selectAdminPackage(name, selector = null) {
3091
+ this.dispatch({ type: "admin/packages/select", name, selector });
3068
3092
  if (!name) return;
3093
+ // Selection token minted by the reducer just now; every response from
3094
+ // this selection carries it so a slow response for another COPY of
3095
+ // the same name (scope shadowing) can never land on this one.
3096
+ const seq = this.getState().admin?.packages?.selectionSeq ?? 0;
3069
3097
  await Promise.all([
3070
3098
  (async () => {
3071
3099
  try {
3072
- const detail = await this.transport.getAgentPackage(name);
3100
+ const detail = await this.transport.getAgentPackage(name, selector);
3073
3101
  if (!detail) throw new Error(`package "${name}" not found`);
3074
- this.dispatch({ type: "admin/packages/detail/loaded", name, detail });
3102
+ this.dispatch({ type: "admin/packages/detail/loaded", name, seq, detail });
3075
3103
  } catch (error) {
3076
- this.dispatch({ type: "admin/packages/detail/loadFailed", name, error: error?.message || String(error) });
3104
+ this.dispatch({ type: "admin/packages/detail/loadFailed", name, seq, error: error?.message || String(error) });
3077
3105
  }
3078
3106
  })(),
3079
3107
  (async () => {
3080
3108
  try {
3081
- const tree = await this.transport.getAgentPackageTree(name);
3109
+ const tree = await this.transport.getAgentPackageTree(name, null, selector);
3082
3110
  // A slower tree for a PREVIOUS selection must not clobber
3083
3111
  // the current package's workspace (stale-response race).
3084
- if (this.getState().admin?.packages?.selectedName !== name) return;
3085
- this.dispatch({ type: "admin/packages/tree/loaded", name, tree });
3112
+ if ((this.getState().admin?.packages?.selectionSeq ?? 0) !== seq) return;
3113
+ this.dispatch({ type: "admin/packages/tree/loaded", name, seq, tree });
3086
3114
  // The package's own CHANGELOG, when it ships one. Loaded
3087
3115
  // alongside the tree rather than on demand because it is
3088
3116
  // the first thing a reviewer wants: what changed, why, and
@@ -3091,11 +3119,12 @@ export class PilotSwarmUiController {
3091
3119
  if (hasChangelog && typeof this.transport.getAgentPackageFile === "function") {
3092
3120
  void (async () => {
3093
3121
  try {
3094
- const file = await this.transport.getAgentPackageFile(name, null, "CHANGELOG.md");
3095
- if (this.getState().admin?.packages?.selectedName !== name) return;
3122
+ const file = await this.transport.getAgentPackageFile(name, null, "CHANGELOG.md", selector);
3123
+ if ((this.getState().admin?.packages?.selectionSeq ?? 0) !== seq) return;
3096
3124
  this.dispatch({
3097
3125
  type: "admin/packages/changelog/loaded",
3098
3126
  name,
3127
+ seq,
3099
3128
  content: typeof file === "string" ? file : (file?.content ?? file?.text ?? ""),
3100
3129
  });
3101
3130
  } catch {
@@ -3104,13 +3133,13 @@ export class PilotSwarmUiController {
3104
3133
  }
3105
3134
  })();
3106
3135
  } else {
3107
- this.dispatch({ type: "admin/packages/changelog/loaded", name, content: null });
3136
+ this.dispatch({ type: "admin/packages/changelog/loaded", name, seq, content: null });
3108
3137
  }
3109
3138
  // Default preview: plugin.json (always present in a valid package).
3110
3139
  const first = tree?.files?.find((f) => f.path === "plugin.json") ?? tree?.files?.[0];
3111
3140
  if (first) void this.selectAdminPackageFile(first.path);
3112
3141
  } catch (error) {
3113
- this.dispatch({ type: "admin/packages/tree/loadFailed", name, error: error?.message || String(error) });
3142
+ this.dispatch({ type: "admin/packages/tree/loadFailed", name, seq, error: error?.message || String(error) });
3114
3143
  }
3115
3144
  })(),
3116
3145
  ]);
@@ -3121,14 +3150,22 @@ export class PilotSwarmUiController {
3121
3150
  const pkgs = this.getState().admin?.packages;
3122
3151
  if (!pkgs?.list?.length) return;
3123
3152
  // Same shared→user projection the settings tree renders, so j/k walks
3124
- // the list in VISUAL order regardless of transport ordering.
3125
- const names = [
3153
+ // the list in VISUAL order regardless of transport ordering. Rows are
3154
+ // COPIES, not names: a shadowed name appears once per scope.
3155
+ const rows = [
3126
3156
  ...pkgs.list.filter((p) => p.scope === "shared"),
3127
3157
  ...pkgs.list.filter((p) => p.scope !== "shared"),
3128
- ].map((p) => p.name);
3129
- const index = names.indexOf(pkgs.selectedName);
3130
- const next = names[Math.min(names.length - 1, Math.max(0, (index < 0 ? (delta > 0 ? -1 : 0) : index) + delta))];
3131
- if (next && next !== pkgs.selectedName) await this.selectAdminPackage(next);
3158
+ ];
3159
+ const keyOf = (row) => `${row.name}\u0001${row.scope ?? ""}\u0001${row.owner?.subject ?? ""}`;
3160
+ const selectedKey = pkgs.selectedName
3161
+ ? `${pkgs.selectedName}\u0001${pkgs.selectedSelector?.scope ?? ""}\u0001${pkgs.selectedSelector?.owner?.subject ?? ""}`
3162
+ : null;
3163
+ let index = rows.findIndex((row) => keyOf(row) === selectedKey);
3164
+ if (index < 0) index = rows.findIndex((row) => row.name === pkgs.selectedName);
3165
+ const next = rows[Math.min(rows.length - 1, Math.max(0, (index < 0 ? (delta > 0 ? -1 : 0) : index) + delta))];
3166
+ if (next && (next.name !== pkgs.selectedName || keyOf(next) !== selectedKey)) {
3167
+ await this.selectAdminPackage(next.name, packageRowSelector(next));
3168
+ }
3132
3169
  }
3133
3170
 
3134
3171
  toggleAdminPackageDir(dir) {
@@ -3139,12 +3176,17 @@ export class PilotSwarmUiController {
3139
3176
  const pkgs = this.getState().admin?.packages;
3140
3177
  const name = pkgs?.selectedName;
3141
3178
  if (!name || !filePath) return;
3179
+ // Tag the preview with the current selection token so a slow file for
3180
+ // one copy can't render under another copy of the same name (their
3181
+ // file paths are identical — both ship plugin.json).
3182
+ const seq = pkgs?.selectionSeq ?? 0;
3183
+ const selector = pkgs?.selectedSelector ?? null;
3142
3184
  this.dispatch({ type: "admin/packages/file/loading", path: filePath });
3143
3185
  try {
3144
- const file = await this.transport.getAgentPackageFile(name, null, filePath);
3145
- this.dispatch({ type: "admin/packages/file/loaded", file });
3186
+ const file = await this.transport.getAgentPackageFile(name, null, filePath, selector);
3187
+ this.dispatch({ type: "admin/packages/file/loaded", seq, file });
3146
3188
  } catch (error) {
3147
- this.dispatch({ type: "admin/packages/file/loadFailed", path: filePath, error: error?.message || String(error) });
3189
+ this.dispatch({ type: "admin/packages/file/loadFailed", seq, path: filePath, error: error?.message || String(error) });
3148
3190
  }
3149
3191
  }
3150
3192
 
@@ -3157,32 +3199,53 @@ export class PilotSwarmUiController {
3157
3199
  async runAdminPackageAction(kind, arg = null) {
3158
3200
  const pkgs = this.getState().admin?.packages;
3159
3201
  const name = pkgs?.selectedName;
3202
+ const selector = pkgs?.selectedSelector ?? null;
3160
3203
  if (!name) return;
3161
3204
  this.dispatch({ type: "admin/packages/action/pending", action: kind });
3162
3205
  try {
3163
3206
  switch (kind) {
3164
3207
  case "promote":
3165
- await this.transport.setAgentPackageScope(name, "shared");
3208
+ await this.transport.setAgentPackageScope(name, "shared", selector);
3166
3209
  break;
3167
3210
  case "demote":
3168
- await this.transport.setAgentPackageScope(name, "user");
3211
+ await this.transport.setAgentPackageScope(name, "user", selector);
3212
+ break;
3213
+ // Publish the selected copy's version (arg, default active)
3214
+ // into the same-named package in the OTHER scope. THE update
3215
+ // path when the shared name already exists — promote can only
3216
+ // move a row to an unused name.
3217
+ case "republish":
3218
+ await this.transport.republishAgentPackageVersion(
3219
+ name, arg, selector?.scope === "shared" ? "user" : "shared",
3220
+ );
3169
3221
  break;
3170
3222
  case "pin":
3171
- await this.transport.pinAgentPackageVersion(name, arg);
3223
+ await this.transport.pinAgentPackageVersion(name, arg, selector);
3172
3224
  break;
3173
3225
  case "enable":
3174
3226
  case "disable":
3175
- await this.transport.setAgentPackageEnabled(name, kind === "enable");
3227
+ await this.transport.setAgentPackageEnabled(name, kind === "enable", selector);
3176
3228
  break;
3177
3229
  case "delete":
3178
- await this.transport.deleteAgentPackage(name);
3230
+ await this.transport.deleteAgentPackage(name, selector);
3179
3231
  break;
3180
3232
  default:
3181
3233
  throw new Error(`unknown package action: ${kind}`);
3182
3234
  }
3183
3235
  this.dispatch({ type: "admin/packages/action/done" });
3184
3236
  await this.refreshAdminAgentPackages();
3185
- if (kind !== "delete") await this.selectAdminPackage(name);
3237
+ // Re-select the copy that still exists. promote/demote MOVE the row
3238
+ // to the other scope, so the pre-action selector now points at a
3239
+ // copy that is gone — re-selecting it would error the pane with
3240
+ // "package not found". Every other action leaves the copy in place.
3241
+ if (kind !== "delete") {
3242
+ const nextSelector = kind === "promote"
3243
+ ? { scope: "shared", ...(selector?.owner ? { owner: selector.owner } : {}) }
3244
+ : kind === "demote"
3245
+ ? { scope: "user", ...(selector?.owner ? { owner: selector.owner } : {}) }
3246
+ : selector;
3247
+ await this.selectAdminPackage(name, nextSelector);
3248
+ }
3186
3249
  } catch (error) {
3187
3250
  this.dispatch({ type: "admin/packages/action/failed", error: error?.message || String(error) });
3188
3251
  }
@@ -7225,7 +7288,14 @@ export class PilotSwarmUiController {
7225
7288
  }
7226
7289
 
7227
7290
  setFocus(focusRegion) {
7228
- this.dispatch({ type: "ui/focus", focusRegion: normalizeFocusRegion(focusRegion, this.getCurrentLayout()) });
7291
+ // Carry the raw request alongside the normalized region: on a phone a
7292
+ // workspace region (sessions/chat) normalizes to inspector, and the
7293
+ // mobile follow-focus effect must not read that as "open diagnostics".
7294
+ this.dispatch({
7295
+ type: "ui/focus",
7296
+ focusRegion: normalizeFocusRegion(focusRegion, this.getCurrentLayout()),
7297
+ requestedFocusRegion: focusRegion,
7298
+ });
7229
7299
  }
7230
7300
 
7231
7301
  focusNext() {
@@ -57,6 +57,16 @@ export function getMaxSessionPaneHeight(totalHeight, bodyHeight) {
57
57
  return Math.max(MIN_SESSION_PANE_HEIGHT, Math.min(maxByChatMinimum, maxByWindow));
58
58
  }
59
59
 
60
+ export function getDiagnosticsSplitAdjustBounds(columnHeight, dividerHeight) {
61
+ const height = Math.max(0, Number(columnHeight) || 0);
62
+ const divider = clamp(Math.max(0, Number(dividerHeight) || 0), 0, height);
63
+ const minAdjust = -(height / 2);
64
+ return {
65
+ minAdjust,
66
+ maxAdjust: Math.max(minAdjust, (height / 2) - divider),
67
+ };
68
+ }
69
+
60
70
  export function computeLegacyLayout(viewport, paneAdjust = 0, promptRows = 1, sessionPaneAdjust = 0, activityPaneAdjust = 0, fullscreenPane = null) {
61
71
  const safeViewport = normalizeViewport(viewport);
62
72
  const totalWidth = safeViewport.width;