pim-agent 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/packages/core/src/extensions/bash/MemoryCap.ts +10 -2
- package/packages/core/src/extensions/bash/run.ts +8 -2
- package/packages/core/src/session/SearchIndex.ts +4 -3
- package/packages/core/src/session/SessionDigest.ts +2 -2
- package/packages/core/src/session/UserPrompt.ts +34 -0
- package/packages/core/src/shared/Renderer.ts +5 -5
- package/packages/core/src/shared/Tools.ts +37 -1
- package/packages/protocol/src/ServerEvent.ts +8 -0
- package/packages/server/src/SessionProjection.ts +4 -1
- package/packages/server/src/SessionStream.ts +9 -0
- package/packages/telegram/src/Bot.ts +12 -2
- package/packages/tui/src/extensions/working-indicator/index.ts +3 -2
- package/packages/web/dist/client/assets/{abnfDiagram-O67JEVCF-w0u0UKcC.js → abnfDiagram-O67JEVCF-C4h_e8a0.js} +1 -1
- package/packages/web/dist/client/assets/{arc-C8AeY-3C.js → arc-DOFrJD2P.js} +1 -1
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-IjTj0B7Q.js +1 -0
- package/packages/web/dist/client/assets/{architectureDiagram-NJMV4G6O-CLdCZfsP.js → architectureDiagram-NJMV4G6O-CMywPNO0.js} +1 -1
- package/packages/web/dist/client/assets/{blockDiagram-BEXU5L5S-BgAbOzdH.js → blockDiagram-BEXU5L5S-CilAxS33.js} +1 -1
- package/packages/web/dist/client/assets/{c4Diagram-YGBWAQC7-DGRXXzDl.js → c4Diagram-YGBWAQC7-B-dWG8Iz.js} +1 -1
- package/packages/web/dist/client/assets/channel-C4sZuBrb.js +1 -0
- package/packages/web/dist/client/assets/{chunk-3FUC2YCW-Dmz4_CY0.js → chunk-3FUC2YCW-Bsj57hpn.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-5DYCD2WN-D6q0r_NW.js → chunk-5DYCD2WN-zGw1cRpq.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-742MDFTN-biXvhzMn.js → chunk-742MDFTN-DywDPd1I.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7INBJB4K-CtfPEr8P.js → chunk-7INBJB4K-CVbwe-xT.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7M6MHVWA-CTixWKLk.js → chunk-7M6MHVWA-CHZ-gvHw.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7PRAP22T-DijOiKl2.js → chunk-7PRAP22T-WD7cf9gl.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GTNCS2PH-DLId7dTl.js → chunk-GTNCS2PH-BTulktWP.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GWA4HPMP-YUQxYmiu.js → chunk-GWA4HPMP-D3rtBoTv.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-MBY4JIJT-VWR3HSRr.js → chunk-MBY4JIJT-B8O-Qwvz.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-NETBCI7D-B8SeJoMY.js → chunk-NETBCI7D-DZlxcBK5.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-O7XYJQB3-CeLpEz0Q.js → chunk-O7XYJQB3-4-W0jJea.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-UA2S7LBM-cBGKkXV_.js → chunk-UA2S7LBM-D_rURue5.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-WEXAMYUT-BesXAOy9.js → chunk-WEXAMYUT-CEL3e6t3.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-XXDRQBXY-DiuGUc8m.js → chunk-XXDRQBXY-o4820CpE.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-Z7XXMR3K-Dr2W5_t1.js → chunk-Z7XXMR3K-BohM0wWu.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-ZIGJFQKS-CwoMYXLJ.js → chunk-ZIGJFQKS-BjwLZi8g.js} +1 -1
- package/packages/web/dist/client/assets/{classDiagram-v2-NBCMYWYE-Gc3jAsDf.js → classDiagram-v2-NBCMYWYE-D0ZfjRwg.js} +1 -1
- package/packages/web/dist/client/assets/{core-C27Q2ZSN.js → core-Dzrz3GvC.js} +1 -1
- package/packages/web/dist/client/assets/{cose-bilkent-JH36ORCC-ox5QohTH.js → cose-bilkent-JH36ORCC-CNlUwO2B.js} +1 -1
- package/packages/web/dist/client/assets/{cynefin-OW5HDTMX-CjQ-AjuJ.js → cynefin-OW5HDTMX-Bg2hWhJY.js} +1 -1
- package/packages/web/dist/client/assets/{cynefinDiagram-VND7K2PF-BVajmbbO.js → cynefinDiagram-VND7K2PF-Dt4WbdoO.js} +1 -1
- package/packages/web/dist/client/assets/{dagre-6A5THRUB-BtXhDxGN.js → dagre-6A5THRUB-D3J4e_FL.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-22UHCM2B-DwjrV0H_.js → diagram-22UHCM2B-DcBAyGud.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-3UASUU5V-DQ1E_6hO.js → diagram-3UASUU5V-knaPopyA.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-ATOU4E4O-wVYWlHRV.js → diagram-ATOU4E4O-Cdt-UXR3.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-CDSNMT55-CMlxHWMz.js → diagram-CDSNMT55-0Nc7NbM-.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MLGK6HIB-Cbiwo7t9.js → diagram-MLGK6HIB-obWj-j_j.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MPIPVDR6-Cv4zIyW1.js → diagram-MPIPVDR6-CNPimc-A.js} +1 -1
- package/packages/web/dist/client/assets/{dist-Dl4GbwtH.js → dist-CrAX-R0u.js} +1 -1
- package/packages/web/dist/client/assets/{ebnfDiagram-ZINNZB2B-Bd8xl8W2.js → ebnfDiagram-ZINNZB2B-CeIzXygs.js} +1 -1
- package/packages/web/dist/client/assets/{elk-276RUBZZ-DPRtUxgw.js → elk-276RUBZZ-DZpv0cFN.js} +1 -1
- package/packages/web/dist/client/assets/{erDiagram-OPXOYQCR-BNoG4SxS.js → erDiagram-OPXOYQCR-BA3y9LPc.js} +1 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-CeuR-O65.js +1 -0
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-BMqk3vdL.js +1 -0
- package/packages/web/dist/client/assets/{ganttDiagram-FUAMR5RP-BtFYI7uw.js → ganttDiagram-FUAMR5RP-UaQqElIK.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraph-4MIJSDKK-Di6RG5Kg.js → gitGraph-4MIJSDKK-cQmMFm4p.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraphDiagram-X574FWY7-J4_JKGBH.js → gitGraphDiagram-X574FWY7-BmYgXYTo.js} +1 -1
- package/packages/web/dist/client/assets/{index-Cn66jcLF.js → index-BxPglwap.js} +6 -6
- package/packages/web/dist/client/assets/{index-BD7ptjuS.css → index-CmVu3w8s.css} +1 -1
- package/packages/web/dist/client/assets/{info-A6RAGUB7-wk6vNDP4.js → info-A6RAGUB7-TiduRcJ3.js} +1 -1
- package/packages/web/dist/client/assets/{infoDiagram-VRGFBTTK-Zl7Uhlcj.js → infoDiagram-VRGFBTTK-hFFOKGKl.js} +1 -1
- package/packages/web/dist/client/assets/{ishikawaDiagram-OU5B5YK6-I0VVed8w.js → ishikawaDiagram-OU5B5YK6-Bwocylgy.js} +1 -1
- package/packages/web/dist/client/assets/{journeyDiagram-ZHPQQLJL-CLGZAy0Q.js → journeyDiagram-ZHPQQLJL-vZ1hiG_4.js} +1 -1
- package/packages/web/dist/client/assets/{kanban-definition-PNTS6WVX-D3Zv63YL.js → kanban-definition-PNTS6WVX-BY_kNV28.js} +1 -1
- package/packages/web/dist/client/assets/{line-C4_qzTJY.js → line-D2gp374O.js} +1 -1
- package/packages/web/dist/client/assets/{linear-Dbp9FWGm.js → linear-EkWWd1l3.js} +1 -1
- package/packages/web/dist/client/assets/{mermaid-parser.core-Cbd2Flfk.js → mermaid-parser.core-CeboWX-k.js} +3 -3
- package/packages/web/dist/client/assets/{mermaid.core-CPXk02t0.js → mermaid.core-zdZDrs5K.js} +4 -4
- package/packages/web/dist/client/assets/{mindmap-definition-NLK3R4M7-hcjd2vg0.js → mindmap-definition-NLK3R4M7-gGYhS2WF.js} +1 -1
- package/packages/web/dist/client/assets/{packet-AYTQ26CC-CLiY7MdL.js → packet-AYTQ26CC-Dy4sLRUY.js} +1 -1
- package/packages/web/dist/client/assets/{pegDiagram-GJSIUBJH-Or6L-npJ.js → pegDiagram-GJSIUBJH-BzhQfVk9.js} +1 -1
- package/packages/web/dist/client/assets/{pie-WAS4IAKB-DTF5qxhB.js → pie-WAS4IAKB-DLnc8q-D.js} +1 -1
- package/packages/web/dist/client/assets/{pieDiagram-5QR66LMP-wDNyDsTs.js → pieDiagram-5QR66LMP-CFOryLv5.js} +1 -1
- package/packages/web/dist/client/assets/{quadrantDiagram-O4NWA36T-BL_0xWWi.js → quadrantDiagram-O4NWA36T-BJzJC3Pb.js} +1 -1
- package/packages/web/dist/client/assets/{radar-RG4KPBEZ-hK8uEd3E.js → radar-RG4KPBEZ-WzU2xFD1.js} +1 -1
- package/packages/web/dist/client/assets/{railroad-74A4TZTK-Cj1mtGfH.js → railroad-74A4TZTK-BxrFrtoZ.js} +1 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-WLTxQJbM.js +1 -0
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-Pr2MbT1G.js +1 -0
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-BnNqXJLR.js +1 -0
- package/packages/web/dist/client/assets/{railroadDiagram-XR7U4H2S-BUXe7pvJ.js → railroadDiagram-XR7U4H2S-CwCJ4qML.js} +1 -1
- package/packages/web/dist/client/assets/{requirementDiagram-PLB6GJNP-DBnKurFY.js → requirementDiagram-PLB6GJNP-N_e-xK1X.js} +1 -1
- package/packages/web/dist/client/assets/{sankeyDiagram-IPEJSGJF-BDlSxPY7.js → sankeyDiagram-IPEJSGJF-BxeoAN36.js} +1 -1
- package/packages/web/dist/client/assets/{sequenceDiagram-PO4LG4MO-BcKSq_cS.js → sequenceDiagram-PO4LG4MO-MSPwJ13c.js} +1 -1
- package/packages/web/dist/client/assets/{src-kcIgRrGC.js → src-D28B8eI9.js} +1 -1
- package/packages/web/dist/client/assets/{stateDiagram-v2-GCMORJYK-D-1tpyK1.js → stateDiagram-v2-GCMORJYK-D_aZ5Igh.js} +1 -1
- package/packages/web/dist/client/assets/{swimlanes-2SLR337P-edQaMeEJ.js → swimlanes-2SLR337P-DBPV-dq1.js} +1 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-HaI5QjO5.js +8 -0
- package/packages/web/dist/client/assets/{timeline-definition-EJHVYXUP-BHspcgaG.js → timeline-definition-EJHVYXUP-D_NN2X_H.js} +1 -1
- package/packages/web/dist/client/assets/{treeView-Q6P3EWNA-Bvc71ryx.js → treeView-Q6P3EWNA-D61xAbMJ.js} +1 -1
- package/packages/web/dist/client/assets/{treemap-WGGIJYW6-CoZvoF_t.js → treemap-WGGIJYW6-C4YKLl2j.js} +1 -1
- package/packages/web/dist/client/assets/{usecaseDiagram-POWQR4AR-B203AiCD.js → usecaseDiagram-POWQR4AR-02veKF4D.js} +1 -1
- package/packages/web/dist/client/assets/{vennDiagram-UO4OBE2U-Cia3spa9.js → vennDiagram-UO4OBE2U-DEgSBAmX.js} +1 -1
- package/packages/web/dist/client/assets/{wardley-WFR3VGLG-C7qHTXAu.js → wardley-WFR3VGLG-CZ6hgt6M.js} +1 -1
- package/packages/web/dist/client/assets/{wardleyDiagram-VNRHLVJA-CK2R_SgC.js → wardleyDiagram-VNRHLVJA-Bh1SCQA_.js} +1 -1
- package/packages/web/dist/client/assets/{xychartDiagram-PMCCYNJV-BBLqtYJ_.js → xychartDiagram-PMCCYNJV-C2v7l5nz.js} +1 -1
- package/packages/web/dist/client/index.html +2 -2
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-D-GDy9ga.js +0 -1
- package/packages/web/dist/client/assets/channel-BJtpIKaC.js +0 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-Dh9l6A3t.js +0 -1
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-DoJ97uSW.js +0 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-t8ibqa0P.js +0 -1
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-B4RYlcUM.js +0 -1
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-DFqfvrfB.js +0 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-vI6XtOyR.js +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pim-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "A batteries-included distro of Pi, accessible in your terminal, browser and Telegram.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
"vite": "^8.2.2"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@earendil-works/pi-coding-agent": "1.0
|
|
80
|
-
"@earendil-works/pi-server": "1.0
|
|
79
|
+
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
80
|
+
"@earendil-works/pi-server": "1.1.0",
|
|
81
81
|
"diff": "^9.0.0",
|
|
82
82
|
"fzf": "^0.5.2",
|
|
83
83
|
"grammy": "^1.46.0",
|
|
@@ -10,8 +10,16 @@ export type MemoryScope = {
|
|
|
10
10
|
readonly unit: string;
|
|
11
11
|
readonly limitBytes: number;
|
|
12
12
|
readonly argv: readonly string[];
|
|
13
|
+
/** Shell run first inside the scope; makes the kernel's OOM kill take the whole command. */
|
|
14
|
+
readonly prelude: string;
|
|
13
15
|
};
|
|
14
16
|
|
|
17
|
+
// The kernel kills the whole group on OOM, as OOMPolicy=kill would, but the unit never ends in
|
|
18
|
+
// Result=oom-kill, which desktops (Plasma's oom_notifier) report as "system low on memory".
|
|
19
|
+
// Only ever run inside our scope: anywhere else it would mark pim's own cgroup.
|
|
20
|
+
const OOM_GROUP_PRELUDE =
|
|
21
|
+
'{ read -r __pim_cg < /proc/self/cgroup; echo 1 > "/sys/fs/cgroup${__pim_cg#0::}/memory.oom.group"; unset __pim_cg; } 2>/dev/null; ';
|
|
22
|
+
|
|
15
23
|
let supported: Promise<boolean> | null = null;
|
|
16
24
|
let owner: Promise<string | null> | null = null;
|
|
17
25
|
|
|
@@ -93,6 +101,7 @@ async function scope(): Promise<MemoryScope | null> {
|
|
|
93
101
|
return {
|
|
94
102
|
unit,
|
|
95
103
|
limitBytes: limit,
|
|
104
|
+
prelude: OOM_GROUP_PRELUDE,
|
|
96
105
|
argv: [
|
|
97
106
|
"systemd-run",
|
|
98
107
|
"--user",
|
|
@@ -103,8 +112,7 @@ async function scope(): Promise<MemoryScope | null> {
|
|
|
103
112
|
`--unit=${unit}`,
|
|
104
113
|
`--property=MemoryMax=${limit}`,
|
|
105
114
|
"--property=MemorySwapMax=0",
|
|
106
|
-
"--property=OOMPolicy=
|
|
107
|
-
// The kernel's group kill races systemd's OOM stop; both must SIGKILL so run.ts can tell.
|
|
115
|
+
"--property=OOMPolicy=continue",
|
|
108
116
|
"--property=KillSignal=SIGKILL",
|
|
109
117
|
...(bindTo
|
|
110
118
|
? [`--property=BindsTo=${bindTo}`, `--property=After=${bindTo}`]
|
|
@@ -100,7 +100,13 @@ export async function runBashCommand(
|
|
|
100
100
|
|
|
101
101
|
// setsid: own process group (pgid == pid), so the whole tree can be signalled.
|
|
102
102
|
const proc = Bun.spawn({
|
|
103
|
-
cmd: [
|
|
103
|
+
cmd: [
|
|
104
|
+
...(scope?.argv ?? []),
|
|
105
|
+
"setsid",
|
|
106
|
+
"bash",
|
|
107
|
+
"-lc",
|
|
108
|
+
(scope?.prelude ?? "") + RUNNER,
|
|
109
|
+
],
|
|
104
110
|
cwd,
|
|
105
111
|
stdout: "pipe",
|
|
106
112
|
stderr: "pipe",
|
|
@@ -207,7 +213,7 @@ export async function runBashCommand(
|
|
|
207
213
|
const stdout = stdoutCap.snapshot(sniffed !== null);
|
|
208
214
|
const stderr = stderrCap.snapshot();
|
|
209
215
|
|
|
210
|
-
//
|
|
216
|
+
// The kernel's OOM group kill is a SIGKILL; systemd's Result never says oom-kill (see MemoryCap).
|
|
211
217
|
const memoryLimitHit =
|
|
212
218
|
scope !== null && signalCode === "SIGKILL" && !timedOut && !aborted
|
|
213
219
|
? scope.limitBytes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
import { Attachments } from "../attachments/Attachments";
|
|
4
3
|
import { Levenshtein } from "../shared/Levenshtein";
|
|
5
4
|
import { Pool } from "../shared/Pool";
|
|
6
5
|
import { MessageText } from "./MessageText";
|
|
@@ -12,6 +11,7 @@ import {
|
|
|
12
11
|
type Durable,
|
|
13
12
|
} from "./SessionDigest";
|
|
14
13
|
import type { SessionSummary } from "./SessionRegistry";
|
|
14
|
+
import { UserPrompt } from "./UserPrompt";
|
|
15
15
|
|
|
16
16
|
/** Half-open character offsets; non-overlapping and ascending. */
|
|
17
17
|
export type SearchRange = readonly [start: number, end: number];
|
|
@@ -527,9 +527,10 @@ function turnOf(line: string, seq: number): Turn | undefined {
|
|
|
527
527
|
if (message.role !== "user" && message.role !== "assistant") {
|
|
528
528
|
return undefined;
|
|
529
529
|
}
|
|
530
|
-
const said = MessageText.textOf(message.content);
|
|
531
530
|
const text = (
|
|
532
|
-
message.role === "user"
|
|
531
|
+
message.role === "user"
|
|
532
|
+
? UserPrompt.of(message.content).text
|
|
533
|
+
: MessageText.textOf(message.content)
|
|
533
534
|
).trim();
|
|
534
535
|
return text === "" ? undefined : { seq, role: message.role, text };
|
|
535
536
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
3
|
import { Attachments } from "../attachments/Attachments";
|
|
4
|
-
import {
|
|
4
|
+
import { UserPrompt } from "./UserPrompt";
|
|
5
5
|
|
|
6
6
|
/** Catalogue summary of a session file. */
|
|
7
7
|
export type SessionDigest = {
|
|
@@ -138,7 +138,7 @@ function firstUserMessage(lines: readonly string[]): string | undefined {
|
|
|
138
138
|
if (entry?.type !== "message" || entry.message.role !== "user") {
|
|
139
139
|
continue;
|
|
140
140
|
}
|
|
141
|
-
const said =
|
|
141
|
+
const said = UserPrompt.of(entry.message.content);
|
|
142
142
|
const text =
|
|
143
143
|
said.text.trim() ||
|
|
144
144
|
said.files.map((file) => Attachments.nameOf(file.path)).join(", ");
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { UserMessage } from "@earendil-works/pi-ai";
|
|
2
|
+
import {
|
|
3
|
+
parseSkillBlock,
|
|
4
|
+
type ParsedSkillBlock,
|
|
5
|
+
} from "@earendil-works/pi-coding-agent";
|
|
6
|
+
|
|
7
|
+
import { Attachments, type PromptAttachment } from "../attachments/Attachments";
|
|
8
|
+
import { MessageText } from "./MessageText";
|
|
9
|
+
|
|
10
|
+
/** A skill pi expanded inline into the prompt. */
|
|
11
|
+
export type SkillUse = Pick<ParsedSkillBlock, "name" | "content">;
|
|
12
|
+
|
|
13
|
+
/** A stored user message as the user typed it, with what pi expanded into it set apart. */
|
|
14
|
+
export type UserPrompt = {
|
|
15
|
+
readonly text: string;
|
|
16
|
+
readonly files: readonly PromptAttachment[];
|
|
17
|
+
readonly skill?: SkillUse;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function of(content: UserMessage["content"]): UserPrompt {
|
|
21
|
+
const raw = MessageText.textOf(content);
|
|
22
|
+
const block = parseSkillBlock(raw);
|
|
23
|
+
if (block === null) {
|
|
24
|
+
return Attachments.parse(raw);
|
|
25
|
+
}
|
|
26
|
+
const said = Attachments.parse(block.userMessage ?? "");
|
|
27
|
+
return {
|
|
28
|
+
...said,
|
|
29
|
+
text: [`/skill:${block.name}`, said.text].filter(Boolean).join(" "),
|
|
30
|
+
skill: { name: block.name, content: block.content },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const UserPrompt = { of };
|
|
@@ -27,12 +27,12 @@ export type PrefixSpec = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const GAPPED_PREFIX: PrefixSpec = {
|
|
30
|
-
prefix: "
|
|
31
|
-
width:
|
|
30
|
+
prefix: "│ ",
|
|
31
|
+
width: 2,
|
|
32
32
|
};
|
|
33
33
|
const TIGHT_PREFIX: PrefixSpec = {
|
|
34
|
-
prefix: "
|
|
35
|
-
width:
|
|
34
|
+
prefix: "│",
|
|
35
|
+
width: 1,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
class ToolTitle implements Component {
|
|
@@ -213,7 +213,7 @@ function titleHead(args: {
|
|
|
213
213
|
}): string {
|
|
214
214
|
const { label, theme, markerColor, labelColor } = args;
|
|
215
215
|
return (
|
|
216
|
-
theme.fg(markerColor, "
|
|
216
|
+
theme.fg(markerColor, "▪") +
|
|
217
217
|
" " +
|
|
218
218
|
theme.fg(labelColor ?? "toolTitle", theme.bold(label))
|
|
219
219
|
);
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
ExtensionAPI,
|
|
4
4
|
ToolDefinition,
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { Box, type Component } from "@earendil-works/pi-tui";
|
|
6
7
|
import { validateToolArguments, type JsonObject } from "@earendil-works/pi-ai";
|
|
7
8
|
import type { Static, TSchema } from "typebox";
|
|
8
9
|
import { Levenshtein } from "./Levenshtein";
|
|
@@ -136,9 +137,23 @@ function wrap<TParams extends TSchema, TDetails = unknown, TState = unknown>(
|
|
|
136
137
|
if (effect !== undefined) {
|
|
137
138
|
effects.set(def.name, effect as ErasedToolEffect);
|
|
138
139
|
}
|
|
140
|
+
const { renderCall, renderResult } =
|
|
141
|
+
toViewModel === undefined ? piDef : synthesizeRenderers(def, toViewModel);
|
|
142
|
+
const self = def.renderShell === "self";
|
|
139
143
|
return {
|
|
140
144
|
...piDef,
|
|
141
|
-
|
|
145
|
+
renderCall:
|
|
146
|
+
self && renderCall
|
|
147
|
+
? (args, theme, context) =>
|
|
148
|
+
padded(context, (inner) => renderCall(args, theme, inner))
|
|
149
|
+
: renderCall,
|
|
150
|
+
renderResult:
|
|
151
|
+
self && renderResult
|
|
152
|
+
? (result, options, theme, context) =>
|
|
153
|
+
padded(context, (inner) =>
|
|
154
|
+
renderResult(result, options, theme, inner)
|
|
155
|
+
)
|
|
156
|
+
: renderResult,
|
|
142
157
|
prepareArguments: (rawArgs: unknown): Static<TParams> => {
|
|
143
158
|
const prepared = def.prepareArguments
|
|
144
159
|
? def.prepareArguments(rawArgs)
|
|
@@ -291,6 +306,27 @@ function synthesizeRenderers<TParams extends TSchema, TDetails, TState>(
|
|
|
291
306
|
};
|
|
292
307
|
}
|
|
293
308
|
|
|
309
|
+
type PadContext = {
|
|
310
|
+
readonly lastComponent: Component | undefined;
|
|
311
|
+
readonly outputPad: number;
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
/** pi leaves the `outputPad` margin to `renderShell: "self"` renderers. */
|
|
315
|
+
function padded<C extends PadContext>(
|
|
316
|
+
context: C,
|
|
317
|
+
draw: (context: C) => Component
|
|
318
|
+
): Component {
|
|
319
|
+
const last = context.lastComponent;
|
|
320
|
+
const box = new Box(context.outputPad, 0);
|
|
321
|
+
box.addChild(
|
|
322
|
+
draw({
|
|
323
|
+
...context,
|
|
324
|
+
lastComponent: last instanceof Box ? last.children[0] : last,
|
|
325
|
+
})
|
|
326
|
+
);
|
|
327
|
+
return box;
|
|
328
|
+
}
|
|
329
|
+
|
|
294
330
|
function parseIssues(message: string): Issue[] {
|
|
295
331
|
const issues: Issue[] = [];
|
|
296
332
|
for (const line of message.split("\n")) {
|
|
@@ -4,6 +4,7 @@ import type { PickerItem } from "#core/picker/PickerItem";
|
|
|
4
4
|
import type { ExtensionEntry } from "#core/shared/PiExtensions";
|
|
5
5
|
import type { SearchRange, SearchSnippet } from "#core/session/SearchIndex";
|
|
6
6
|
import type { LeaseFrontend } from "#core/session/SessionLease";
|
|
7
|
+
import type { SkillUse } from "#core/session/UserPrompt";
|
|
7
8
|
import type { UpdateSkip } from "#core/shared/Updater";
|
|
8
9
|
import type { NoticeSeverity, ToolView } from "#core/view/ViewBlock";
|
|
9
10
|
import type { ChangeList, FileDiff, FileLines } from "./Diff";
|
|
@@ -44,6 +45,8 @@ export type DurableEvent =
|
|
|
44
45
|
readonly thinking?: string;
|
|
45
46
|
/** User messages only. */
|
|
46
47
|
readonly attachments?: readonly AttachmentView[];
|
|
48
|
+
/** User messages only; `text` then holds the command as typed. */
|
|
49
|
+
readonly skill?: SkillUse;
|
|
47
50
|
readonly toolCalls?: readonly ToolCallView[];
|
|
48
51
|
/** Model call error; assistant messages only. */
|
|
49
52
|
readonly error?: string;
|
|
@@ -55,6 +58,8 @@ export type DurableEvent =
|
|
|
55
58
|
readonly name: string;
|
|
56
59
|
readonly view: ToolView;
|
|
57
60
|
readonly isError: boolean;
|
|
61
|
+
/** Absent when the tool did not run, or for results recorded before pi measured it. */
|
|
62
|
+
readonly durationMs?: number;
|
|
58
63
|
}
|
|
59
64
|
| {
|
|
60
65
|
readonly seq: number;
|
|
@@ -140,6 +145,7 @@ export type EphemeralEvent =
|
|
|
140
145
|
readonly callId: string;
|
|
141
146
|
readonly view: ToolView;
|
|
142
147
|
readonly isError: boolean;
|
|
148
|
+
readonly durationMs?: number;
|
|
143
149
|
}
|
|
144
150
|
/** Cached picker answers for this cwd are stale. */
|
|
145
151
|
| {
|
|
@@ -231,6 +237,8 @@ export type EphemeralEvent =
|
|
|
231
237
|
readonly tps?: number;
|
|
232
238
|
/** Absent when idle. */
|
|
233
239
|
readonly turnElapsedMs?: number;
|
|
240
|
+
/** The last turn was aborted rather than finished. */
|
|
241
|
+
readonly interrupted?: boolean;
|
|
234
242
|
/** Context filled, 0–100. Absent until a turn has reported usage. */
|
|
235
243
|
readonly contextPercent?: number;
|
|
236
244
|
readonly contextWindow?: number;
|
|
@@ -7,6 +7,7 @@ import type { FileEntry } from "@earendil-works/pi-coding-agent";
|
|
|
7
7
|
import { Attachments } from "#core/attachments/Attachments";
|
|
8
8
|
import { EventLog, type LoggedEntry } from "#core/session/EventLog";
|
|
9
9
|
import { MessageText } from "#core/session/MessageText";
|
|
10
|
+
import { UserPrompt } from "#core/session/UserPrompt";
|
|
10
11
|
import { Tools } from "#core/shared/Tools";
|
|
11
12
|
import type {
|
|
12
13
|
AttachmentView,
|
|
@@ -83,7 +84,7 @@ export class SessionProjection {
|
|
|
83
84
|
const timestamp = Date.parse(entry.timestamp);
|
|
84
85
|
switch (message.role) {
|
|
85
86
|
case "user": {
|
|
86
|
-
const said =
|
|
87
|
+
const said = UserPrompt.of(message.content);
|
|
87
88
|
const attachments: readonly AttachmentView[] = said.files.map(
|
|
88
89
|
(file) => ({
|
|
89
90
|
name: Attachments.nameOf(file.path),
|
|
@@ -99,6 +100,7 @@ export class SessionProjection {
|
|
|
99
100
|
text: said.text,
|
|
100
101
|
timestamp,
|
|
101
102
|
...(attachments.length === 0 ? {} : { attachments }),
|
|
103
|
+
...(said.skill === undefined ? {} : { skill: said.skill }),
|
|
102
104
|
};
|
|
103
105
|
}
|
|
104
106
|
case "assistant": {
|
|
@@ -143,6 +145,7 @@ export class SessionProjection {
|
|
|
143
145
|
callId: message.toolCallId,
|
|
144
146
|
name: message.toolName,
|
|
145
147
|
isError: message.isError,
|
|
148
|
+
durationMs: message.durationMs,
|
|
146
149
|
view: Tools.viewOf({
|
|
147
150
|
name: message.toolName,
|
|
148
151
|
args: this.callArgs.get(message.toolCallId) ?? {},
|
|
@@ -40,6 +40,7 @@ type LiveTool = {
|
|
|
40
40
|
view: ToolView;
|
|
41
41
|
isError: boolean;
|
|
42
42
|
done: boolean;
|
|
43
|
+
durationMs: number | undefined;
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
type LiveMessage = {
|
|
@@ -105,6 +106,7 @@ export class SessionStream implements SessionUi {
|
|
|
105
106
|
private uiSeq = 0;
|
|
106
107
|
private readonly dispatching: string[] = [];
|
|
107
108
|
private turnStartedAt = 0;
|
|
109
|
+
private interrupted = false;
|
|
108
110
|
private gitCwd: string | undefined;
|
|
109
111
|
private gitStop: (() => void) | undefined;
|
|
110
112
|
private gitBranch: string | null = null;
|
|
@@ -422,6 +424,7 @@ export class SessionStream implements SessionUi {
|
|
|
422
424
|
callId: tool.callId,
|
|
423
425
|
view: tool.view,
|
|
424
426
|
isError: tool.isError,
|
|
427
|
+
durationMs: tool.durationMs,
|
|
425
428
|
});
|
|
426
429
|
}
|
|
427
430
|
}
|
|
@@ -465,6 +468,7 @@ export class SessionStream implements SessionUi {
|
|
|
465
468
|
...(this.repoBusy?.() === true ? { repoBusy: true } : {}),
|
|
466
469
|
...(tps === undefined ? {} : { tps }),
|
|
467
470
|
...(turnElapsedMs === undefined ? {} : { turnElapsedMs }),
|
|
471
|
+
...(this.interrupted ? { interrupted: true } : {}),
|
|
468
472
|
...(usage?.percent === null || usage === undefined
|
|
469
473
|
? {}
|
|
470
474
|
: {
|
|
@@ -534,6 +538,7 @@ export class SessionStream implements SessionUi {
|
|
|
534
538
|
switch (event.type) {
|
|
535
539
|
case "agent_start":
|
|
536
540
|
this.turnStartedAt = Date.now();
|
|
541
|
+
this.interrupted = false;
|
|
537
542
|
this.liveTurn = [];
|
|
538
543
|
this.emit(this.sessionState());
|
|
539
544
|
return;
|
|
@@ -569,6 +574,7 @@ export class SessionStream implements SessionUi {
|
|
|
569
574
|
view,
|
|
570
575
|
isError: false,
|
|
571
576
|
done: false,
|
|
577
|
+
durationMs: undefined,
|
|
572
578
|
});
|
|
573
579
|
this.emit({
|
|
574
580
|
type: "tool_call",
|
|
@@ -609,12 +615,14 @@ export class SessionStream implements SessionUi {
|
|
|
609
615
|
tool.view = view;
|
|
610
616
|
tool.isError = event.isError;
|
|
611
617
|
tool.done = true;
|
|
618
|
+
tool.durationMs = event.durationMs;
|
|
612
619
|
}
|
|
613
620
|
this.emit({
|
|
614
621
|
type: "tool_end",
|
|
615
622
|
callId: event.toolCallId,
|
|
616
623
|
view,
|
|
617
624
|
isError: event.isError,
|
|
625
|
+
durationMs: event.durationMs,
|
|
618
626
|
});
|
|
619
627
|
if (Tools.effectOf(event.toolName)?.kind !== "readOnly") {
|
|
620
628
|
this.invalidatePickers("files");
|
|
@@ -652,6 +660,7 @@ export class SessionStream implements SessionUi {
|
|
|
652
660
|
return;
|
|
653
661
|
}
|
|
654
662
|
case "agent_settled":
|
|
663
|
+
this.interrupted = event.aborted;
|
|
655
664
|
void this.flushDurable().then(() => {
|
|
656
665
|
// Clear only after the superseding durable events are sent.
|
|
657
666
|
this.liveTurn = [];
|
|
@@ -182,7 +182,13 @@ export class Bot {
|
|
|
182
182
|
prompt: Prompt
|
|
183
183
|
): Promise<void> {
|
|
184
184
|
const renderer = new Renderer(session, this.grammy.api);
|
|
185
|
-
|
|
185
|
+
let aborted = false;
|
|
186
|
+
const unsubscribe = agent.subscribe((event) => {
|
|
187
|
+
if (event.type === "agent_settled") {
|
|
188
|
+
aborted = event.aborted;
|
|
189
|
+
}
|
|
190
|
+
renderer.handleEvent(event);
|
|
191
|
+
});
|
|
186
192
|
await renderer.start();
|
|
187
193
|
try {
|
|
188
194
|
await agent.prompt(prompt.text, {
|
|
@@ -190,7 +196,11 @@ export class Bot {
|
|
|
190
196
|
source: "rpc",
|
|
191
197
|
});
|
|
192
198
|
const final = extractFinalResult(agent);
|
|
193
|
-
|
|
199
|
+
if (aborted && final.state === "ok") {
|
|
200
|
+
await renderer.finish("", "cancelled");
|
|
201
|
+
} else {
|
|
202
|
+
await renderer.finish(final.text, final.state);
|
|
203
|
+
}
|
|
194
204
|
} catch (err) {
|
|
195
205
|
const msg = (err as Error).message ?? String(err);
|
|
196
206
|
console.error(`[bot] turn failed:`, err);
|
|
@@ -54,12 +54,13 @@ export default function (pi: ExtensionAPI): void {
|
|
|
54
54
|
timer = setInterval(() => setWorkingMessage(ctx), 1000);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
pi.on("
|
|
57
|
+
pi.on("agent_settled", (event, ctx) => {
|
|
58
58
|
stopTimer();
|
|
59
59
|
if (!ctx.hasUI) {
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
|
-
const
|
|
62
|
+
const verb = event.aborted ? "Interrupted after" : "Clanked for";
|
|
63
|
+
const message = `⣿ ${verb} ${Format.formatElapsed(Date.now() - startedAt)}\n`;
|
|
63
64
|
ctx.ui.setWidget(FINAL_WIDGET_ID, [ctx.ui.theme.fg("muted", message)]);
|
|
64
65
|
});
|
|
65
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e,t}from"./mermaid-parser.core-
|
|
1
|
+
import{m as e,t}from"./mermaid-parser.core-CeboWX-k.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-D28B8eI9.js";import"./chunk-O7XYJQB3-4-W0jJea.js";import{n as i,r as a,t as o}from"./chunk-GTNCS2PH-BTulktWP.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-zdZDrs5K.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=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 l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-CrAX-R0u.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-FOHPRMQF-CoA4358r.js";import{M as e}from"./mermaid-parser.core-CeboWX-k.js";export{e as createArchitectureServices};
|