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.
- package/mcp/dist/src/tools/agent-packages.d.ts.map +1 -1
- package/mcp/dist/src/tools/agent-packages.js +34 -14
- package/mcp/dist/src/tools/agent-packages.js.map +1 -1
- package/package.json +2 -2
- package/tui/src/node-sdk-transport.js +113 -18
- package/ui/core/src/controller.js +99 -29
- package/ui/core/src/layout.js +10 -0
- package/ui/core/src/reducer.js +52 -5
- package/ui/core/src/selectors.js +49 -7
- package/ui/react/src/web-app.js +76 -19
- package/web/dist/assets/{abnfDiagram-VRR7QNED-DrJhXhSQ.js → abnfDiagram-VRR7QNED-Hsly1fgf.js} +1 -1
- package/web/dist/assets/{arc-BEaG9DWd.js → arc-DiQLL9vM.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-D9fc1Imx.js → architectureDiagram-ZJ3FMSHR-B8ry8WNZ.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-rS5Eikvt.js → blockDiagram-677ZJIJ3-Z4PcukIo.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-HKLlX5cR.js → c4Diagram-LMCZKHZV-Cahkc0gc.js} +1 -1
- package/web/dist/assets/channel-BHLBPE50.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-kq0TyLSB.js → chunk-2Q5K7J3B-CtZuWH4J.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-O-LMarT5.js → chunk-32BRIVSS-C0M390-k.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-Di4h0CAu.js → chunk-5VM5RSS4-ClvX9u5j.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-C8rgqUOt.js → chunk-EX3LRPZG-BVAet5KG.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-BSH41q4T.js → chunk-JWPE2WC7-BccmZmrr.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-BAFuQHAC.js → chunk-MOJQB5TN-BN5MKe94.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-DAg6JOs7.js → chunk-RYQCIY6F-DfWw-ACP.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-DbVrT8BG.js → chunk-V7JOEXUC-BgUEoLnN.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-C6f5_Grp.js → chunk-VR4S4FIN-k1eKfFNA.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-CqcCYpqA.js → chunk-XXDRQBXY-DPyV10yR.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-rj9D2TSL.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-rj9D2TSL.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-DJw04eFh.js → cose-bilkent-JH36ORCC-Bt_rpukK.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-CpjwdEIU.js → cynefin-VYW2F7L2-Z8eMzFMv.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-RqEIWoT0.js → cynefinDiagram-TSTJHNR4-BJSNawFi.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-C1eGQNK2.js → dagre-VKFMJZFB-D6dNl8jc.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-BODLQ7dz.js → diagram-FQU43EPY-Cy1nbGsU.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-DlhmukMC.js → diagram-G47NLZAW-CmrbuA_d.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-Ba_jZoCN.js → diagram-NH7WQ7WH-PoLNQE2j.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-DnSiAJBG.js → diagram-OA4YK3LP-BZwNFcSV.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-B3KoQ7_W.js → diagram-WEI45ONY-pKw0b_fN.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-ChnFc5gf.js → ebnfDiagram-CCIWWBDH-UNctuQCV.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-D2KkJXLZ.js → erDiagram-Q63AITRT-DxIETMif.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-CmybZufj.js → flowDiagram-23GEKE2U-C06IdNKV.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-BzPurW_v.js → ganttDiagram-NO4QXBWP-fU7aGyP1.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-DAbXl4gO.js → gitGraphDiagram-IHSO6WYX-9UKkPJm6.js} +1 -1
- package/web/dist/assets/index-B8nGlHwb.js +24 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-C6qGjNA1.js → infoDiagram-FWYZ7A6U-C6F06SQJ.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-D2d1tO-9.js → ishikawaDiagram-FXEZZL3T-CB-O9NfO.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-fP13w1b7.js → journeyDiagram-5HDEW3XC-B-8MOf-H.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-BJfWAXZ0.js → kanban-definition-HUTT4EX6-DX0XA3hI.js} +1 -1
- package/web/dist/assets/{linear-CltApkHf.js → linear-D60PrjTW.js} +1 -1
- package/web/dist/assets/{mermaid.core-B1Dwetk3.js → mermaid.core-bonzwapf.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-CdRUD7LF.js → mindmap-definition-LN4V7U3C-Y-6Dum33.js} +1 -1
- package/web/dist/assets/{papaparse.min-C1y3wBH1.js → papaparse.min-Cas1JfRG.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-CeQkqN6Q.js → pegDiagram-2B236MQR-_paO0yDw.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-Dqgc87jA.js → pieDiagram-ENE6RG2P-xT1_Gpn4.js} +1 -1
- package/web/dist/assets/pilotswarm-BT6tOknQ.js +96 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CD7f-w6m.js → quadrantDiagram-ABIIQ3AL-1usdLFOF.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-CcsAijSC.js → railroadDiagram-RFXS5EU6-R3lwHOz9.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-BkzF80pL.js → requirementDiagram-TGXJPOKE-BL8J1__Z.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-D9XOFw7Y.js → sankeyDiagram-HTMAVEWB-Dz6--0pl.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-BFfaS_Sz.js → sequenceDiagram-DBY2YBRQ-CG2Xpkct.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-CDJV16tP.js → sizeCapture-X5ZJPWSS-BPbYfjxj.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-C0E-MPXO.js → stateDiagram-2N3HPSRC-46x_y_aA.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-C2tnolSo.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-n5Vsv7n9.js → swimlanes-5IMT3BWC-SXdMo4zJ.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-Dh6Sn__t.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-DW2gV8-n.js → timeline-definition-FHXFAJF6-CGgT-b38.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-D9dbDm08.js → vennDiagram-L72KCM5P-BGS3xBa_.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-CIcG7fiC.js → wardleyDiagram-EHGQE667-m2U3wEZJ.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-elEIFsc9.js → xychartDiagram-FW5EYKEG-DI6tQysg.js} +1 -1
- package/web/dist/index.html +2 -2
- package/web/runtime.js +30 -7
- package/web/dist/assets/channel-DRy7FvyF.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-C35RhB8X.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-C35RhB8X.js +0 -1
- package/web/dist/assets/index-CRY94nFp.js +0 -24
- package/web/dist/assets/pilotswarm-DayYdi39.js +0 -96
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-BMqXeMJu.js +0 -1
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-CGl4gRnH.js +0 -8
package/ui/core/src/reducer.js
CHANGED
|
@@ -19,6 +19,20 @@ import {
|
|
|
19
19
|
createInitialState,
|
|
20
20
|
} from "./state.js";
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Is this package detail/tree/changelog response for a selection the user has
|
|
24
|
+
* already left? Responses carry the selectionSeq captured when their fetch
|
|
25
|
+
* started; the NAME alone cannot tell two copies of a shadowed name apart
|
|
26
|
+
* (scope shadowing: one name, two packages), so a name-only guard let a slow
|
|
27
|
+
* response for one copy land on top of the other. Name-only actions (older
|
|
28
|
+
* hosts) keep the historical name compare.
|
|
29
|
+
*/
|
|
30
|
+
function packageResponseIsStale(packages, action) {
|
|
31
|
+
if (packages.selectedName !== action.name) return true;
|
|
32
|
+
if (typeof action.seq === "number") return (packages.selectionSeq ?? 0) !== action.seq;
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
22
36
|
function cloneHistoryMap(historyMap) {
|
|
23
37
|
return new Map(historyMap);
|
|
24
38
|
}
|
|
@@ -619,6 +633,7 @@ function applyVisibleSessionSelection(state, nextSessions) {
|
|
|
619
633
|
sessions = {
|
|
620
634
|
...sessions,
|
|
621
635
|
activeSessionId: intentTargetId,
|
|
636
|
+
listDeselected: false,
|
|
622
637
|
navigationIntent: intent.status === "resolved"
|
|
623
638
|
? intent
|
|
624
639
|
: { sessionId: intent.sessionId, status: "resolved" },
|
|
@@ -1026,6 +1041,15 @@ export function appReducer(state, action) {
|
|
|
1026
1041
|
ui: {
|
|
1027
1042
|
...state.ui,
|
|
1028
1043
|
focusRegion: action.focusRegion,
|
|
1044
|
+
// The RAW region the caller asked for, before layout
|
|
1045
|
+
// normalization. A workspace region (sessions/chat) with no
|
|
1046
|
+
// slot in the current layout normalizes to the first
|
|
1047
|
+
// focusable pane — inspector, on a phone — so the normalized
|
|
1048
|
+
// value alone cannot tell "focus the inspector" from
|
|
1049
|
+
// "sessions got rewritten to inspector". The mobile
|
|
1050
|
+
// follow-focus pane switch reads this to avoid opening
|
|
1051
|
+
// diagnostics when the user only asked for the workspace.
|
|
1052
|
+
requestedFocusRegion: action.requestedFocusRegion ?? action.focusRegion,
|
|
1029
1053
|
},
|
|
1030
1054
|
};
|
|
1031
1055
|
|
|
@@ -1087,6 +1111,10 @@ export function appReducer(state, action) {
|
|
|
1087
1111
|
if (!sessionId) return state;
|
|
1088
1112
|
const nextSessions = {
|
|
1089
1113
|
...state.sessions,
|
|
1114
|
+
// A deep link is explicit navigation. Keep the list highlight
|
|
1115
|
+
// aligned with the linked chat even if empty-space click had
|
|
1116
|
+
// previously deselected the session row.
|
|
1117
|
+
listDeselected: false,
|
|
1090
1118
|
navigationIntent: { sessionId, status: "pending" },
|
|
1091
1119
|
filterExceptionId: null,
|
|
1092
1120
|
};
|
|
@@ -2319,6 +2347,7 @@ export function appReducer(state, action) {
|
|
|
2319
2347
|
workerState: Array.isArray(action.workerState) ? action.workerState : [],
|
|
2320
2348
|
fetchedAt: Date.now(),
|
|
2321
2349
|
selectedName: stillThere ? previous.selectedName : null,
|
|
2350
|
+
selectedSelector: stillThere ? (previous.selectedSelector ?? null) : null,
|
|
2322
2351
|
...(stillThere ? {} : { detail: null, workspace: { ...previous.workspace, tree: null, selectedPath: null, file: null } }),
|
|
2323
2352
|
},
|
|
2324
2353
|
},
|
|
@@ -2336,6 +2365,18 @@ export function appReducer(state, action) {
|
|
|
2336
2365
|
packages: {
|
|
2337
2366
|
...state.admin.packages,
|
|
2338
2367
|
selectedName: action.name || null,
|
|
2368
|
+
// WHICH copy of the name: {scope, owner} from the row
|
|
2369
|
+
// the user clicked. One name can be two packages
|
|
2370
|
+
// (scope shadowing) — without this every read and
|
|
2371
|
+
// action fell back to "own copy first" and could
|
|
2372
|
+
// target the row the user was NOT looking at.
|
|
2373
|
+
selectedSelector: action.selector || null,
|
|
2374
|
+
// Monotonic selection token. The stale-response guards
|
|
2375
|
+
// below compare it, because comparing the NAME alone
|
|
2376
|
+
// cannot tell two copies of a shadowed name apart — a
|
|
2377
|
+
// slow response for the user copy could land on top of
|
|
2378
|
+
// the shared copy the user just clicked.
|
|
2379
|
+
selectionSeq: (state.admin.packages.selectionSeq ?? 0) + 1,
|
|
2339
2380
|
detail: null,
|
|
2340
2381
|
detailLoading: Boolean(action.name),
|
|
2341
2382
|
detailError: null,
|
|
@@ -2354,17 +2395,17 @@ export function appReducer(state, action) {
|
|
|
2354
2395
|
};
|
|
2355
2396
|
}
|
|
2356
2397
|
case "admin/packages/detail/loaded": {
|
|
2357
|
-
if (state.admin.packages
|
|
2398
|
+
if (packageResponseIsStale(state.admin.packages, action)) return state;
|
|
2358
2399
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, detail: action.detail, detailLoading: false, detailError: null } } };
|
|
2359
2400
|
}
|
|
2360
2401
|
case "admin/packages/detail/loadFailed": {
|
|
2361
|
-
if (state.admin.packages
|
|
2402
|
+
if (packageResponseIsStale(state.admin.packages, action)) return state;
|
|
2362
2403
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, detail: null, detailLoading: false, detailError: action.error || "Failed to load package" } } };
|
|
2363
2404
|
}
|
|
2364
2405
|
case "admin/packages/changelog/loaded": {
|
|
2365
2406
|
// Stale-response guard, same as the tree: a slow changelog for a
|
|
2366
2407
|
// previously-selected package must not surface under the current one.
|
|
2367
|
-
if (state.admin.packages
|
|
2408
|
+
if (packageResponseIsStale(state.admin.packages, action)) return state;
|
|
2368
2409
|
return {
|
|
2369
2410
|
...state,
|
|
2370
2411
|
admin: {
|
|
@@ -2377,7 +2418,7 @@ export function appReducer(state, action) {
|
|
|
2377
2418
|
};
|
|
2378
2419
|
}
|
|
2379
2420
|
case "admin/packages/tree/loaded": {
|
|
2380
|
-
if (state.admin.packages
|
|
2421
|
+
if (packageResponseIsStale(state.admin.packages, action)) return state;
|
|
2381
2422
|
const topDirs = Array.isArray(action.tree?.dirs)
|
|
2382
2423
|
? action.tree.dirs.filter((dir) => !dir.includes("/"))
|
|
2383
2424
|
: [];
|
|
@@ -2400,7 +2441,7 @@ export function appReducer(state, action) {
|
|
|
2400
2441
|
};
|
|
2401
2442
|
}
|
|
2402
2443
|
case "admin/packages/tree/loadFailed": {
|
|
2403
|
-
if (state.admin.packages
|
|
2444
|
+
if (packageResponseIsStale(state.admin.packages, action)) return state;
|
|
2404
2445
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, workspace: { ...state.admin.packages.workspace, treeLoading: false, treeError: action.error || "Failed to load package files" } } } };
|
|
2405
2446
|
}
|
|
2406
2447
|
case "admin/packages/toggleDir": {
|
|
@@ -2414,11 +2455,17 @@ export function appReducer(state, action) {
|
|
|
2414
2455
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, workspace: { ...state.admin.packages.workspace, selectedPath: action.path, file: null, fileLoading: true, fileError: null } } } };
|
|
2415
2456
|
}
|
|
2416
2457
|
case "admin/packages/file/loaded": {
|
|
2458
|
+
// Path AND selection token: two copies of a shadowed name have the
|
|
2459
|
+
// SAME file paths (both ship plugin.json), so a slow preview for
|
|
2460
|
+
// the previously-selected copy would otherwise land under the
|
|
2461
|
+
// current one. The seq check tells the two copies apart.
|
|
2417
2462
|
if (state.admin.packages.workspace.selectedPath !== action.file?.path) return state;
|
|
2463
|
+
if (typeof action.seq === "number" && (state.admin.packages.selectionSeq ?? 0) !== action.seq) return state;
|
|
2418
2464
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, workspace: { ...state.admin.packages.workspace, file: action.file, fileLoading: false, fileError: null } } } };
|
|
2419
2465
|
}
|
|
2420
2466
|
case "admin/packages/file/loadFailed": {
|
|
2421
2467
|
if (state.admin.packages.workspace.selectedPath !== action.path) return state;
|
|
2468
|
+
if (typeof action.seq === "number" && (state.admin.packages.selectionSeq ?? 0) !== action.seq) return state;
|
|
2422
2469
|
return { ...state, admin: { ...state.admin, packages: { ...state.admin.packages, workspace: { ...state.admin.packages.workspace, fileLoading: false, fileError: action.error || "Failed to load file" } } } };
|
|
2423
2470
|
}
|
|
2424
2471
|
case "admin/packages/action/pending": {
|
package/ui/core/src/selectors.js
CHANGED
|
@@ -3724,9 +3724,29 @@ export function selectAdminConsole(state) {
|
|
|
3724
3724
|
distinctPackageOwners.add(key);
|
|
3725
3725
|
}
|
|
3726
3726
|
const decoratePackageOwners = distinctPackageOwners.size > 1;
|
|
3727
|
+
// Copy-identity helpers: one NAME can be two packages (scope shadowing),
|
|
3728
|
+
// so row selection and highlighting key on (name, scope, owner) — never
|
|
3729
|
+
// the bare name.
|
|
3730
|
+
const packageCopyKey = (name, scope, owner) =>
|
|
3731
|
+
`${name}\u0001${scope === "shared" ? "shared" : "user"}\u0001${scope === "shared" ? "" : (owner?.subject ?? "")}`;
|
|
3732
|
+
const selectedCopyKey = pkgState.selectedName
|
|
3733
|
+
? packageCopyKey(
|
|
3734
|
+
pkgState.selectedName,
|
|
3735
|
+
pkgState.selectedSelector?.scope ?? null,
|
|
3736
|
+
pkgState.selectedSelector?.owner ?? principal ?? null,
|
|
3737
|
+
)
|
|
3738
|
+
: null;
|
|
3739
|
+
const rowMatchesSelection = (pkg) => {
|
|
3740
|
+
if (admin.section !== "packages" || pkgState.selectedName !== pkg.name) return false;
|
|
3741
|
+
// Legacy selection with no selector: fall back to name-only so an
|
|
3742
|
+
// in-flight selection from an older host still highlights something.
|
|
3743
|
+
if (!pkgState.selectedSelector?.scope) return true;
|
|
3744
|
+
return packageCopyKey(pkg.name, pkg.scope, pkg.owner) === selectedCopyKey;
|
|
3745
|
+
};
|
|
3727
3746
|
const packageRow = (pkg) => ({
|
|
3728
3747
|
name: pkg.name,
|
|
3729
3748
|
scope: pkg.scope === "shared" ? "shared" : "user",
|
|
3749
|
+
owner: pkg.owner ?? null,
|
|
3730
3750
|
enabled: Boolean(pkg.enabled),
|
|
3731
3751
|
semver: pkg.active?.semver || null,
|
|
3732
3752
|
sha7: pkg.active?.sha256 ? String(pkg.active.sha256).slice(0, 7) : null,
|
|
@@ -3742,7 +3762,7 @@ export function selectAdminConsole(state) {
|
|
|
3742
3762
|
: ownerBadgeFor(resolvePackageOwner(pkg, ownerDirectory)),
|
|
3743
3763
|
// Highlight only while the Agents section is active — otherwise the
|
|
3744
3764
|
// GitHub Keys screen shows a double selection.
|
|
3745
|
-
selected:
|
|
3765
|
+
selected: rowMatchesSelection(pkg),
|
|
3746
3766
|
});
|
|
3747
3767
|
// Admins are served every user-scope package, but another person's private
|
|
3748
3768
|
// agents are not part of YOUR workspace — keep them out of the main tree
|
|
@@ -3787,13 +3807,13 @@ export function selectAdminConsole(state) {
|
|
|
3787
3807
|
{ id: "ghcp", kind: "section", depth: 0, label: "GitHub Keys", selected: section === "ghcp" },
|
|
3788
3808
|
{ id: "agents", kind: "section", depth: 0, label: "Agents", selected: section === "packages" && !pkgState.selectedName },
|
|
3789
3809
|
{ id: "group:shared", kind: "group", depth: 1, label: "Shared", count: sharedRows.length },
|
|
3790
|
-
...sharedRows.map((row) => ({ id: `pkg:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3810
|
+
...sharedRows.map((row) => ({ id: `pkg:shared:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3791
3811
|
{ id: "group:user", kind: "group", depth: 1, label: "User", count: userRows.length },
|
|
3792
|
-
...userRows.map((row) => ({ id: `pkg:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3812
|
+
...userRows.map((row) => ({ id: `pkg:user:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3793
3813
|
...(otherUserRows.length > 0
|
|
3794
3814
|
? [
|
|
3795
3815
|
{ id: "group:others", kind: "group", depth: 1, label: "Other users", count: otherUserRows.length },
|
|
3796
|
-
...otherUserRows.map((row) => ({ id: `pkg:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3816
|
+
...otherUserRows.map((row) => ({ id: `pkg:user:${row.owner?.subject ?? "?"}:${row.name}`, kind: "package", depth: 2, label: row.name, ...row })),
|
|
3797
3817
|
]
|
|
3798
3818
|
: []),
|
|
3799
3819
|
// The worker registry is a hard-gated admin read; hide the section
|
|
@@ -3805,7 +3825,10 @@ export function selectAdminConsole(state) {
|
|
|
3805
3825
|
const detail = pkgState.detail || null;
|
|
3806
3826
|
let packageDetail = null;
|
|
3807
3827
|
if (pkgState.selectedName) {
|
|
3808
|
-
const
|
|
3828
|
+
const sameName = pkgList.filter((pkg) => pkg.name === pkgState.selectedName);
|
|
3829
|
+
const summary = (pkgState.selectedSelector?.scope
|
|
3830
|
+
? sameName.find((pkg) => packageCopyKey(pkg.name, pkg.scope, pkg.owner) === selectedCopyKey)
|
|
3831
|
+
: sameName[0]) ?? sameName[0] ?? null;
|
|
3809
3832
|
const activeVersion = detail?.versions?.find((v) => v.versionId === detail.activeVersionId) || null;
|
|
3810
3833
|
const manifest = activeVersion?.manifest || summary?.active?.manifest || {};
|
|
3811
3834
|
// Workers are ephemeral pods: rows for retired pod names linger until
|
|
@@ -3819,9 +3842,22 @@ export function selectAdminConsole(state) {
|
|
|
3819
3842
|
return !Number.isNaN(at.getTime()) && at.getTime() >= liveCutoff;
|
|
3820
3843
|
});
|
|
3821
3844
|
const fleetTotal = workerRows.length;
|
|
3845
|
+
// Workers report installed state by bare name — except when two
|
|
3846
|
+
// same-named copies are installed at once, where each row gets a
|
|
3847
|
+
// qualified key (name#scope[:owner8]) so the collision stays visible.
|
|
3848
|
+
// Read whichever key this copy answers to.
|
|
3849
|
+
const installedRowFor = (worker) => {
|
|
3850
|
+
const installed = worker.installed || {};
|
|
3851
|
+
const scope = detail?.scope || summary?.scope || pkgState.selectedSelector?.scope || null;
|
|
3852
|
+
const ownerSubject = (detail?.owner?.subject || summary?.owner?.subject || pkgState.selectedSelector?.owner?.subject || "");
|
|
3853
|
+
const qualified = scope === "user"
|
|
3854
|
+
? `${pkgState.selectedName}#user${ownerSubject ? `:${ownerSubject.slice(0, 8)}` : ""}`
|
|
3855
|
+
: `${pkgState.selectedName}#shared`;
|
|
3856
|
+
return installed[qualified] ?? installed[pkgState.selectedName];
|
|
3857
|
+
};
|
|
3822
3858
|
const fleetCurrent = activeVersion
|
|
3823
|
-
? workerRows.filter((worker) => worker
|
|
3824
|
-
&& worker
|
|
3859
|
+
? workerRows.filter((worker) => installedRowFor(worker)?.semver === activeVersion.semver
|
|
3860
|
+
&& installedRowFor(worker)?.status === "ok").length
|
|
3825
3861
|
: 0;
|
|
3826
3862
|
const canManage = detail ? ownsPackage(detail) : (summary ? ownsPackage(summary) : false);
|
|
3827
3863
|
packageDetail = {
|
|
@@ -3856,6 +3892,12 @@ export function selectAdminConsole(state) {
|
|
|
3856
3892
|
: null,
|
|
3857
3893
|
actionPending: pkgState.action?.pending || null,
|
|
3858
3894
|
actionError: pkgState.action?.error || null,
|
|
3895
|
+
// Which same-named copies exist, for the republish affordance and
|
|
3896
|
+
// the shadowing note. Counterparts the caller can SEE only —
|
|
3897
|
+
// exactly what the list already enforces.
|
|
3898
|
+
hasSharedCounterpart: sameName.some((pkg) => pkg.scope === "shared"),
|
|
3899
|
+
hasOwnUserCounterpart: sameName.some((pkg) => pkg.scope !== "shared" && isMinePackage(pkg)),
|
|
3900
|
+
copyCount: sameName.length,
|
|
3859
3901
|
};
|
|
3860
3902
|
}
|
|
3861
3903
|
|
package/ui/react/src/web-app.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
formatCompactNumber,
|
|
18
18
|
formatCronTimestampForClient,
|
|
19
19
|
formatHumanDurationSeconds,
|
|
20
|
+
getDiagnosticsSplitAdjustBounds,
|
|
20
21
|
getPromptInputRows,
|
|
21
22
|
getTheme,
|
|
22
23
|
isThemeLight,
|
|
@@ -3925,6 +3926,7 @@ function SessionDetailBox({ session, childCount = 0 }) {
|
|
|
3925
3926
|
// used, so the box height still cannot move with the selection.
|
|
3926
3927
|
field("Title", session?.title, "is-title"),
|
|
3927
3928
|
field("ID", session?.sessionId, "is-id"),
|
|
3929
|
+
field("Owner", session?.owner ? formatAdminPrincipalLabel(session.owner) : null),
|
|
3928
3930
|
field("Model", model),
|
|
3929
3931
|
field("Context", context, percent != null && percent >= 85 ? "is-hot" : percent != null && percent >= 70 ? "is-warm" : ""),
|
|
3930
3932
|
field("Cron", cron, session?.cronActive === true ? "is-armed" : ""),
|
|
@@ -8194,12 +8196,13 @@ function Toolbar({ controller, mobile, canvasPaneOpen = false, onToggleCanvasPan
|
|
|
8194
8196
|
const leftButtons = buttonDefs.filter((d) => !RIGHT_GROUP.has(d.key)).map(withRestore);
|
|
8195
8197
|
const rightButtons = buttonDefs.filter((d) => RIGHT_GROUP.has(d.key)).map(withRestore);
|
|
8196
8198
|
const toolbar = React.createElement("div", { className: "ps-toolbar" },
|
|
8197
|
-
// Three columns:
|
|
8198
|
-
//
|
|
8199
|
-
//
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
React.createElement("div", { className: "ps-toolbar-actions" },
|
|
8199
|
+
// Three columns: left rail | main controls | right rail. Full-screen
|
|
8200
|
+
// canvas uses the otherwise-empty left rail for the normal actions so
|
|
8201
|
+
// they do not crowd the canvas metadata and controls across the top.
|
|
8202
|
+
React.createElement("div", { className: "ps-toolbar-side is-left" },
|
|
8203
|
+
canvasMaximized ? leftButtons.map(renderButton) : null),
|
|
8204
|
+
React.createElement("div", { className: "ps-toolbar-actions" },
|
|
8205
|
+
canvasMaximized ? null : leftButtons.map(renderButton)),
|
|
8203
8206
|
React.createElement("div", { className: "ps-toolbar-side is-right" },
|
|
8204
8207
|
// The portal header parks its version/status meta here, LEFT of
|
|
8205
8208
|
// the tool buttons, and its sign-out glyph in the slot after
|
|
@@ -8749,11 +8752,11 @@ function DiagnosticsSplitResizeHandle({ controller, splitAdjust = 0 }) {
|
|
|
8749
8752
|
const onMove = (event) => {
|
|
8750
8753
|
const st = dragStateRef.current;
|
|
8751
8754
|
if (!st) return;
|
|
8752
|
-
//
|
|
8753
|
-
//
|
|
8754
|
-
//
|
|
8755
|
-
//
|
|
8756
|
-
const next =
|
|
8755
|
+
// The first grid track is `50% + adjust`, while the divider takes
|
|
8756
|
+
// real space between the two panes. Its bounds are asymmetric:
|
|
8757
|
+
// -column/2 makes Inspector 0px; column/2-divider makes Activity
|
|
8758
|
+
// 0px. Using one symmetric half-range left an 8-9px pane remnant.
|
|
8759
|
+
const next = clamp(st.start + (event.clientY - st.startY), st.minAdjust, st.maxAdjust);
|
|
8757
8760
|
controller.dispatch({ type: "ui/diagnosticsSplitAdjust", diagnosticsSplitAdjust: next });
|
|
8758
8761
|
};
|
|
8759
8762
|
const onUp = () => {
|
|
@@ -8781,8 +8784,15 @@ function DiagnosticsSplitResizeHandle({ controller, splitAdjust = 0 }) {
|
|
|
8781
8784
|
event.preventDefault();
|
|
8782
8785
|
capturePointerForDrag(event);
|
|
8783
8786
|
const col = event.currentTarget.closest(".ps-workspace-column");
|
|
8784
|
-
const
|
|
8785
|
-
|
|
8787
|
+
const columnHeight = Math.max(0, col?.getBoundingClientRect?.().height || 0);
|
|
8788
|
+
const dividerHeight = Math.max(0, event.currentTarget.getBoundingClientRect().height || 0);
|
|
8789
|
+
const { minAdjust, maxAdjust } = getDiagnosticsSplitAdjustBounds(columnHeight, dividerHeight);
|
|
8790
|
+
dragStateRef.current = {
|
|
8791
|
+
startY: event.clientY,
|
|
8792
|
+
start: clamp(Number(splitAdjust) || 0, minAdjust, maxAdjust),
|
|
8793
|
+
minAdjust,
|
|
8794
|
+
maxAdjust,
|
|
8795
|
+
};
|
|
8786
8796
|
setDragging(true);
|
|
8787
8797
|
document.body.classList.add("is-resizing-pane-y");
|
|
8788
8798
|
},
|
|
@@ -8790,9 +8800,17 @@ function DiagnosticsSplitResizeHandle({ controller, splitAdjust = 0 }) {
|
|
|
8790
8800
|
onKeyDown: (event) => {
|
|
8791
8801
|
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
8792
8802
|
event.preventDefault();
|
|
8803
|
+
const col = event.currentTarget.closest(".ps-workspace-column");
|
|
8804
|
+
const columnHeight = Math.max(0, col?.getBoundingClientRect?.().height || 0);
|
|
8805
|
+
const dividerHeight = Math.max(0, event.currentTarget.getBoundingClientRect().height || 0);
|
|
8806
|
+
const { minAdjust, maxAdjust } = getDiagnosticsSplitAdjustBounds(columnHeight, dividerHeight);
|
|
8793
8807
|
controller.dispatch({
|
|
8794
8808
|
type: "ui/diagnosticsSplitAdjust",
|
|
8795
|
-
diagnosticsSplitAdjust: (
|
|
8809
|
+
diagnosticsSplitAdjust: clamp(
|
|
8810
|
+
(Number(splitAdjust) || 0) + (event.key === "ArrowDown" ? dividerHeight : -dividerHeight),
|
|
8811
|
+
minAdjust,
|
|
8812
|
+
maxAdjust,
|
|
8813
|
+
),
|
|
8796
8814
|
});
|
|
8797
8815
|
},
|
|
8798
8816
|
},
|
|
@@ -9984,7 +10002,14 @@ function AdminSettingsTree({ controller, view }) {
|
|
|
9984
10002
|
`${row.label}`, React.createElement("span", { className: "ps-admin-tree__count" }, String(row.count ?? 0)));
|
|
9985
10003
|
}
|
|
9986
10004
|
const onClick = row.kind === "package"
|
|
9987
|
-
|
|
10005
|
+
// The selector says WHICH copy this row is — one name can be a
|
|
10006
|
+
// shared package and a user copy at once (scope shadowing).
|
|
10007
|
+
? () => controller.selectAdminPackage(row.name, {
|
|
10008
|
+
scope: row.scope === "shared" ? "shared" : "user",
|
|
10009
|
+
...(row.scope !== "shared" && row.owner?.provider && row.owner?.subject
|
|
10010
|
+
? { owner: { provider: row.owner.provider, subject: row.owner.subject } }
|
|
10011
|
+
: {}),
|
|
10012
|
+
})
|
|
9988
10013
|
: () => controller.setAdminSection(row.id === "agents" ? "packages" : row.id === "workers" ? "workers" : "ghcp");
|
|
9989
10014
|
return React.createElement("button", {
|
|
9990
10015
|
key: row.id,
|
|
@@ -10100,8 +10125,29 @@ function AdminPackageDetailPane({ controller, view }) {
|
|
|
10100
10125
|
disabled: Boolean(pending),
|
|
10101
10126
|
title: `Publish a new version of ${detail.name} from a repo folder`,
|
|
10102
10127
|
}, "Update"),
|
|
10103
|
-
|
|
10104
|
-
|
|
10128
|
+
// Promote MOVES this row to shared scope, so it only works
|
|
10129
|
+
// while the shared name is free. Once a shared copy exists,
|
|
10130
|
+
// the update path is republish: this version's exact bytes
|
|
10131
|
+
// become a new version of the existing shared package.
|
|
10132
|
+
detail.scope === "user" && detail.hasSharedCounterpart
|
|
10133
|
+
? React.createElement("button", {
|
|
10134
|
+
type: "button",
|
|
10135
|
+
className: "ps-mini-button",
|
|
10136
|
+
onClick: act("republish", detail.activeSemver),
|
|
10137
|
+
disabled: Boolean(pending) || !detail.activeSemver,
|
|
10138
|
+
title: `Publish ${detail.name}@${detail.activeSemver ?? "?"} into the existing shared package`,
|
|
10139
|
+
}, pending === "republish" ? "Publishing…" : `Publish ${detail.activeSemver ?? ""} to shared`)
|
|
10140
|
+
: React.createElement("button", { type: "button", className: "ps-mini-button", onClick: act(detail.scope === "shared" ? "demote" : "promote"), disabled: Boolean(pending) },
|
|
10141
|
+
detail.scope === "shared" ? "Demote to user" : "Promote to shared"),
|
|
10142
|
+
detail.scope === "shared" && !detail.hasOwnUserCounterpart
|
|
10143
|
+
? React.createElement("button", {
|
|
10144
|
+
type: "button",
|
|
10145
|
+
className: "ps-mini-button",
|
|
10146
|
+
onClick: act("republish", detail.activeSemver),
|
|
10147
|
+
disabled: Boolean(pending) || !detail.activeSemver,
|
|
10148
|
+
title: "Copy the active version into your user scope as a private test bench",
|
|
10149
|
+
}, pending === "republish" ? "Copying…" : "Copy to my user scope")
|
|
10150
|
+
: null,
|
|
10105
10151
|
React.createElement("button", { type: "button", className: "ps-mini-button", onClick: act(detail.enabled ? "disable" : "enable"), disabled: Boolean(pending) },
|
|
10106
10152
|
detail.enabled ? "Disable" : "Enable"),
|
|
10107
10153
|
React.createElement("button", { type: "button", className: "ps-mini-button is-danger", onClick: confirmDelete, disabled: Boolean(pending) }, "Delete"))
|
|
@@ -10593,6 +10639,7 @@ export function PilotSwarmWebApp({ controller }) {
|
|
|
10593
10639
|
diagnosticsPaneAdjust: rootState.ui.layout?.diagnosticsPaneAdjust ?? 0,
|
|
10594
10640
|
diagnosticsSplitAdjust: rootState.ui.layout?.diagnosticsSplitAdjust ?? 0,
|
|
10595
10641
|
focusRegion: rootState.ui.focusRegion,
|
|
10642
|
+
requestedFocusRegion: rootState.ui.requestedFocusRegion,
|
|
10596
10643
|
inspectorTab: rootState.ui.inspectorTab,
|
|
10597
10644
|
filesFullscreen: Boolean(rootState.files.fullscreen),
|
|
10598
10645
|
selectedArtifactId: rootState.files.selectedArtifactId || null,
|
|
@@ -10881,10 +10928,20 @@ export function PilotSwarmWebApp({ controller }) {
|
|
|
10881
10928
|
// toolbar: the sessions-only layout's list reclaims focus, which
|
|
10882
10929
|
// bounced the user out of Inspector the instant they tapped it.
|
|
10883
10930
|
// Returning to Main is the Main button's job now.
|
|
10884
|
-
|
|
10931
|
+
//
|
|
10932
|
+
// Gate on the RAW request, not the normalized region: on a phone a
|
|
10933
|
+
// workspace region (sessions/chat) normalizes to inspector, so the
|
|
10934
|
+
// Main button's own setFocus("chat") would otherwise land here as an
|
|
10935
|
+
// "inspector" focus and yank the user into diagnostics the instant
|
|
10936
|
+
// they asked for the workspace. Only a focus the caller genuinely
|
|
10937
|
+
// aimed at inspector/activity switches the pane.
|
|
10938
|
+
const requested = state.requestedFocusRegion;
|
|
10939
|
+
if (mobile
|
|
10940
|
+
&& (state.focusRegion === "inspector" || state.focusRegion === "activity")
|
|
10941
|
+
&& (requested === "inspector" || requested === "activity")) {
|
|
10885
10942
|
setMobilePane(state.focusRegion);
|
|
10886
10943
|
}
|
|
10887
|
-
}, [mobile, state.focusRegion]);
|
|
10944
|
+
}, [mobile, state.focusRegion, state.requestedFocusRegion]);
|
|
10888
10945
|
|
|
10889
10946
|
React.useEffect(() => {
|
|
10890
10947
|
const visibleTabs = getVisibleInspectorTabs(controller);
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-DrJhXhSQ.js → abnfDiagram-VRR7QNED-Hsly1fgf.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-BN5MKe94.js";import{p as f}from"./chunk-JWPE2WC7-BccmZmrr.js";import{_ as n,l as o}from"./mermaid.core-bonzwapf.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-Z8eMzFMv.js";import"./pilotswarm-BT6tOknQ.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-bonzwapf.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|