cli-jaw 1.7.34 → 1.7.35
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/dist/bin/cli-jaw.js +5 -1
- package/dist/bin/cli-jaw.js.map +1 -1
- package/dist/bin/commands/dashboard.js +78 -0
- package/dist/bin/commands/dashboard.js.map +1 -0
- package/dist/lib/quota-copilot.js +5 -0
- package/dist/lib/quota-copilot.js.map +1 -1
- package/dist/src/agent/args.js +2 -0
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/events.js +43 -1
- package/dist/src/agent/events.js.map +1 -1
- package/dist/src/manager/constants.js +9 -0
- package/dist/src/manager/constants.js.map +1 -0
- package/dist/src/manager/metadata.js +35 -0
- package/dist/src/manager/metadata.js.map +1 -0
- package/dist/src/manager/proxy.js +134 -0
- package/dist/src/manager/proxy.js.map +1 -0
- package/dist/src/manager/scan.js +111 -0
- package/dist/src/manager/scan.js.map +1 -0
- package/dist/src/manager/server.js +85 -0
- package/dist/src/manager/server.js.map +1 -0
- package/dist/src/manager/types.js +2 -0
- package/dist/src/manager/types.js.map +1 -0
- package/dist/src/routes/quota.js +42 -0
- package/dist/src/routes/quota.js.map +1 -1
- package/package.json +6 -1
- package/public/css/chat.css +27 -0
- package/public/css/diagram.css +48 -2
- package/public/dist/assets/api-Cl2oljO1.js +1 -0
- package/public/dist/assets/{index-wUWc2M5K.js → app-58Z9R8qM.js} +4 -4
- package/public/dist/assets/app-DWH_NZRE.css +1 -0
- package/public/dist/assets/architecture-YZFGNWBL-D4g_rKok.js +1 -0
- package/public/dist/assets/architectureDiagram-Q4EWVU46-DVbii_Pt.js +1 -0
- package/public/dist/assets/blockDiagram-DXYQGD6D-BStipezp.js +1 -0
- package/public/dist/assets/c4Diagram-AHTNJAMY-BYno4Snw.js +1 -0
- package/public/dist/assets/classDiagram-6PBFFD2Q-QzqRo_9X.js +1 -0
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-CchGqJUH.js +1 -0
- package/public/dist/assets/{constants-BU8a_R5s.js → constants-fUXYKkoK.js} +1 -1
- package/public/dist/assets/cose-bilkent-S5V4N54A-TJS1iaqp.js +1 -0
- package/public/dist/assets/dagre-KV5264BT-C_DCJZ7t.js +1 -0
- package/public/dist/assets/diagram-5BDNPKRD-CKix1NRO.js +1 -0
- package/public/dist/assets/diagram-G4DWMVQ6-CoDTDNnx.js +1 -0
- package/public/dist/assets/diagram-MMDJMWI5-DYx0PwrY.js +1 -0
- package/public/dist/assets/diagram-TYMM5635-Bx1779dG.js +1 -0
- package/public/dist/assets/{employees-p53cgGmH.js → employees-CnA_uLbJ.js} +1 -1
- package/public/dist/assets/erDiagram-SMLLAGMA-C0INYE-d.js +1 -0
- package/public/dist/assets/flowDiagram-DWJPFMVM-DfQIgEdB.js +1 -0
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-B8o_Hblo.js +1 -0
- package/public/dist/assets/gitGraph-7Q5UKJZL-DBMf1L33.js +1 -0
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-B2nqnLHi.js +1 -0
- package/public/dist/assets/idb-cache-C5ilDI6r.js +1 -0
- package/public/dist/assets/info-OMHHGYJF-C3gtg5Od.js +1 -0
- package/public/dist/assets/infoDiagram-42DDH7IO-Brz9iwrL.js +1 -0
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-C0YeQJh0.js +1 -0
- package/public/dist/assets/journeyDiagram-VCZTEJTY-BypDthzR.js +1 -0
- package/public/dist/assets/kanban-definition-6JOO6SKY-LkyDUgUP.js +1 -0
- package/public/dist/assets/katex-BL3z5Bli.js +1 -0
- package/public/dist/assets/manager-D4L7R_7R.css +1 -0
- package/public/dist/assets/manager-DtTAKPgY.js +9 -0
- package/public/dist/assets/memory-BN3grLR7.js +1 -0
- package/public/dist/assets/{memory-C2i7ZIvv.js → memory-RKpZbPTW.js} +1 -1
- package/public/dist/assets/mermaid.core-D6PDYVgC.js +1 -0
- package/public/dist/assets/mindmap-definition-QFDTVHPH-rV1Hipx-.js +1 -0
- package/public/dist/assets/packet-4T2RLAQJ-BuK6y2B7.js +1 -0
- package/public/dist/assets/pie-ZZUOXDRM-x8CPu972.js +1 -0
- package/public/dist/assets/pieDiagram-DEJITSTG-DpxKH4h4.js +1 -0
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-BkRLuqoa.js +1 -0
- package/public/dist/assets/radar-PYXPWWZC-CsTAKlcV.js +1 -0
- package/public/dist/assets/render-D9bnLVR_.js +30 -0
- package/public/dist/assets/requirementDiagram-MS252O5E-BdqZlJ0O.js +1 -0
- package/public/dist/assets/sankeyDiagram-XADWPNL6-b3SwMAxC.js +1 -0
- package/public/dist/assets/sequenceDiagram-FGHM5R23-BmjI6n81.js +1 -0
- package/public/dist/assets/{settings-BUEiZgkm.js → settings-B8oUfDm4.js} +8 -8
- package/public/dist/assets/settings-DvGS6X_5.js +1 -0
- package/public/dist/assets/{skills-CSuSbBWa.js → skills-CHB_WsxF.js} +1 -1
- package/public/dist/assets/skills-WhnGcvvJ.js +1 -0
- package/public/dist/assets/{slash-commands-D-v0DlbY.js → slash-commands-CbsN2LqT.js} +1 -1
- package/public/dist/assets/slash-commands-DOh3zvJ7.js +1 -0
- package/public/dist/assets/stateDiagram-FHFEXIEX-DRsIDvF8.js +1 -0
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-IJMg9fYC.js +1 -0
- package/public/dist/assets/timeline-definition-GMOUNBTQ-B-0E30rh.js +1 -0
- package/public/dist/assets/treeView-SZITEDCU-CRgtpI0K.js +1 -0
- package/public/dist/assets/treemap-W4RFUUIX-DB5B-smF.js +1 -0
- package/public/dist/assets/ui-Cg8zuDaT.js +131 -0
- package/public/dist/assets/ui-HckqJaBX.js +1 -0
- package/public/dist/assets/{vendor-mermaid-UktBx7L0.js → vendor-mermaid-DHVxHqbi.js} +6 -6
- package/public/dist/assets/{vendor-render-D2YP6GiF.js → vendor-render-BaFgDHeH.js} +1 -1
- package/public/dist/assets/vennDiagram-DHZGUBPP-BBd9TC4D.js +1 -0
- package/public/dist/assets/wardley-RL74JXVD-BzCH0WF9.js +1 -0
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-DgenAPEz.js +1 -0
- package/public/dist/assets/ws-DSntry14.js +14 -0
- package/public/dist/assets/xychartDiagram-5P7HB3ND-BmvcJ6sg.js +1 -0
- package/public/dist/index.html +2 -2
- package/public/dist/manager/index.html +14 -0
- package/public/js/diagram/iframe-renderer.ts +196 -77
- package/public/js/features/process-block.ts +2 -2
- package/public/js/features/settings-cli-status.ts +20 -1
- package/public/js/features/settings-types.ts +1 -1
- package/public/js/render.ts +16 -3
- package/public/js/ui.ts +42 -0
- package/public/js/ws.ts +20 -4
- package/public/manager/index.html +13 -0
- package/public/manager/src/App.tsx +185 -0
- package/public/manager/src/InstancePreview.tsx +72 -0
- package/public/manager/src/api.ts +8 -0
- package/public/manager/src/main.tsx +9 -0
- package/public/manager/src/preview.ts +35 -0
- package/public/manager/src/styles.css +309 -0
- package/public/manager/src/types.ts +44 -0
- package/public/dist/assets/api-COrKYKcO.js +0 -1
- package/public/dist/assets/architecture-YZFGNWBL-B2Nc8YC_.js +0 -1
- package/public/dist/assets/architectureDiagram-Q4EWVU46-EML5rtmP.js +0 -1
- package/public/dist/assets/blockDiagram-DXYQGD6D-Ds9bBl-N.js +0 -1
- package/public/dist/assets/c4Diagram-AHTNJAMY-BVpUT3Om.js +0 -1
- package/public/dist/assets/classDiagram-6PBFFD2Q-DG8IYzhr.js +0 -1
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-B5j0d5gs.js +0 -1
- package/public/dist/assets/cose-bilkent-S5V4N54A-kNrexiHE.js +0 -1
- package/public/dist/assets/dagre-KV5264BT-Ylb1W0yQ.js +0 -1
- package/public/dist/assets/diagram-5BDNPKRD-CPxqMVrp.js +0 -1
- package/public/dist/assets/diagram-G4DWMVQ6-Dm1xfj8I.js +0 -1
- package/public/dist/assets/diagram-MMDJMWI5-VsjfxFEK.js +0 -1
- package/public/dist/assets/diagram-TYMM5635-CrMZri_r.js +0 -1
- package/public/dist/assets/erDiagram-SMLLAGMA-Felxus25.js +0 -1
- package/public/dist/assets/flowDiagram-DWJPFMVM-kQrkSkw2.js +0 -1
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-CulD-LkD.js +0 -1
- package/public/dist/assets/gitGraph-7Q5UKJZL-DbbbZYM5.js +0 -1
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-oTUYJsKL.js +0 -1
- package/public/dist/assets/idb-cache-C7z4qE00.js +0 -1
- package/public/dist/assets/index-CLKLbGzn.css +0 -1
- package/public/dist/assets/info-OMHHGYJF-auV0JwD8.js +0 -1
- package/public/dist/assets/infoDiagram-42DDH7IO-B2XOJXrL.js +0 -1
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-CsmszxH_.js +0 -1
- package/public/dist/assets/journeyDiagram-VCZTEJTY-MmzEBROj.js +0 -1
- package/public/dist/assets/kanban-definition-6JOO6SKY-DcbxzAKu.js +0 -1
- package/public/dist/assets/katex-Bh3QhMKY.js +0 -1
- package/public/dist/assets/memory-6zLEr-qI.js +0 -1
- package/public/dist/assets/mermaid.core-CoRN09Dx.js +0 -1
- package/public/dist/assets/mindmap-definition-QFDTVHPH-CMqZWcUf.js +0 -1
- package/public/dist/assets/packet-4T2RLAQJ-C_PFKo5G.js +0 -1
- package/public/dist/assets/pie-ZZUOXDRM-CcqLxwbG.js +0 -1
- package/public/dist/assets/pieDiagram-DEJITSTG-C9r3BQ9f.js +0 -1
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-Du4pEL4T.js +0 -1
- package/public/dist/assets/radar-PYXPWWZC-BWOF5omS.js +0 -1
- package/public/dist/assets/render-CulTuvJs.js +0 -30
- package/public/dist/assets/requirementDiagram-MS252O5E-Dyz9eEFP.js +0 -1
- package/public/dist/assets/sankeyDiagram-XADWPNL6-DLgUCKs2.js +0 -1
- package/public/dist/assets/sequenceDiagram-FGHM5R23-c0nA9K_Q.js +0 -1
- package/public/dist/assets/settings-BhrOslae.js +0 -1
- package/public/dist/assets/skills-CgwxEvFx.js +0 -1
- package/public/dist/assets/slash-commands-Bo8jvBfI.js +0 -1
- package/public/dist/assets/stateDiagram-FHFEXIEX-D2aVOdby.js +0 -1
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-DuwdzBLR.js +0 -1
- package/public/dist/assets/timeline-definition-GMOUNBTQ-PuaZYI31.js +0 -1
- package/public/dist/assets/treeView-SZITEDCU-D8mODguI.js +0 -1
- package/public/dist/assets/treemap-W4RFUUIX-DqqBuiM1.js +0 -1
- package/public/dist/assets/ui-4JiRyxJy.js +0 -131
- package/public/dist/assets/ui-Dx0MwI23.js +0 -1
- package/public/dist/assets/vennDiagram-DHZGUBPP-4blQ8E1z.js +0 -1
- package/public/dist/assets/wardley-RL74JXVD-Dn1IRCw2.js +0 -1
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-OUBAKNJu.js +0 -1
- package/public/dist/assets/ws-DKtFfZsY.js +0 -14
- package/public/dist/assets/xychartDiagram-5P7HB3ND-CyZD7ovz.js +0 -1
- /package/public/dist/assets/{api-DygAf_G_.js → api-CnBOYa3F.js} +0 -0
- /package/public/dist/assets/{idb-cache-DbK81tgv.js → idb-cache-CjnC_K0x.js} +0 -0
- /package/public/dist/assets/{locale-CxI5nTcf.js → locale-heAuYK-3.js} +0 -0
- /package/public/dist/assets/{rolldown-runtime-FhOqtrmT.js → rolldown-runtime-DE9SaGGd.js} +0 -0
- /package/public/dist/assets/{state-O6NVkWcL.js → state-CPF7TImo.js} +0 -0
- /package/public/dist/assets/{vendor-icons-Bs4t7RP2.js → vendor-icons-D2l6ddC0.js} +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const DASHBOARD_DEFAULT_PORT = '24576';
|
|
2
|
+
export const DASHBOARD_FALLBACK_PORT_START = 24577;
|
|
3
|
+
export const DASHBOARD_FALLBACK_PORT_END = 24590;
|
|
4
|
+
export const MANAGED_INSTANCE_HOST = '127.0.0.1';
|
|
5
|
+
export const MANAGED_INSTANCE_PORT_FROM = 3457;
|
|
6
|
+
export const MANAGED_INSTANCE_PORT_COUNT = 50;
|
|
7
|
+
export const MANAGED_INSTANCE_PORT_TO = MANAGED_INSTANCE_PORT_FROM + MANAGED_INSTANCE_PORT_COUNT - 1;
|
|
8
|
+
export const DASHBOARD_SCAN_TIMEOUT_MS = 450;
|
|
9
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/manager/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAC9C,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AACnD,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC;AAEjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC;AACjD,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,wBAAwB,GACjC,0BAA0B,GAAG,2BAA2B,GAAG,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
function asRecord(value) {
|
|
4
|
+
return value && typeof value === 'object' ? value : null;
|
|
5
|
+
}
|
|
6
|
+
function readString(source, keys) {
|
|
7
|
+
if (!source)
|
|
8
|
+
return null;
|
|
9
|
+
for (const key of keys) {
|
|
10
|
+
const value = source[key];
|
|
11
|
+
if (typeof value === 'string' && value.trim())
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
export function deriveDashboardInstanceId(homePath) {
|
|
17
|
+
if (!homePath)
|
|
18
|
+
return null;
|
|
19
|
+
const base = basename(homePath);
|
|
20
|
+
if (base === '.cli-jaw')
|
|
21
|
+
return 'default';
|
|
22
|
+
const hash = createHash('md5').update(homePath).digest('hex').slice(0, 8);
|
|
23
|
+
return `${base.replace(/^\./, '')}-${hash}`;
|
|
24
|
+
}
|
|
25
|
+
export function normalizeSettingsMetadata(settingsBody) {
|
|
26
|
+
const root = asRecord(settingsBody);
|
|
27
|
+
const data = asRecord(root?.data);
|
|
28
|
+
const source = data || root;
|
|
29
|
+
const workingDir = readString(source, ['workingDir', 'cwd']);
|
|
30
|
+
const homeDisplay = readString(source, ['jawHome', 'JAW_HOME', 'home', 'homePath']) || workingDir;
|
|
31
|
+
const currentCli = readString(source, ['cli', 'currentCli']);
|
|
32
|
+
const currentModel = readString(source, ['model', 'currentModel']);
|
|
33
|
+
return { homeDisplay, workingDir, currentCli, currentModel };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/manager/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC,SAAS,QAAQ,CAAC,KAAc;IAC5B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC;AAED,SAAS,UAAU,CAAC,MAAsC,EAAE,IAAc;IACtE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAuB;IAC7D,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,YAAqB;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,IAAI,IAAI,CAAC;IAE5B,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC;IAClG,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IAEnE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import net from 'node:net';
|
|
3
|
+
import { MANAGED_INSTANCE_HOST, MANAGED_INSTANCE_PORT_COUNT, MANAGED_INSTANCE_PORT_FROM, } from './constants.js';
|
|
4
|
+
function positiveInt(value, fallback) {
|
|
5
|
+
const parsed = Number(value);
|
|
6
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
7
|
+
}
|
|
8
|
+
export function dashboardProxyRange(options = {}) {
|
|
9
|
+
const from = positiveInt(options.from, MANAGED_INSTANCE_PORT_FROM);
|
|
10
|
+
const count = positiveInt(options.count, MANAGED_INSTANCE_PORT_COUNT);
|
|
11
|
+
return { from, to: from + Math.max(1, count) - 1 };
|
|
12
|
+
}
|
|
13
|
+
export function isDashboardProxyPortAllowed(port, range) {
|
|
14
|
+
return Number.isInteger(port) && port >= range.from && port <= range.to;
|
|
15
|
+
}
|
|
16
|
+
function safeDecodePath(path) {
|
|
17
|
+
try {
|
|
18
|
+
return decodeURIComponent(path);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function isUnsafeProxyPath(targetPath) {
|
|
25
|
+
if (!targetPath.startsWith('/'))
|
|
26
|
+
return true;
|
|
27
|
+
if (/%2f/i.test(targetPath) || /%5c/i.test(targetPath))
|
|
28
|
+
return true;
|
|
29
|
+
const decoded = safeDecodePath(targetPath);
|
|
30
|
+
if (!decoded)
|
|
31
|
+
return true;
|
|
32
|
+
if (decoded.includes('\\'))
|
|
33
|
+
return true;
|
|
34
|
+
const pathname = decoded.split(/[?#]/, 1)[0] || '/';
|
|
35
|
+
return pathname.split('/').some(segment => segment === '..');
|
|
36
|
+
}
|
|
37
|
+
export function parseDashboardProxyUrl(originalUrl, range) {
|
|
38
|
+
const match = originalUrl.match(/^\/i\/(\d+)(\/.*)?$/);
|
|
39
|
+
if (!match)
|
|
40
|
+
return { ok: false, status: 404, reason: 'proxy route not found' };
|
|
41
|
+
const port = Number(match[1]);
|
|
42
|
+
if (!isDashboardProxyPortAllowed(port, range)) {
|
|
43
|
+
return { ok: false, status: 403, reason: 'proxy port is outside the allowed dashboard range' };
|
|
44
|
+
}
|
|
45
|
+
const targetPath = match[2] || '/';
|
|
46
|
+
if (isUnsafeProxyPath(targetPath)) {
|
|
47
|
+
return { ok: false, status: 400, reason: 'unsafe proxy path' };
|
|
48
|
+
}
|
|
49
|
+
return { ok: true, port, targetPath };
|
|
50
|
+
}
|
|
51
|
+
function sanitizeResponseHeaders(headers, port) {
|
|
52
|
+
const next = {};
|
|
53
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
54
|
+
const lower = key.toLowerCase();
|
|
55
|
+
if (lower === 'x-frame-options' || lower === 'content-security-policy')
|
|
56
|
+
continue;
|
|
57
|
+
if (lower === 'location' && typeof value === 'string') {
|
|
58
|
+
next[key] = value.replace(`http://${MANAGED_INSTANCE_HOST}:${port}`, `/i/${port}`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
next[key] = value;
|
|
62
|
+
}
|
|
63
|
+
return next;
|
|
64
|
+
}
|
|
65
|
+
function proxyHttpRequest(req, res, range) {
|
|
66
|
+
const parsed = parseDashboardProxyUrl(req.originalUrl, range);
|
|
67
|
+
if (!parsed.ok) {
|
|
68
|
+
res.status(parsed.status).json({ ok: false, error: parsed.reason });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const upstream = http.request({
|
|
72
|
+
hostname: MANAGED_INSTANCE_HOST,
|
|
73
|
+
port: parsed.port,
|
|
74
|
+
method: req.method,
|
|
75
|
+
path: parsed.targetPath,
|
|
76
|
+
headers: {
|
|
77
|
+
...req.headers,
|
|
78
|
+
host: `${MANAGED_INSTANCE_HOST}:${parsed.port}`,
|
|
79
|
+
origin: `http://${MANAGED_INSTANCE_HOST}:${parsed.port}`,
|
|
80
|
+
referer: `http://${MANAGED_INSTANCE_HOST}:${parsed.port}/`,
|
|
81
|
+
},
|
|
82
|
+
}, (upstreamRes) => {
|
|
83
|
+
res.writeHead(upstreamRes.statusCode || 502, upstreamRes.statusMessage, sanitizeResponseHeaders(upstreamRes.headers, parsed.port));
|
|
84
|
+
upstreamRes.pipe(res);
|
|
85
|
+
});
|
|
86
|
+
upstream.on('error', (error) => {
|
|
87
|
+
if (!res.headersSent) {
|
|
88
|
+
res.status(502).json({ ok: false, error: error.message });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
res.end();
|
|
92
|
+
});
|
|
93
|
+
req.pipe(upstream);
|
|
94
|
+
}
|
|
95
|
+
export function buildProxyUpgradeRequest(req, targetPath, targetPort) {
|
|
96
|
+
const lines = [`${req.method || 'GET'} ${targetPath} HTTP/${req.httpVersion}`];
|
|
97
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
98
|
+
if (value == null)
|
|
99
|
+
continue;
|
|
100
|
+
const headerValue = Array.isArray(value) ? value.join(', ') : value;
|
|
101
|
+
const headerName = key.toLowerCase() === 'host' ? 'Host' : key;
|
|
102
|
+
lines.push(`${headerName}: ${key.toLowerCase() === 'host' ? `${MANAGED_INSTANCE_HOST}:${targetPort}` : headerValue}`);
|
|
103
|
+
}
|
|
104
|
+
lines.push('', '');
|
|
105
|
+
return lines.join('\r\n');
|
|
106
|
+
}
|
|
107
|
+
function proxyWebSocketUpgrade(req, socket, head, range) {
|
|
108
|
+
const parsed = parseDashboardProxyUrl(req.url || '', range);
|
|
109
|
+
if (!parsed.ok) {
|
|
110
|
+
socket.write(`HTTP/1.1 ${parsed.status} ${parsed.reason}\r\nConnection: close\r\n\r\n`);
|
|
111
|
+
socket.destroy();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const upstream = net.connect(parsed.port, MANAGED_INSTANCE_HOST, () => {
|
|
115
|
+
upstream.write(buildProxyUpgradeRequest(req, parsed.targetPath, parsed.port));
|
|
116
|
+
if (head.length)
|
|
117
|
+
upstream.write(head);
|
|
118
|
+
socket.pipe(upstream).pipe(socket);
|
|
119
|
+
});
|
|
120
|
+
upstream.on('error', () => {
|
|
121
|
+
socket.write('HTTP/1.1 502 Bad Gateway\r\nConnection: close\r\n\r\n');
|
|
122
|
+
socket.destroy();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
export function installDashboardProxy(app, server, options = {}) {
|
|
126
|
+
const range = dashboardProxyRange(options);
|
|
127
|
+
app.use('/i/:port', (req, res) => {
|
|
128
|
+
proxyHttpRequest(req, res, range);
|
|
129
|
+
});
|
|
130
|
+
server.on('upgrade', (req, socket, head) => {
|
|
131
|
+
proxyWebSocketUpgrade(req, socket, head, range);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../../src/manager/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { DASHBOARD_DEFAULT_PORT, DASHBOARD_SCAN_TIMEOUT_MS, MANAGED_INSTANCE_HOST, MANAGED_INSTANCE_PORT_COUNT, MANAGED_INSTANCE_PORT_FROM, } from './constants.js';
|
|
2
|
+
import { deriveDashboardInstanceId, normalizeSettingsMetadata } from './metadata.js';
|
|
3
|
+
function toPositiveInt(value, fallback) {
|
|
4
|
+
const parsed = Number(value);
|
|
5
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
6
|
+
}
|
|
7
|
+
function scanRange(options) {
|
|
8
|
+
const from = toPositiveInt(options.from, MANAGED_INSTANCE_PORT_FROM);
|
|
9
|
+
const rawCount = toPositiveInt(options.count, MANAGED_INSTANCE_PORT_COUNT);
|
|
10
|
+
const count = Math.min(rawCount, MANAGED_INSTANCE_PORT_COUNT);
|
|
11
|
+
return { from, count, to: from + count - 1 };
|
|
12
|
+
}
|
|
13
|
+
function isAbortError(error) {
|
|
14
|
+
return error instanceof Error && error.name === 'TimeoutError'
|
|
15
|
+
|| error instanceof Error && error.name === 'AbortError';
|
|
16
|
+
}
|
|
17
|
+
async function readJson(fetchImpl, url, timeoutMs) {
|
|
18
|
+
const response = await fetchImpl(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
19
|
+
if (!response.ok)
|
|
20
|
+
throw new Error(`http_${response.status}`);
|
|
21
|
+
const body = await response.json();
|
|
22
|
+
return body && typeof body === 'object' ? body : {};
|
|
23
|
+
}
|
|
24
|
+
function readNumber(body, key) {
|
|
25
|
+
const value = body[key];
|
|
26
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
27
|
+
}
|
|
28
|
+
function readString(body, key) {
|
|
29
|
+
const value = body[key];
|
|
30
|
+
return typeof value === 'string' && value.trim() ? value : null;
|
|
31
|
+
}
|
|
32
|
+
function buildBaseRow(port, status, checkedAt, reason) {
|
|
33
|
+
return {
|
|
34
|
+
port,
|
|
35
|
+
url: `http://localhost:${port}`,
|
|
36
|
+
status,
|
|
37
|
+
ok: status === 'online',
|
|
38
|
+
version: null,
|
|
39
|
+
uptime: null,
|
|
40
|
+
instanceId: null,
|
|
41
|
+
homeDisplay: null,
|
|
42
|
+
workingDir: null,
|
|
43
|
+
currentCli: null,
|
|
44
|
+
currentModel: null,
|
|
45
|
+
serviceMode: 'unknown',
|
|
46
|
+
lastCheckedAt: checkedAt,
|
|
47
|
+
healthReason: reason,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function scanPort(port, fetchImpl, timeoutMs, checkedAt) {
|
|
51
|
+
const baseUrl = `http://${MANAGED_INSTANCE_HOST}:${port}`;
|
|
52
|
+
try {
|
|
53
|
+
const health = await readJson(fetchImpl, `${baseUrl}/api/health`, timeoutMs);
|
|
54
|
+
const row = buildBaseRow(port, 'online', checkedAt, null);
|
|
55
|
+
row.version = readString(health, 'version');
|
|
56
|
+
row.uptime = readNumber(health, 'uptime');
|
|
57
|
+
try {
|
|
58
|
+
const settings = await readJson(fetchImpl, `${baseUrl}/api/settings`, timeoutMs);
|
|
59
|
+
const metadata = normalizeSettingsMetadata(settings);
|
|
60
|
+
row.homeDisplay = metadata.homeDisplay;
|
|
61
|
+
row.workingDir = metadata.workingDir;
|
|
62
|
+
row.currentCli = metadata.currentCli;
|
|
63
|
+
row.currentModel = metadata.currentModel;
|
|
64
|
+
row.instanceId = deriveDashboardInstanceId(metadata.homeDisplay);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
row.healthReason = `metadata unavailable: ${error.message}`;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const runtime = await readJson(fetchImpl, `${baseUrl}/api/runtime`, timeoutMs);
|
|
71
|
+
const data = runtime.data && typeof runtime.data === 'object'
|
|
72
|
+
? runtime.data
|
|
73
|
+
: runtime;
|
|
74
|
+
row.currentCli ||= readString(data, 'cli');
|
|
75
|
+
row.currentModel ||= readString(data, 'model');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Runtime is optional for phase 10.2; health/settings still identify the row.
|
|
79
|
+
}
|
|
80
|
+
return row;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const status = isAbortError(error) ? 'timeout' : 'offline';
|
|
84
|
+
return buildBaseRow(port, status, checkedAt, error.message || status);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function scanDashboardInstances(options = {}) {
|
|
88
|
+
const { from, count, to } = scanRange(options);
|
|
89
|
+
const checkedAt = new Date().toISOString();
|
|
90
|
+
const timeoutMs = toPositiveInt(options.timeoutMs, DASHBOARD_SCAN_TIMEOUT_MS);
|
|
91
|
+
const fetchImpl = options.fetchImpl || fetch;
|
|
92
|
+
const managerPort = toPositiveInt(options.managerPort, Number(DASHBOARD_DEFAULT_PORT));
|
|
93
|
+
const ports = Array.from({ length: count }, (_, index) => from + index);
|
|
94
|
+
const instances = await Promise.all(ports.map(port => scanPort(port, fetchImpl, timeoutMs, checkedAt)));
|
|
95
|
+
return {
|
|
96
|
+
manager: {
|
|
97
|
+
port: managerPort,
|
|
98
|
+
rangeFrom: from,
|
|
99
|
+
rangeTo: to,
|
|
100
|
+
checkedAt,
|
|
101
|
+
proxy: {
|
|
102
|
+
enabled: true,
|
|
103
|
+
basePath: '/i',
|
|
104
|
+
allowedFrom: from,
|
|
105
|
+
allowedTo: to,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
instances,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/manager/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import helmet from 'helmet';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { DASHBOARD_DEFAULT_PORT, MANAGED_INSTANCE_PORT_COUNT, MANAGED_INSTANCE_PORT_FROM, } from './constants.js';
|
|
8
|
+
import { scanDashboardInstances } from './scan.js';
|
|
9
|
+
import { installDashboardProxy } from './proxy.js';
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const serverRoot = join(__dirname, '..', '..');
|
|
12
|
+
const projectRoot = existsSync(join(serverRoot, 'package.json'))
|
|
13
|
+
? serverRoot
|
|
14
|
+
: join(serverRoot, '..');
|
|
15
|
+
const app = express();
|
|
16
|
+
const port = Number(process.env.DASHBOARD_PORT || DASHBOARD_DEFAULT_PORT);
|
|
17
|
+
const scanFrom = Number(process.env.DASHBOARD_SCAN_FROM || MANAGED_INSTANCE_PORT_FROM);
|
|
18
|
+
const scanCount = Number(process.env.DASHBOARD_SCAN_COUNT || MANAGED_INSTANCE_PORT_COUNT);
|
|
19
|
+
app.use(helmet({
|
|
20
|
+
contentSecurityPolicy: false,
|
|
21
|
+
crossOriginEmbedderPolicy: false,
|
|
22
|
+
}));
|
|
23
|
+
app.get('/api/dashboard/health', (_req, res) => {
|
|
24
|
+
res.json({
|
|
25
|
+
ok: true,
|
|
26
|
+
port,
|
|
27
|
+
rangeFrom: scanFrom,
|
|
28
|
+
rangeTo: scanFrom + scanCount - 1,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
app.get('/api/dashboard/instances', async (req, res) => {
|
|
32
|
+
try {
|
|
33
|
+
const from = Number(req.query.from || scanFrom);
|
|
34
|
+
const count = Number(req.query.count || scanCount);
|
|
35
|
+
const result = await scanDashboardInstances({ from, count, managerPort: port });
|
|
36
|
+
res.json(result);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
res.status(500).json({ ok: false, error: error.message });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const distRoot = join(projectRoot, 'public', 'dist');
|
|
43
|
+
const sourceRoot = join(projectRoot, 'public');
|
|
44
|
+
const managerHtmlCandidates = [
|
|
45
|
+
join(distRoot, 'manager', 'index.html'),
|
|
46
|
+
join(distRoot, 'public', 'manager', 'index.html'),
|
|
47
|
+
join(distRoot, 'manager.html'),
|
|
48
|
+
join(sourceRoot, 'manager', 'index.html'),
|
|
49
|
+
];
|
|
50
|
+
const server = app.listen(port, '127.0.0.1', () => {
|
|
51
|
+
const url = `http://localhost:${port}`;
|
|
52
|
+
console.log(`\n Jaw Manager — ${url}`);
|
|
53
|
+
console.log(` Scanning: ${scanFrom}-${scanFrom + scanCount - 1}\n`);
|
|
54
|
+
if (process.env.JAW_DASHBOARD_OPEN === '1') {
|
|
55
|
+
const openCmd = process.platform === 'darwin' ? 'open'
|
|
56
|
+
: process.platform === 'win32' ? 'cmd'
|
|
57
|
+
: 'xdg-open';
|
|
58
|
+
const openArgs = process.platform === 'win32'
|
|
59
|
+
? ['/c', 'start', '', url]
|
|
60
|
+
: [url];
|
|
61
|
+
const opener = spawn(openCmd, openArgs, { detached: true, stdio: 'ignore' });
|
|
62
|
+
opener.unref();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
installDashboardProxy(app, server, { from: scanFrom, count: scanCount });
|
|
66
|
+
app.use('/dist', express.static(distRoot));
|
|
67
|
+
app.use('/assets', express.static(join(distRoot, 'assets')));
|
|
68
|
+
app.use('/manager', express.static(join(sourceRoot, 'manager')));
|
|
69
|
+
app.get('/{*splat}', (_req, res) => {
|
|
70
|
+
const htmlPath = managerHtmlCandidates.find(candidate => existsSync(candidate));
|
|
71
|
+
if (!htmlPath) {
|
|
72
|
+
return res.status(500).send('manager dashboard has not been built');
|
|
73
|
+
}
|
|
74
|
+
res.sendFile(htmlPath);
|
|
75
|
+
});
|
|
76
|
+
server.on('error', (error) => {
|
|
77
|
+
if (error.code === 'EADDRINUSE') {
|
|
78
|
+
console.error(`[dashboard] port ${port} already in use`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.error(`[dashboard] listen error: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
process.exit(1);
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/manager/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EACH,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,GAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC5D,CAAC,CAAC,UAAU;IACZ,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAC7B,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,sBAAsB,CAAC,CAAC;AAC1E,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,0BAA0B,CAAC,CAAC;AACvF,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,2BAA2B,CAAC,CAAC;AAE1F,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;IACX,qBAAqB,EAAE,KAAK;IAC5B,yBAAyB,EAAE,KAAK;CACnC,CAAC,CAAC,CAAC;AAEJ,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAC3C,GAAG,CAAC,IAAI,CAAC;QACL,EAAE,EAAE,IAAI;QACR,IAAI;QACJ,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,CAAC;KACpC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnD,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAC/C,MAAM,qBAAqB,GAAG;IAC1B,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC;IACvC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC;IACjD,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC9B,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;IAC9C,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,IAAI,QAAQ,GAAG,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC;IAErE,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM;YAClD,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK;gBAClC,CAAC,CAAC,UAAU,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;YACzC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC;YAC1B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3C,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7D,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAEjE,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAC/B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACxE,CAAC;IACD,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;IAChD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,oBAAoB,IAAI,iBAAiB,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/manager/types.ts"],"names":[],"mappings":""}
|
package/dist/src/routes/quota.js
CHANGED
|
@@ -3,6 +3,48 @@ import { execSync } from 'child_process';
|
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import { join } from 'path';
|
|
6
|
+
function clampPercent(value) {
|
|
7
|
+
return Math.max(0, Math.min(100, value));
|
|
8
|
+
}
|
|
9
|
+
export function classifyGeminiQuotaTier(modelId) {
|
|
10
|
+
if (modelId.includes('flash-lite'))
|
|
11
|
+
return 'flash-lite';
|
|
12
|
+
if (modelId.includes('pro'))
|
|
13
|
+
return 'pro';
|
|
14
|
+
if (modelId.includes('flash'))
|
|
15
|
+
return 'flash';
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
export function normalizeGeminiQuotaBuckets(buckets) {
|
|
19
|
+
const selected = new Map();
|
|
20
|
+
for (const bucket of buckets) {
|
|
21
|
+
if (!bucket.modelId || bucket.remainingFraction == null)
|
|
22
|
+
continue;
|
|
23
|
+
const tier = classifyGeminiQuotaTier(bucket.modelId);
|
|
24
|
+
if (tier !== 'flash' && tier !== 'pro')
|
|
25
|
+
continue;
|
|
26
|
+
const remainingFraction = Math.max(0, Math.min(1, bucket.remainingFraction));
|
|
27
|
+
const percent = clampPercent(Math.round((1 - remainingFraction) * 100));
|
|
28
|
+
const existing = selected.get(tier);
|
|
29
|
+
if (existing && remainingFraction >= existing.remainingFraction)
|
|
30
|
+
continue;
|
|
31
|
+
selected.set(tier, {
|
|
32
|
+
label: tier === 'pro' ? 'P' : 'F',
|
|
33
|
+
percent,
|
|
34
|
+
resetsAt: bucket.resetTime ?? null,
|
|
35
|
+
modelId: bucket.modelId,
|
|
36
|
+
remainingFraction,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const order = ['flash', 'pro'];
|
|
40
|
+
return order.flatMap((tier) => {
|
|
41
|
+
const window = selected.get(tier);
|
|
42
|
+
if (!window)
|
|
43
|
+
return [];
|
|
44
|
+
const { remainingFraction: _remainingFraction, ...publicWindow } = window;
|
|
45
|
+
return [publicWindow];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
6
48
|
// macOS-only: reads Claude Code OAuth token from system keychain.
|
|
7
49
|
// On Linux/WSL: returns null → classified as { authenticated: false } by /api/quota.
|
|
8
50
|
export function readClaudeCreds() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../../../src/routes/quota.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../../../src/routes/quota.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cli-jaw",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.35",
|
|
4
4
|
"description": "Personal AI assistant powered by 5 engines (Claude, Codex, Gemini, OpenCode, Copilot) — Web, Terminal, Telegram, and Discord interfaces with 107 built-in skills",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -91,6 +91,8 @@
|
|
|
91
91
|
"mermaid": "^11.14.0",
|
|
92
92
|
"node-fetch": "^3.3.2",
|
|
93
93
|
"playwright-core": "^1.58.2",
|
|
94
|
+
"react": "^19.2.5",
|
|
95
|
+
"react-dom": "^19.2.5",
|
|
94
96
|
"ws": "^8.18.0"
|
|
95
97
|
},
|
|
96
98
|
"devDependencies": {
|
|
@@ -98,7 +100,10 @@
|
|
|
98
100
|
"@types/dompurify": "^3.0.5",
|
|
99
101
|
"@types/express": "^5.0.6",
|
|
100
102
|
"@types/node": "^25.5.2",
|
|
103
|
+
"@types/react": "^19.2.14",
|
|
104
|
+
"@types/react-dom": "^19.2.3",
|
|
101
105
|
"@types/ws": "^8.5.0",
|
|
106
|
+
"@vitejs/plugin-react": "^5.2.0",
|
|
102
107
|
"tsx": "^4.21.0",
|
|
103
108
|
"typescript": "^6.0.2",
|
|
104
109
|
"vite": "^8.0.3"
|
package/public/css/chat.css
CHANGED
|
@@ -133,6 +133,33 @@
|
|
|
133
133
|
gap: 0;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
.chat-restore-indicator {
|
|
137
|
+
position: absolute;
|
|
138
|
+
left: 50%;
|
|
139
|
+
bottom: var(--space-4);
|
|
140
|
+
z-index: 3;
|
|
141
|
+
display: inline-flex;
|
|
142
|
+
align-items: center;
|
|
143
|
+
gap: var(--space-2);
|
|
144
|
+
transform: translateX(-50%);
|
|
145
|
+
padding: 6px 10px;
|
|
146
|
+
border: 1px solid var(--border);
|
|
147
|
+
border-radius: var(--radius-md);
|
|
148
|
+
background: color-mix(in oklch, var(--surface) 88%, transparent);
|
|
149
|
+
color: var(--text-dim);
|
|
150
|
+
box-shadow: var(--shadow-md);
|
|
151
|
+
font-size: var(--text-xs);
|
|
152
|
+
pointer-events: none;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.chat-restore-dot {
|
|
156
|
+
width: 6px;
|
|
157
|
+
height: 6px;
|
|
158
|
+
border-radius: 50%;
|
|
159
|
+
background: var(--accent);
|
|
160
|
+
animation: processDotPulse 1.2s ease-in-out infinite;
|
|
161
|
+
}
|
|
162
|
+
|
|
136
163
|
/* Inner container provides scrollbar range via its height */
|
|
137
164
|
.chat-messages.vs-active > .vs-inner {
|
|
138
165
|
position: relative;
|
package/public/css/diagram.css
CHANGED
|
@@ -133,8 +133,10 @@
|
|
|
133
133
|
z-index: 2;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
/* Widget:
|
|
137
|
-
.diagram-widget .diagram-
|
|
136
|
+
/* Widget: zoom rightmost, copy middle, save leftmost */
|
|
137
|
+
.diagram-widget .diagram-zoom-btn { right: var(--space-2); }
|
|
138
|
+
.diagram-widget .diagram-copy-btn { right: calc(var(--space-2) + 36px); }
|
|
139
|
+
.diagram-widget .diagram-save-btn { right: calc(var(--space-2) + 72px); }
|
|
138
140
|
|
|
139
141
|
/* SVG: zoom rightmost, copy middle, save leftmost */
|
|
140
142
|
.diagram-svg .diagram-copy-btn { right: calc(var(--space-2) + 36px); }
|
|
@@ -189,6 +191,50 @@
|
|
|
189
191
|
max-width: 1200px;
|
|
190
192
|
}
|
|
191
193
|
|
|
194
|
+
.diagram-widget-overlay .diagram-overlay-content {
|
|
195
|
+
width: min(1100px, 94vw);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.diagram-widget-overlay.maximized .diagram-overlay-content {
|
|
199
|
+
width: min(1500px, 98vw);
|
|
200
|
+
height: min(1000px, 94vh);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.diagram-widget-expanded {
|
|
204
|
+
margin: 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.diagram-widget-expanded iframe {
|
|
208
|
+
min-height: 420px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.diagram-widget-overlay.maximized .diagram-widget-expanded,
|
|
212
|
+
.diagram-widget-overlay.maximized .diagram-widget-expanded iframe {
|
|
213
|
+
height: 100%;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.diagram-size-toggle-btn {
|
|
217
|
+
position: absolute;
|
|
218
|
+
top: var(--space-4);
|
|
219
|
+
right: calc(var(--space-4) + 48px);
|
|
220
|
+
width: 40px;
|
|
221
|
+
height: 40px;
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
justify-content: center;
|
|
225
|
+
background: var(--surface);
|
|
226
|
+
border: 1px solid var(--border);
|
|
227
|
+
border-radius: 50%;
|
|
228
|
+
color: var(--text);
|
|
229
|
+
font-size: 18px;
|
|
230
|
+
cursor: pointer;
|
|
231
|
+
z-index: 10000;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.diagram-size-toggle-btn:hover {
|
|
235
|
+
background: var(--bg);
|
|
236
|
+
}
|
|
237
|
+
|
|
192
238
|
.diagram-overlay-close {
|
|
193
239
|
position: absolute;
|
|
194
240
|
top: var(--space-4);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./api-CnBOYa3F.js";export{e as api};
|