@hotmeshio/long-tail 0.8.2 → 0.8.3
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/build/scripts/twin-farm.d.ts +45 -0
- package/build/scripts/twin-farm.js +441 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/dashboard/dist/assets/{AdminDashboard-Nvja-XIJ.js → AdminDashboard-Dhr7sUq6.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Nvja-XIJ.js.map → AdminDashboard-Dhr7sUq6.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Sf2god7q.js → AgentConfigPage-CUPm8FjH.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Sf2god7q.js.map → AgentConfigPage-CUPm8FjH.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DtgDeZJR.js → AgentDetailPage-C9Tmmhhc.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-DtgDeZJR.js.map → AgentDetailPage-C9Tmmhhc.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-C6zqP_xC.js → AgentsPage-Pj47ZJ2U.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-C6zqP_xC.js.map → AgentsPage-Pj47ZJ2U.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-D61kC7Is.js → AvailableEscalationsPage-BxakNqha.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-D61kC7Is.js.map → AvailableEscalationsPage-BxakNqha.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-ChgljKHj.js → BotPicker-CCIo5ic0.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-ChgljKHj.js.map → BotPicker-CCIo5ic0.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-DeybKoZM.js → CapabilitiesPage-XFVq4iPX.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-DeybKoZM.js.map → CapabilitiesPage-XFVq4iPX.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BPiTuPBk.js → CollapsibleSection-CBKICsCu.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BPiTuPBk.js.map → CollapsibleSection-CBKICsCu.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-DXOcPWtd.js → CredentialsPage-BN_d7ybc.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-DXOcPWtd.js.map → CredentialsPage-BN_d7ybc.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-D3411N8x.js → CronLabel-4V_EXMUg.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-D3411N8x.js.map → CronLabel-4V_EXMUg.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-WG2tPSbV.js → CustomDurationPicker-BdurQj-B.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-WG2tPSbV.js.map → CustomDurationPicker-BdurQj-B.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BFWEGSD7.js → ElapsedCell-CO8XMSJX.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BFWEGSD7.js.map → ElapsedCell-CO8XMSJX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-D2Y5Yeqn.js → EscalationSchemaPage-hzFtuyha.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-D2Y5Yeqn.js.map → EscalationSchemaPage-hzFtuyha.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-VlLcX2YM.js → EscalationsOverview-qlo0mxxa.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-VlLcX2YM.js.map → EscalationsOverview-qlo0mxxa.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-3MJw14jp.js → EventTable-D9RjAT_a.js} +2 -2
- package/dashboard/dist/assets/{EventTable-3MJw14jp.js.map → EventTable-D9RjAT_a.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-QaUUrPnh.js → GraphInvokePage-CU3r2tzN.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-QaUUrPnh.js.map → GraphInvokePage-CU3r2tzN.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Br0A3iOp.js → HomePage-B7pb4-Gx.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Br0A3iOp.js.map → HomePage-B7pb4-Gx.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-d4MGQefV.js → ListToolbar-C_64Y22Z.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-d4MGQefV.js.map → ListToolbar-C_64Y22Z.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CUzJD5Z5.js → McpOverview-D-4eSOTc.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CUzJD5Z5.js.map → McpOverview-D-4eSOTc.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-pYSZmV3M.js → McpQueryDetailPage-BYwDb8LC.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-pYSZmV3M.js.map → McpQueryDetailPage-BYwDb8LC.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CA5C5dss.js → McpQueryPage-CIijB5t2.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CA5C5dss.js.map → McpQueryPage-CIijB5t2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CrRkXwAe.js → McpRunDetailPage-CQmhfgju.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CrRkXwAe.js.map → McpRunDetailPage-CQmhfgju.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BqRBDbkn.js → McpRunsPage-CdDyeOdi.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BqRBDbkn.js.map → McpRunsPage-CdDyeOdi.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-Cz_0K8tj.js +2 -0
- package/dashboard/dist/assets/{OperationsPage--uVJxzmP.js.map → OperationsPage-Cz_0K8tj.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-D-UMrTqI.js → OperatorDashboard-DFORmS46.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-D-UMrTqI.js.map → OperatorDashboard-DFORmS46.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BV6D_wuR.js → ProcessDetailPage-DwypVFE2.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BV6D_wuR.js.map → ProcessDetailPage-DwypVFE2.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-BAalEHpx.js → ProcessesListPage-tNLvALwT.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-BAalEHpx.js.map → ProcessesListPage-tNLvALwT.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-ClE7rUoo.js → RoleDetailPage-BPsrUqIa.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-ClE7rUoo.js.map → RoleDetailPage-BPsrUqIa.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DMsgZioQ.js → RolesPage-txueySPI.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DMsgZioQ.js.map → RolesPage-txueySPI.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-VCnEYIwj.js → RunAsSelector-Bvefon9B.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-VCnEYIwj.js.map → RunAsSelector-Bvefon9B.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-3eCY2-_V.js → StickyPagination-CeQCzVIA.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-3eCY2-_V.js.map → StickyPagination-CeQCzVIA.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-70kDFH4o.js → StreamMessageDetail-6wEm6o6t.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-70kDFH4o.js.map → StreamMessageDetail-6wEm6o6t.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BOXRit6t.js → SwimlaneTimeline-C97Rldf5.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BOXRit6t.js.map → SwimlaneTimeline-C97Rldf5.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-YxGQE9Qg.js → TaskDetailPage-B09mLOCE.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-YxGQE9Qg.js.map → TaskDetailPage-B09mLOCE.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DuLJQN7Q.js → TasksListPage-CQhiSGkN.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DuLJQN7Q.js.map → TasksListPage-CQhiSGkN.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-dnc1ZjKc.js → TimeAgo-BkyeBcMF.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-dnc1ZjKc.js.map → TimeAgo-BkyeBcMF.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CDR6cTyq.js → TimestampCell-DVp_UdEB.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CDR6cTyq.js.map → TimestampCell-DVp_UdEB.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-CfwGdRdz.js → ToolTestPanel-CZOuRP_i.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-CfwGdRdz.js.map → ToolTestPanel-CZOuRP_i.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-f2qaeGFz.js → TopicDetailPage-0mvQde8R.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-f2qaeGFz.js.map → TopicDetailPage-0mvQde8R.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CwYdVmyK.js → TopicsPage-DkvsHLLe.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CwYdVmyK.js.map → TopicsPage-DkvsHLLe.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CRE7EZPU.js → UserName-EaD_Tz9y.js} +2 -2
- package/dashboard/dist/assets/{UserName-CRE7EZPU.js.map → UserName-EaD_Tz9y.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BjNBu-Zt.js → WorkflowExecutionPage-CjMSQ9Bb.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BjNBu-Zt.js.map → WorkflowExecutionPage-CjMSQ9Bb.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DfpvbzNt.js → WorkflowsDashboard-BgUz_jO6.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DfpvbzNt.js.map → WorkflowsDashboard-BgUz_jO6.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-BwD2lQwj.js → WorkflowsOverview-BzUjUfAz.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-BwD2lQwj.js.map → WorkflowsOverview-BzUjUfAz.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BhHb7j2s.js → YamlWorkflowDetailPage-C48Ui513.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BhHb7j2s.js.map → YamlWorkflowDetailPage-C48Ui513.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-SBRpY2dI.js → YamlWorkflowsPage-CQ-dk84N.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-SBRpY2dI.js.map → YamlWorkflowsPage-CQ-dk84N.js.map} +1 -1
- package/dashboard/dist/assets/{agents-VbkdqWCr.js → agents-O1GlQE9p.js} +2 -2
- package/dashboard/dist/assets/{agents-VbkdqWCr.js.map → agents-O1GlQE9p.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CsgYcYU_.js → bots-DB5Z7MEk.js} +2 -2
- package/dashboard/dist/assets/{bots-CsgYcYU_.js.map → bots-DB5Z7MEk.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CMhFyoDl.js → capabilities-Du9EfNdT.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CMhFyoDl.js.map → capabilities-Du9EfNdT.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BstXtPbV.js → controlplane-ku4V2nVk.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BstXtPbV.js.map → controlplane-ku4V2nVk.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-DajPgfuV.js → escalation-columns-C-xaR_Qg.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-DajPgfuV.js.map → escalation-columns-C-xaR_Qg.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-C0BNAeIG.js → escalation-oVVz7Lw2.js} +2 -2
- package/dashboard/dist/assets/{escalation-C0BNAeIG.js.map → escalation-oVVz7Lw2.js.map} +1 -1
- package/dashboard/dist/assets/{index-D_6JFBiM.js → index-61yKjTkk.js} +2 -2
- package/dashboard/dist/assets/{index-D_6JFBiM.js.map → index-61yKjTkk.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cl1vY8Lg.js → index-Bcgsf2yD.js} +2 -2
- package/dashboard/dist/assets/{index-Cl1vY8Lg.js.map → index-Bcgsf2yD.js.map} +1 -1
- package/dashboard/dist/assets/{index-BY5m8rhE.js → index-BwXtXaw8.js} +2 -2
- package/dashboard/dist/assets/{index-BY5m8rhE.js.map → index-BwXtXaw8.js.map} +1 -1
- package/dashboard/dist/assets/{index-BcaQ_hCz.js → index-CAzFU1rn.js} +2 -2
- package/dashboard/dist/assets/{index-BcaQ_hCz.js.map → index-CAzFU1rn.js.map} +1 -1
- package/dashboard/dist/assets/{index-fqU_l4dC.js → index-CxlsLEr1.js} +2 -2
- package/dashboard/dist/assets/{index-fqU_l4dC.js.map → index-CxlsLEr1.js.map} +1 -1
- package/dashboard/dist/assets/{index-DWlPFH3T.js → index-CyXilW90.js} +2 -2
- package/dashboard/dist/assets/{index-DWlPFH3T.js.map → index-CyXilW90.js.map} +1 -1
- package/dashboard/dist/assets/{index-BYf0oNSQ.js → index-D0bDVU2a.js} +2 -2
- package/dashboard/dist/assets/{index-BYf0oNSQ.js.map → index-D0bDVU2a.js.map} +1 -1
- package/dashboard/dist/assets/{index-CSixdp5W.js → index-DcZDyLHC.js} +2 -2
- package/dashboard/dist/assets/{index-CSixdp5W.js.map → index-DcZDyLHC.js.map} +1 -1
- package/dashboard/dist/assets/{index-CXnSqSFH.js → index-DgAmkmtv.js} +2 -2
- package/dashboard/dist/assets/{index-CXnSqSFH.js.map → index-DgAmkmtv.js.map} +1 -1
- package/dashboard/dist/assets/{index-CvFQtPWA.js → index-DkZnXWTA.js} +2 -2
- package/dashboard/dist/assets/{index-CvFQtPWA.js.map → index-DkZnXWTA.js.map} +1 -1
- package/dashboard/dist/assets/{index-BWLVqWLU.js → index-DsKK1fCc.js} +2 -2
- package/dashboard/dist/assets/{index-BWLVqWLU.js.map → index-DsKK1fCc.js.map} +1 -1
- package/dashboard/dist/assets/{index-C8k3Z2su.js → index-MbEPoyTe.js} +3 -3
- package/dashboard/dist/assets/{index-C8k3Z2su.js.map → index-MbEPoyTe.js.map} +1 -1
- package/dashboard/dist/assets/{index-CaSMWhLU.js → index-aHhMmZ0W.js} +2 -2
- package/dashboard/dist/assets/{index-CaSMWhLU.js.map → index-aHhMmZ0W.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-Bskl1MbC.js → knowledge-CTjJVvIG.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Bskl1MbC.js.map → knowledge-CTjJVvIG.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C_qz25AB.js → mcp-CsHkygRS.js} +2 -2
- package/dashboard/dist/assets/{mcp-C_qz25AB.js.map → mcp-CsHkygRS.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CJx58s1A.js → mcp-query-BCt4tpjO.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CJx58s1A.js.map → mcp-query-BCt4tpjO.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-B6GzpgtG.js → pipelines-BpGmuS5V.js} +2 -2
- package/dashboard/dist/assets/{pipelines-B6GzpgtG.js.map → pipelines-BpGmuS5V.js.map} +1 -1
- package/dashboard/dist/assets/{roles-D8lPvFgG.js → roles-lHLgLwOY.js} +2 -2
- package/dashboard/dist/assets/{roles-D8lPvFgG.js.map → roles-lHLgLwOY.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BWHakSYf.js → tasks-BHfimh-E.js} +2 -2
- package/dashboard/dist/assets/{tasks-BWHakSYf.js.map → tasks-BHfimh-E.js.map} +1 -1
- package/dashboard/dist/assets/{topics-0dXzPX8t.js → topics-BW2cS79q.js} +2 -2
- package/dashboard/dist/assets/{topics-0dXzPX8t.js.map → topics-BW2cS79q.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-Dpixlgp-.js → useEventHooks-CeOIM1Ix.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-Dpixlgp-.js.map → useEventHooks-CeOIM1Ix.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DQMc77ok.js → useNamespace-CEVLPGGY.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DQMc77ok.js.map → useNamespace-CEVLPGGY.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DO5bHOVE.js → useYamlActivityEvents-DdRNcy7s.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DO5bHOVE.js.map → useYamlActivityEvents-DdRNcy7s.js.map} +1 -1
- package/dashboard/dist/assets/{users-B_LVbnUk.js → users-CAih5Fty.js} +2 -2
- package/dashboard/dist/assets/{users-B_LVbnUk.js.map → users-CAih5Fty.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-WmmGDAvo.js → workflows-C_gCwB9q.js} +2 -2
- package/dashboard/dist/assets/{workflows-WmmGDAvo.js.map → workflows-C_gCwB9q.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BS7KHhU1.js → yaml-workflows-CPabf8Sf.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BS7KHhU1.js.map → yaml-workflows-CPabf8Sf.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/OperationsPage--uVJxzmP.js +0 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* twin-farm — drive the printer-twin example end to end, effortlessly.
|
|
3
|
+
*
|
|
4
|
+
* Spins up the whole DIGITAL side of the physical/digital twin farm from one
|
|
5
|
+
* command and plays every human part automatically, so a single run exercises
|
|
6
|
+
* the full lifecycle: register → advertise → dispatch → print → settle, plus the
|
|
7
|
+
* failure detour (cancel → service → back in the pool). The PHYSICAL side is the
|
|
8
|
+
* app's farm-manager backend — `mock` by default (self-contained), or `http`
|
|
9
|
+
* against a real print-farm-manager host once you wire the office up.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* npm run twin:farm
|
|
13
|
+
* FLEET=6 ORDERS=10 UNITS=2 npm run twin:farm
|
|
14
|
+
* FAIL_PCT=25 npm run twin:farm # rehearse dead-machine → service
|
|
15
|
+
* FARM_MANAGER_URL=http://192.168.1.50:4000 npm run twin:farm # preflight the office link
|
|
16
|
+
* FLEET=4 ORDERS=4 KEEP=1 npm run twin:farm # leave twins running to poke in the UI
|
|
17
|
+
*
|
|
18
|
+
* Env vars:
|
|
19
|
+
* BASE_URL long-tail API (default http://localhost:3000)
|
|
20
|
+
* FLEET printer twins to launch (default 4)
|
|
21
|
+
* ORDERS orders to place (default 6)
|
|
22
|
+
* UNITS max units per order (default 2; capped to the fleet that
|
|
23
|
+
* shares an order's filament, so every order is satisfiable)
|
|
24
|
+
* FILAMENTS comma-separated filament pool the fleet + orders draw from
|
|
25
|
+
* (default "pla,petg")
|
|
26
|
+
* ARRIVAL_S average seconds between order arrivals (default 2)
|
|
27
|
+
* FAIL_PCT percent of print jobs to cancel mid-print, exercising the
|
|
28
|
+
* service path (default 0). Best-effort: it races the
|
|
29
|
+
* physical side, so raise MOCK_PRINT_SECONDS on the app for
|
|
30
|
+
* a wider window (see README).
|
|
31
|
+
* POLL_MS poll interval ms (default 750)
|
|
32
|
+
* BROKER_IDLE idle broker ticks before it self-terminates (default 40)
|
|
33
|
+
* RUN_BROKER launch a broker (default 1; set 0 if one already runs)
|
|
34
|
+
* KEEP 1 = leave twins advertising at the end (default 0 = retire
|
|
35
|
+
* them with a power-down so nothing lingers between runs)
|
|
36
|
+
* FARM_MANAGER_URL optional: GET this before running and report reachability,
|
|
37
|
+
* a preflight for the office laptop → farm-manager-host link
|
|
38
|
+
*
|
|
39
|
+
* Capabilities: each twin is registered with a capability profile (xl/pdac/soft).
|
|
40
|
+
* By default the fleet is fully capable and only filament routes; set FLEET_CAPS
|
|
41
|
+
* to vary it (e.g. "xl,soft|pdac|full|full" — one spec per printer, pipe-separated,
|
|
42
|
+
* each a comma list of capabilities or "full"/"base"). Orders only ever require a
|
|
43
|
+
* capability the fleet can satisfy for the chosen filament and unit count.
|
|
44
|
+
*/
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* twin-farm — drive the printer-twin example end to end, effortlessly.
|
|
4
|
+
*
|
|
5
|
+
* Spins up the whole DIGITAL side of the physical/digital twin farm from one
|
|
6
|
+
* command and plays every human part automatically, so a single run exercises
|
|
7
|
+
* the full lifecycle: register → advertise → dispatch → print → settle, plus the
|
|
8
|
+
* failure detour (cancel → service → back in the pool). The PHYSICAL side is the
|
|
9
|
+
* app's farm-manager backend — `mock` by default (self-contained), or `http`
|
|
10
|
+
* against a real print-farm-manager host once you wire the office up.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* npm run twin:farm
|
|
14
|
+
* FLEET=6 ORDERS=10 UNITS=2 npm run twin:farm
|
|
15
|
+
* FAIL_PCT=25 npm run twin:farm # rehearse dead-machine → service
|
|
16
|
+
* FARM_MANAGER_URL=http://192.168.1.50:4000 npm run twin:farm # preflight the office link
|
|
17
|
+
* FLEET=4 ORDERS=4 KEEP=1 npm run twin:farm # leave twins running to poke in the UI
|
|
18
|
+
*
|
|
19
|
+
* Env vars:
|
|
20
|
+
* BASE_URL long-tail API (default http://localhost:3000)
|
|
21
|
+
* FLEET printer twins to launch (default 4)
|
|
22
|
+
* ORDERS orders to place (default 6)
|
|
23
|
+
* UNITS max units per order (default 2; capped to the fleet that
|
|
24
|
+
* shares an order's filament, so every order is satisfiable)
|
|
25
|
+
* FILAMENTS comma-separated filament pool the fleet + orders draw from
|
|
26
|
+
* (default "pla,petg")
|
|
27
|
+
* ARRIVAL_S average seconds between order arrivals (default 2)
|
|
28
|
+
* FAIL_PCT percent of print jobs to cancel mid-print, exercising the
|
|
29
|
+
* service path (default 0). Best-effort: it races the
|
|
30
|
+
* physical side, so raise MOCK_PRINT_SECONDS on the app for
|
|
31
|
+
* a wider window (see README).
|
|
32
|
+
* POLL_MS poll interval ms (default 750)
|
|
33
|
+
* BROKER_IDLE idle broker ticks before it self-terminates (default 40)
|
|
34
|
+
* RUN_BROKER launch a broker (default 1; set 0 if one already runs)
|
|
35
|
+
* KEEP 1 = leave twins advertising at the end (default 0 = retire
|
|
36
|
+
* them with a power-down so nothing lingers between runs)
|
|
37
|
+
* FARM_MANAGER_URL optional: GET this before running and report reachability,
|
|
38
|
+
* a preflight for the office laptop → farm-manager-host link
|
|
39
|
+
*
|
|
40
|
+
* Capabilities: each twin is registered with a capability profile (xl/pdac/soft).
|
|
41
|
+
* By default the fleet is fully capable and only filament routes; set FLEET_CAPS
|
|
42
|
+
* to vary it (e.g. "xl,soft|pdac|full|full" — one spec per printer, pipe-separated,
|
|
43
|
+
* each a comma list of capabilities or "full"/"base"). Orders only ever require a
|
|
44
|
+
* capability the fleet can satisfy for the chosen filament and unit count.
|
|
45
|
+
*/
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
try {
|
|
48
|
+
require('dotenv/config');
|
|
49
|
+
}
|
|
50
|
+
catch { /* dotenv optional */ }
|
|
51
|
+
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
|
52
|
+
const FLEET = parseInt(process.env.FLEET || '4', 10);
|
|
53
|
+
const ORDERS = parseInt(process.env.ORDERS || '6', 10);
|
|
54
|
+
const UNITS = parseInt(process.env.UNITS || '2', 10);
|
|
55
|
+
const FILAMENTS = (process.env.FILAMENTS || 'pla,petg').split(',').map((f) => f.trim()).filter(Boolean);
|
|
56
|
+
const ARRIVAL_S = parseFloat(process.env.ARRIVAL_S || '2');
|
|
57
|
+
const FAIL_PCT = parseInt(process.env.FAIL_PCT || '0', 10);
|
|
58
|
+
const POLL_MS = parseInt(process.env.POLL_MS || '750', 10);
|
|
59
|
+
const BROKER_IDLE = parseInt(process.env.BROKER_IDLE || '40', 10);
|
|
60
|
+
const RUN_BROKER = process.env.RUN_BROKER !== '0';
|
|
61
|
+
const KEEP = process.env.KEEP === '1';
|
|
62
|
+
const FARM_MANAGER_URL = process.env.FARM_MANAGER_URL || '';
|
|
63
|
+
const CAPABILITY_KEYS = ['xl', 'pdac', 'soft'];
|
|
64
|
+
const MODELS = ['Fab-X1', 'Fab-X1C', 'Fab-P2', 'Fab-Mini'];
|
|
65
|
+
let token = '';
|
|
66
|
+
let userId = '';
|
|
67
|
+
let done = false;
|
|
68
|
+
const stats = { registered: 0, dispatched: 0, printed: 0, cancelled: 0, serviced: 0, settled: 0 };
|
|
69
|
+
function ts() { return new Date().toISOString().slice(11, 19); }
|
|
70
|
+
function sleep(ms) { return new Promise((r) => setTimeout(r, ms)); }
|
|
71
|
+
function ageSeconds(iso) { return (Date.now() - new Date(iso).getTime()) / 1000; }
|
|
72
|
+
// Deterministic per-item jitter — FNV-1a hash of a key into [0, 1). Stable
|
|
73
|
+
// across polls, so a job's fail/no-fail verdict never flip-flops mid-run.
|
|
74
|
+
function jitter(key, salt = '') {
|
|
75
|
+
let h = 2166136261;
|
|
76
|
+
for (const c of salt + key) {
|
|
77
|
+
h ^= c.charCodeAt(0);
|
|
78
|
+
h = Math.imul(h, 16777619);
|
|
79
|
+
}
|
|
80
|
+
return ((h >>> 0) % 1000) / 1000;
|
|
81
|
+
}
|
|
82
|
+
function spread(base, r) { return base * (0.4 + 1.2 * r); }
|
|
83
|
+
// ── HTTP + auth (mirrors ortho-populate) ──────────────────────────────────────
|
|
84
|
+
async function api(method, path, body) {
|
|
85
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
86
|
+
method,
|
|
87
|
+
headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) },
|
|
88
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
89
|
+
});
|
|
90
|
+
const data = await res.json().catch(() => ({}));
|
|
91
|
+
if (!res.ok)
|
|
92
|
+
throw new Error(`${method} ${path} → ${res.status}: ${JSON.stringify(data)}`);
|
|
93
|
+
return data;
|
|
94
|
+
}
|
|
95
|
+
async function login() {
|
|
96
|
+
const auth = await api('POST', '/api/auth/login', { username: 'superadmin', password: 'l0ngt@1l' });
|
|
97
|
+
token = auth.token;
|
|
98
|
+
userId = auth.user?.id || '';
|
|
99
|
+
if (!token) {
|
|
100
|
+
console.error('[auth] Login failed');
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
console.log(`[${ts()}] Logged in (userId ${userId.slice(0, 8)}…)`);
|
|
104
|
+
}
|
|
105
|
+
// ── Pace Board role config (idempotent — never clobbers admin tuning) ─────────
|
|
106
|
+
/**
|
|
107
|
+
* Ensure the twin farm's roles are operationalized on the Pace Board. The
|
|
108
|
+
* startup seeder (examples/seed-twin.ts) normally owns this; the driver repeats
|
|
109
|
+
* it so `npm run twin:farm` populates the board even against an app that did not
|
|
110
|
+
* seed the examples. Only UNCONFIGURED roles (no title) are touched — a role an
|
|
111
|
+
* admin has tuned keeps its dials.
|
|
112
|
+
*
|
|
113
|
+
* Topology: print-jobs ─▶ printer-fleet (production line), with print-servicer
|
|
114
|
+
* a side-quest root merging into the fleet.
|
|
115
|
+
*/
|
|
116
|
+
const TWIN_ROLE_CONFIG = [
|
|
117
|
+
{ role: 'print-jobs', title: 'Print Jobs', parent_role: null, sla_minutes: 5, target_per_hour: 30, priority_threshold_minutes: 5, description: 'Order demand — one print-job escalation per unit, claimed as a set.' },
|
|
118
|
+
{ role: 'printer-fleet', title: 'Printer Fleet', parent_role: 'print-jobs', sla_minutes: 5, target_per_hour: 30, priority_threshold_minutes: 5, description: 'Twin availability adverts and in-flight print rows — the machines at work.', upstream_roles: ['print-servicer'] },
|
|
119
|
+
{ role: 'print-servicer', title: 'Print Servicer', parent_role: null, sla_minutes: 10, target_per_hour: 10, priority_threshold_minutes: 10, description: 'Register unboxed machines and restore ones that fell offline.' },
|
|
120
|
+
];
|
|
121
|
+
async function ensureTwinRoles() {
|
|
122
|
+
const details = await api('GET', '/api/roles/details').catch(() => ({ roles: [] }));
|
|
123
|
+
const configured = new Map((details?.roles ?? []).map((r) => [r.role, r]));
|
|
124
|
+
// Create bare rows first — upstream_roles references must resolve.
|
|
125
|
+
for (const cfg of TWIN_ROLE_CONFIG) {
|
|
126
|
+
if (!configured.has(cfg.role))
|
|
127
|
+
await api('POST', '/api/roles', { role: cfg.role }).catch(() => { });
|
|
128
|
+
}
|
|
129
|
+
let applied = 0;
|
|
130
|
+
for (const cfg of TWIN_ROLE_CONFIG) {
|
|
131
|
+
const row = configured.get(cfg.role);
|
|
132
|
+
if (row?.title)
|
|
133
|
+
continue; // already configured — respect admin tuning
|
|
134
|
+
const { role, ...body } = cfg;
|
|
135
|
+
await api('PATCH', `/api/roles/${role}`, { ...body, ops_visible: true }).then(() => { applied++; }).catch((err) => {
|
|
136
|
+
console.warn(`[${ts()}] ⚠ role ${role}: ${String(err.message).slice(0, 80)}`);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
console.log(`[${ts()}] Pace Board roles ready (print-jobs → printer-fleet, print-servicer side)${applied ? ` — configured ${applied}` : ''}`);
|
|
140
|
+
}
|
|
141
|
+
function parseCapSpec(spec) {
|
|
142
|
+
const s = spec.trim().toLowerCase();
|
|
143
|
+
if (s === 'full' || s === '')
|
|
144
|
+
return { xl: true, pdac: true, soft: true };
|
|
145
|
+
if (s === 'base' || s === 'none')
|
|
146
|
+
return { xl: false, pdac: false, soft: false };
|
|
147
|
+
const set = { xl: false, pdac: false, soft: false };
|
|
148
|
+
for (const k of s.split(',').map((x) => x.trim())) {
|
|
149
|
+
if (CAPABILITY_KEYS.includes(k))
|
|
150
|
+
set[k] = true;
|
|
151
|
+
}
|
|
152
|
+
return set;
|
|
153
|
+
}
|
|
154
|
+
function planFleet(batchTag) {
|
|
155
|
+
const capSpecs = (process.env.FLEET_CAPS || '').split('|').map((s) => s.trim()).filter(Boolean);
|
|
156
|
+
return Array.from({ length: FLEET }, (_, i) => {
|
|
157
|
+
const filament = FILAMENTS[i % FILAMENTS.length];
|
|
158
|
+
const caps = capSpecs.length ? parseCapSpec(capSpecs[i % capSpecs.length]) : { xl: true, pdac: true, soft: true };
|
|
159
|
+
const printerId = `${batchTag}-p${i}`;
|
|
160
|
+
return { printerId, wfId: printerId, filament, caps, model: MODELS[i % MODELS.length], serialNumber: `SN-${batchTag.slice(-6)}-${i}` };
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function planOrders(batchTag, fleet) {
|
|
164
|
+
return Array.from({ length: ORDERS }, (_, i) => {
|
|
165
|
+
const filament = FILAMENTS[i % FILAMENTS.length];
|
|
166
|
+
const pool = fleet.filter((t) => t.filament === filament);
|
|
167
|
+
const units = Math.max(1, Math.min(UNITS, pool.length));
|
|
168
|
+
// Require a rotating capability only if enough printers of this filament have
|
|
169
|
+
// it — otherwise the order would never place. Proves capability routing when
|
|
170
|
+
// the fleet varies; a no-op (but still-threaded) facet when it's fully capable.
|
|
171
|
+
const cap = CAPABILITY_KEYS[i % CAPABILITY_KEYS.length];
|
|
172
|
+
const capable = pool.filter((t) => t.caps[cap]).length;
|
|
173
|
+
const require = (i % 2 === 0 && capable >= units) ? { [cap]: true } : {};
|
|
174
|
+
return { index: i, wfId: `${batchTag}-o${i}`, orderId: `TWIN-${batchTag.slice(-6)}-${i}`, filament, require, units };
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// ── Launch twins + broker + orders ────────────────────────────────────────────
|
|
178
|
+
async function startTwin(spec) {
|
|
179
|
+
await api('POST', '/api/workflows/printerTwin/invoke', {
|
|
180
|
+
workflowId: spec.wfId,
|
|
181
|
+
data: { printerId: spec.printerId, operatorId: userId },
|
|
182
|
+
metadata: { source: 'twin-farm' },
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async function startBroker(batchTag) {
|
|
186
|
+
const wfId = `${batchTag}-broker`;
|
|
187
|
+
await api('POST', '/api/workflows/twinBroker/invoke', {
|
|
188
|
+
workflowId: wfId,
|
|
189
|
+
data: { brokerId: userId, tickSeconds: 1, idleTickSeconds: 3, maxIdleRuns: BROKER_IDLE },
|
|
190
|
+
metadata: { source: 'twin-farm' },
|
|
191
|
+
});
|
|
192
|
+
return wfId;
|
|
193
|
+
}
|
|
194
|
+
async function placeOrder(spec) {
|
|
195
|
+
await api('POST', '/api/workflows/twinOrder/invoke', {
|
|
196
|
+
workflowId: spec.wfId,
|
|
197
|
+
data: {
|
|
198
|
+
orderId: spec.orderId,
|
|
199
|
+
filament: spec.filament,
|
|
200
|
+
require: spec.require,
|
|
201
|
+
units: Array.from({ length: spec.units }, (_, u) => ({ gcodeUrl: `https://example.com/${spec.orderId}-u${u}.gcode` })),
|
|
202
|
+
operatorId: userId,
|
|
203
|
+
},
|
|
204
|
+
metadata: { source: 'twin-farm' },
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// ── Human automation: the print-servicer ──────────────────────────────────────
|
|
208
|
+
/** Resolve registration escalations — the servicer bringing a machine online. */
|
|
209
|
+
async function registerLoop(fleet) {
|
|
210
|
+
while (!done) {
|
|
211
|
+
try {
|
|
212
|
+
const resp = await api('GET', '/api/escalations/available?role=print-servicer&subtype=registering&limit=100');
|
|
213
|
+
for (const esc of resp?.escalations ?? []) {
|
|
214
|
+
const spec = fleet.get(String(esc.metadata?.printerId ?? ''));
|
|
215
|
+
if (!spec)
|
|
216
|
+
continue;
|
|
217
|
+
await api('POST', `/api/escalations/${esc.id}/resolve`, {
|
|
218
|
+
resolverPayload: {
|
|
219
|
+
serialNumber: spec.serialNumber,
|
|
220
|
+
model: spec.model,
|
|
221
|
+
manufactureDate: '2026-01-15',
|
|
222
|
+
filament: spec.filament,
|
|
223
|
+
certifications: 'CE, RoHS',
|
|
224
|
+
xl: spec.caps.xl, pdac: spec.caps.pdac, soft: spec.caps.soft,
|
|
225
|
+
notes: 'Auto-registered by twin-farm',
|
|
226
|
+
},
|
|
227
|
+
}).then(() => {
|
|
228
|
+
stats.registered++;
|
|
229
|
+
const c = CAPABILITY_KEYS.filter((k) => spec.caps[k]).join('+') || 'base';
|
|
230
|
+
console.log(`[${ts()}] [register] ${spec.printerId} — ${spec.model} ${spec.filament} (${c}) [${stats.registered}/${FLEET}]`);
|
|
231
|
+
}).catch(() => { });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
logPollErr('register', err);
|
|
236
|
+
}
|
|
237
|
+
if (!done)
|
|
238
|
+
await sleep(POLL_MS);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** Resolve service escalations — the servicer realigning a downed machine. */
|
|
242
|
+
async function serviceLoop() {
|
|
243
|
+
while (!done) {
|
|
244
|
+
try {
|
|
245
|
+
const resp = await api('GET', '/api/escalations/available?role=print-servicer&subtype=service&limit=100');
|
|
246
|
+
for (const esc of resp?.escalations ?? []) {
|
|
247
|
+
await api('POST', `/api/escalations/${esc.id}/resolve`, {
|
|
248
|
+
resolverPayload: { action: 'restored', notes: 'Auto-serviced by twin-farm' },
|
|
249
|
+
}).then(() => {
|
|
250
|
+
stats.serviced++;
|
|
251
|
+
console.log(`[${ts()}] [service] ${esc.metadata?.printerId ?? esc.id.slice(0, 8)} restored [${stats.serviced}]`);
|
|
252
|
+
}).catch(() => { });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
logPollErr('service', err);
|
|
257
|
+
}
|
|
258
|
+
if (!done)
|
|
259
|
+
await sleep(POLL_MS);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/** Cancel a deterministic fraction of in-flight prints — the power-outage /
|
|
263
|
+
* dead-machine drill. Best-effort: it races the physical side's resolve. */
|
|
264
|
+
async function failLoop() {
|
|
265
|
+
if (FAIL_PCT <= 0)
|
|
266
|
+
return;
|
|
267
|
+
const acted = new Set();
|
|
268
|
+
while (!done) {
|
|
269
|
+
try {
|
|
270
|
+
const resp = await api('GET', '/api/escalations/available?role=printer-fleet&subtype=printing&limit=100');
|
|
271
|
+
for (const esc of resp?.escalations ?? []) {
|
|
272
|
+
const jobId = String(esc.metadata?.jobId ?? esc.id);
|
|
273
|
+
if (acted.has(jobId))
|
|
274
|
+
continue;
|
|
275
|
+
if (jitter(jobId, 'fail') * 100 >= FAIL_PCT)
|
|
276
|
+
continue;
|
|
277
|
+
acted.add(jobId);
|
|
278
|
+
await api('POST', `/api/escalations/${esc.id}/cancel`).then(() => {
|
|
279
|
+
stats.cancelled++;
|
|
280
|
+
console.log(`[${ts()}] [FAIL] cancelled print ${jobId} — machine went dark [${stats.cancelled}]`);
|
|
281
|
+
}).catch(() => { });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
logPollErr('fail', err);
|
|
286
|
+
}
|
|
287
|
+
if (!done)
|
|
288
|
+
await sleep(Math.min(POLL_MS, 300));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let lastPollErr = '';
|
|
292
|
+
function logPollErr(loop, err) {
|
|
293
|
+
const msg = `[${loop}] ${String(err?.message).slice(0, 80)}`;
|
|
294
|
+
if (msg !== lastPollErr) {
|
|
295
|
+
console.warn(`[${ts()}] ⚠ ${msg}`);
|
|
296
|
+
lastPollErr = msg;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ── Order arrival + settlement watch ──────────────────────────────────────────
|
|
300
|
+
async function orderLoop(orders) {
|
|
301
|
+
for (const order of orders) {
|
|
302
|
+
if (done)
|
|
303
|
+
break;
|
|
304
|
+
try {
|
|
305
|
+
await placeOrder(order);
|
|
306
|
+
const req = Object.keys(order.require).length ? ` require:${Object.keys(order.require).join('+')}` : '';
|
|
307
|
+
console.log(`[${ts()}] [order] ${order.index + 1}/${orders.length} ${order.orderId} — ${order.filament} ×${order.units}${req}`);
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
console.error(`[${ts()}] [order] ${order.orderId} FAILED: ${String(err.message).slice(0, 100)}`);
|
|
311
|
+
}
|
|
312
|
+
await sleep(spread(ARRIVAL_S, jitter(order.wfId, 'arrive')) * 1000);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/** Poll each order's result; a settled order returns its outcomes. */
|
|
316
|
+
async function settlementWatch(orders) {
|
|
317
|
+
const settled = new Set();
|
|
318
|
+
let stalled = 0;
|
|
319
|
+
const STALL_S = Math.max(40, ORDERS * (ARRIVAL_S + 8));
|
|
320
|
+
while (!done) {
|
|
321
|
+
await sleep(1000);
|
|
322
|
+
let progressed = false;
|
|
323
|
+
for (const order of orders) {
|
|
324
|
+
if (settled.has(order.wfId))
|
|
325
|
+
continue;
|
|
326
|
+
try {
|
|
327
|
+
const resp = await api('GET', `/api/workflows/${order.wfId}/result`);
|
|
328
|
+
const data = resp?.result?.data;
|
|
329
|
+
if (data && data.completedAt !== undefined) {
|
|
330
|
+
settled.add(order.wfId);
|
|
331
|
+
progressed = true;
|
|
332
|
+
stats.settled++;
|
|
333
|
+
const outcomes = data.outcomes ?? [];
|
|
334
|
+
const ok = outcomes.filter((o) => o.outcome === 'success').length;
|
|
335
|
+
const bad = outcomes.length - ok;
|
|
336
|
+
stats.printed += ok;
|
|
337
|
+
stats.dispatched += outcomes.length;
|
|
338
|
+
console.log(`[${ts()}] [settle] ${order.orderId} — ${ok} printed${bad ? `, ${bad} cancelled` : ''} [${stats.settled}/${ORDERS}]`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch { /* 202 still running */ }
|
|
342
|
+
}
|
|
343
|
+
if (stats.settled >= ORDERS) {
|
|
344
|
+
done = true;
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
stalled = progressed ? 0 : stalled + 1;
|
|
348
|
+
if (stalled && stalled % 10 === 0)
|
|
349
|
+
console.log(`[${ts()}] … ${stats.settled}/${ORDERS} settled — waiting (${stalled}s quiet)`);
|
|
350
|
+
if (stalled >= STALL_S) {
|
|
351
|
+
console.warn(`[${ts()}] ⚠ stalled ${stalled}s at ${stats.settled}/${ORDERS} — stopping`);
|
|
352
|
+
done = true;
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// ── Teardown: retire idle twins so nothing lingers ────────────────────────────
|
|
358
|
+
async function retireTwins(fleet) {
|
|
359
|
+
if (KEEP) {
|
|
360
|
+
console.log(`[${ts()}] KEEP=1 — leaving ${fleet.length} twins advertising`);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
await sleep(2000); // let any last twin re-advertise after a service visit
|
|
364
|
+
let retired = 0;
|
|
365
|
+
for (let sweep = 0; sweep < 4 && retired < fleet.length; sweep++) {
|
|
366
|
+
try {
|
|
367
|
+
const resp = await api('GET', '/api/escalations/available?role=printer-fleet&subtype=ready&limit=200');
|
|
368
|
+
for (const esc of resp?.escalations ?? []) {
|
|
369
|
+
try {
|
|
370
|
+
await api('POST', `/api/escalations/${esc.id}/resolve`, { resolverPayload: { powerdown: true } });
|
|
371
|
+
retired++;
|
|
372
|
+
}
|
|
373
|
+
catch { /* claimed or already gone */ }
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch { /* ignore */ }
|
|
377
|
+
if (retired < fleet.length)
|
|
378
|
+
await sleep(1500);
|
|
379
|
+
}
|
|
380
|
+
console.log(`[${ts()}] Retired ${retired} idle twin${retired === 1 ? '' : 's'}`);
|
|
381
|
+
}
|
|
382
|
+
// ── Optional office-link preflight ────────────────────────────────────────────
|
|
383
|
+
async function preflightFarmManager() {
|
|
384
|
+
if (!FARM_MANAGER_URL)
|
|
385
|
+
return;
|
|
386
|
+
process.stdout.write(`[${ts()}] Preflight → ${FARM_MANAGER_URL} … `);
|
|
387
|
+
try {
|
|
388
|
+
const ctrl = new AbortController();
|
|
389
|
+
const t = setTimeout(() => ctrl.abort(), 4000);
|
|
390
|
+
const res = await fetch(FARM_MANAGER_URL, { signal: ctrl.signal }).finally(() => clearTimeout(t));
|
|
391
|
+
console.log(`reachable (HTTP ${res.status}). Set FARM_MANAGER_BACKEND=http + FARM_MANAGER_BASE_URL on the app to dispatch for real.`);
|
|
392
|
+
}
|
|
393
|
+
catch (err) {
|
|
394
|
+
console.log(`UNREACHABLE (${String(err?.message).slice(0, 60)}). Check the office wifi link — see the README connectivity walkthrough.`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
398
|
+
async function main() {
|
|
399
|
+
const runId = Math.floor(Date.now() / 1000).toString();
|
|
400
|
+
const batchTag = `twin-${runId}`;
|
|
401
|
+
const fleet = planFleet(batchTag);
|
|
402
|
+
const fleetById = new Map(fleet.map((t) => [t.printerId, t]));
|
|
403
|
+
console.log(`\n Twin Farm ── ${FLEET} printers, ${ORDERS} orders (≤${UNITS} units), filaments [${FILAMENTS.join(', ')}]`);
|
|
404
|
+
console.log(` arrival=${ARRIVAL_S}s poll=${POLL_MS}ms fail=${FAIL_PCT}% broker=${RUN_BROKER ? `on (idle≤${BROKER_IDLE})` : 'external'} keep=${KEEP}`);
|
|
405
|
+
console.log(` Server: ${BASE_URL}\n`);
|
|
406
|
+
await login();
|
|
407
|
+
await ensureTwinRoles();
|
|
408
|
+
await preflightFarmManager();
|
|
409
|
+
// 1. Launch the fleet — each twin raises a registration escalation and parks.
|
|
410
|
+
console.log(`\n[${ts()}] Launching ${FLEET} twins …`);
|
|
411
|
+
for (const spec of fleet)
|
|
412
|
+
await startTwin(spec);
|
|
413
|
+
// 2. Register + service loops start now so twins come online as they appear.
|
|
414
|
+
const humanLoops = [registerLoop(fleetById), serviceLoop(), failLoop()];
|
|
415
|
+
// 3. Broker (once the humans are watching).
|
|
416
|
+
if (RUN_BROKER) {
|
|
417
|
+
await startBroker(batchTag);
|
|
418
|
+
console.log(`[${ts()}] Broker running`);
|
|
419
|
+
}
|
|
420
|
+
// 4. Wait for the fleet to register before placing demand (so orders place).
|
|
421
|
+
const registerDeadline = Date.now() + 30_000;
|
|
422
|
+
while (stats.registered < FLEET && Date.now() < registerDeadline && !done)
|
|
423
|
+
await sleep(500);
|
|
424
|
+
if (stats.registered < FLEET)
|
|
425
|
+
console.warn(`[${ts()}] ⚠ only ${stats.registered}/${FLEET} registered — placing orders anyway`);
|
|
426
|
+
// 5. Orders arrive; settlement watch drives the run to completion.
|
|
427
|
+
const orders = planOrders(batchTag, fleet);
|
|
428
|
+
console.log(`\n[${ts()}] Placing ${ORDERS} orders …\n`);
|
|
429
|
+
const startMs = Date.now();
|
|
430
|
+
await Promise.all([orderLoop(orders), settlementWatch(orders), ...humanLoops.map((p) => p.catch(() => { }))]);
|
|
431
|
+
const elapsed = ((Date.now() - startMs) / 1000).toFixed(1);
|
|
432
|
+
await retireTwins(fleet);
|
|
433
|
+
console.log(`\n[${ts()}] Done in ${elapsed}s`);
|
|
434
|
+
console.log(` Registered: ${stats.registered}/${FLEET}`);
|
|
435
|
+
console.log(` Orders: ${stats.settled}/${ORDERS} settled`);
|
|
436
|
+
console.log(` Units: ${stats.printed} printed${stats.cancelled ? `, ${stats.cancelled} cancelled` : ''} (${stats.dispatched} dispatched)`);
|
|
437
|
+
console.log(` Serviced: ${stats.serviced}`);
|
|
438
|
+
console.log(`\n Dashboard: ${BASE_URL}/escalations\n`);
|
|
439
|
+
process.exit(0);
|
|
440
|
+
}
|
|
441
|
+
main().catch((err) => { console.error(err); process.exit(1); });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../index.ts","../vitest.config.ts","../vitest.integration.config.ts","../adapters/express.ts","../api/agent-subscriptions.ts","../api/agents.ts","../api/auth-sso.ts","../api/auth.ts","../api/bot-accounts.ts","../api/capabilities.ts","../api/controlplane.ts","../api/dba.ts","../api/diagnostics.ts","../api/exports.ts","../api/files.ts","../api/index.ts","../api/insight.ts","../api/knowledge.ts","../api/maintenance.ts","../api/namespaces.ts","../api/overview.ts","../api/pipelines.ts","../api/roles.ts","../api/settings.ts","../api/tasks.ts","../api/topics.ts","../api/users.ts","../api/workflow-sets.ts","../api/escalations/bulk.ts","../api/escalations/cancel.ts","../api/escalations/claim.ts","../api/escalations/create.ts","../api/escalations/facets.ts","../api/escalations/helpers.ts","../api/escalations/index.ts","../api/escalations/list.ts","../api/escalations/metadata.ts","../api/escalations/resolve.ts","../api/escalations/single.ts","../api/mcp/index.ts","../api/mcp/servers.ts","../api/mcp/tools.ts","../api/workflows/config.ts","../api/workflows/discovery.ts","../api/workflows/index.ts","../api/workflows/invocation.ts","../api/yaml-workflows/cron.ts","../api/yaml-workflows/crud.ts","../api/yaml-workflows/deploy.ts","../api/yaml-workflows/helpers.ts","../api/yaml-workflows/index.ts","../api/yaml-workflows/versions.ts","../bin/ltc.ts","../lib/cli/auth.ts","../lib/cli/client.ts","../lib/cli/compile.ts","../lib/cli/format.ts","../lib/cli/init.ts","../lib/cli/output.ts","../lib/cli/scanner.ts","../lib/cli/types.ts","../lib/cli/commands/escalations.ts","../lib/cli/commands/knowledge.ts","../lib/cli/commands/mcp.ts","../lib/cli/commands/pipelines.ts","../lib/cli/commands/roles.ts","../lib/cli/commands/status.ts","../lib/cli/commands/streams.ts","../lib/cli/commands/users.ts","../lib/cli/commands/workflows.ts","../lib/db/index.ts","../lib/db/migrate.ts","../lib/events/callback.ts","../lib/events/index.ts","../lib/events/matching.ts","../lib/events/memory.ts","../lib/events/nats-ws-proxy.ts","../lib/events/nats.ts","../lib/events/publish.ts","../lib/events/socketio.ts","../lib/events/system-events.ts","../lib/logger/index.ts","../lib/logger/pino.ts","../lib/storage/index.ts","../lib/storage/local.ts","../lib/storage/mime.ts","../lib/storage/s3.ts","../lib/storage/types.ts","../lib/telemetry/honeycomb.ts","../lib/telemetry/index.ts","../modules/auth.ts","../modules/config.ts","../modules/defaults.ts","../modules/features.ts","../modules/ltconfig.ts","../modules/maintenance.ts","../modules/sso.ts","../modules/utils.ts","../modules/version.ts","../routes/agents.ts","../routes/auth-sso.ts","../routes/auth.ts","../routes/bot-accounts.ts","../routes/capabilities.ts","../routes/controlplane.ts","../routes/dba.ts","../routes/delegation.ts","../routes/diagnostics.ts","../routes/docs.ts","../routes/exports.ts","../routes/file-browser.ts","../routes/files.ts","../routes/index.ts","../routes/insight.ts","../routes/knowledge.ts","../routes/maintenance.ts","../routes/mcp-endpoint.ts","../routes/mcp.ts","../routes/namespaces.ts","../routes/nats-credentials.ts","../routes/oauth.ts","../routes/overview.ts","../routes/pipelines.ts","../routes/roles.ts","../routes/settings.ts","../routes/tasks.ts","../routes/topics.ts","../routes/users.ts","../routes/workflow-sets.ts","../routes/escalations/bulk.ts","../routes/escalations/facets.ts","../routes/escalations/index.ts","../routes/escalations/list.ts","../routes/escalations/metadata.ts","../routes/escalations/resolve.ts","../routes/escalations/single.ts","../routes/workflows/config.ts","../routes/workflows/discovery.ts","../routes/workflows/index.ts","../routes/workflows/invocation.ts","../routes/yaml-workflows/cron.ts","../routes/yaml-workflows/crud.ts","../routes/yaml-workflows/deployment.ts","../routes/yaml-workflows/index.ts","../routes/yaml-workflows/versions.ts","../scripts/ortho-populate.ts","../scripts/process-helpers.ts","../scripts/process.ts","../scripts/token.ts","../sdk/index.ts","../services/dba.ts","../services/hotmesh-utils.ts","../services/workflow-invocation.ts","../services/agent/index.ts","../services/agent/input-mapper.ts","../services/agent/sql.ts","../services/agent/subscription-sql.ts","../services/agent/subscriptions.ts","../services/agent/trigger-registry.ts","../services/auth/bot-api-key.ts","../services/auth/delegation.ts","../services/auth/index.ts","../services/auth/service-token.ts","../services/auth/sql.ts","../services/config/cache.ts","../services/config/index.ts","../services/config/provider.ts","../services/config/read.ts","../services/config/sql.ts","../services/config/write.ts","../services/controlplane/index.ts","../services/controlplane/quorum-bridge.ts","../services/controlplane/sql.ts","../services/controlplane/stream-messages-sql.ts","../services/controlplane/types.ts","../services/cron/index.ts","../services/diagnostics/index.ts","../services/diagnostics/patterns.ts","../services/escalation/bulk.ts","../services/escalation/client.ts","../services/escalation/crud.ts","../services/escalation/facet-sql.ts","../services/escalation/facets.ts","../services/escalation/index.ts","../services/escalation/map.ts","../services/escalation/metrics-cache.ts","../services/escalation/queries.ts","../services/escalation/sql.ts","../services/escalation/types.ts","../services/escalation-strategy/default.ts","../services/escalation-strategy/index.ts","../services/escalation-strategy/mcp.ts","../services/export/client.ts","../services/export/index.ts","../services/export/post-process.ts","../services/export/types.ts","../services/iam/activity.ts","../services/iam/bots.ts","../services/iam/context.ts","../services/iam/credentials.ts","../services/iam/envelope.ts","../services/iam/ephemeral.ts","../services/iam/index.ts","../services/iam/principal.ts","../services/iam/resolve.ts","../services/iam/sql.ts","../services/insight/index.ts","../services/insight/prompts.ts","../services/interceptor/activity-interceptor.ts","../services/interceptor/completion.ts","../services/interceptor/context.ts","../services/interceptor/escalation.ts","../services/interceptor/index.ts","../services/interceptor/lifecycle.ts","../services/interceptor/state.ts","../services/interceptor/types.ts","../services/interceptor/activities/config.ts","../services/interceptor/activities/escalation.ts","../services/interceptor/activities/index.ts","../services/interceptor/activities/task.ts","../services/interceptor/activities/workflow.ts","../services/llm/detect.ts","../services/llm/index.ts","../services/llm/translate.ts","../services/llm/types.ts","../services/llm/providers/anthropic.ts","../services/llm/providers/openai.ts","../services/maintenance/index.ts","../services/mcp/adapter.ts","../services/mcp/db.ts","../services/mcp/exposure.ts","../services/mcp/external-server.ts","../services/mcp/index.ts","../services/mcp/register-tool.ts","../services/mcp/seed-service-account.ts","../services/mcp/server-lifecycle.ts","../services/mcp/server-tools.ts","../services/mcp/server.ts","../services/mcp/sql.ts","../services/mcp/types.ts","../services/mcp/workflow-compiler-server.ts","../services/mcp/workflow-server.ts","../services/mcp/client/connection-dispatch.ts","../services/mcp/client/connection-lifecycle.ts","../services/mcp/client/connection-test.ts","../services/mcp/client/connection.ts","../services/mcp/client/index.ts","../services/mcp/client/tools.ts","../services/mcp/db-server/index.ts","../services/mcp/db-server/schemas.ts","../services/mcp/db-server/tools.ts","../services/mcp/playwright-server/index.ts","../services/mcp/playwright-server/lifecycle.ts","../services/mcp/playwright-server/schemas.ts","../services/mcp/playwright-server/tools.ts","../services/namespace/index.ts","../services/namespace/sql.ts","../services/namespace/types.ts","../services/oauth/crypto.ts","../services/oauth/db.ts","../services/oauth/index.ts","../services/oauth/sql.ts","../services/oauth/state.ts","../services/oauth/providers/anthropic.ts","../services/oauth/providers/github.ts","../services/oauth/providers/google.ts","../services/oauth/providers/index.ts","../services/oauth/providers/microsoft.ts","../services/oauth/providers/mock.ts","../services/oauth/providers/registry.ts","../services/oauth/providers/types.ts","../services/orchestrator/condition.ts","../services/orchestrator/index.ts","../services/orchestrator/types.ts","../services/overview/index.ts","../services/overview/sql.ts","../services/pipelines/enrichment.ts","../services/pipelines/events.ts","../services/pipelines/execution-builder.ts","../services/pipelines/index.ts","../services/pipelines/queries.ts","../services/pipelines/sql.ts","../services/pipelines/types.ts","../services/role/index.ts","../services/role/sql.ts","../services/role/types.ts","../services/task/crud.ts","../services/task/index.ts","../services/task/process.ts","../services/task/resolve.ts","../services/task/sql.ts","../services/task/types.ts","../services/topics/index.ts","../services/topics/sql.ts","../services/topics/system-topics.ts","../services/user/auth.ts","../services/user/crud.ts","../services/user/index.ts","../services/user/rbac.ts","../services/user/roles.ts","../services/user/scope.ts","../services/user/seed-admin.ts","../services/user/sql.ts","../services/user/sso-provision.ts","../services/user/types.ts","../services/workers/registry.ts","../services/workflow-sets/db.ts","../services/workflow-sets/index.ts","../services/workflow-sets/sql.ts","../services/yaml-workflow/builder-regenerate.ts","../services/yaml-workflow/db-utils.ts","../services/yaml-workflow/db-versions.ts","../services/yaml-workflow/db.ts","../services/yaml-workflow/deployer-helpers.ts","../services/yaml-workflow/deployer.ts","../services/yaml-workflow/generator.ts","../services/yaml-workflow/index.ts","../services/yaml-workflow/input-analyzer-helpers.ts","../services/yaml-workflow/input-analyzer.ts","../services/yaml-workflow/invoke.ts","../services/yaml-workflow/pipe-validator.ts","../services/yaml-workflow/sql.ts","../services/yaml-workflow/types.ts","../services/yaml-workflow/durable-compiler/index.ts","../services/yaml-workflow/durable-compiler/parser.ts","../services/yaml-workflow/durable-compiler/prompts.ts","../services/yaml-workflow/durable-compiler/types.ts","../services/yaml-workflow/pattern-detector/array-source.ts","../services/yaml-workflow/pattern-detector/collapse.ts","../services/yaml-workflow/pattern-detector/index.ts","../services/yaml-workflow/pattern-detector/run-detection.ts","../services/yaml-workflow/pattern-detector/types.ts","../services/yaml-workflow/pipeline/analyze.ts","../services/yaml-workflow/pipeline/extract-helpers.ts","../services/yaml-workflow/pipeline/extract.ts","../services/yaml-workflow/pipeline/index.ts","../services/yaml-workflow/pipeline/prompt-templates.ts","../services/yaml-workflow/pipeline/prompts.ts","../services/yaml-workflow/pipeline/validate.ts","../services/yaml-workflow/pipeline/build/dag-assembly.ts","../services/yaml-workflow/pipeline/build/dag.ts","../services/yaml-workflow/pipeline/build/index.ts","../services/yaml-workflow/pipeline/build/iteration.ts","../services/yaml-workflow/pipeline/build/metadata.ts","../services/yaml-workflow/pipeline/build/transform.ts","../services/yaml-workflow/pipeline/build/utils.ts","../services/yaml-workflow/pipeline/build/wiring.ts","../services/yaml-workflow/pipeline/compile/index.ts","../services/yaml-workflow/pipeline/compile/llm-call.ts","../services/yaml-workflow/pipeline/compile/parse-plan.ts","../services/yaml-workflow/pipeline/compile/summarize.ts","../services/yaml-workflow/workers/callbacks.ts","../services/yaml-workflow/workers/events.ts","../services/yaml-workflow/workers/index.ts","../services/yaml-workflow/workers/register.ts","../services/yaml-workflow/workers/scope.ts","../start/adapters.ts","../start/config.ts","../start/graph-workflows.ts","../start/index.ts","../start/server.ts","../start/socket-auth.ts","../start/workers.ts","../system/index.ts","../system/activities/claude-code.ts","../system/activities/file-storage.ts","../system/activities/http.ts","../system/activities/knowledge.ts","../system/activities/oauth.ts","../system/activities/schema-exchange.ts","../system/activities/sql.ts","../system/activities/triage/cache.ts","../system/activities/triage/context.ts","../system/activities/triage/discovery.ts","../system/activities/triage/index.ts","../system/activities/triage/llm.ts","../system/activities/triage/tools.ts","../system/mcp-servers/claude-code.ts","../system/mcp-servers/docs.ts","../system/mcp-servers/events.ts","../system/mcp-servers/file-storage.ts","../system/mcp-servers/http-fetch.ts","../system/mcp-servers/human-queue-schemas.ts","../system/mcp-servers/human-queue.ts","../system/mcp-servers/knowledge.ts","../system/mcp-servers/oauth.ts","../system/mcp-servers/schema-exchange.ts","../system/mcp-servers/translation.ts","../system/mcp-servers/vision-prompts.ts","../system/mcp-servers/vision.ts","../system/mcp-servers/workflow-compiler.ts","../system/mcp-servers/workflow.ts","../system/mcp-servers/admin/agent-subscriptions.ts","../system/mcp-servers/admin/agents.ts","../system/mcp-servers/admin/bot-accounts.ts","../system/mcp-servers/admin/controlplane.ts","../system/mcp-servers/admin/diagnostics.ts","../system/mcp-servers/admin/escalations.ts","../system/mcp-servers/admin/exports.ts","../system/mcp-servers/admin/index.ts","../system/mcp-servers/admin/maintenance.ts","../system/mcp-servers/admin/mcp-servers.ts","../system/mcp-servers/admin/ortho.ts","../system/mcp-servers/admin/overview.ts","../system/mcp-servers/admin/pipelines.ts","../system/mcp-servers/admin/schemas.ts","../system/mcp-servers/admin/settings.ts","../system/mcp-servers/admin/tasks.ts","../system/mcp-servers/admin/topics.ts","../system/mcp-servers/admin/users.ts","../system/mcp-servers/admin/workflow-config.ts","../system/mcp-servers/admin/workflows.ts","../system/mcp-servers/admin/yaml-workflows.ts","../system/mcp-servers/db-query/index.ts","../system/mcp-servers/db-query/schemas.ts","../system/mcp-servers/db-query/tools.ts","../system/seed/index.ts","../system/seed/tool-manifests-admin.ts","../system/seed/tool-manifests-data.ts","../system/seed/tool-manifests-escalation.ts","../system/seed/tool-manifests-events.ts","../system/seed/tool-manifests-knowledge.ts","../system/seed/tool-manifests-workflows.ts","../system/workflows/tool-result-guard.ts","../system/workflows/capability-invoke/activities.ts","../system/workflows/capability-invoke/index.ts","../system/workflows/mcp-deterministic/activities.ts","../system/workflows/mcp-deterministic/index.ts","../system/workflows/mcp-query/index.ts","../system/workflows/mcp-query/prompts.ts","../system/workflows/mcp-query/strategy-advisors.ts","../system/workflows/mcp-query/types.ts","../system/workflows/mcp-query/activities/caches.ts","../system/workflows/mcp-query/activities/discovery.ts","../system/workflows/mcp-query/activities/index.ts","../system/workflows/mcp-query/activities/llm.ts","../system/workflows/mcp-query/activities/tool-executor.ts","../system/workflows/mcp-query/activities/tool-loader.ts","../system/workflows/mcp-query-router/activities.ts","../system/workflows/mcp-query-router/index.ts","../system/workflows/mcp-query-router/prompts.ts","../system/workflows/mcp-triage/activities-proxy.ts","../system/workflows/mcp-triage/index.ts","../system/workflows/mcp-triage/prompts.ts","../system/workflows/mcp-triage/response-builders.ts","../system/workflows/mcp-triage/response.ts","../system/workflows/mcp-triage/types.ts","../system/workflows/mcp-triage-deterministic/activities.ts","../system/workflows/mcp-triage-deterministic/index.ts","../system/workflows/mcp-triage-router/activities.ts","../system/workflows/mcp-triage-router/index.ts","../system/workflows/mcp-workflow-builder/index.ts","../system/workflows/mcp-workflow-builder/prompts.ts","../system/workflows/mcp-workflow-builder/activities/caches.ts","../system/workflows/mcp-workflow-builder/activities/index.ts","../system/workflows/mcp-workflow-builder/activities/llm.ts","../system/workflows/mcp-workflow-builder/activities/tool-loader.ts","../system/workflows/mcp-workflow-planner/index.ts","../system/workflows/mcp-workflow-planner/prompts.ts","../system/workflows/mcp-workflow-planner/activities/analyze.ts","../system/workflows/mcp-workflow-planner/activities/index.ts","../system/workflows/mcp-workflow-planner/activities/persist.ts","../system/workflows/mcp-workflow-planner/activities/plan.ts","../system/workflows/shared/discovery.ts","../system/workflows/shared/index.ts","../system/workflows/shared/llm-caller.ts","../system/workflows/shared/prompts.ts","../system/workflows/shared/strategy-advisors.ts","../system/workflows/shared/tool-executor.ts","../system/workflows/shared/tool-loader.ts","../system/workflows/shared/types.ts","../types/agent.ts","../types/auth.ts","../types/config.ts","../types/delegation.ts","../types/discovery.ts","../types/envelope.ts","../types/escalation-strategy.ts","../types/escalation.ts","../types/events.ts","../types/export.ts","../types/express.d.ts","../types/facets.ts","../types/index.ts","../types/logger.ts","../types/maintenance.ts","../types/mcp.ts","../types/oauth.ts","../types/sdk.ts","../types/startup.ts","../types/task.ts","../types/telemetry.ts","../types/tool-context.ts","../types/user.ts","../types/workflow-set.ts","../types/workflow.ts","../types/yaml-workflow.ts","../workers/index.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../index.ts","../vitest.config.ts","../vitest.integration.config.ts","../adapters/express.ts","../api/agent-subscriptions.ts","../api/agents.ts","../api/auth-sso.ts","../api/auth.ts","../api/bot-accounts.ts","../api/capabilities.ts","../api/controlplane.ts","../api/dba.ts","../api/diagnostics.ts","../api/exports.ts","../api/files.ts","../api/index.ts","../api/insight.ts","../api/knowledge.ts","../api/maintenance.ts","../api/namespaces.ts","../api/overview.ts","../api/pipelines.ts","../api/roles.ts","../api/settings.ts","../api/tasks.ts","../api/topics.ts","../api/users.ts","../api/workflow-sets.ts","../api/escalations/bulk.ts","../api/escalations/cancel.ts","../api/escalations/claim.ts","../api/escalations/create.ts","../api/escalations/facets.ts","../api/escalations/helpers.ts","../api/escalations/index.ts","../api/escalations/list.ts","../api/escalations/metadata.ts","../api/escalations/resolve.ts","../api/escalations/single.ts","../api/mcp/index.ts","../api/mcp/servers.ts","../api/mcp/tools.ts","../api/workflows/config.ts","../api/workflows/discovery.ts","../api/workflows/index.ts","../api/workflows/invocation.ts","../api/yaml-workflows/cron.ts","../api/yaml-workflows/crud.ts","../api/yaml-workflows/deploy.ts","../api/yaml-workflows/helpers.ts","../api/yaml-workflows/index.ts","../api/yaml-workflows/versions.ts","../bin/ltc.ts","../lib/cli/auth.ts","../lib/cli/client.ts","../lib/cli/compile.ts","../lib/cli/format.ts","../lib/cli/init.ts","../lib/cli/output.ts","../lib/cli/scanner.ts","../lib/cli/types.ts","../lib/cli/commands/escalations.ts","../lib/cli/commands/knowledge.ts","../lib/cli/commands/mcp.ts","../lib/cli/commands/pipelines.ts","../lib/cli/commands/roles.ts","../lib/cli/commands/status.ts","../lib/cli/commands/streams.ts","../lib/cli/commands/users.ts","../lib/cli/commands/workflows.ts","../lib/db/index.ts","../lib/db/migrate.ts","../lib/events/callback.ts","../lib/events/index.ts","../lib/events/matching.ts","../lib/events/memory.ts","../lib/events/nats-ws-proxy.ts","../lib/events/nats.ts","../lib/events/publish.ts","../lib/events/socketio.ts","../lib/events/system-events.ts","../lib/logger/index.ts","../lib/logger/pino.ts","../lib/storage/index.ts","../lib/storage/local.ts","../lib/storage/mime.ts","../lib/storage/s3.ts","../lib/storage/types.ts","../lib/telemetry/honeycomb.ts","../lib/telemetry/index.ts","../modules/auth.ts","../modules/config.ts","../modules/defaults.ts","../modules/features.ts","../modules/ltconfig.ts","../modules/maintenance.ts","../modules/sso.ts","../modules/utils.ts","../modules/version.ts","../routes/agents.ts","../routes/auth-sso.ts","../routes/auth.ts","../routes/bot-accounts.ts","../routes/capabilities.ts","../routes/controlplane.ts","../routes/dba.ts","../routes/delegation.ts","../routes/diagnostics.ts","../routes/docs.ts","../routes/exports.ts","../routes/file-browser.ts","../routes/files.ts","../routes/index.ts","../routes/insight.ts","../routes/knowledge.ts","../routes/maintenance.ts","../routes/mcp-endpoint.ts","../routes/mcp.ts","../routes/namespaces.ts","../routes/nats-credentials.ts","../routes/oauth.ts","../routes/overview.ts","../routes/pipelines.ts","../routes/roles.ts","../routes/settings.ts","../routes/tasks.ts","../routes/topics.ts","../routes/users.ts","../routes/workflow-sets.ts","../routes/escalations/bulk.ts","../routes/escalations/facets.ts","../routes/escalations/index.ts","../routes/escalations/list.ts","../routes/escalations/metadata.ts","../routes/escalations/resolve.ts","../routes/escalations/single.ts","../routes/workflows/config.ts","../routes/workflows/discovery.ts","../routes/workflows/index.ts","../routes/workflows/invocation.ts","../routes/yaml-workflows/cron.ts","../routes/yaml-workflows/crud.ts","../routes/yaml-workflows/deployment.ts","../routes/yaml-workflows/index.ts","../routes/yaml-workflows/versions.ts","../scripts/ortho-populate.ts","../scripts/process-helpers.ts","../scripts/process.ts","../scripts/token.ts","../scripts/twin-farm.ts","../sdk/index.ts","../services/dba.ts","../services/hotmesh-utils.ts","../services/workflow-invocation.ts","../services/agent/index.ts","../services/agent/input-mapper.ts","../services/agent/sql.ts","../services/agent/subscription-sql.ts","../services/agent/subscriptions.ts","../services/agent/trigger-registry.ts","../services/auth/bot-api-key.ts","../services/auth/delegation.ts","../services/auth/index.ts","../services/auth/service-token.ts","../services/auth/sql.ts","../services/config/cache.ts","../services/config/index.ts","../services/config/provider.ts","../services/config/read.ts","../services/config/sql.ts","../services/config/write.ts","../services/controlplane/index.ts","../services/controlplane/quorum-bridge.ts","../services/controlplane/sql.ts","../services/controlplane/stream-messages-sql.ts","../services/controlplane/types.ts","../services/cron/index.ts","../services/diagnostics/index.ts","../services/diagnostics/patterns.ts","../services/escalation/bulk.ts","../services/escalation/client.ts","../services/escalation/crud.ts","../services/escalation/facet-sql.ts","../services/escalation/facets.ts","../services/escalation/index.ts","../services/escalation/map.ts","../services/escalation/metrics-cache.ts","../services/escalation/queries.ts","../services/escalation/sql.ts","../services/escalation/types.ts","../services/escalation-strategy/default.ts","../services/escalation-strategy/index.ts","../services/escalation-strategy/mcp.ts","../services/export/client.ts","../services/export/index.ts","../services/export/post-process.ts","../services/export/types.ts","../services/iam/activity.ts","../services/iam/bots.ts","../services/iam/context.ts","../services/iam/credentials.ts","../services/iam/envelope.ts","../services/iam/ephemeral.ts","../services/iam/index.ts","../services/iam/principal.ts","../services/iam/resolve.ts","../services/iam/sql.ts","../services/insight/index.ts","../services/insight/prompts.ts","../services/interceptor/activity-interceptor.ts","../services/interceptor/completion.ts","../services/interceptor/context.ts","../services/interceptor/escalation.ts","../services/interceptor/index.ts","../services/interceptor/lifecycle.ts","../services/interceptor/state.ts","../services/interceptor/types.ts","../services/interceptor/activities/config.ts","../services/interceptor/activities/escalation.ts","../services/interceptor/activities/index.ts","../services/interceptor/activities/task.ts","../services/interceptor/activities/workflow.ts","../services/llm/detect.ts","../services/llm/index.ts","../services/llm/translate.ts","../services/llm/types.ts","../services/llm/providers/anthropic.ts","../services/llm/providers/openai.ts","../services/maintenance/index.ts","../services/mcp/adapter.ts","../services/mcp/db.ts","../services/mcp/exposure.ts","../services/mcp/external-server.ts","../services/mcp/index.ts","../services/mcp/register-tool.ts","../services/mcp/seed-service-account.ts","../services/mcp/server-lifecycle.ts","../services/mcp/server-tools.ts","../services/mcp/server.ts","../services/mcp/sql.ts","../services/mcp/types.ts","../services/mcp/workflow-compiler-server.ts","../services/mcp/workflow-server.ts","../services/mcp/client/connection-dispatch.ts","../services/mcp/client/connection-lifecycle.ts","../services/mcp/client/connection-test.ts","../services/mcp/client/connection.ts","../services/mcp/client/index.ts","../services/mcp/client/tools.ts","../services/mcp/db-server/index.ts","../services/mcp/db-server/schemas.ts","../services/mcp/db-server/tools.ts","../services/mcp/playwright-server/index.ts","../services/mcp/playwright-server/lifecycle.ts","../services/mcp/playwright-server/schemas.ts","../services/mcp/playwright-server/tools.ts","../services/namespace/index.ts","../services/namespace/sql.ts","../services/namespace/types.ts","../services/oauth/crypto.ts","../services/oauth/db.ts","../services/oauth/index.ts","../services/oauth/sql.ts","../services/oauth/state.ts","../services/oauth/providers/anthropic.ts","../services/oauth/providers/github.ts","../services/oauth/providers/google.ts","../services/oauth/providers/index.ts","../services/oauth/providers/microsoft.ts","../services/oauth/providers/mock.ts","../services/oauth/providers/registry.ts","../services/oauth/providers/types.ts","../services/orchestrator/condition.ts","../services/orchestrator/index.ts","../services/orchestrator/types.ts","../services/overview/index.ts","../services/overview/sql.ts","../services/pipelines/enrichment.ts","../services/pipelines/events.ts","../services/pipelines/execution-builder.ts","../services/pipelines/index.ts","../services/pipelines/queries.ts","../services/pipelines/sql.ts","../services/pipelines/types.ts","../services/role/index.ts","../services/role/sql.ts","../services/role/types.ts","../services/task/crud.ts","../services/task/index.ts","../services/task/process.ts","../services/task/resolve.ts","../services/task/sql.ts","../services/task/types.ts","../services/topics/index.ts","../services/topics/sql.ts","../services/topics/system-topics.ts","../services/user/auth.ts","../services/user/crud.ts","../services/user/index.ts","../services/user/rbac.ts","../services/user/roles.ts","../services/user/scope.ts","../services/user/seed-admin.ts","../services/user/sql.ts","../services/user/sso-provision.ts","../services/user/types.ts","../services/workers/registry.ts","../services/workflow-sets/db.ts","../services/workflow-sets/index.ts","../services/workflow-sets/sql.ts","../services/yaml-workflow/builder-regenerate.ts","../services/yaml-workflow/db-utils.ts","../services/yaml-workflow/db-versions.ts","../services/yaml-workflow/db.ts","../services/yaml-workflow/deployer-helpers.ts","../services/yaml-workflow/deployer.ts","../services/yaml-workflow/generator.ts","../services/yaml-workflow/index.ts","../services/yaml-workflow/input-analyzer-helpers.ts","../services/yaml-workflow/input-analyzer.ts","../services/yaml-workflow/invoke.ts","../services/yaml-workflow/pipe-validator.ts","../services/yaml-workflow/sql.ts","../services/yaml-workflow/types.ts","../services/yaml-workflow/durable-compiler/index.ts","../services/yaml-workflow/durable-compiler/parser.ts","../services/yaml-workflow/durable-compiler/prompts.ts","../services/yaml-workflow/durable-compiler/types.ts","../services/yaml-workflow/pattern-detector/array-source.ts","../services/yaml-workflow/pattern-detector/collapse.ts","../services/yaml-workflow/pattern-detector/index.ts","../services/yaml-workflow/pattern-detector/run-detection.ts","../services/yaml-workflow/pattern-detector/types.ts","../services/yaml-workflow/pipeline/analyze.ts","../services/yaml-workflow/pipeline/extract-helpers.ts","../services/yaml-workflow/pipeline/extract.ts","../services/yaml-workflow/pipeline/index.ts","../services/yaml-workflow/pipeline/prompt-templates.ts","../services/yaml-workflow/pipeline/prompts.ts","../services/yaml-workflow/pipeline/validate.ts","../services/yaml-workflow/pipeline/build/dag-assembly.ts","../services/yaml-workflow/pipeline/build/dag.ts","../services/yaml-workflow/pipeline/build/index.ts","../services/yaml-workflow/pipeline/build/iteration.ts","../services/yaml-workflow/pipeline/build/metadata.ts","../services/yaml-workflow/pipeline/build/transform.ts","../services/yaml-workflow/pipeline/build/utils.ts","../services/yaml-workflow/pipeline/build/wiring.ts","../services/yaml-workflow/pipeline/compile/index.ts","../services/yaml-workflow/pipeline/compile/llm-call.ts","../services/yaml-workflow/pipeline/compile/parse-plan.ts","../services/yaml-workflow/pipeline/compile/summarize.ts","../services/yaml-workflow/workers/callbacks.ts","../services/yaml-workflow/workers/events.ts","../services/yaml-workflow/workers/index.ts","../services/yaml-workflow/workers/register.ts","../services/yaml-workflow/workers/scope.ts","../start/adapters.ts","../start/config.ts","../start/graph-workflows.ts","../start/index.ts","../start/server.ts","../start/socket-auth.ts","../start/workers.ts","../system/index.ts","../system/activities/claude-code.ts","../system/activities/file-storage.ts","../system/activities/http.ts","../system/activities/knowledge.ts","../system/activities/oauth.ts","../system/activities/schema-exchange.ts","../system/activities/sql.ts","../system/activities/triage/cache.ts","../system/activities/triage/context.ts","../system/activities/triage/discovery.ts","../system/activities/triage/index.ts","../system/activities/triage/llm.ts","../system/activities/triage/tools.ts","../system/mcp-servers/claude-code.ts","../system/mcp-servers/docs.ts","../system/mcp-servers/events.ts","../system/mcp-servers/file-storage.ts","../system/mcp-servers/http-fetch.ts","../system/mcp-servers/human-queue-schemas.ts","../system/mcp-servers/human-queue.ts","../system/mcp-servers/knowledge.ts","../system/mcp-servers/oauth.ts","../system/mcp-servers/schema-exchange.ts","../system/mcp-servers/translation.ts","../system/mcp-servers/vision-prompts.ts","../system/mcp-servers/vision.ts","../system/mcp-servers/workflow-compiler.ts","../system/mcp-servers/workflow.ts","../system/mcp-servers/admin/agent-subscriptions.ts","../system/mcp-servers/admin/agents.ts","../system/mcp-servers/admin/bot-accounts.ts","../system/mcp-servers/admin/controlplane.ts","../system/mcp-servers/admin/diagnostics.ts","../system/mcp-servers/admin/escalations.ts","../system/mcp-servers/admin/exports.ts","../system/mcp-servers/admin/index.ts","../system/mcp-servers/admin/maintenance.ts","../system/mcp-servers/admin/mcp-servers.ts","../system/mcp-servers/admin/ortho.ts","../system/mcp-servers/admin/overview.ts","../system/mcp-servers/admin/pipelines.ts","../system/mcp-servers/admin/schemas.ts","../system/mcp-servers/admin/settings.ts","../system/mcp-servers/admin/tasks.ts","../system/mcp-servers/admin/topics.ts","../system/mcp-servers/admin/users.ts","../system/mcp-servers/admin/workflow-config.ts","../system/mcp-servers/admin/workflows.ts","../system/mcp-servers/admin/yaml-workflows.ts","../system/mcp-servers/db-query/index.ts","../system/mcp-servers/db-query/schemas.ts","../system/mcp-servers/db-query/tools.ts","../system/seed/index.ts","../system/seed/tool-manifests-admin.ts","../system/seed/tool-manifests-data.ts","../system/seed/tool-manifests-escalation.ts","../system/seed/tool-manifests-events.ts","../system/seed/tool-manifests-knowledge.ts","../system/seed/tool-manifests-workflows.ts","../system/workflows/tool-result-guard.ts","../system/workflows/capability-invoke/activities.ts","../system/workflows/capability-invoke/index.ts","../system/workflows/mcp-deterministic/activities.ts","../system/workflows/mcp-deterministic/index.ts","../system/workflows/mcp-query/index.ts","../system/workflows/mcp-query/prompts.ts","../system/workflows/mcp-query/strategy-advisors.ts","../system/workflows/mcp-query/types.ts","../system/workflows/mcp-query/activities/caches.ts","../system/workflows/mcp-query/activities/discovery.ts","../system/workflows/mcp-query/activities/index.ts","../system/workflows/mcp-query/activities/llm.ts","../system/workflows/mcp-query/activities/tool-executor.ts","../system/workflows/mcp-query/activities/tool-loader.ts","../system/workflows/mcp-query-router/activities.ts","../system/workflows/mcp-query-router/index.ts","../system/workflows/mcp-query-router/prompts.ts","../system/workflows/mcp-triage/activities-proxy.ts","../system/workflows/mcp-triage/index.ts","../system/workflows/mcp-triage/prompts.ts","../system/workflows/mcp-triage/response-builders.ts","../system/workflows/mcp-triage/response.ts","../system/workflows/mcp-triage/types.ts","../system/workflows/mcp-triage-deterministic/activities.ts","../system/workflows/mcp-triage-deterministic/index.ts","../system/workflows/mcp-triage-router/activities.ts","../system/workflows/mcp-triage-router/index.ts","../system/workflows/mcp-workflow-builder/index.ts","../system/workflows/mcp-workflow-builder/prompts.ts","../system/workflows/mcp-workflow-builder/activities/caches.ts","../system/workflows/mcp-workflow-builder/activities/index.ts","../system/workflows/mcp-workflow-builder/activities/llm.ts","../system/workflows/mcp-workflow-builder/activities/tool-loader.ts","../system/workflows/mcp-workflow-planner/index.ts","../system/workflows/mcp-workflow-planner/prompts.ts","../system/workflows/mcp-workflow-planner/activities/analyze.ts","../system/workflows/mcp-workflow-planner/activities/index.ts","../system/workflows/mcp-workflow-planner/activities/persist.ts","../system/workflows/mcp-workflow-planner/activities/plan.ts","../system/workflows/shared/discovery.ts","../system/workflows/shared/index.ts","../system/workflows/shared/llm-caller.ts","../system/workflows/shared/prompts.ts","../system/workflows/shared/strategy-advisors.ts","../system/workflows/shared/tool-executor.ts","../system/workflows/shared/tool-loader.ts","../system/workflows/shared/types.ts","../types/agent.ts","../types/auth.ts","../types/config.ts","../types/delegation.ts","../types/discovery.ts","../types/envelope.ts","../types/escalation-strategy.ts","../types/escalation.ts","../types/events.ts","../types/export.ts","../types/express.d.ts","../types/facets.ts","../types/index.ts","../types/logger.ts","../types/maintenance.ts","../types/mcp.ts","../types/oauth.ts","../types/sdk.ts","../types/startup.ts","../types/task.ts","../types/telemetry.ts","../types/tool-context.ts","../types/user.ts","../types/workflow-set.ts","../types/workflow.ts","../types/yaml-workflow.ts","../workers/index.ts"],"version":"5.9.3"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-
|
|
2
|
-
//# sourceMappingURL=AdminDashboard-
|
|
1
|
+
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-BHfimh-E.js";import{t as m}from"./index-MbEPoyTe.js";import{f as c}from"./useEventHooks-CeOIM1Ix.js";import{u}from"./mcp-CsHkygRS.js";import{P as d}from"./PageHeaderWithStats-W3akV6nB.js";import"./vendor-react-CXumBFUA.js";import"./vendor-icons-DOIDKgo6.js";function j(){var a;c();const{data:s}=n({limit:1}),{data:e}=m({status:"pending",limit:1}),{data:t}=u(),r=((a=t==null?void 0:t.servers)==null?void 0:a.filter(i=>i.status==="connected").length)??0,l=t?`${r}/${t.total}`:"—";return o.jsx("div",{children:o.jsx(d,{title:"Admin",stats:[{label:"Tasks",value:(s==null?void 0:s.total)??"—"},{label:"Pending Escalations",value:(e==null?void 0:e.total)??"—",dotClass:"bg-status-pending"},{label:"MCP Servers",value:l},{label:"System",value:"Healthy",dotClass:"bg-status-success"}]})})}export{j as AdminDashboard};
|
|
2
|
+
//# sourceMappingURL=AdminDashboard-Dhr7sUq6.js.map
|