titan-agent 5.4.2 → 5.5.6
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/README.md +1 -1
- package/dist/agent/agent.js +9 -5
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/agentLoop.js +7 -3
- package/dist/agent/agentLoop.js.map +1 -1
- package/dist/agent/checkpoint.js +2 -2
- package/dist/agent/checkpoint.js.map +1 -1
- package/dist/agent/commandPost.js +3 -3
- package/dist/agent/commandPost.js.map +1 -1
- package/dist/agent/goalProposer.js +2 -2
- package/dist/agent/goalProposer.js.map +1 -1
- package/dist/agent/goals.js +3 -3
- package/dist/agent/goals.js.map +1 -1
- package/dist/agent/peerAdvise.js +1 -1
- package/dist/agent/peerAdvise.js.map +1 -1
- package/dist/agent/planner.js +4 -4
- package/dist/agent/planner.js.map +1 -1
- package/dist/agent/userProfile.js +2 -2
- package/dist/agent/userProfile.js.map +1 -1
- package/dist/cli/doctor.js +33 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/onboard.js +4 -4
- package/dist/cli/onboard.js.map +1 -1
- package/dist/config/config.js +3 -3
- package/dist/config/config.js.map +1 -1
- package/dist/config/schema.js +8 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/gateway/routes/adminRouter.js +500 -0
- package/dist/gateway/routes/adminRouter.js.map +1 -0
- package/dist/gateway/routes/agents.js +231 -0
- package/dist/gateway/routes/agents.js.map +1 -0
- package/dist/gateway/routes/agentsRouter.js +32 -0
- package/dist/gateway/routes/agentsRouter.js.map +1 -0
- package/dist/gateway/routes/checkpoints.js +41 -0
- package/dist/gateway/routes/checkpoints.js.map +1 -0
- package/dist/gateway/routes/commandPost.js +755 -0
- package/dist/gateway/routes/commandPost.js.map +1 -0
- package/dist/gateway/routes/companies.js +166 -0
- package/dist/gateway/routes/companies.js.map +1 -0
- package/dist/gateway/routes/files.js +295 -0
- package/dist/gateway/routes/files.js.map +1 -0
- package/dist/gateway/routes/hardwareRouter.js +151 -0
- package/dist/gateway/routes/hardwareRouter.js.map +1 -0
- package/dist/gateway/routes/mcpRouter.js +88 -0
- package/dist/gateway/routes/mcpRouter.js.map +1 -0
- package/dist/gateway/routes/mesh.js +464 -0
- package/dist/gateway/routes/mesh.js.map +1 -0
- package/dist/gateway/routes/metricsRouter.js +131 -0
- package/dist/gateway/routes/metricsRouter.js.map +1 -0
- package/dist/gateway/routes/organism.js +82 -0
- package/dist/gateway/routes/organism.js.map +1 -0
- package/dist/gateway/routes/paperclip.js +101 -0
- package/dist/gateway/routes/paperclip.js.map +1 -0
- package/dist/gateway/routes/sessions.js +227 -0
- package/dist/gateway/routes/sessions.js.map +1 -0
- package/dist/gateway/routes/skills.js +295 -0
- package/dist/gateway/routes/skills.js.map +1 -0
- package/dist/gateway/routes/socialRouter.js +145 -0
- package/dist/gateway/routes/socialRouter.js.map +1 -0
- package/dist/gateway/routes/systemRouter.js +220 -0
- package/dist/gateway/routes/systemRouter.js.map +1 -0
- package/dist/gateway/routes/teamsRecipes.js +297 -0
- package/dist/gateway/routes/teamsRecipes.js.map +1 -0
- package/dist/gateway/routes/tests.js +401 -0
- package/dist/gateway/routes/tests.js.map +1 -0
- package/dist/gateway/routes/traces.js +33 -0
- package/dist/gateway/routes/traces.js.map +1 -0
- package/dist/gateway/routes/voiceRouter.js +770 -0
- package/dist/gateway/routes/voiceRouter.js.map +1 -0
- package/dist/gateway/routes/watchRouter.js +131 -0
- package/dist/gateway/routes/watchRouter.js.map +1 -0
- package/dist/gateway/server.js +1179 -7379
- package/dist/gateway/server.js.map +1 -1
- package/dist/mcp/registry.js +2 -2
- package/dist/mcp/registry.js.map +1 -1
- package/dist/memory/episodic.js +2 -2
- package/dist/memory/episodic.js.map +1 -1
- package/dist/memory/learning.js +3 -3
- package/dist/memory/learning.js.map +1 -1
- package/dist/memory/memory.js +3 -3
- package/dist/memory/memory.js.map +1 -1
- package/dist/organism/drives.js +2 -2
- package/dist/organism/drives.js.map +1 -1
- package/dist/providers/errorTaxonomy.js +13 -0
- package/dist/providers/errorTaxonomy.js.map +1 -1
- package/dist/providers/ollama.js +3 -1
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai_compat.js +4 -3
- package/dist/providers/openai_compat.js.map +1 -1
- package/dist/providers/router.js +13 -0
- package/dist/providers/router.js.map +1 -1
- package/dist/safety/fixOscillation.js +15 -0
- package/dist/safety/fixOscillation.js.map +1 -1
- package/dist/safety/killSwitch.js +2 -2
- package/dist/safety/killSwitch.js.map +1 -1
- package/dist/safety/selfRepair.js +7 -3
- package/dist/safety/selfRepair.js.map +1 -1
- package/dist/skills/builtin/agent_debate.js +2 -2
- package/dist/skills/builtin/agent_debate.js.map +1 -1
- package/dist/skills/builtin/apply_patch.js +3 -3
- package/dist/skills/builtin/apply_patch.js.map +1 -1
- package/dist/skills/builtin/shell.js +2 -2
- package/dist/skills/builtin/shell.js.map +1 -1
- package/dist/skills/builtin/voice_control.js +49 -0
- package/dist/skills/builtin/voice_control.js.map +1 -0
- package/dist/skills/builtin/widget_gallery.js +6 -1
- package/dist/skills/builtin/widget_gallery.js.map +1 -1
- package/dist/skills/registry.js +15 -4
- package/dist/skills/registry.js.map +1 -1
- package/dist/storage/JsonStorage.js +4 -4
- package/dist/storage/JsonStorage.js.map +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/helpers.js +3 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/lifecycle.js +86 -0
- package/dist/utils/lifecycle.js.map +1 -0
- package/dist/voice/bridge.js +136 -0
- package/dist/voice/bridge.js.map +1 -0
- package/docs/COO-MASTER-PLAN-2026-05-02.md +474 -0
- package/docs/HANDOFF/2026-04-29.md +141 -0
- package/docs/HANDOFF-2026-04-30.md +144 -0
- package/docs/HANDOFF-2026-05-03.md +114 -0
- package/docs/adr/2026-04-29-widget-pipeline-traceability.md +49 -0
- package/docs/agent-memory/README.md +45 -0
- package/docs/agent-memory/commands.md +100 -0
- package/docs/agent-memory/context-tree.md +101 -0
- package/docs/agent-memory/current-state.md +54 -0
- package/docs/agent-memory/decisions.md +78 -0
- package/docs/agent-memory/known-issues.md +76 -0
- package/docs/agent-memory/reflections.md +52 -0
- package/docs/agent-memory/skills-candidates.md +80 -0
- package/docs/superpowers/plans/2026-04-29-comprehensive-audit.md +256 -0
- package/docs/superpowers/plans/2026-04-29-comprehensive-test-plan.md +396 -0
- package/docs/superpowers/plans/2026-04-29-fix-all-prs.md +251 -0
- package/docs/superpowers/plans/2026-04-29-gitnexus-gap-remediation.md +969 -0
- package/package.json +5 -2
- package/ui/dist/assets/{AuditPanel-CM6Wg9hO.js → AuditPanel-VzSndmDN.js} +2 -2
- package/ui/dist/assets/{AutonomyPanel-CESx3ANg.js → AutonomyPanel-BiFouzAV.js} +2 -2
- package/ui/dist/assets/AutopilotPanel-fjOfM668.js +1 -0
- package/ui/dist/assets/{AutoresearchPanel-DR47NqT5.js → AutoresearchPanel-CVCxzAH3.js} +2 -2
- package/ui/dist/assets/BackupPanel-CHVTG--q.js +1 -0
- package/ui/dist/assets/{BrowserPanel-C15x9bLn.js → BrowserPanel-D5mvMKFU.js} +2 -2
- package/ui/dist/assets/CPActivity-B12mt35m.js +1 -0
- package/ui/dist/assets/CPAgentDetail-DsdShc-1.js +1 -0
- package/ui/dist/assets/CPAgents-j_7C-oQV.js +1 -0
- package/ui/dist/assets/CPApprovals-BShKSX9X.js +1 -0
- package/ui/dist/assets/CPCosts-CKPlhBDs.js +1 -0
- package/ui/dist/assets/CPDashboard-11c0nkxK.js +1 -0
- package/ui/dist/assets/CPFiles-BhLEOnXy.js +1 -0
- package/ui/dist/assets/CPGoals-Bi3t1b2P.js +1 -0
- package/ui/dist/assets/CPInbox-Bbr7khp6.js +11 -0
- package/ui/dist/assets/CPIssueDetail-DSdgNK8r.js +1 -0
- package/ui/dist/assets/CPIssues-DDEVKhX6.js +1 -0
- package/ui/dist/assets/CPLayout-DgPOfyGv.js +17 -0
- package/ui/dist/assets/CPOrg-Df73RrRJ.js +8 -0
- package/ui/dist/assets/CPRuns-ByioAz8w.js +1 -0
- package/ui/dist/assets/{CPSocial-nb-j7sOE.js → CPSocial-Dlnr_w1X.js} +2 -2
- package/ui/dist/assets/ChannelsPanel-DQjQCTK5.js +1 -0
- package/ui/dist/assets/CheckpointsPanel-C4vKjlAJ.js +1 -0
- package/ui/dist/assets/CommandPostHub-C9pp5Giq.js +24 -0
- package/ui/dist/assets/CronPanel-C6bzUfrD.js +1 -0
- package/ui/dist/assets/DaemonPanel-BA5Tb_UO.js +1 -0
- package/ui/dist/assets/{DataTable-B2Ma8hfi.js → DataTable-CH7IYJJh.js} +1 -1
- package/ui/dist/assets/{EmptyState-CcKyk5Yn.js → EmptyState-jU6yNDnF.js} +1 -1
- package/ui/dist/assets/{EvalHarnessPanel-BqtMc1ZM.js → EvalHarnessPanel-DnYqredY.js} +2 -2
- package/ui/dist/assets/EvalPanel-ChO7CD1r.js +1 -0
- package/ui/dist/assets/{FilesPanel-3QKvrWPo.js → FilesPanel-CaUkv2is.js} +2 -2
- package/ui/dist/assets/FleetPanel-DC_5uj0N.js +1 -0
- package/ui/dist/assets/{HomelabPanel-DhrjTX9m.js → HomelabPanel-CE5PGRpL.js} +2 -2
- package/ui/dist/assets/InfraView-C-uSlvb9.js +2 -0
- package/ui/dist/assets/InlineEditableField-BMQjiE6-.js +1 -0
- package/ui/dist/assets/Input-Bu_b3qmY.js +1 -0
- package/ui/dist/assets/IntegrationsPanel-DsYpAq43.js +1 -0
- package/ui/dist/assets/IntelligenceView-DUdIO1K7.js +2 -0
- package/ui/dist/assets/LearningPanel-UpQZC-mA.js +1 -0
- package/ui/dist/assets/LogsPanel-ClXJ4fcr.js +1 -0
- package/ui/dist/assets/McpPanel-JKgtIERQ.js +1 -0
- package/ui/dist/assets/{MemoryGraphPanel-Bzvjmzvk.js → MemoryGraphPanel-Bo2OrvA6.js} +2 -2
- package/ui/dist/assets/MemoryWikiPanel-BqJ1AmYm.js +11 -0
- package/ui/dist/assets/{MeshPanel-C3LJSlht.js → MeshPanel-BJVGYvwk.js} +2 -2
- package/ui/dist/assets/Modal-CAAooiZU.js +1 -0
- package/ui/dist/assets/NvidiaPanel-BtCg3G4w.js +1 -0
- package/ui/dist/assets/OrganismPanel-DgrTTzcF.js +1 -0
- package/ui/dist/assets/OverviewPanel-rVav1Hox.js +1 -0
- package/ui/dist/assets/{PageHeader-BimceqQo.js → PageHeader-CnZtP8ek.js} +1 -1
- package/ui/dist/assets/PaperclipPanel-C-FKdhiF.js +1 -0
- package/ui/dist/assets/{PersonasPanel-L1j78p6H.js → PersonasPanel-BmlxokfB.js} +1 -1
- package/ui/dist/assets/RecipesPanel-BNKKChis.js +1 -0
- package/ui/dist/assets/SecurityPanel-I7JRHiNy.js +1 -0
- package/ui/dist/assets/SelfImprovePanel-u9h0Lt3p.js +1 -0
- package/ui/dist/assets/{SelfProposalsPanel-lNmiDThB.js → SelfProposalsPanel-DKl9iBjM.js} +2 -2
- package/ui/dist/assets/SessionsPanel-BhRiWI_g.js +1 -0
- package/ui/dist/assets/{SessionsTab-JQbltWww.js → SessionsTab-Bk08wyeY.js} +1 -1
- package/ui/dist/assets/SettingsPanel-haLfmG2k.js +1 -0
- package/ui/dist/assets/SettingsView--gi3fxI8.js +2 -0
- package/ui/dist/assets/{SkeletonLoader-atQtpcF5.js → SkeletonLoader-B5v09EF_.js} +1 -1
- package/ui/dist/assets/{SkillsPanel-DlFs2ih7.js → SkillsPanel-BlAHFLcQ.js} +1 -1
- package/ui/dist/assets/SomaView-CExtS3zw.js +5 -0
- package/ui/dist/assets/{StatCard-DciE_Iqc.js → StatCard-BIsyMybM.js} +1 -1
- package/ui/dist/assets/{StatusBadge-BtfSPoW2.js → StatusBadge-D5nU7El8.js} +1 -1
- package/ui/dist/assets/Tabs-BBYZrBI8.js +1 -0
- package/ui/dist/assets/TeamsPanel-LPXJg823.js +1 -0
- package/ui/dist/assets/TelemetryPanel-EqpRBmOI.js +1 -0
- package/ui/dist/assets/TitanCanvas-BCbWnLMd.js +985 -0
- package/ui/dist/assets/ToolsView-CeP0Zz-N.js +2 -0
- package/ui/dist/assets/{Tooltip-70UK0E2I.js → Tooltip-BSO2XVpF.js} +1 -1
- package/ui/dist/assets/TraceViewer-BKI7o5B0.js +1 -0
- package/ui/dist/assets/TrainingPanel-c-RhjdE1.js +1 -0
- package/ui/dist/assets/VoiceOverlay-D-gc58b0.js +27 -0
- package/ui/dist/assets/VramPanel-C6xc7zgd.js +1 -0
- package/ui/dist/assets/{WatchView-C-sGFpVy.js → WatchView-dqBVCVH0.js} +1 -1
- package/ui/dist/assets/WorkTab-CBoLNrTM.js +1 -0
- package/ui/dist/assets/{WorkflowsPanel-CvgQU1xI.js → WorkflowsPanel-BAnSTOYe.js} +2 -2
- package/ui/dist/assets/approvalHeadline-DB9SgR-9.js +1 -0
- package/ui/dist/assets/{arrow-left-DwqHtJiU.js → arrow-left-5chqas7J.js} +1 -1
- package/ui/dist/assets/briefcase-D4vLzudp.js +6 -0
- package/ui/dist/assets/{chart-column-BtNO6sRy.js → chart-column-CdFlBpoP.js} +1 -1
- package/ui/dist/assets/check-Bpm1IONe.js +6 -0
- package/ui/dist/assets/chevron-down-D7OLjvuD.js +6 -0
- package/ui/dist/assets/chevron-right-aQEw2mUW.js +6 -0
- package/ui/dist/assets/chevron-up-C5g6pEj8.js +6 -0
- package/ui/dist/assets/{circle-check-big-DZRE_MbN.js → circle-check-big-fPhEdP88.js} +1 -1
- package/ui/dist/assets/clock-CTsgP_Sn.js +6 -0
- package/ui/dist/assets/{dollar-sign-aVG3a5eL.js → dollar-sign-CudFVYFc.js} +1 -1
- package/ui/dist/assets/{download-BxiWJU4G.js → download-DZRxDn67.js} +1 -1
- package/ui/dist/assets/external-link-BZ0y_Ahx.js +6 -0
- package/ui/dist/assets/{eye-off-CkgfFYhm.js → eye-off-BmJF0YYx.js} +1 -1
- package/ui/dist/assets/folder-DA43TRCm.js +11 -0
- package/ui/dist/assets/{funnel-PkLdxKyC.js → funnel-J3mULzrz.js} +1 -1
- package/ui/dist/assets/{git-branch-BM-Gw95X.js → git-branch-oHibJqDq.js} +1 -1
- package/ui/dist/assets/{index-D0RJ8701.css → index-BR0vfkIi.css} +1 -1
- package/ui/dist/assets/{index-CahJbWSR.js → index-DzwowwSI.js} +20 -20
- package/ui/dist/assets/{layers-BuGf4FIJ.js → layers-DsyEyu7z.js} +1 -1
- package/ui/dist/assets/{legacy-CR6o4t-y.js → legacy-8ITl64sV.js} +1 -1
- package/ui/dist/assets/{lightbulb-n8gc_XAL.js → lightbulb-C54Ske-p.js} +1 -1
- package/ui/dist/assets/list-todo-Cnd4rdoK.js +6 -0
- package/ui/dist/assets/loader-circle-1YOBsoQp.js +6 -0
- package/ui/dist/assets/network-DbGDAdrn.js +6 -0
- package/ui/dist/assets/{pause-DCV52koX.js → pause-CYhO_uQo.js} +1 -1
- package/ui/dist/assets/{play-CcJ9BnCh.js → play-DVY9c5Ck.js} +1 -1
- package/ui/dist/assets/{plug-CfWBXfCl.js → plug-BcXjlPUL.js} +1 -1
- package/ui/dist/assets/plus-Csu2v9GN.js +6 -0
- package/ui/dist/assets/{proxy-CzZDfLmm.js → proxy-DxS2_9D7.js} +1 -1
- package/ui/dist/assets/rotate-ccw-Co-_W04j.js +6 -0
- package/ui/dist/assets/save-Btx-kpoW.js +6 -0
- package/ui/dist/assets/search-0hXTwEZR.js +6 -0
- package/ui/dist/assets/send-TEpapzQR.js +6 -0
- package/ui/dist/assets/shield-check-DjBJXZUr.js +6 -0
- package/ui/dist/assets/{square-DJpUhlxi.js → square-OweUvjP-.js} +1 -1
- package/ui/dist/assets/{target-DWcmM_9m.js → target-BRW80Xer.js} +1 -1
- package/ui/dist/assets/terminal-BtiqJ628.js +16 -0
- package/ui/dist/assets/{toggle-right-YusFQ69L.js → toggle-right-CKtSrl28.js} +1 -1
- package/ui/dist/assets/{trash-2-CK7yQ55V.js → trash-2-DgWrHVax.js} +1 -1
- package/ui/dist/assets/{trending-up-DGjFyubC.js → trending-up-MpIrE4j6.js} +1 -1
- package/ui/dist/assets/{trophy-uQv_NgDB.js → trophy-CECuZNhX.js} +1 -1
- package/ui/dist/assets/users-dZgv4ePG.js +16 -0
- package/ui/dist/assets/wrench-CDz3xYve.js +11 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/AutopilotPanel-DtEet1hJ.js +0 -1
- package/ui/dist/assets/BackupPanel-BGP8p3l3.js +0 -1
- package/ui/dist/assets/CPAgents-DYUtPzSq.js +0 -1
- package/ui/dist/assets/CPDashboard-Bf0-SyCh.js +0 -6
- package/ui/dist/assets/CPFiles-CxgxjQcO.js +0 -1
- package/ui/dist/assets/CPGoals-BsmCMTvT.js +0 -1
- package/ui/dist/assets/CPInbox-tMSbmQ9H.js +0 -11
- package/ui/dist/assets/ChannelsPanel-DP5C2OKd.js +0 -1
- package/ui/dist/assets/CheckpointsPanel-DlranVLZ.js +0 -1
- package/ui/dist/assets/CommandPostHub-BgxIa4Ev.js +0 -29
- package/ui/dist/assets/CronPanel-LoT5yKwJ.js +0 -1
- package/ui/dist/assets/DaemonPanel-DBGMqaE_.js +0 -1
- package/ui/dist/assets/EvalPanel-Bc33j0pN.js +0 -1
- package/ui/dist/assets/FleetPanel-CSsXuQYj.js +0 -1
- package/ui/dist/assets/InfraView-CR6HyrL6.js +0 -2
- package/ui/dist/assets/InlineEditableField-CnvF-yFR.js +0 -1
- package/ui/dist/assets/Input-GTHp2Rkr.js +0 -1
- package/ui/dist/assets/IntegrationsPanel-CymCRE3T.js +0 -1
- package/ui/dist/assets/IntelligenceView-C1IHxJRC.js +0 -2
- package/ui/dist/assets/LearningPanel-DOCES3lH.js +0 -1
- package/ui/dist/assets/LogsPanel-BLnAqEaZ.js +0 -1
- package/ui/dist/assets/McpPanel-ChUzmr3z.js +0 -1
- package/ui/dist/assets/MemoryWikiPanel-Dwk3Aqwd.js +0 -11
- package/ui/dist/assets/NvidiaPanel-CeZK_-CV.js +0 -1
- package/ui/dist/assets/OrganismPanel-BB6YOiQV.js +0 -1
- package/ui/dist/assets/OverviewPanel-BmtBhQnv.js +0 -1
- package/ui/dist/assets/PaperclipPanel-C-brgwA3.js +0 -1
- package/ui/dist/assets/RecipesPanel-34lCfynJ.js +0 -1
- package/ui/dist/assets/SecurityPanel-CBTPWLj6.js +0 -1
- package/ui/dist/assets/SelfImprovePanel-BrPbFHhG.js +0 -1
- package/ui/dist/assets/SessionsPanel-DAEYIn83.js +0 -1
- package/ui/dist/assets/SettingsPanel-CzRROAYQ.js +0 -1
- package/ui/dist/assets/SettingsView-CN7ii2uw.js +0 -2
- package/ui/dist/assets/SomaView-Ba642Oqb.js +0 -5
- package/ui/dist/assets/TeamsPanel-DKQ5z2Qe.js +0 -1
- package/ui/dist/assets/TelemetryPanel-B6KAc55Q.js +0 -1
- package/ui/dist/assets/TitanCanvas-C-s0A-lv.js +0 -1092
- package/ui/dist/assets/ToolsView-Dei0KMP0.js +0 -2
- package/ui/dist/assets/TraceViewer-BniolyBx.js +0 -1
- package/ui/dist/assets/TrainingPanel-Bz4CTPGW.js +0 -1
- package/ui/dist/assets/VoiceOverlay-CmNCrLcd.js +0 -37
- package/ui/dist/assets/VramPanel-Xh_OtRDR.js +0 -1
- package/ui/dist/assets/WorkTab-BjLNmgIK.js +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import logger from "./logger.js";
|
|
3
|
+
const COMPONENT = "LifecycleManager";
|
|
4
|
+
class LifecycleManager {
|
|
5
|
+
entries = [];
|
|
6
|
+
shutdownInProgress = false;
|
|
7
|
+
register(name, start, stop) {
|
|
8
|
+
if (this.entries.find((e) => e.name === name)) {
|
|
9
|
+
logger.warn(COMPONENT, `Service "${name}" already registered, skipping duplicate`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
this.entries.push({ name, start, stop, running: false, status: "idle" });
|
|
13
|
+
}
|
|
14
|
+
async startAll() {
|
|
15
|
+
for (const entry of this.entries) {
|
|
16
|
+
try {
|
|
17
|
+
entry.status = "starting";
|
|
18
|
+
logger.info(COMPONENT, `Starting ${entry.name}...`);
|
|
19
|
+
await entry.start();
|
|
20
|
+
entry.running = true;
|
|
21
|
+
entry.status = "running";
|
|
22
|
+
entry.startTime = Date.now();
|
|
23
|
+
logger.info(COMPONENT, `${entry.name} started (${Date.now() - entry.startTime}ms)`);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
entry.status = "error";
|
|
26
|
+
entry.lastError = err.message;
|
|
27
|
+
logger.error(COMPONENT, `Failed to start ${entry.name}: ${entry.lastError}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async stopAll() {
|
|
32
|
+
if (this.shutdownInProgress) {
|
|
33
|
+
logger.warn(COMPONENT, "Shutdown already in progress");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.shutdownInProgress = true;
|
|
37
|
+
const reverse = [...this.entries].reverse();
|
|
38
|
+
for (const entry of reverse) {
|
|
39
|
+
if (!entry.running && entry.status === "idle") continue;
|
|
40
|
+
try {
|
|
41
|
+
entry.status = "stopping";
|
|
42
|
+
logger.info(COMPONENT, `Stopping ${entry.name}...`);
|
|
43
|
+
await entry.stop();
|
|
44
|
+
entry.running = false;
|
|
45
|
+
entry.status = "idle";
|
|
46
|
+
entry.stopTime = Date.now();
|
|
47
|
+
const uptime = entry.startTime ? entry.stopTime - entry.startTime : 0;
|
|
48
|
+
logger.info(COMPONENT, `${entry.name} stopped (uptime: ${uptime}ms)`);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
entry.status = "error";
|
|
51
|
+
entry.lastError = err.message;
|
|
52
|
+
logger.error(COMPONENT, `Failed to stop ${entry.name}: ${entry.lastError}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.shutdownInProgress = false;
|
|
56
|
+
}
|
|
57
|
+
/** Attach signal handlers for graceful shutdown */
|
|
58
|
+
gracefulShutdown(signal) {
|
|
59
|
+
logger.info(COMPONENT, `Received ${signal}, initiating graceful shutdown...`);
|
|
60
|
+
this.stopAll().then(() => {
|
|
61
|
+
logger.info(COMPONENT, "All services stopped. Exiting.");
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}).catch((err) => {
|
|
64
|
+
logger.error(COMPONENT, `Shutdown failed: ${err.message}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
getStatus() {
|
|
69
|
+
return this.entries.map((e) => ({
|
|
70
|
+
name: e.name,
|
|
71
|
+
status: e.status,
|
|
72
|
+
running: e.running,
|
|
73
|
+
uptime: e.startTime ? Date.now() - e.startTime : 0
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
let _manager = null;
|
|
78
|
+
function getLifecycleManager() {
|
|
79
|
+
if (!_manager) _manager = new LifecycleManager();
|
|
80
|
+
return _manager;
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
LifecycleManager,
|
|
84
|
+
getLifecycleManager
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/lifecycle.ts"],"sourcesContent":["/**\n * TITAN Lifecycle Manager\n *\n * Central registry for all daemon/sidecar/server processes.\n * Provides coordinated shutdown in reverse dependency order.\n *\n * Usage:\n * const lm = new LifecycleManager();\n * lm.register('f5tts', () => startF5TTSHandler(), () => stopF5TTSHandler());\n * lm.register('paperclip', () => startPaperclip(...), () => stopPaperclip());\n * lm.register('voice', () => bridge.start(), () => bridge.stop());\n * \n * await lm.startAll(); // start in registration order\n * await lm.stopAll(); // stop in reverse order\n * await lm.gracefulShutdown(SIGTERM); // handles process signals\n */\n\nimport logger from './logger.js';\n\ninterface LifecycleEntry {\n name: string;\n start: () => Promise<void> | void;\n stop: () => Promise<void> | void;\n running: boolean;\n status: 'idle' | 'starting' | 'running' | 'stopping' | 'error';\n lastError?: string;\n startTime?: number;\n stopTime?: number;\n}\n\nconst COMPONENT = 'LifecycleManager';\n\nexport class LifecycleManager {\n private entries: LifecycleEntry[] = [];\n private shutdownInProgress = false;\n\n register(\n name: string,\n start: () => Promise<void> | void,\n stop: () => Promise<void> | void\n ): void {\n if (this.entries.find(e => e.name === name)) {\n logger.warn(COMPONENT, `Service \"${name}\" already registered, skipping duplicate`);\n return;\n }\n this.entries.push({ name, start, stop, running: false, status: 'idle' });\n }\n\n async startAll(): Promise<void> {\n for (const entry of this.entries) {\n try {\n entry.status = 'starting';\n logger.info(COMPONENT, `Starting ${entry.name}...`);\n await entry.start();\n entry.running = true;\n entry.status = 'running';\n entry.startTime = Date.now();\n logger.info(COMPONENT, `${entry.name} started (${Date.now() - entry.startTime!}ms)`);\n } catch (err) {\n entry.status = 'error';\n entry.lastError = (err as Error).message;\n logger.error(COMPONENT, `Failed to start ${entry.name}: ${entry.lastError}`);\n // Continue with next service — don't let one failure block the rest\n }\n }\n }\n\n async stopAll(): Promise<void> {\n if (this.shutdownInProgress) {\n logger.warn(COMPONENT, 'Shutdown already in progress');\n return;\n }\n this.shutdownInProgress = true;\n\n // Stop in reverse dependency order\n const reverse = [...this.entries].reverse();\n\n for (const entry of reverse) {\n if (!entry.running && entry.status === 'idle') continue;\n try {\n entry.status = 'stopping';\n logger.info(COMPONENT, `Stopping ${entry.name}...`);\n await entry.stop();\n entry.running = false;\n entry.status = 'idle';\n entry.stopTime = Date.now();\n const uptime = entry.startTime ? entry.stopTime - entry.startTime : 0;\n logger.info(COMPONENT, `${entry.name} stopped (uptime: ${uptime}ms)`);\n } catch (err) {\n entry.status = 'error';\n entry.lastError = (err as Error).message;\n logger.error(COMPONENT, `Failed to stop ${entry.name}: ${entry.lastError}`);\n // Continue — don't let one failure prevent cleanup of others\n }\n }\n\n this.shutdownInProgress = false;\n }\n\n /** Attach signal handlers for graceful shutdown */\n gracefulShutdown(signal: NodeJS.Signals | string): void {\n logger.info(COMPONENT, `Received ${signal}, initiating graceful shutdown...`);\n this.stopAll().then(() => {\n logger.info(COMPONENT, 'All services stopped. Exiting.');\n process.exit(0);\n }).catch((err) => {\n logger.error(COMPONENT, `Shutdown failed: ${(err as Error).message}`);\n process.exit(1);\n });\n }\n\n getStatus(): Array<{ name: string; status: string; running: boolean; uptime: number }> {\n return this.entries.map(e => ({\n name: e.name,\n status: e.status,\n running: e.running,\n uptime: e.startTime ? Date.now() - e.startTime : 0,\n }));\n }\n}\n\n// Singleton for the running gateway process\nlet _manager: LifecycleManager | null = null;\n\nexport function getLifecycleManager(): LifecycleManager {\n if (!_manager) _manager = new LifecycleManager();\n return _manager;\n}\n"],"mappings":";AAiBA,OAAO,YAAY;AAanB,MAAM,YAAY;AAEX,MAAM,iBAAiB;AAAA,EACpB,UAA4B,CAAC;AAAA,EAC7B,qBAAqB;AAAA,EAE7B,SACE,MACA,OACA,MACM;AACN,QAAI,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,IAAI,GAAG;AAC3C,aAAO,KAAK,WAAW,YAAY,IAAI,0CAA0C;AACjF;AAAA,IACF;AACA,SAAK,QAAQ,KAAK,EAAE,MAAM,OAAO,MAAM,SAAS,OAAO,QAAQ,OAAO,CAAC;AAAA,EACzE;AAAA,EAEA,MAAM,WAA0B;AAC9B,eAAW,SAAS,KAAK,SAAS;AAChC,UAAI;AACF,cAAM,SAAS;AACf,eAAO,KAAK,WAAW,YAAY,MAAM,IAAI,KAAK;AAClD,cAAM,MAAM,MAAM;AAClB,cAAM,UAAU;AAChB,cAAM,SAAS;AACf,cAAM,YAAY,KAAK,IAAI;AAC3B,eAAO,KAAK,WAAW,GAAG,MAAM,IAAI,aAAa,KAAK,IAAI,IAAI,MAAM,SAAU,KAAK;AAAA,MACrF,SAAS,KAAK;AACZ,cAAM,SAAS;AACf,cAAM,YAAa,IAAc;AACjC,eAAO,MAAM,WAAW,mBAAmB,MAAM,IAAI,KAAK,MAAM,SAAS,EAAE;AAAA,MAE7E;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,oBAAoB;AAC3B,aAAO,KAAK,WAAW,8BAA8B;AACrD;AAAA,IACF;AACA,SAAK,qBAAqB;AAG1B,UAAM,UAAU,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ;AAE1C,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,WAAW,MAAM,WAAW,OAAQ;AAC/C,UAAI;AACF,cAAM,SAAS;AACf,eAAO,KAAK,WAAW,YAAY,MAAM,IAAI,KAAK;AAClD,cAAM,MAAM,KAAK;AACjB,cAAM,UAAU;AAChB,cAAM,SAAS;AACf,cAAM,WAAW,KAAK,IAAI;AAC1B,cAAM,SAAS,MAAM,YAAY,MAAM,WAAW,MAAM,YAAY;AACpE,eAAO,KAAK,WAAW,GAAG,MAAM,IAAI,qBAAqB,MAAM,KAAK;AAAA,MACtE,SAAS,KAAK;AACZ,cAAM,SAAS;AACf,cAAM,YAAa,IAAc;AACjC,eAAO,MAAM,WAAW,kBAAkB,MAAM,IAAI,KAAK,MAAM,SAAS,EAAE;AAAA,MAE5E;AAAA,IACF;AAEA,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA,EAGA,iBAAiB,QAAuC;AACtD,WAAO,KAAK,WAAW,YAAY,MAAM,mCAAmC;AAC5E,SAAK,QAAQ,EAAE,KAAK,MAAM;AACxB,aAAO,KAAK,WAAW,gCAAgC;AACvD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,aAAO,MAAM,WAAW,oBAAqB,IAAc,OAAO,EAAE;AACpE,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,YAAuF;AACrF,WAAO,KAAK,QAAQ,IAAI,QAAM;AAAA,MAC5B,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE;AAAA,MACX,QAAQ,EAAE,YAAY,KAAK,IAAI,IAAI,EAAE,YAAY;AAAA,IACnD,EAAE;AAAA,EACJ;AACF;AAGA,IAAI,WAAoC;AAEjC,SAAS,sBAAwC;AACtD,MAAI,CAAC,SAAU,YAAW,IAAI,iBAAiB;AAC/C,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import logger from "../utils/logger.js";
|
|
7
|
+
const COMPONENT = "VoiceBridge";
|
|
8
|
+
class TitanAgentBridge {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
options;
|
|
13
|
+
proc = null;
|
|
14
|
+
status = { running: false, uptime: 0 };
|
|
15
|
+
startTime = 0;
|
|
16
|
+
pendingAudio = /* @__PURE__ */ new Map();
|
|
17
|
+
async start() {
|
|
18
|
+
const python = this.options.pythonPath || process.env.TITAN_PYTHON_PATH || "python3";
|
|
19
|
+
const script = this.options.agentScript || "./titan-voice-agent/agent.py";
|
|
20
|
+
const model = this.options.model || this.options.whisperModel || "base";
|
|
21
|
+
try {
|
|
22
|
+
this.proc = spawn(python, [script, "--server", "--model", model, "--device", this.options.device || "auto"], {
|
|
23
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
24
|
+
env: { ...process.env, TITAN_VOICE_MODEL: model },
|
|
25
|
+
detached: false
|
|
26
|
+
});
|
|
27
|
+
} catch (err) {
|
|
28
|
+
logger.warn(COMPONENT, `Failed to spawn TitanAgent: ${err.message}`);
|
|
29
|
+
this.status.lastError = err.message;
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
const pidFile = join(homedir(), ".titan", "voice-bridge.pid");
|
|
33
|
+
try {
|
|
34
|
+
if (this.proc.pid) {
|
|
35
|
+
fs.writeFileSync(pidFile, String(this.proc.pid), "utf-8");
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
this.proc.stdout?.on("data", (data) => {
|
|
40
|
+
const lines = data.toString().split("\n");
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
if (!line.trim()) continue;
|
|
43
|
+
try {
|
|
44
|
+
const msg = JSON.parse(line);
|
|
45
|
+
if (msg.type === "ready") {
|
|
46
|
+
logger.info(COMPONENT, "TitanAgent ready");
|
|
47
|
+
} else if (msg.type === "transcript" && msg.requestId) {
|
|
48
|
+
const pending = this.pendingAudio.get(msg.requestId);
|
|
49
|
+
if (pending) {
|
|
50
|
+
pending.resolve(msg.text || "");
|
|
51
|
+
this.pendingAudio.delete(msg.requestId);
|
|
52
|
+
}
|
|
53
|
+
} else if (msg.type === "error" && msg.requestId) {
|
|
54
|
+
const pending = this.pendingAudio.get(msg.requestId);
|
|
55
|
+
if (pending) {
|
|
56
|
+
pending.reject(new Error(msg.message || "Audio processing error"));
|
|
57
|
+
this.pendingAudio.delete(msg.requestId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
logger.debug(COMPONENT, line.trim());
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
this.proc.stderr?.on("data", (data) => {
|
|
66
|
+
const msg = data.toString().trim();
|
|
67
|
+
logger.error(COMPONENT, msg);
|
|
68
|
+
this.status.lastError = msg;
|
|
69
|
+
});
|
|
70
|
+
this.proc.on("close", (code) => {
|
|
71
|
+
logger.warn(COMPONENT, `TitanAgent exited with code ${code}`);
|
|
72
|
+
this.status.running = false;
|
|
73
|
+
for (const [id, { reject }] of this.pendingAudio) {
|
|
74
|
+
reject(new Error("TitanAgent process exited"));
|
|
75
|
+
this.pendingAudio.delete(id);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
fs.unlinkSync(pidFile);
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
this.startTime = Date.now();
|
|
83
|
+
this.status.running = true;
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
85
|
+
}
|
|
86
|
+
async processAudio(audioBuffer) {
|
|
87
|
+
if (!this.proc?.stdin?.writable) {
|
|
88
|
+
throw new Error("TitanAgent not running");
|
|
89
|
+
}
|
|
90
|
+
const requestId = Math.random().toString(36).slice(2);
|
|
91
|
+
const payload = JSON.stringify({ type: "audio", requestId, data: audioBuffer.toString("base64") }) + "\n";
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
const timeout = setTimeout(() => {
|
|
94
|
+
this.pendingAudio.delete(requestId);
|
|
95
|
+
reject(new Error("Audio processing timeout"));
|
|
96
|
+
}, 3e4);
|
|
97
|
+
const wrappedResolve = (value) => {
|
|
98
|
+
clearTimeout(timeout);
|
|
99
|
+
resolve(value);
|
|
100
|
+
};
|
|
101
|
+
this.pendingAudio.set(requestId, { resolve: wrappedResolve, reject });
|
|
102
|
+
this.proc.stdin.write(payload, (err) => {
|
|
103
|
+
if (err) {
|
|
104
|
+
clearTimeout(timeout);
|
|
105
|
+
this.pendingAudio.delete(requestId);
|
|
106
|
+
reject(err);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
getStatus() {
|
|
112
|
+
return {
|
|
113
|
+
...this.status,
|
|
114
|
+
uptime: this.status.running ? Date.now() - this.startTime : 0
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async stop() {
|
|
118
|
+
if (!this.proc) return;
|
|
119
|
+
this.proc.kill("SIGTERM");
|
|
120
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
121
|
+
if (!this.proc.killed) {
|
|
122
|
+
this.proc.kill("SIGKILL");
|
|
123
|
+
}
|
|
124
|
+
this.status.running = false;
|
|
125
|
+
this.proc = null;
|
|
126
|
+
const pidFile = join(homedir(), ".titan", "voice-bridge.pid");
|
|
127
|
+
try {
|
|
128
|
+
fs.unlinkSync(pidFile);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
TitanAgentBridge
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/voice/bridge.ts"],"sourcesContent":["/**\n * TitanAgent TypeScript Bridge\n *\n * Spawns titan-voice-agent/agent.py as a child process and\n * communicates via JSON over stdin/stdout. Makes the voice agent\n * visible to the TITAN core graph (GitNexus Process tracing).\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport fs from 'fs';\nimport logger from '../utils/logger.js';\n\ninterface VoiceAgentOptions {\n pythonPath?: string;\n agentScript?: string;\n model?: string;\n device?: string;\n whisperModel?: string;\n ttsModel?: string;\n}\n\nexport interface AgentStatus {\n running: boolean;\n uptime: number;\n lastError?: string;\n}\n\nconst COMPONENT = 'VoiceBridge';\n\nexport class TitanAgentBridge {\n private proc: ChildProcess | null = null;\n private status: AgentStatus = { running: false, uptime: 0 };\n private startTime = 0;\n private pendingAudio = new Map<string, { resolve: (value: string) => void; reject: (reason: Error) => void }>();\n\n constructor(private options: VoiceAgentOptions = {}) {}\n\n async start(): Promise<void> {\n const python = this.options.pythonPath || process.env.TITAN_PYTHON_PATH || 'python3';\n const script = this.options.agentScript || './titan-voice-agent/agent.py';\n const model = this.options.model || this.options.whisperModel || 'base';\n\n try {\n this.proc = spawn(python, [script, '--server', '--model', model, '--device', this.options.device || 'auto'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, TITAN_VOICE_MODEL: model },\n detached: false,\n });\n } catch (err) {\n logger.warn(COMPONENT, `Failed to spawn TitanAgent: ${(err as Error).message}`);\n this.status.lastError = (err as Error).message;\n throw err;\n }\n\n // Write PID file for orphan prevention\n const pidFile = join(homedir(), '.titan', 'voice-bridge.pid');\n try {\n if (this.proc.pid) {\n fs.writeFileSync(pidFile, String(this.proc.pid), 'utf-8');\n }\n } catch { /* non-critical */ }\n\n this.proc.stdout?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const msg = JSON.parse(line);\n if (msg.type === 'ready') {\n logger.info(COMPONENT, 'TitanAgent ready');\n } else if (msg.type === 'transcript' && msg.requestId) {\n const pending = this.pendingAudio.get(msg.requestId);\n if (pending) {\n pending.resolve(msg.text || '');\n this.pendingAudio.delete(msg.requestId);\n }\n } else if (msg.type === 'error' && msg.requestId) {\n const pending = this.pendingAudio.get(msg.requestId);\n if (pending) {\n pending.reject(new Error(msg.message || 'Audio processing error'));\n this.pendingAudio.delete(msg.requestId);\n }\n }\n } catch {\n logger.debug(COMPONENT, line.trim());\n }\n }\n });\n\n this.proc.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n logger.error(COMPONENT, msg);\n this.status.lastError = msg;\n });\n\n this.proc.on('close', (code) => {\n logger.warn(COMPONENT, `TitanAgent exited with code ${code}`);\n this.status.running = false;\n // Reject all pending audio requests\n for (const [id, { reject }] of this.pendingAudio) {\n reject(new Error('TitanAgent process exited'));\n this.pendingAudio.delete(id);\n }\n // Clean up PID file\n try { fs.unlinkSync(pidFile); } catch { /* already gone */ }\n });\n\n this.startTime = Date.now();\n this.status.running = true;\n\n // Wait briefly for startup\n await new Promise<void>((resolve) => setTimeout(resolve, 500));\n }\n\n async processAudio(audioBuffer: Buffer): Promise<string> {\n if (!this.proc?.stdin?.writable) {\n throw new Error('TitanAgent not running');\n }\n\n const requestId = Math.random().toString(36).slice(2);\n const payload = JSON.stringify({ type: 'audio', requestId, data: audioBuffer.toString('base64') }) + '\\n';\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingAudio.delete(requestId);\n reject(new Error('Audio processing timeout'));\n }, 30000);\n\n const wrappedResolve = (value: string) => {\n clearTimeout(timeout);\n resolve(value);\n };\n\n this.pendingAudio.set(requestId, { resolve: wrappedResolve, reject });\n this.proc!.stdin!.write(payload, (err) => {\n if (err) {\n clearTimeout(timeout);\n this.pendingAudio.delete(requestId);\n reject(err);\n }\n });\n });\n }\n\n getStatus(): AgentStatus {\n return {\n ...this.status,\n uptime: this.status.running ? Date.now() - this.startTime : 0\n };\n }\n\n async stop(): Promise<void> {\n if (!this.proc) return;\n this.proc.kill('SIGTERM');\n await new Promise(resolve => setTimeout(resolve, 2000));\n if (!this.proc.killed) {\n this.proc.kill('SIGKILL');\n }\n this.status.running = false;\n this.proc = null;\n // Clean up PID file\n const pidFile = join(homedir(), '.titan', 'voice-bridge.pid');\n try { fs.unlinkSync(pidFile); } catch { /* already gone */ }\n }\n}\n"],"mappings":"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","names":[]}
|