waterplane 0.1.17 → 0.1.19
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/CHANGELOG.md +41 -0
- package/NOTICES.md +18 -7
- package/README.md +46 -2
- package/SECURITY.md +196 -12
- package/node_modules/@waterplane/shared/dist/desktopfiles.d.ts +24 -2
- package/node_modules/@waterplane/shared/dist/desktopfiles.js +73 -3
- package/node_modules/@waterplane/shared/dist/desktopfiles.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/hosts.d.ts +31 -0
- package/node_modules/@waterplane/shared/dist/hosts.js +46 -1
- package/node_modules/@waterplane/shared/dist/hosts.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/hosturl.d.ts +55 -0
- package/node_modules/@waterplane/shared/dist/hosturl.js +85 -0
- package/node_modules/@waterplane/shared/dist/hosturl.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/index.d.ts +4 -0
- package/node_modules/@waterplane/shared/dist/index.js +4 -0
- package/node_modules/@waterplane/shared/dist/index.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/installrow.d.ts +6 -1
- package/node_modules/@waterplane/shared/dist/installrow.js +20 -1
- package/node_modules/@waterplane/shared/dist/installrow.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/lanroute.d.ts +5 -0
- package/node_modules/@waterplane/shared/dist/lanroute.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/pairing.d.ts +96 -2
- package/node_modules/@waterplane/shared/dist/pairing.js +71 -3
- package/node_modules/@waterplane/shared/dist/pairing.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/pake.d.ts +131 -0
- package/node_modules/@waterplane/shared/dist/pake.js +272 -0
- package/node_modules/@waterplane/shared/dist/pake.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/peer.d.ts +63 -0
- package/node_modules/@waterplane/shared/dist/peer.js +41 -0
- package/node_modules/@waterplane/shared/dist/peer.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/plugin/api.d.ts +15 -0
- package/node_modules/@waterplane/shared/dist/plugin/version.d.ts +5 -1
- package/node_modules/@waterplane/shared/dist/plugin/version.js +5 -1
- package/node_modules/@waterplane/shared/dist/plugin/version.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/repotwins.d.ts +47 -0
- package/node_modules/@waterplane/shared/dist/repotwins.js +80 -0
- package/node_modules/@waterplane/shared/dist/repotwins.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/sessioncost/costwords.d.ts +7 -2
- package/node_modules/@waterplane/shared/dist/sessioncost/costwords.js +6 -3
- package/node_modules/@waterplane/shared/dist/sessioncost/costwords.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/waiting.d.ts +64 -0
- package/node_modules/@waterplane/shared/dist/waiting.js +86 -0
- package/node_modules/@waterplane/shared/dist/waiting.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/wire/messages/hostcore.d.ts +3 -0
- package/node_modules/@waterplane/shared/dist/wire/notify.d.ts +2 -0
- package/node_modules/@waterplane/shared/dist/wire/notify.js +2 -0
- package/node_modules/@waterplane/shared/dist/wire/notify.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/repo.d.ts +30 -1
- package/node_modules/@waterplane/shared/dist/wire/repo.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/session/context.d.ts +4 -0
- package/node_modules/@waterplane/shared/dist/wire/session/context.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/sysstat.d.ts +7 -0
- package/node_modules/@waterplane/shared/dist/wire/telemetry.d.ts +3 -0
- package/node_modules/@waterplane/shared/package.json +3 -0
- package/npm-shrinkwrap.json +30 -2
- package/package.json +2 -1
- package/packages/extensions/desktop/helper/Capture.swift +245 -0
- package/packages/extensions/desktop/helper/H264.swift +226 -0
- package/packages/extensions/desktop/helper/Info.plist +20 -0
- package/packages/extensions/desktop/helper/Input.swift +195 -0
- package/packages/extensions/desktop/helper/Jpeg.swift +81 -0
- package/packages/extensions/desktop/helper/PROTOCOL.md +366 -0
- package/packages/extensions/desktop/helper/Params.swift +133 -0
- package/packages/extensions/desktop/helper/Probe.swift +119 -0
- package/packages/extensions/desktop/helper/Protocol.swift +224 -0
- package/packages/extensions/desktop/helper/Request.swift +51 -0
- package/packages/extensions/desktop/helper/Responsibility.swift +133 -0
- package/packages/extensions/desktop/helper/Server.swift +334 -0
- package/packages/extensions/desktop/helper/Synthetic.swift +281 -0
- package/packages/extensions/desktop/helper/build.sh +53 -0
- package/packages/extensions/desktop/helper/main.swift +79 -0
- package/packages/extensions/desktop/helper/selftest-driver +626 -0
- package/packages/extensions/desktop/helper/selftest.sh +16 -0
- package/packages/extensions/desktop/helper-win/Capture.cs +299 -0
- package/packages/extensions/desktop/helper-win/H264.cs +340 -0
- package/packages/extensions/desktop/helper-win/Input.cs +257 -0
- package/packages/extensions/desktop/helper-win/Jpeg.cs +75 -0
- package/packages/extensions/desktop/helper-win/Main.cs +118 -0
- package/packages/extensions/desktop/helper-win/Native.cs +276 -0
- package/packages/extensions/desktop/helper-win/Params.cs +138 -0
- package/packages/extensions/desktop/helper-win/Protocol.cs +206 -0
- package/packages/extensions/desktop/helper-win/Server.cs +304 -0
- package/packages/extensions/desktop/helper-win/Synthetic.cs +88 -0
- package/packages/extensions/desktop/helper-win/build.sh +57 -0
- package/packages/extensions/desktop/helper-win/selftest.sh +36 -0
- package/packages/extensions/desktop/waterplane-plugin.json +24 -0
- package/packages/host/dist/agentlogs.d.ts +18 -0
- package/packages/host/dist/agentlogs.js +58 -0
- package/packages/host/dist/agentlogs.js.map +1 -0
- package/packages/host/dist/agents.d.ts +5 -0
- package/packages/host/dist/agents.js +3 -2
- package/packages/host/dist/agents.js.map +1 -1
- package/packages/host/dist/alwayson.js +1 -1
- package/packages/host/dist/alwayson.js.map +1 -1
- package/packages/host/dist/answergate.js +3 -2
- package/packages/host/dist/answergate.js.map +1 -1
- package/packages/host/dist/attentionstore.d.ts +4 -0
- package/packages/host/dist/attentionstore.js +17 -0
- package/packages/host/dist/attentionstore.js.map +1 -1
- package/packages/host/dist/auth.d.ts +28 -0
- package/packages/host/dist/auth.js +65 -2
- package/packages/host/dist/auth.js.map +1 -1
- package/packages/host/dist/cli/pair.d.ts +4 -0
- package/packages/host/dist/cli/pair.js +18 -5
- package/packages/host/dist/cli/pair.js.map +1 -1
- package/packages/host/dist/composer.d.ts +6 -0
- package/packages/host/dist/composer.js +7 -1
- package/packages/host/dist/composer.js.map +1 -1
- package/packages/host/dist/ctxlog/ctxagents.d.ts +0 -29
- package/packages/host/dist/ctxlog/ctxagents.js +41 -8
- package/packages/host/dist/ctxlog/ctxagents.js.map +1 -1
- package/packages/host/dist/der.d.ts +19 -0
- package/packages/host/dist/der.js +51 -0
- package/packages/host/dist/der.js.map +1 -0
- package/packages/host/dist/doctor.d.ts +2 -0
- package/packages/host/dist/doctor.js +10 -2
- package/packages/host/dist/doctor.js.map +1 -1
- package/packages/host/dist/extensions/desktop/host/auto.d.mts +71 -0
- package/packages/host/dist/extensions/desktop/host/auto.mjs +114 -0
- package/packages/host/dist/extensions/desktop/host/auto.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/desktop.d.mts +51 -0
- package/packages/host/dist/extensions/desktop/host/desktop.mjs +113 -0
- package/packages/host/dist/extensions/desktop/host/desktop.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/helperbin.d.mts +71 -0
- package/packages/host/dist/extensions/desktop/host/helperbin.mjs +160 -0
- package/packages/host/dist/extensions/desktop/host/helperbin.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/index.d.mts +4 -0
- package/packages/host/dist/extensions/desktop/host/index.mjs +88 -0
- package/packages/host/dist/extensions/desktop/host/index.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/knobs.d.mts +52 -0
- package/packages/host/dist/extensions/desktop/host/knobs.mjs +81 -0
- package/packages/host/dist/extensions/desktop/host/knobs.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/probe.d.mts +57 -0
- package/packages/host/dist/extensions/desktop/host/probe.mjs +119 -0
- package/packages/host/dist/extensions/desktop/host/probe.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/records.d.mts +40 -0
- package/packages/host/dist/extensions/desktop/host/records.mjs +101 -0
- package/packages/host/dist/extensions/desktop/host/records.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/session.d.mts +86 -0
- package/packages/host/dist/extensions/desktop/host/session.mjs +318 -0
- package/packages/host/dist/extensions/desktop/host/session.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/setup.d.mts +28 -0
- package/packages/host/dist/extensions/desktop/host/setup.mjs +217 -0
- package/packages/host/dist/extensions/desktop/host/setup.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/host/status.d.mts +27 -0
- package/packages/host/dist/extensions/desktop/host/status.mjs +62 -0
- package/packages/host/dist/extensions/desktop/host/status.mjs.map +1 -0
- package/packages/host/dist/extensions/desktop/shared/wire.d.mts +206 -0
- package/packages/host/dist/extensions/desktop/shared/wire.mjs +174 -0
- package/packages/host/dist/extensions/desktop/shared/wire.mjs.map +1 -0
- package/packages/host/dist/git.d.ts +23 -6
- package/packages/host/dist/git.js +54 -26
- package/packages/host/dist/git.js.map +1 -1
- package/packages/host/dist/gitfetchfail.d.ts +24 -0
- package/packages/host/dist/gitfetchfail.js +62 -0
- package/packages/host/dist/gitfetchfail.js.map +1 -0
- package/packages/host/dist/gitlog.d.ts +4 -0
- package/packages/host/dist/gitlog.js +8 -3
- package/packages/host/dist/gitlog.js.map +1 -1
- package/packages/host/dist/gitnotify.d.ts +7 -1
- package/packages/host/dist/gitnotify.js +61 -1
- package/packages/host/dist/gitnotify.js.map +1 -1
- package/packages/host/dist/healthwatch.js +1 -1
- package/packages/host/dist/healthwatch.js.map +1 -1
- package/packages/host/dist/host.js +5 -1
- package/packages/host/dist/host.js.map +1 -1
- package/packages/host/dist/hoststore.js +4 -4
- package/packages/host/dist/hoststore.js.map +1 -1
- package/packages/host/dist/lantls.d.ts +145 -0
- package/packages/host/dist/lantls.js +337 -0
- package/packages/host/dist/lantls.js.map +1 -0
- package/packages/host/dist/main.js +10 -2
- package/packages/host/dist/main.js.map +1 -1
- package/packages/host/dist/net.d.ts +7 -0
- package/packages/host/dist/net.js +9 -0
- package/packages/host/dist/net.js.map +1 -1
- package/packages/host/dist/origin.d.ts +4 -0
- package/packages/host/dist/origin.js +6 -0
- package/packages/host/dist/origin.js.map +1 -1
- package/packages/host/dist/pair.d.ts +54 -5
- package/packages/host/dist/pair.js +139 -34
- package/packages/host/dist/pair.js.map +1 -1
- package/packages/host/dist/pairpake.d.ts +58 -0
- package/packages/host/dist/pairpake.js +208 -0
- package/packages/host/dist/pairpake.js.map +1 -0
- package/packages/host/dist/passive.d.ts +2 -0
- package/packages/host/dist/passive.js +4 -0
- package/packages/host/dist/passive.js.map +1 -1
- package/packages/host/dist/peers/client.d.ts +3 -1
- package/packages/host/dist/peers/client.js +4 -0
- package/packages/host/dist/peers/client.js.map +1 -1
- package/packages/host/dist/peers/routes.d.ts +6 -1
- package/packages/host/dist/peers/routes.js +39 -0
- package/packages/host/dist/peers/routes.js.map +1 -1
- package/packages/host/dist/permmode.js +3 -3
- package/packages/host/dist/plugins/pluginapi.js +13 -0
- package/packages/host/dist/plugins/pluginapi.js.map +1 -1
- package/packages/host/dist/plugins/pluginregistry.d.ts +6 -0
- package/packages/host/dist/plugins/pluginregistry.js.map +1 -1
- package/packages/host/dist/prepushcheck.d.ts +34 -0
- package/packages/host/dist/prepushcheck.js +157 -0
- package/packages/host/dist/prepushcheck.js.map +1 -0
- package/packages/host/dist/prs.js +2 -1
- package/packages/host/dist/prs.js.map +1 -1
- package/packages/host/dist/reponames.d.ts +26 -0
- package/packages/host/dist/reponames.js +119 -0
- package/packages/host/dist/reponames.js.map +1 -0
- package/packages/host/dist/repos.js +13 -0
- package/packages/host/dist/repos.js.map +1 -1
- package/packages/host/dist/routes/apigitcheck.d.ts +2 -0
- package/packages/host/dist/routes/apigitcheck.js +29 -0
- package/packages/host/dist/routes/apigitcheck.js.map +1 -0
- package/packages/host/dist/routes/apihost.js +28 -1
- package/packages/host/dist/routes/apihost.js.map +1 -1
- package/packages/host/dist/routes/apiio.js +2 -1
- package/packages/host/dist/routes/apiio.js.map +1 -1
- package/packages/host/dist/routes/apirepofiles.js +2 -1
- package/packages/host/dist/routes/apirepofiles.js.map +1 -1
- package/packages/host/dist/routes/apisystem.js +21 -3
- package/packages/host/dist/routes/apisystem.js.map +1 -1
- package/packages/host/dist/server/http.js +31 -5
- package/packages/host/dist/server/http.js.map +1 -1
- package/packages/host/dist/server/intentEvents.js +3 -2
- package/packages/host/dist/server/intentEvents.js.map +1 -1
- package/packages/host/dist/server/plugins.d.ts +13 -0
- package/packages/host/dist/server/plugins.js +26 -0
- package/packages/host/dist/server/plugins.js.map +1 -1
- package/packages/host/dist/server/sessionEvents.js +10 -9
- package/packages/host/dist/server/sessionEvents.js.map +1 -1
- package/packages/host/dist/server/wsops.js +3 -1
- package/packages/host/dist/server/wsops.js.map +1 -1
- package/packages/host/dist/sessionSearch.js +3 -1
- package/packages/host/dist/sessionSearch.js.map +1 -1
- package/packages/host/dist/sessions/apiretry.d.ts +14 -0
- package/packages/host/dist/sessions/apiretry.js +28 -2
- package/packages/host/dist/sessions/apiretry.js.map +1 -1
- package/packages/host/dist/sessions/core.d.ts +5 -0
- package/packages/host/dist/sysstat.js +10 -1
- package/packages/host/dist/sysstat.js.map +1 -1
- package/packages/host/dist/tokenscan.d.ts +4 -2
- package/packages/host/dist/tokenscan.js +5 -3
- package/packages/host/dist/tokenscan.js.map +1 -1
- package/packages/host/dist/transcript/transcriptparse.js +5 -2
- package/packages/host/dist/transcript/transcriptparse.js.map +1 -1
- package/packages/host/dist/turnagents.d.ts +8 -1
- package/packages/host/dist/turnagents.js +49 -16
- package/packages/host/dist/turnagents.js.map +1 -1
- package/packages/host/dist/updatekey.d.ts +22 -0
- package/packages/host/dist/updatekey.js +140 -0
- package/packages/host/dist/updatekey.js.map +1 -0
- package/packages/host/dist/webbundle.d.ts +15 -6
- package/packages/host/dist/webbundle.js +44 -7
- package/packages/host/dist/webbundle.js.map +1 -1
- package/packages/host/dist/wincpu.d.ts +13 -0
- package/packages/host/dist/wincpu.js +101 -0
- package/packages/host/dist/wincpu.js.map +1 -0
- package/packages/host/package.json +2 -1
- package/packages/web/dist/assets/demo-iVbE6mpm.js +26 -0
- package/packages/web/dist/assets/icons-D8RlmSLR.js +1 -0
- package/packages/web/dist/assets/index-DiZysQBa.css +1 -0
- package/packages/web/dist/assets/index-NA--kuEl.js +170 -0
- package/packages/web/dist/assets/noble-DV-r0OkE.js +1 -0
- package/packages/web/dist/assets/{react-CoSyT_xY.js → react-CjmvHigY.js} +2 -2
- package/packages/web/dist/assets/rolldown-runtime-4tVxZq34.js +1 -0
- package/packages/web/dist/assets/shared-CsHyApn-.js +51 -0
- package/packages/web/dist/assets/sheets-CDv71Sfe.js +256 -0
- package/packages/web/dist/assets/xterm-BHsKrDzh.js +16 -0
- package/packages/web/dist/build-id.txt +1 -1
- package/packages/web/dist/buildstamp.json +1 -1
- package/packages/web/dist/index.html +9 -9
- package/packages/web/dist/sw.js +2 -2
- package/release.json +7 -3
- package/packages/web/dist/assets/demo-DkCtg-SJ.js +0 -26
- package/packages/web/dist/assets/icons-B48F-4nA.js +0 -1
- package/packages/web/dist/assets/index-BYRdfW3T.js +0 -170
- package/packages/web/dist/assets/index-DcZrEQNl.css +0 -1
- package/packages/web/dist/assets/rolldown-runtime-BpQH8Ho1.js +0 -1
- package/packages/web/dist/assets/shared-DjRRLGfw.js +0 -50
- package/packages/web/dist/assets/sheets-BGN7Cs73.js +0 -248
- package/packages/web/dist/assets/xterm-C8zLTNGk.js +0 -16
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
* that cannot be placed withholds every running total, because a total missing
|
|
33
33
|
* it would read as complete.
|
|
34
34
|
*/
|
|
35
|
-
import {
|
|
35
|
+
import { statSync } from "node:fs";
|
|
36
36
|
import { join } from "node:path";
|
|
37
37
|
import { AGENT_LIVE_MS, normalizeModel } from "@waterplane/shared";
|
|
38
38
|
import { agentUsage } from "./ctxlog.js";
|
|
39
|
-
import { readMeta } from "./agents.js";
|
|
39
|
+
import { agentLogId, agentLogs, agentLogWorkflow, PARENT_TAIL, readMeta, readTail, readWorkflowJournal } from "./agents.js";
|
|
40
40
|
/** Per-directory ledgers, kept so a poll re-reads only the agent logs that
|
|
41
41
|
* grew — `agentUsage` is incremental given its previous result. */
|
|
42
42
|
const cache = new Map();
|
|
@@ -52,15 +52,13 @@ export function agentsMtime(logPath) {
|
|
|
52
52
|
const dir = subagentsDirOf(logPath);
|
|
53
53
|
let names;
|
|
54
54
|
try {
|
|
55
|
-
names =
|
|
55
|
+
names = agentLogs(dir);
|
|
56
56
|
}
|
|
57
57
|
catch {
|
|
58
58
|
return 0;
|
|
59
59
|
}
|
|
60
60
|
let max = 0;
|
|
61
61
|
for (const n of names) {
|
|
62
|
-
if (!n.startsWith("agent-") || !n.endsWith(".jsonl"))
|
|
63
|
-
continue;
|
|
64
62
|
try {
|
|
65
63
|
max = Math.max(max, statSync(join(dir, n)).mtimeMs);
|
|
66
64
|
}
|
|
@@ -85,13 +83,31 @@ export function noteRetired(line, at, into) {
|
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* `wf_… → the Workflow call that launched it`, off the launch's own tool_result
|
|
88
|
+
* record. A workflow's agents name no `toolUseId` in their meta files, so this
|
|
89
|
+
* is the lookup that puts them on a turn. Read off the structured `toolUseResult`
|
|
90
|
+
* and never the text: a tool result that merely quotes a launch receipt is not one.
|
|
91
|
+
*/
|
|
92
|
+
export function noteWorkflowLaunch(rec, into) {
|
|
93
|
+
const r = rec;
|
|
94
|
+
const runId = r?.toolUseResult?.runId;
|
|
95
|
+
if (typeof runId !== "string" || !runId.startsWith("wf_"))
|
|
96
|
+
return;
|
|
97
|
+
const content = r?.message?.content;
|
|
98
|
+
if (!Array.isArray(content))
|
|
99
|
+
return;
|
|
100
|
+
const res = content.find((b) => b?.type === "tool_result" && typeof b.tool_use_id === "string");
|
|
101
|
+
if (res)
|
|
102
|
+
into.set(runId, res.tool_use_id);
|
|
103
|
+
}
|
|
88
104
|
/**
|
|
89
105
|
* Put each agent's spend on the turn that started it, in place.
|
|
90
106
|
*
|
|
91
107
|
* `partial`: the parent log was tail-read, so earlier turns — and the calls of
|
|
92
108
|
* agents started there — are missing; no running total is published.
|
|
93
109
|
*/
|
|
94
|
-
export function attachAgentSpend(turns, logPath, retired, partial, now = Date.now()) {
|
|
110
|
+
export function attachAgentSpend(turns, logPath, retired, partial, now = Date.now(), workflows = new Map()) {
|
|
95
111
|
const dir = subagentsDirOf(logPath);
|
|
96
112
|
const use = agentUsage(dir, cache.get(dir) ?? null);
|
|
97
113
|
if (!use)
|
|
@@ -107,17 +123,31 @@ export function attachAgentSpend(turns, logPath, retired, partial, now = Date.no
|
|
|
107
123
|
for (const b of t.blocks) {
|
|
108
124
|
if (b.kind !== "tool")
|
|
109
125
|
continue;
|
|
110
|
-
if (b.name === "Task" || b.name === "Agent")
|
|
126
|
+
if (b.name === "Task" || b.name === "Agent" || b.name === "Workflow")
|
|
111
127
|
turnOfCall.set(b.id, t);
|
|
112
128
|
if (b.ok !== undefined)
|
|
113
129
|
answered.add(b.id);
|
|
114
130
|
}
|
|
115
131
|
}
|
|
116
132
|
const metas = new Map();
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
133
|
+
const fileOf = new Map();
|
|
134
|
+
for (const [name, f] of use.files) {
|
|
135
|
+
const id = agentLogId(name);
|
|
136
|
+
metas.set(id, readMeta(join(dir, `${name.slice(0, -".jsonl".length)}.meta.json`)));
|
|
137
|
+
fileOf.set(id, f);
|
|
120
138
|
}
|
|
139
|
+
/** A workflow's agent gets no notification of its own: its journal says when
|
|
140
|
+
* it ended, and only an agent still writing is worth reading one for. */
|
|
141
|
+
const journals = new Map();
|
|
142
|
+
const workflowEnded = (wf, id) => {
|
|
143
|
+
let j = journals.get(wf);
|
|
144
|
+
if (!j) {
|
|
145
|
+
j = readWorkflowJournal(readTail(join(dir, "workflows", wf, "journal.jsonl"), PARENT_TAIL));
|
|
146
|
+
journals.set(wf, j);
|
|
147
|
+
}
|
|
148
|
+
const key = j.agentKey.get(id);
|
|
149
|
+
return key !== undefined && j.ended.has(key);
|
|
150
|
+
};
|
|
121
151
|
/** The top-level agent an agent descends from; itself when it is one. Null
|
|
122
152
|
* on a broken or cyclic chain. */
|
|
123
153
|
const rootOf = (id) => {
|
|
@@ -147,9 +177,10 @@ export function attachAgentSpend(turns, logPath, retired, partial, now = Date.no
|
|
|
147
177
|
const perTurn = new Array(turns.length).fill(0);
|
|
148
178
|
const seenCalls = new Set();
|
|
149
179
|
for (const [name, f] of use.files) {
|
|
150
|
-
const id = name
|
|
180
|
+
const id = agentLogId(name);
|
|
181
|
+
const wf = agentLogWorkflow(name);
|
|
151
182
|
const root = rootOf(id);
|
|
152
|
-
const call = root ? metas.get(root)?.toolUseId : undefined;
|
|
183
|
+
const call = wf ? workflows.get(wf) : root ? metas.get(root)?.toolUseId : undefined;
|
|
153
184
|
const t = call ? turnOfCall.get(call) : undefined;
|
|
154
185
|
if (!t || !root) {
|
|
155
186
|
if (f.tok > 0)
|
|
@@ -158,10 +189,12 @@ export function attachAgentSpend(turns, logPath, retired, partial, now = Date.no
|
|
|
158
189
|
}
|
|
159
190
|
if (call)
|
|
160
191
|
seenCalls.add(call);
|
|
161
|
-
const rootFile =
|
|
162
|
-
const live =
|
|
163
|
-
?
|
|
164
|
-
:
|
|
192
|
+
const rootFile = fileOf.get(root);
|
|
193
|
+
const live = wf
|
|
194
|
+
? now - f.mtime <= AGENT_LIVE_MS && !workflowEnded(wf, id)
|
|
195
|
+
: root === id
|
|
196
|
+
? runningTop(id, f.mtime)
|
|
197
|
+
: now - f.mtime <= AGENT_LIVE_MS && !!rootFile && runningTop(root, Math.max(rootFile.mtime, f.mtime));
|
|
165
198
|
if (live)
|
|
166
199
|
t.agentsRunning = (t.agentsRunning ?? 0) + 1;
|
|
167
200
|
if (f.cost.total > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turnagents.js","sourceRoot":"","sources":["../src/turnagents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"turnagents.js","sourceRoot":"","sources":["../src/turnagents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAmC,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAwB,MAAM,aAAa,CAAC;AAElJ;oEACoE;AACpE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAC5C,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,2DAA2D;AAC3D,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;AAC5D,CAAC;AAED;;6BAE6B;AAC7B,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IACnD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,GAAG,uCAAuC,CAAC;AAC3D,MAAM,YAAY,GAAG,+CAA+C,CAAC;AAErE;mDACmD;AACnD,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,EAAU,EAAE,IAAyB;IAC7E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAAE,OAAO;IAClF,KAAK,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC;QAC5C,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC;QACjB,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,GAAG,IAAI;gBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY,EAAE,IAAyB;IACxE,MAAM,CAAC,GAAG,GAAsF,CAAC;IACjG,MAAM,KAAK,GAAG,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO;IAClE,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;IACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,aAAa,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC;IAChG,IAAI,GAAG;QAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;AAC5C,CAAC;AAID;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAuB,EACvB,OAAe,EACf,OAA4B,EAC5B,OAAgB,EAChB,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAChB,YAAiC,IAAI,GAAG,EAAE;IAE1C,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,uDAAuD;IACzE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpB,IAAI,KAAK,CAAC,IAAI,GAAG,SAAS;QAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;IAErE,qEAAqE;IACrE,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YAChC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9F,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;gBAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5B,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAS,CAAC,CAAC;QAC3F,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpB,CAAC;IACD;8EAC0E;IAC1E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;IACpD,MAAM,aAAa,GAAG,CAAC,EAAU,EAAE,EAAU,EAAW,EAAE;QACxD,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,eAAe,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;YAC5F,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,OAAO,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC;IACF;uCACmC;IACnC,MAAM,MAAM,GAAG,CAAC,EAAU,EAAiB,EAAE;QAC3C,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;YACxC,IAAI,CAAC,CAAC;gBAAE,OAAO,GAAG,CAAC;YACnB,GAAG,GAAG,CAAC,CAAC;QACV,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,SAAiB,EAAW,EAAE;QAC5D,IAAI,GAAG,GAAG,SAAS,GAAG,aAAa;YAAE,OAAO,KAAK,CAAC;QAClD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,SAAS;YAAE,OAAO,KAAK,CAAC;QAC1D,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE,YAAY,KAAK,YAAY,IAAI,CAAC,EAAE,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAC;QAChG,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC,CAAC,sCAAsC;IAC3F,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,KAAK,CAAS,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClD,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;gBAAE,QAAQ,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9D,IAAI,IAAI;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,EAAE;YACb,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,aAAa,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC;YAC1D,CAAC,CAAC,IAAI,KAAK,EAAE;gBACb,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,aAAa,IAAI,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACxG,IAAI,IAAI;YAAE,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACtD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;YAAE,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QAChF,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;YACvE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;YACzD,IAAI,CAAC,CAAC,EAAE,CAAC;gBAAC,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;gBAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC;YAC3D,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;YACf,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;gBAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACpE,CAAC;IACH,CAAC;IACD,2EAA2E;IAC3E,+EAA+E;IAC/E,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACxD,sEAAsE;QACtE,+DAA+D;QAC/D,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,aAAa;YAAE,SAAS;QACjE,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,IAAI,QAAQ;QAAE,OAAO;IAChC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI;YAAE,CAAC,CAAC,eAAe,GAAG,GAAG,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** What the signature covers, beside `hostId` and `gen`, which this file adds. */
|
|
2
|
+
export interface UpdateBody {
|
|
3
|
+
buildId: string;
|
|
4
|
+
total: number;
|
|
5
|
+
files: {
|
|
6
|
+
path: string;
|
|
7
|
+
size: number;
|
|
8
|
+
sha256: string;
|
|
9
|
+
}[];
|
|
10
|
+
}
|
|
11
|
+
/** `signed`: base64 of the JSON a phone reads. `sig`: base64 P1363 `r‖s` over those decoded bytes. */
|
|
12
|
+
export interface UpdateSignature {
|
|
13
|
+
signed: string;
|
|
14
|
+
sig: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function updateKeyFile(root: string): string;
|
|
17
|
+
/** base64 SPKI DER of this desktop's update key, or undefined when there is none to give. */
|
|
18
|
+
export declare function updatePublicKey(root: string): string | undefined;
|
|
19
|
+
/** Sign one build. Undefined means serve it unsigned: never throws, the reason is logged. */
|
|
20
|
+
export declare function signUpdate(root: string, body: UpdateBody): UpdateSignature | undefined;
|
|
21
|
+
/** For tests: forget what is held for `root`, as a restart would. */
|
|
22
|
+
export declare function forgetUpdateKey(root: string): void;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This desktop's update signing key: what lets a phone tell a web bundle this
|
|
3
|
+
* desktop published from one a relay on the Wi-Fi made up.
|
|
4
|
+
*
|
|
5
|
+
* The manifest's hashes arrive in the same answer as the rest of it, so whoever
|
|
6
|
+
* can change the files can change the hashes. A phone that pinned `updateKey`
|
|
7
|
+
* over a protected route can check `sig` over `signed` instead, and a relay has
|
|
8
|
+
* no way to produce one. The key is per desktop, not per project, because people
|
|
9
|
+
* build their own bundles and a private key shipped to every desktop is no key.
|
|
10
|
+
* P-256, not Ed25519: `minSdk` is 24 and old WebViews lack Ed25519.
|
|
11
|
+
*
|
|
12
|
+
* `<state dir>/update-key.json`, mode 0600, created the first time anything asks:
|
|
13
|
+
* the private key (PKCS#8 DER, base64), `gen` and `lastBuildId`.
|
|
14
|
+
*
|
|
15
|
+
* `gen` is what stops an old signed bundle being replayed: it moves up by one
|
|
16
|
+
* only when the served build id differs from `lastBuildId`, so a poll or a
|
|
17
|
+
* restart leaves it alone, and a real revert to an older build gets a higher
|
|
18
|
+
* number than the build it replaces. It reaches the disk before anything is
|
|
19
|
+
* signed with it, so a crash can never hand out the same number twice.
|
|
20
|
+
*
|
|
21
|
+
* Degrade, never break. A file that cannot be read is moved aside and a new key
|
|
22
|
+
* made, which each phone asks about once. When the disk refuses, `signUpdate`
|
|
23
|
+
* and `updatePublicKey` answer undefined, the reason goes to the console once,
|
|
24
|
+
* and the bundle is served unsigned.
|
|
25
|
+
*/
|
|
26
|
+
import { createPrivateKey, createPublicKey, generateKeyPairSync, sign } from "node:crypto";
|
|
27
|
+
import { chmodSync, renameSync } from "node:fs";
|
|
28
|
+
import { join } from "node:path";
|
|
29
|
+
import { logTag } from "@waterplane/shared";
|
|
30
|
+
import { hostStateDir } from "./branddirs.js";
|
|
31
|
+
import { corruptPathFor, readJsonGuardedDetail, writeJsonAtomic } from "./jsonstore.js";
|
|
32
|
+
import { lanIdentity } from "./lanid.js";
|
|
33
|
+
const held = new Map();
|
|
34
|
+
/** Reasons already on the console, so a phone polling a broken disk logs each one once. */
|
|
35
|
+
const said = new Set();
|
|
36
|
+
export function updateKeyFile(root) {
|
|
37
|
+
return join(hostStateDir(root), "update-key.json");
|
|
38
|
+
}
|
|
39
|
+
function privateKeyOf(key) {
|
|
40
|
+
try {
|
|
41
|
+
const k = createPrivateKey({ key: Buffer.from(key, "base64"), format: "der", type: "pkcs8" });
|
|
42
|
+
return k.asymmetricKeyDetails?.namedCurve === "prime256v1" ? k : null;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isStoredKey(v) {
|
|
49
|
+
const j = v;
|
|
50
|
+
return typeof j?.key === "string" && privateKeyOf(j.key) !== null
|
|
51
|
+
&& Number.isSafeInteger(j.gen) && j.gen >= 0
|
|
52
|
+
&& (j.lastBuildId === null || typeof j.lastBuildId === "string");
|
|
53
|
+
}
|
|
54
|
+
function hold(s) {
|
|
55
|
+
const privateKey = privateKeyOf(s.key);
|
|
56
|
+
if (!privateKey)
|
|
57
|
+
throw new Error("update key is not a P-256 key");
|
|
58
|
+
const publicKey = createPublicKey(privateKey).export({ format: "der", type: "spki" }).toString("base64");
|
|
59
|
+
return { key: s.key, gen: s.gen, lastBuildId: s.lastBuildId, privateKey, publicKey };
|
|
60
|
+
}
|
|
61
|
+
function save(file, s) {
|
|
62
|
+
writeJsonAtomic(file, { key: s.key, gen: s.gen, lastBuildId: s.lastBuildId }, { mode: 0o600 });
|
|
63
|
+
}
|
|
64
|
+
/** The key of `root`: held, else read, else made. Throws only when the disk refuses a new one. */
|
|
65
|
+
function load(root) {
|
|
66
|
+
const hit = held.get(root);
|
|
67
|
+
if (hit)
|
|
68
|
+
return hit;
|
|
69
|
+
const file = updateKeyFile(root);
|
|
70
|
+
const read = readJsonGuardedDetail(file, null, isStoredKey);
|
|
71
|
+
if (read.value) {
|
|
72
|
+
try {
|
|
73
|
+
chmodSync(file, 0o600);
|
|
74
|
+
}
|
|
75
|
+
catch { /* best effort on odd filesystems */ }
|
|
76
|
+
const k = hold(read.value);
|
|
77
|
+
held.set(root, k);
|
|
78
|
+
return k;
|
|
79
|
+
}
|
|
80
|
+
if (read.corrupt) {
|
|
81
|
+
// jsonstore leaves a file it could not open where it is. A rename needs no
|
|
82
|
+
// read access, and the next write must never land on the only copy.
|
|
83
|
+
const movedTo = read.corrupt.movedTo ?? corruptPathFor(file);
|
|
84
|
+
if (!read.corrupt.movedTo)
|
|
85
|
+
renameSync(file, movedTo);
|
|
86
|
+
console.error(`${logTag} update signing key could not be read (${read.corrupt.error}); kept as ${movedTo}. Making a new key: each phone asks once before it trusts it.`);
|
|
87
|
+
}
|
|
88
|
+
const key = generateKeyPairSync("ec", { namedCurve: "prime256v1" }).privateKey.export({ format: "der", type: "pkcs8" }).toString("base64");
|
|
89
|
+
const k = hold({ key, gen: 0, lastBuildId: null });
|
|
90
|
+
save(file, k);
|
|
91
|
+
held.set(root, k);
|
|
92
|
+
return k;
|
|
93
|
+
}
|
|
94
|
+
/** `gen` for this build: the same one for the same build, and on disk before it is returned. */
|
|
95
|
+
function advance(root, k, buildId) {
|
|
96
|
+
if (k.lastBuildId === buildId)
|
|
97
|
+
return k.gen;
|
|
98
|
+
save(updateKeyFile(root), { key: k.key, gen: k.gen + 1, lastBuildId: buildId });
|
|
99
|
+
k.gen += 1;
|
|
100
|
+
k.lastBuildId = buildId;
|
|
101
|
+
return k.gen;
|
|
102
|
+
}
|
|
103
|
+
function refused(root, what, e) {
|
|
104
|
+
const why = `${what}: ${e?.message ?? e}`;
|
|
105
|
+
if (!said.has(`${root}\0${why}`))
|
|
106
|
+
console.error(`${logTag} ${why}`);
|
|
107
|
+
said.add(`${root}\0${why}`);
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
/** base64 SPKI DER of this desktop's update key, or undefined when there is none to give. */
|
|
111
|
+
export function updatePublicKey(root) {
|
|
112
|
+
try {
|
|
113
|
+
return load(root).publicKey;
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
return refused(root, "no update signing key", e);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Sign one build. Undefined means serve it unsigned: never throws, the reason is logged. */
|
|
120
|
+
export function signUpdate(root, body) {
|
|
121
|
+
try {
|
|
122
|
+
const { hostId } = lanIdentity(root);
|
|
123
|
+
const k = load(root);
|
|
124
|
+
const gen = advance(root, k, body.buildId);
|
|
125
|
+
const files = body.files.map(({ path, size, sha256 }) => ({ path, size, sha256 }));
|
|
126
|
+
const bytes = Buffer.from(JSON.stringify({ v: 1, hostId, buildId: body.buildId, gen, total: body.total, files }), "utf8");
|
|
127
|
+
const sig = sign("sha256", bytes, { key: k.privateKey, dsaEncoding: "ieee-p1363" });
|
|
128
|
+
said.clear();
|
|
129
|
+
return { signed: bytes.toString("base64"), sig: sig.toString("base64") };
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
return refused(root, "web bundle served unsigned", e);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** For tests: forget what is held for `root`, as a restart would. */
|
|
136
|
+
export function forgetUpdateKey(root) {
|
|
137
|
+
held.delete(root);
|
|
138
|
+
said.clear();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=updatekey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updatekey.js","sourceRoot":"","sources":["../src/updatekey.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,15 +23,24 @@ export interface BundleManifest {
|
|
|
23
23
|
total: number;
|
|
24
24
|
/** Present when `ok` is false — safe to show to the user. */
|
|
25
25
|
reason?: string;
|
|
26
|
+
/** base64 of the JSON this manifest's signature covers. A new client reads
|
|
27
|
+
* only this, so nothing has to be put in a canonical form. Old clients ignore it. */
|
|
28
|
+
signed?: string;
|
|
29
|
+
/** base64 P1363 `r‖s`, ECDSA P-256 SHA-256 over the decoded `signed` bytes. */
|
|
30
|
+
sig?: string;
|
|
26
31
|
}
|
|
27
32
|
/**
|
|
28
|
-
* The manifest for the bundle currently on disk
|
|
29
|
-
*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
* The manifest for the bundle currently on disk, signed with the key of `root`.
|
|
34
|
+
* With no `root` there is no state dir to keep a key in, so it stays unsigned.
|
|
35
|
+
*/
|
|
36
|
+
export declare function webBundleManifest(root?: string): BundleManifest;
|
|
37
|
+
/**
|
|
38
|
+
* `base` with `signed` and `sig`, or `base` itself when it cannot be signed. Signs
|
|
39
|
+
* once per manifest object: the phone polls this, and `hashedManifest` hands back
|
|
40
|
+
* the same object until the tree changes. A refused manifest describes no build
|
|
41
|
+
* and is never signed.
|
|
33
42
|
*/
|
|
34
|
-
export declare function
|
|
43
|
+
export declare function signedManifest(base: BundleManifest, root: string): BundleManifest;
|
|
35
44
|
/**
|
|
36
45
|
* Resolve one bundle-relative path to a real file, or null.
|
|
37
46
|
*
|
|
@@ -20,18 +20,27 @@
|
|
|
20
20
|
* id that changed per build would have the phone re-downloading ~900 KB over
|
|
21
21
|
* a roaming link to arrive at a byte-identical bundle.
|
|
22
22
|
* - **Per-file `sha256`**, so the client can verify each piece before it
|
|
23
|
-
* replaces a working app. This
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* replaces a working app. This catches a truncated transfer on a bad link and
|
|
24
|
+
* nothing more: the hashes come in the same answer as the rest of the
|
|
25
|
+
* manifest, so whoever can change one can change the other.
|
|
26
|
+
* - **`signed` + `sig` are the defence.** `signed` carries the build id, the
|
|
27
|
+
* file list, this desktop's `hostId` and a rising `gen`; `sig` is this
|
|
28
|
+
* desktop's own P-256 key over those bytes (`updatekey.ts`). A phone that
|
|
29
|
+
* pinned the key over a protected route reads only what is inside `signed`,
|
|
30
|
+
* so a relay on the Wi-Fi can neither change a bundle nor replay an older
|
|
31
|
+
* one. It does nothing for a phone with no pin, and nothing against a hostile
|
|
32
|
+
* desktop, which holds the key and can already run arbitrary code on your
|
|
33
|
+
* machine (see SECURITY.md).
|
|
27
34
|
* - **Degrade, never break.** No `dist`, no `build-id.txt`, or a bundle past the
|
|
28
35
|
* caps ⇒ `ok: false` with a reason, and the shell simply says updating is
|
|
29
|
-
* unavailable and keeps running what it has.
|
|
36
|
+
* unavailable and keeps running what it has. No usable signing key ⇒ the same
|
|
37
|
+
* manifest with no `signed`, and the reason on the console.
|
|
30
38
|
*/
|
|
31
39
|
import { createHash } from "node:crypto";
|
|
32
40
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
33
41
|
import { join, relative, resolve, sep } from "node:path";
|
|
34
42
|
import { BRAND } from "@waterplane/shared";
|
|
43
|
+
import { signUpdate } from "./updatekey.js";
|
|
35
44
|
/** Why a dist with no `build-id.txt` is refused, and what to do in either kind
|
|
36
45
|
* of install: a checkout builds it; a release tarball ships it, so one without
|
|
37
46
|
* it is a damaged install. */
|
|
@@ -49,14 +58,42 @@ const MAX_TOTAL = 64 * 1024 * 1024;
|
|
|
49
58
|
/** Cheap fingerprint of the tree (paths + sizes + mtimes), to skip re-hashing. */
|
|
50
59
|
let cacheKey = "";
|
|
51
60
|
let cached = null;
|
|
61
|
+
/** The signed copy of one cached manifest. A failed signing is not kept, so the next poll tries again. */
|
|
62
|
+
let signedCopy = null;
|
|
52
63
|
/**
|
|
53
|
-
* The manifest for the bundle currently on disk
|
|
64
|
+
* The manifest for the bundle currently on disk, signed with the key of `root`.
|
|
65
|
+
* With no `root` there is no state dir to keep a key in, so it stays unsigned.
|
|
66
|
+
*/
|
|
67
|
+
export function webBundleManifest(root) {
|
|
68
|
+
const base = hashedManifest();
|
|
69
|
+
return root === undefined ? base : signedManifest(base, root);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* `base` with `signed` and `sig`, or `base` itself when it cannot be signed. Signs
|
|
73
|
+
* once per manifest object: the phone polls this, and `hashedManifest` hands back
|
|
74
|
+
* the same object until the tree changes. A refused manifest describes no build
|
|
75
|
+
* and is never signed.
|
|
76
|
+
*/
|
|
77
|
+
export function signedManifest(base, root) {
|
|
78
|
+
if (!base.ok || !base.buildId)
|
|
79
|
+
return base;
|
|
80
|
+
if (signedCopy?.base === base && signedCopy.root === root)
|
|
81
|
+
return signedCopy.out;
|
|
82
|
+
const sig = signUpdate(root, { buildId: base.buildId, total: base.total, files: base.files });
|
|
83
|
+
if (!sig)
|
|
84
|
+
return base;
|
|
85
|
+
const out = { ...base, ...sig };
|
|
86
|
+
signedCopy = { base, root, out };
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The hashed manifest of the tree.
|
|
54
91
|
*
|
|
55
92
|
* Hashes are cached against a paths+sizes+mtimes fingerprint: the phone polls
|
|
56
93
|
* this, and re-reading ~1 MB per poll to produce a value that changes a few
|
|
57
94
|
* times a day is waste. A rebuild moves an mtime, so the cache cannot go stale.
|
|
58
95
|
*/
|
|
59
|
-
|
|
96
|
+
function hashedManifest() {
|
|
60
97
|
let files;
|
|
61
98
|
try {
|
|
62
99
|
files = walk(WEB_DIST).sort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webbundle.js","sourceRoot":"","sources":["../src/webbundle.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"webbundle.js","sourceRoot":"","sources":["../src/webbundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const WIN_CPU_STALE_MS = 15000;
|
|
2
|
+
/** One line of the child's output → percent busy, or null. Accepts `12.5`; a
|
|
3
|
+
* comma decimal, text, blank or an out-of-range value is null. Utility may
|
|
4
|
+
* exceed 100 on a turbo-boosted core, so up to 200 is clamped, beyond is null. */
|
|
5
|
+
export declare function parseCpuLine(line: string): number | null;
|
|
6
|
+
/** Stop the child (shutdown). */
|
|
7
|
+
export declare function stopWindowsCpu(): void;
|
|
8
|
+
/** The newest Windows-wide reading, or null (not WSL, interop missing, child
|
|
9
|
+
* dead, or reading stale). Starts the child lazily on first call. */
|
|
10
|
+
export declare function windowsCpuNow(now?: number): {
|
|
11
|
+
pct: number;
|
|
12
|
+
at: number;
|
|
13
|
+
} | null;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows-wide CPU for a host that runs inside WSL2.
|
|
3
|
+
*
|
|
4
|
+
* Inside the VM `/proc/stat` (and so `os.cpus()` and the load average) only
|
|
5
|
+
* describes the VM's own load; Task Manager shows the whole machine, so the
|
|
6
|
+
* phone read far LOWER than the desktop beside it. Here ONE long-running
|
|
7
|
+
* `powershell.exe` (WSL interop) prints the machine's utilisation every
|
|
8
|
+
* couple of seconds; we keep the newest line. No process is spawned per poll.
|
|
9
|
+
*
|
|
10
|
+
* It reads the WMI perf class (`Win32_PerfFormattedData_*`), whose class and
|
|
11
|
+
* property names are English on every locale — unlike `typeperf`'s counter
|
|
12
|
+
* paths, which are localised. `Processor Information` `PercentProcessorUtility`
|
|
13
|
+
* is what Task Manager's CPU graph uses; the older `PercentProcessorTime` is
|
|
14
|
+
* the fallback. A line that is not a number in range is DROPPED, and a reading
|
|
15
|
+
* older than STALE_MS is ABSENT: the caller then falls back to the VM's own
|
|
16
|
+
* figure and says so. Never a wrong number.
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { isWsl } from "./ocrlocal.js";
|
|
20
|
+
export const WIN_CPU_STALE_MS = 15_000;
|
|
21
|
+
const RETRY_MS = 60_000;
|
|
22
|
+
const INTERVAL_S = 2;
|
|
23
|
+
/** One line of the child's output → percent busy, or null. Accepts `12.5`; a
|
|
24
|
+
* comma decimal, text, blank or an out-of-range value is null. Utility may
|
|
25
|
+
* exceed 100 on a turbo-boosted core, so up to 200 is clamped, beyond is null. */
|
|
26
|
+
export function parseCpuLine(line) {
|
|
27
|
+
const s = line.trim();
|
|
28
|
+
if (!/^\d{1,3}(\.\d+)?$/.test(s))
|
|
29
|
+
return null;
|
|
30
|
+
const n = Number(s);
|
|
31
|
+
if (!Number.isFinite(n) || n < 0 || n > 200)
|
|
32
|
+
return null;
|
|
33
|
+
return Math.min(100, n);
|
|
34
|
+
}
|
|
35
|
+
const SCRIPT = [
|
|
36
|
+
"$ErrorActionPreference='SilentlyContinue';",
|
|
37
|
+
"$c=[cultureinfo]::InvariantCulture;",
|
|
38
|
+
"while($true){",
|
|
39
|
+
"$v=$null;",
|
|
40
|
+
"$u=Get-CimInstance Win32_PerfFormattedData_Counters_ProcessorInformation -Filter \"Name='_Total'\";",
|
|
41
|
+
"if($u -and $u.PercentProcessorUtility -ne $null){$v=$u.PercentProcessorUtility}",
|
|
42
|
+
"else{$p=Get-CimInstance Win32_PerfFormattedData_PerfOS_Processor -Filter \"Name='_Total'\";if($p){$v=$p.PercentProcessorTime}}",
|
|
43
|
+
"if($v -ne $null){[Console]::Out.WriteLine(([double]$v).ToString('0.0',$c))}",
|
|
44
|
+
`Start-Sleep -Seconds ${INTERVAL_S}}`,
|
|
45
|
+
].join("");
|
|
46
|
+
let latest = null;
|
|
47
|
+
let child = null;
|
|
48
|
+
let failedAt = 0;
|
|
49
|
+
let wsl = null;
|
|
50
|
+
const detectWsl = () => (wsl ??= process.platform === "linux" && isWsl());
|
|
51
|
+
function start() {
|
|
52
|
+
try {
|
|
53
|
+
let buf = "";
|
|
54
|
+
const c = spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", SCRIPT], {
|
|
55
|
+
stdio: ["ignore", "pipe", "ignore"], windowsHide: true,
|
|
56
|
+
});
|
|
57
|
+
child = c;
|
|
58
|
+
c.stdout.setEncoding("utf8");
|
|
59
|
+
c.stdout.on("data", (d) => {
|
|
60
|
+
buf += d;
|
|
61
|
+
let i;
|
|
62
|
+
while ((i = buf.indexOf("\n")) >= 0) {
|
|
63
|
+
const pct = parseCpuLine(buf.slice(0, i));
|
|
64
|
+
buf = buf.slice(i + 1);
|
|
65
|
+
if (pct !== null)
|
|
66
|
+
latest = { pct, at: Date.now() };
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const dead = () => { if (child === c) {
|
|
70
|
+
child = null;
|
|
71
|
+
failedAt = Date.now();
|
|
72
|
+
} };
|
|
73
|
+
c.on("error", dead);
|
|
74
|
+
c.on("exit", dead);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
failedAt = Date.now();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Stop the child (shutdown). */
|
|
81
|
+
export function stopWindowsCpu() {
|
|
82
|
+
const c = child;
|
|
83
|
+
child = null;
|
|
84
|
+
try {
|
|
85
|
+
c?.kill();
|
|
86
|
+
}
|
|
87
|
+
catch { /* already gone */ }
|
|
88
|
+
}
|
|
89
|
+
process.on("exit", stopWindowsCpu);
|
|
90
|
+
/** The newest Windows-wide reading, or null (not WSL, interop missing, child
|
|
91
|
+
* dead, or reading stale). Starts the child lazily on first call. */
|
|
92
|
+
export function windowsCpuNow(now = Date.now()) {
|
|
93
|
+
if (!detectWsl())
|
|
94
|
+
return null;
|
|
95
|
+
if (!child && now - failedAt >= RETRY_MS)
|
|
96
|
+
start();
|
|
97
|
+
if (!latest || now - latest.at > WIN_CPU_STALE_MS)
|
|
98
|
+
return null;
|
|
99
|
+
return latest;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=wincpu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wincpu.js","sourceRoot":"","sources":["../src/wincpu.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"start": "node dist/main.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
+
"@noble/curves": "2.4.0",
|
|
14
15
|
"@waterplane/shared": "*",
|
|
15
16
|
"@xterm/headless": "^5.5.0",
|
|
16
17
|
"node-pty": "1.2.0-beta.15",
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
"ws": "^8.22.0"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@types/node": "^22.
|
|
22
|
+
"@types/node": "^22.20.5",
|
|
22
23
|
"@types/web-push": "^3.6.4",
|
|
23
24
|
"@types/ws": "^8.18.2",
|
|
24
25
|
"tsx": "^4.23.15"
|