@fraziym/axoniz 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/dist/agents/definition.d.ts +15 -0
- package/dist/agents/definition.d.ts.map +1 -0
- package/dist/agents/definition.js +41 -0
- package/dist/agents/definition.js.map +1 -0
- package/dist/agents/index.d.ts +12 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +11 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/registry.d.ts +17 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +23 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/specialized.d.ts +31 -0
- package/dist/agents/specialized.d.ts.map +1 -0
- package/dist/agents/specialized.js +75 -0
- package/dist/agents/specialized.js.map +1 -0
- package/dist/awareness/index.d.ts +14 -0
- package/dist/awareness/index.d.ts.map +1 -0
- package/dist/awareness/index.js +22 -0
- package/dist/awareness/index.js.map +1 -0
- package/dist/awareness/service.d.ts +180 -0
- package/dist/awareness/service.d.ts.map +1 -0
- package/dist/awareness/service.js +789 -0
- package/dist/awareness/service.js.map +1 -0
- package/dist/cli/entry.d.ts +13 -0
- package/dist/cli/entry.d.ts.map +1 -0
- package/dist/cli/entry.js +35 -0
- package/dist/cli/entry.js.map +1 -0
- package/dist/comms/telegram.d.ts +41 -0
- package/dist/comms/telegram.d.ts.map +1 -0
- package/dist/comms/telegram.js +332 -0
- package/dist/comms/telegram.js.map +1 -0
- package/dist/core/agent.d.ts +252 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +1399 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/auth.d.ts +23 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +113 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/authority.d.ts +118 -0
- package/dist/core/authority.d.ts.map +1 -0
- package/dist/core/authority.js +402 -0
- package/dist/core/authority.js.map +1 -0
- package/dist/core/backend/async_queue.d.ts +17 -0
- package/dist/core/backend/async_queue.d.ts.map +1 -0
- package/dist/core/backend/async_queue.js +66 -0
- package/dist/core/backend/async_queue.js.map +1 -0
- package/dist/core/backend/index.d.ts +24 -0
- package/dist/core/backend/index.d.ts.map +1 -0
- package/dist/core/backend/index.js +128 -0
- package/dist/core/backend/index.js.map +1 -0
- package/dist/core/backend/llama_server.d.ts +39 -0
- package/dist/core/backend/llama_server.d.ts.map +1 -0
- package/dist/core/backend/llama_server.js +182 -0
- package/dist/core/backend/llama_server.js.map +1 -0
- package/dist/core/backend/llamacpp.d.ts +40 -0
- package/dist/core/backend/llamacpp.d.ts.map +1 -0
- package/dist/core/backend/llamacpp.js +200 -0
- package/dist/core/backend/llamacpp.js.map +1 -0
- package/dist/core/backend/lmstudio.d.ts +53 -0
- package/dist/core/backend/lmstudio.d.ts.map +1 -0
- package/dist/core/backend/lmstudio.js +274 -0
- package/dist/core/backend/lmstudio.js.map +1 -0
- package/dist/core/backend/ollama.d.ts +25 -0
- package/dist/core/backend/ollama.d.ts.map +1 -0
- package/dist/core/backend/ollama.js +86 -0
- package/dist/core/backend/ollama.js.map +1 -0
- package/dist/core/backend/openai.d.ts +27 -0
- package/dist/core/backend/openai.d.ts.map +1 -0
- package/dist/core/backend/openai.js +84 -0
- package/dist/core/backend/openai.js.map +1 -0
- package/dist/core/backend/types.d.ts +73 -0
- package/dist/core/backend/types.d.ts.map +1 -0
- package/dist/core/backend/types.js +137 -0
- package/dist/core/backend/types.js.map +1 -0
- package/dist/core/chat_store.d.ts +77 -0
- package/dist/core/chat_store.d.ts.map +1 -0
- package/dist/core/chat_store.js +332 -0
- package/dist/core/chat_store.js.map +1 -0
- package/dist/core/cli.d.ts +82 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +602 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +127 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +295 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/debug.d.ts +8 -0
- package/dist/core/debug.d.ts.map +1 -0
- package/dist/core/debug.js +8 -0
- package/dist/core/debug.js.map +1 -0
- package/dist/core/downloader.d.ts +31 -0
- package/dist/core/downloader.d.ts.map +1 -0
- package/dist/core/downloader.js +180 -0
- package/dist/core/downloader.js.map +1 -0
- package/dist/core/errors.d.ts +80 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +134 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/extras.d.ts +160 -0
- package/dist/core/extras.d.ts.map +1 -0
- package/dist/core/extras.js +553 -0
- package/dist/core/extras.js.map +1 -0
- package/dist/core/health.d.ts +27 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +96 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/history.d.ts +50 -0
- package/dist/core/history.d.ts.map +1 -0
- package/dist/core/history.js +276 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/intelligence/ast_index.d.ts +255 -0
- package/dist/core/intelligence/ast_index.d.ts.map +1 -0
- package/dist/core/intelligence/ast_index.js +1369 -0
- package/dist/core/intelligence/ast_index.js.map +1 -0
- package/dist/core/intelligence/confidence.d.ts +113 -0
- package/dist/core/intelligence/confidence.d.ts.map +1 -0
- package/dist/core/intelligence/confidence.js +298 -0
- package/dist/core/intelligence/confidence.js.map +1 -0
- package/dist/core/intelligence/context_compressor.d.ts +80 -0
- package/dist/core/intelligence/context_compressor.d.ts.map +1 -0
- package/dist/core/intelligence/context_compressor.js +245 -0
- package/dist/core/intelligence/context_compressor.js.map +1 -0
- package/dist/core/intelligence/daemon.d.ts +247 -0
- package/dist/core/intelligence/daemon.d.ts.map +1 -0
- package/dist/core/intelligence/daemon.js +842 -0
- package/dist/core/intelligence/daemon.js.map +1 -0
- package/dist/core/intelligence/index.d.ts +60 -0
- package/dist/core/intelligence/index.d.ts.map +1 -0
- package/dist/core/intelligence/index.js +101 -0
- package/dist/core/intelligence/index.js.map +1 -0
- package/dist/core/intelligence/predictor.d.ts +246 -0
- package/dist/core/intelligence/predictor.d.ts.map +1 -0
- package/dist/core/intelligence/predictor.js +590 -0
- package/dist/core/intelligence/predictor.js.map +1 -0
- package/dist/core/intelligence/reflex.d.ts +84 -0
- package/dist/core/intelligence/reflex.d.ts.map +1 -0
- package/dist/core/intelligence/reflex.js +344 -0
- package/dist/core/intelligence/reflex.js.map +1 -0
- package/dist/core/intelligence/self_correction.d.ts +121 -0
- package/dist/core/intelligence/self_correction.d.ts.map +1 -0
- package/dist/core/intelligence/self_correction.js +327 -0
- package/dist/core/intelligence/self_correction.js.map +1 -0
- package/dist/core/intelligence/skill_distiller.d.ts +100 -0
- package/dist/core/intelligence/skill_distiller.d.ts.map +1 -0
- package/dist/core/intelligence/skill_distiller.js +246 -0
- package/dist/core/intelligence/skill_distiller.js.map +1 -0
- package/dist/core/intelligence/swarm.d.ts +330 -0
- package/dist/core/intelligence/swarm.d.ts.map +1 -0
- package/dist/core/intelligence/swarm.js +1064 -0
- package/dist/core/intelligence/swarm.js.map +1 -0
- package/dist/core/intelligence/trajectory.d.ts +107 -0
- package/dist/core/intelligence/trajectory.d.ts.map +1 -0
- package/dist/core/intelligence/trajectory.js +330 -0
- package/dist/core/intelligence/trajectory.js.map +1 -0
- package/dist/core/logger.d.ts +111 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +640 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/loop.d.ts +123 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +423 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/core/memory.d.ts +81 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +328 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/metrics.d.ts +29 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +109 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/models.d.ts +51 -0
- package/dist/core/models.d.ts.map +1 -0
- package/dist/core/models.js +146 -0
- package/dist/core/models.js.map +1 -0
- package/dist/core/optimizer.d.ts +34 -0
- package/dist/core/optimizer.d.ts.map +1 -0
- package/dist/core/optimizer.js +131 -0
- package/dist/core/optimizer.js.map +1 -0
- package/dist/core/persona.d.ts +35 -0
- package/dist/core/persona.d.ts.map +1 -0
- package/dist/core/persona.js +126 -0
- package/dist/core/persona.js.map +1 -0
- package/dist/core/rate_limit.d.ts +23 -0
- package/dist/core/rate_limit.d.ts.map +1 -0
- package/dist/core/rate_limit.js +62 -0
- package/dist/core/rate_limit.js.map +1 -0
- package/dist/core/runner.d.ts +63 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +671 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/stream_parser.d.ts +43 -0
- package/dist/core/stream_parser.d.ts.map +1 -0
- package/dist/core/stream_parser.js +140 -0
- package/dist/core/stream_parser.js.map +1 -0
- package/dist/core/tool_schemas.d.ts +26 -0
- package/dist/core/tool_schemas.d.ts.map +1 -0
- package/dist/core/tool_schemas.js +124 -0
- package/dist/core/tool_schemas.js.map +1 -0
- package/dist/core/which.d.ts +2 -0
- package/dist/core/which.d.ts.map +1 -0
- package/dist/core/which.js +35 -0
- package/dist/core/which.js.map +1 -0
- package/dist/goals/index.d.ts +9 -0
- package/dist/goals/index.d.ts.map +1 -0
- package/dist/goals/index.js +17 -0
- package/dist/goals/index.js.map +1 -0
- package/dist/goals/service.d.ts +115 -0
- package/dist/goals/service.d.ts.map +1 -0
- package/dist/goals/service.js +415 -0
- package/dist/goals/service.js.map +1 -0
- package/dist/goals/types.d.ts +47 -0
- package/dist/goals/types.d.ts.map +1 -0
- package/dist/goals/types.js +66 -0
- package/dist/goals/types.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/autonomous_startup.d.ts +51 -0
- package/dist/integrations/autonomous_startup.d.ts.map +1 -0
- package/dist/integrations/autonomous_startup.js +419 -0
- package/dist/integrations/autonomous_startup.js.map +1 -0
- package/dist/integrations/goose.d.ts +105 -0
- package/dist/integrations/goose.d.ts.map +1 -0
- package/dist/integrations/goose.js +408 -0
- package/dist/integrations/goose.js.map +1 -0
- package/dist/integrations/index.d.ts +21 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +17 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/mcp.d.ts +73 -0
- package/dist/integrations/mcp.d.ts.map +1 -0
- package/dist/integrations/mcp.js +307 -0
- package/dist/integrations/mcp.js.map +1 -0
- package/dist/integrations/mempalace.d.ts +18 -0
- package/dist/integrations/mempalace.d.ts.map +1 -0
- package/dist/integrations/mempalace.js +25 -0
- package/dist/integrations/mempalace.js.map +1 -0
- package/dist/integrations/multi_agent.d.ts +82 -0
- package/dist/integrations/multi_agent.d.ts.map +1 -0
- package/dist/integrations/multi_agent.js +280 -0
- package/dist/integrations/multi_agent.js.map +1 -0
- package/dist/integrations/unified_memory.d.ts +415 -0
- package/dist/integrations/unified_memory.d.ts.map +1 -0
- package/dist/integrations/unified_memory.js +1489 -0
- package/dist/integrations/unified_memory.js.map +1 -0
- package/dist/roles/beru.yaml +48 -0
- package/dist/sidecar/client.d.ts +63 -0
- package/dist/sidecar/client.d.ts.map +1 -0
- package/dist/sidecar/client.js +222 -0
- package/dist/sidecar/client.js.map +1 -0
- package/dist/sidecar/index.d.ts +7 -0
- package/dist/sidecar/index.d.ts.map +1 -0
- package/dist/sidecar/index.js +6 -0
- package/dist/sidecar/index.js.map +1 -0
- package/dist/startup.d.ts +22 -0
- package/dist/startup.d.ts.map +1 -0
- package/dist/startup.js +194 -0
- package/dist/startup.js.map +1 -0
- package/dist/tools/_internal.d.ts +90 -0
- package/dist/tools/_internal.d.ts.map +1 -0
- package/dist/tools/_internal.js +375 -0
- package/dist/tools/_internal.js.map +1 -0
- package/dist/tools/_smoke.d.ts +2 -0
- package/dist/tools/_smoke.d.ts.map +1 -0
- package/dist/tools/_smoke.js +203 -0
- package/dist/tools/_smoke.js.map +1 -0
- package/dist/tools/axodex_tools.d.ts +51 -0
- package/dist/tools/axodex_tools.d.ts.map +1 -0
- package/dist/tools/axodex_tools.js +181 -0
- package/dist/tools/axodex_tools.js.map +1 -0
- package/dist/tools/code_tools.d.ts +33 -0
- package/dist/tools/code_tools.d.ts.map +1 -0
- package/dist/tools/code_tools.js +191 -0
- package/dist/tools/code_tools.js.map +1 -0
- package/dist/tools/computer_tools.d.ts +59 -0
- package/dist/tools/computer_tools.d.ts.map +1 -0
- package/dist/tools/computer_tools.js +348 -0
- package/dist/tools/computer_tools.js.map +1 -0
- package/dist/tools/file_tools.d.ts +51 -0
- package/dist/tools/file_tools.d.ts.map +1 -0
- package/dist/tools/file_tools.js +424 -0
- package/dist/tools/file_tools.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/shell_tools.d.ts +39 -0
- package/dist/tools/shell_tools.d.ts.map +1 -0
- package/dist/tools/shell_tools.js +163 -0
- package/dist/tools/shell_tools.js.map +1 -0
- package/dist/tools/web_tools.d.ts +31 -0
- package/dist/tools/web_tools.d.ts.map +1 -0
- package/dist/tools/web_tools.js +117 -0
- package/dist/tools/web_tools.js.map +1 -0
- package/dist/voice/index.d.ts +41 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +58 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/light_daemon.d.ts +197 -0
- package/dist/voice/light_daemon.d.ts.map +1 -0
- package/dist/voice/light_daemon.js +746 -0
- package/dist/voice/light_daemon.js.map +1 -0
- package/dist/voice/setup.d.ts +63 -0
- package/dist/voice/setup.d.ts.map +1 -0
- package/dist/voice/setup.js +443 -0
- package/dist/voice/setup.js.map +1 -0
- package/dist/voice/stt.d.ts +148 -0
- package/dist/voice/stt.d.ts.map +1 -0
- package/dist/voice/stt.js +361 -0
- package/dist/voice/stt.js.map +1 -0
- package/dist/voice/tts.d.ts +168 -0
- package/dist/voice/tts.d.ts.map +1 -0
- package/dist/voice/tts.js +698 -0
- package/dist/voice/tts.js.map +1 -0
- package/dist/voice/voice_loop.d.ts +101 -0
- package/dist/voice/voice_loop.d.ts.map +1 -0
- package/dist/voice/voice_loop.js +463 -0
- package/dist/voice/voice_loop.js.map +1 -0
- package/dist/voice/wake_word.d.ts +153 -0
- package/dist/voice/wake_word.d.ts.map +1 -0
- package/dist/voice/wake_word.js +458 -0
- package/dist/voice/wake_word.js.map +1 -0
- package/dist/voice/wav.d.ts +99 -0
- package/dist/voice/wav.d.ts.map +1 -0
- package/dist/voice/wav.js +306 -0
- package/dist/voice/wav.js.map +1 -0
- package/dist/web/broker.d.ts +33 -0
- package/dist/web/broker.d.ts.map +1 -0
- package/dist/web/broker.js +58 -0
- package/dist/web/broker.js.map +1 -0
- package/dist/web/open_browser.d.ts +2 -0
- package/dist/web/open_browser.d.ts.map +1 -0
- package/dist/web/open_browser.js +42 -0
- package/dist/web/open_browser.js.map +1 -0
- package/dist/web/server.d.ts +54 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +831 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/static/app.js +4121 -0
- package/dist/web/static/index.html +2281 -0
- package/dist/web/static/js/MODULE_SUMMARY.md +124 -0
- package/dist/web/static/js/a11y.js +165 -0
- package/dist/web/static/js/admin.js +2145 -0
- package/dist/web/static/js/assistant.js +475 -0
- package/dist/web/static/js/calendar/reminders.js +114 -0
- package/dist/web/static/js/calendar/utils.js +166 -0
- package/dist/web/static/js/calendar.js +3348 -0
- package/dist/web/static/js/censor.js +356 -0
- package/dist/web/static/js/chat.js +4546 -0
- package/dist/web/static/js/chatRenderer.js +2294 -0
- package/dist/web/static/js/chatStream.js +276 -0
- package/dist/web/static/js/codeRunner.js +398 -0
- package/dist/web/static/js/color/hex.js +14 -0
- package/dist/web/static/js/colorPicker.js +453 -0
- package/dist/web/static/js/compare/icons.js +77 -0
- package/dist/web/static/js/compare/index.js +1482 -0
- package/dist/web/static/js/compare/models.js +104 -0
- package/dist/web/static/js/compare/panes.js +817 -0
- package/dist/web/static/js/compare/probe.js +78 -0
- package/dist/web/static/js/compare/scoreboard.js +223 -0
- package/dist/web/static/js/compare/selector.js +1335 -0
- package/dist/web/static/js/compare/state.js +58 -0
- package/dist/web/static/js/compare/stream.js +695 -0
- package/dist/web/static/js/compare/vote.js +254 -0
- package/dist/web/static/js/cookbook-diagnosis.js +694 -0
- package/dist/web/static/js/cookbook-hwfit.js +1888 -0
- package/dist/web/static/js/cookbook.js +2093 -0
- package/dist/web/static/js/cookbookDownload.js +633 -0
- package/dist/web/static/js/cookbookProgressSignal.js +29 -0
- package/dist/web/static/js/cookbookRunning.js +3506 -0
- package/dist/web/static/js/cookbookServe.js +2128 -0
- package/dist/web/static/js/document.js +9731 -0
- package/dist/web/static/js/documentLibrary.js +3376 -0
- package/dist/web/static/js/dragSort.js +265 -0
- package/dist/web/static/js/editor/ai-inpaint.js +374 -0
- package/dist/web/static/js/editor/ai-models.js +273 -0
- package/dist/web/static/js/editor/ai-rembg.js +230 -0
- package/dist/web/static/js/editor/ai-tool-runner.js +147 -0
- package/dist/web/static/js/editor/ai-tools-misc.js +216 -0
- package/dist/web/static/js/editor/build/controls.js +366 -0
- package/dist/web/static/js/editor/build/popups.js +112 -0
- package/dist/web/static/js/editor/build/right-panel.js +200 -0
- package/dist/web/static/js/editor/build/toolbar.js +73 -0
- package/dist/web/static/js/editor/build/topbar.js +131 -0
- package/dist/web/static/js/editor/build/transform-popup.js +109 -0
- package/dist/web/static/js/editor/canvas-coords.js +21 -0
- package/dist/web/static/js/editor/canvas-events.js +197 -0
- package/dist/web/static/js/editor/canvas-transforms.js +132 -0
- package/dist/web/static/js/editor/checkerboard.js +24 -0
- package/dist/web/static/js/editor/clipboard-and-drop.js +133 -0
- package/dist/web/static/js/editor/composite-helpers.js +83 -0
- package/dist/web/static/js/editor/filters/blur.js +118 -0
- package/dist/web/static/js/editor/filters/edge-feather.js +70 -0
- package/dist/web/static/js/editor/fx/adj-popup.js +677 -0
- package/dist/web/static/js/editor/fx/filter-string.js +38 -0
- package/dist/web/static/js/editor/fx/histogram.js +67 -0
- package/dist/web/static/js/editor/fx/pixel-pass.js +249 -0
- package/dist/web/static/js/editor/harmonize-masks.js +116 -0
- package/dist/web/static/js/editor/history-panel.js +176 -0
- package/dist/web/static/js/editor/keyboard-shortcuts.js +271 -0
- package/dist/web/static/js/editor/layer-helpers.js +131 -0
- package/dist/web/static/js/editor/layer-panel.js +600 -0
- package/dist/web/static/js/editor/mask-utils.js +91 -0
- package/dist/web/static/js/editor/shortcuts-popover.js +149 -0
- package/dist/web/static/js/editor/slider-ux.js +191 -0
- package/dist/web/static/js/editor/snap.js +107 -0
- package/dist/web/static/js/editor/state.js +257 -0
- package/dist/web/static/js/editor/stroke-pipeline.js +162 -0
- package/dist/web/static/js/editor/stroke-tool-sliders.js +64 -0
- package/dist/web/static/js/editor/tools/clone.js +81 -0
- package/dist/web/static/js/editor/tools/crop.js +137 -0
- package/dist/web/static/js/editor/tools/flood-fill.js +72 -0
- package/dist/web/static/js/editor/tools/lasso-mask.js +171 -0
- package/dist/web/static/js/editor/tools/lasso.js +65 -0
- package/dist/web/static/js/editor/tools/move.js +79 -0
- package/dist/web/static/js/editor/tools/stroke.js +123 -0
- package/dist/web/static/js/editor/tools/transform-drag.js +174 -0
- package/dist/web/static/js/editor/tools/transform-handles.js +271 -0
- package/dist/web/static/js/editor/tools/transform-session.js +381 -0
- package/dist/web/static/js/editor/tools/wand.js +46 -0
- package/dist/web/static/js/editor/wire-import.js +148 -0
- package/dist/web/static/js/editor/wire-inpaint-controls.js +164 -0
- package/dist/web/static/js/editor/wire-merge-buttons.js +103 -0
- package/dist/web/static/js/editor/wire-selection-controls.js +170 -0
- package/dist/web/static/js/editor/wire-topbar-menus.js +174 -0
- package/dist/web/static/js/editor/wire-topbar-overflow.js +49 -0
- package/dist/web/static/js/editor/wire-topbar.js +188 -0
- package/dist/web/static/js/emailInbox.js +1245 -0
- package/dist/web/static/js/emailLibrary/replyRecipients.js +27 -0
- package/dist/web/static/js/emailLibrary/signatureFold.js +339 -0
- package/dist/web/static/js/emailLibrary/state.js +34 -0
- package/dist/web/static/js/emailLibrary/utils.js +202 -0
- package/dist/web/static/js/emailLibrary.js +5217 -0
- package/dist/web/static/js/emojiPicker.js +311 -0
- package/dist/web/static/js/escMenuStack.js +102 -0
- package/dist/web/static/js/fileHandler.js +295 -0
- package/dist/web/static/js/gallery.js +2835 -0
- package/dist/web/static/js/galleryEditor.js +3798 -0
- package/dist/web/static/js/group.js +955 -0
- package/dist/web/static/js/init.js +405 -0
- package/dist/web/static/js/keyboard-shortcuts.js +292 -0
- package/dist/web/static/js/langIcons.js +187 -0
- package/dist/web/static/js/markdown/tableRow.js +19 -0
- package/dist/web/static/js/markdown.js +806 -0
- package/dist/web/static/js/memory.js +1418 -0
- package/dist/web/static/js/modalManager.js +1552 -0
- package/dist/web/static/js/modalSnap.js +782 -0
- package/dist/web/static/js/model/matchKey.js +19 -0
- package/dist/web/static/js/modelPicker.js +695 -0
- package/dist/web/static/js/modelSort.js +33 -0
- package/dist/web/static/js/models.js +642 -0
- package/dist/web/static/js/notes.js +5054 -0
- package/dist/web/static/js/package.json +1 -0
- package/dist/web/static/js/platform.js +47 -0
- package/dist/web/static/js/presets.js +1110 -0
- package/dist/web/static/js/providers.js +93 -0
- package/dist/web/static/js/rag.js +177 -0
- package/dist/web/static/js/research/jobs.js +335 -0
- package/dist/web/static/js/research/panel.js +1233 -0
- package/dist/web/static/js/researchSynapse.js +225 -0
- package/dist/web/static/js/search-chat.js +201 -0
- package/dist/web/static/js/search.js +52 -0
- package/dist/web/static/js/section-management.js +260 -0
- package/dist/web/static/js/sessions.js +3108 -0
- package/dist/web/static/js/settings.js +4991 -0
- package/dist/web/static/js/sidebar-layout.js +573 -0
- package/dist/web/static/js/signature.js +504 -0
- package/dist/web/static/js/skills.js +1908 -0
- package/dist/web/static/js/slashAutocomplete.js +267 -0
- package/dist/web/static/js/slashCommands.js +6099 -0
- package/dist/web/static/js/spinner.js +406 -0
- package/dist/web/static/js/storage.js +123 -0
- package/dist/web/static/js/tasks.js +2699 -0
- package/dist/web/static/js/theme.js +2086 -0
- package/dist/web/static/js/tileManager.js +386 -0
- package/dist/web/static/js/tourAutoplay.js +133 -0
- package/dist/web/static/js/tourHints.js +179 -0
- package/dist/web/static/js/tts-ai.js +521 -0
- package/dist/web/static/js/ui.js +1288 -0
- package/dist/web/static/js/util/ordinal.js +13 -0
- package/dist/web/static/js/voiceRecorder.js +283 -0
- package/dist/web/static/js/windowDrag.js +326 -0
- package/dist/web/static/js/windowResize.js +233 -0
- package/dist/web/static/landing.html +824 -0
- package/dist/web/static/lib/docx.umd.min.js +20116 -0
- package/dist/web/static/lib/highlight.min.js +1213 -0
- package/dist/web/static/lib/html2pdf.bundle.min.js +3 -0
- package/dist/web/static/lib/mammoth.browser.min.js +21 -0
- package/dist/web/static/lib/qrcode.min.js +8 -0
- package/dist/web/static/lib/xlsx.full.min.js +24 -0
- package/dist/web/static/login.html +582 -0
- package/dist/web/static/manifest.json +15 -0
- package/dist/web/static/style.css +35733 -0
- package/dist/web/static/sw.js +144 -0
- package/dist/workflows/engine.d.ts +162 -0
- package/dist/workflows/engine.d.ts.map +1 -0
- package/dist/workflows/engine.js +625 -0
- package/dist/workflows/engine.js.map +1 -0
- package/dist/workflows/index.d.ts +8 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +14 -0
- package/dist/workflows/index.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* axoniz.core.intelligence.daemon
|
|
3
|
+
* =================================
|
|
4
|
+
* Phase 4 — axoniz OS Layer (Background Daemon)
|
|
5
|
+
*
|
|
6
|
+
* This is what no one has attempted in local AI.
|
|
7
|
+
* axoniz runs as a background daemon on your machine:
|
|
8
|
+
*
|
|
9
|
+
* File saved → lint and test automatically
|
|
10
|
+
* Git commit → write the changelog entry
|
|
11
|
+
* Build failed → fix it and retry while you sleep
|
|
12
|
+
* Cron schedule → daily code quality audit
|
|
13
|
+
* File watcher → catch errors before you even ask
|
|
14
|
+
*
|
|
15
|
+
* It stops being a tool you open and becomes infrastructure you run.
|
|
16
|
+
*
|
|
17
|
+
* Architecture:
|
|
18
|
+
* FileWatcher — watches workspace for changes
|
|
19
|
+
* EventQueue — deque of file events
|
|
20
|
+
* DaemonLoop — runs scheduled tasks + reacts to events
|
|
21
|
+
* TaskScheduler — interval-style task scheduling
|
|
22
|
+
*
|
|
23
|
+
* Port notes (Python → Node):
|
|
24
|
+
* - `threading.Thread(daemon=True)` loops → `setInterval` timers that are
|
|
25
|
+
* `unref()`d, so (exactly like a Python daemon thread) they never keep the
|
|
26
|
+
* process alive, and `stop()` clears them.
|
|
27
|
+
* - `queue.Queue(maxsize=500)` → `EventQueue`, a bounded wrapper around the
|
|
28
|
+
* existing `core/backend/async_queue.ts` `AsyncQueue` (reused for the async
|
|
29
|
+
* iteration side) plus a synchronous FIFO so the daemon's poll loop keeps
|
|
30
|
+
* Python's `get_nowait()` / `empty()` semantics. A full queue drops instead
|
|
31
|
+
* of blocking: blocking is impossible on the main thread, and the Python
|
|
32
|
+
* producer ran on its own thread.
|
|
33
|
+
* - `compile(source, path, "exec")` (the Python linter) → heuristic bracket /
|
|
34
|
+
* string-balance checking; Node ships no Python parser. `.js`/`.mjs`/`.cjs`
|
|
35
|
+
* files get a REAL syntax check through `node:vm`. Consequences are
|
|
36
|
+
* documented on `_pySyntaxIssue`.
|
|
37
|
+
* - `_task_vision_sentinel` used pyautogui + pytesseract (OCR). Neither has a
|
|
38
|
+
* Node equivalent in the available dependency set, so the sentinel keeps its
|
|
39
|
+
* schedule and its `AXONIZ_DISABLE_VISION` guard but cannot extract text;
|
|
40
|
+
* it warns once and performs no capture. Documented fidelity loss.
|
|
41
|
+
* - `threading.Lock` around `_pending_lint` is unnecessary on one thread and
|
|
42
|
+
* is omitted.
|
|
43
|
+
*/
|
|
44
|
+
import fs from "node:fs";
|
|
45
|
+
import path from "node:path";
|
|
46
|
+
import vm from "node:vm";
|
|
47
|
+
import { AXONIZ_HOME } from "../config.js";
|
|
48
|
+
import { debug, error, info, warn } from "../debug.js";
|
|
49
|
+
import { AsyncQueue } from "../backend/async_queue.js";
|
|
50
|
+
/** Render an unknown thrown value the way Python's `str(e)` would. */
|
|
51
|
+
export function errText(e) {
|
|
52
|
+
if (e instanceof Error)
|
|
53
|
+
return e.message || e.name;
|
|
54
|
+
if (typeof e === "string")
|
|
55
|
+
return e;
|
|
56
|
+
try {
|
|
57
|
+
return JSON.stringify(e);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return String(e);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class FileEvent {
|
|
64
|
+
path;
|
|
65
|
+
event;
|
|
66
|
+
timestamp;
|
|
67
|
+
size;
|
|
68
|
+
constructor(init, event, timestamp, size = 0) {
|
|
69
|
+
const o = typeof init === "string"
|
|
70
|
+
? { path: init, event: event ?? "", timestamp: timestamp ?? Date.now() / 1000, size }
|
|
71
|
+
: init;
|
|
72
|
+
this.path = o.path;
|
|
73
|
+
this.event = o.event;
|
|
74
|
+
this.timestamp = o.timestamp ?? Date.now() / 1000;
|
|
75
|
+
this.size = o.size ?? 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export class ScheduledTask {
|
|
79
|
+
name;
|
|
80
|
+
interval_sec;
|
|
81
|
+
callback;
|
|
82
|
+
last_run;
|
|
83
|
+
enabled;
|
|
84
|
+
description;
|
|
85
|
+
constructor(init, interval_sec, callback, last_run = 0.0, enabled = true, description = "") {
|
|
86
|
+
const o = typeof init === "string"
|
|
87
|
+
? {
|
|
88
|
+
name: init,
|
|
89
|
+
interval_sec: interval_sec ?? 0,
|
|
90
|
+
callback: callback ?? (() => undefined),
|
|
91
|
+
last_run,
|
|
92
|
+
enabled,
|
|
93
|
+
description,
|
|
94
|
+
}
|
|
95
|
+
: init;
|
|
96
|
+
this.name = o.name;
|
|
97
|
+
this.interval_sec = o.interval_sec;
|
|
98
|
+
this.callback = o.callback;
|
|
99
|
+
this.last_run = o.last_run ?? 0.0;
|
|
100
|
+
this.enabled = o.enabled ?? true;
|
|
101
|
+
this.description = o.description ?? "";
|
|
102
|
+
}
|
|
103
|
+
get intervalSec() {
|
|
104
|
+
return this.interval_sec;
|
|
105
|
+
}
|
|
106
|
+
get lastRun() {
|
|
107
|
+
return this.last_run;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export class DaemonEvent {
|
|
111
|
+
kind;
|
|
112
|
+
payload;
|
|
113
|
+
ts;
|
|
114
|
+
constructor(init, payload, ts) {
|
|
115
|
+
const o = typeof init === "string"
|
|
116
|
+
? { kind: init, payload: payload ?? {}, ts }
|
|
117
|
+
: init;
|
|
118
|
+
this.kind = o.kind;
|
|
119
|
+
this.payload = o.payload;
|
|
120
|
+
this.ts = o.ts ?? Date.now() / 1000;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/* ─── Event queue ───────────────────────────────────────────────────────────── */
|
|
124
|
+
/**
|
|
125
|
+
* Bounded FIFO bridging the file watcher to the daemon loop.
|
|
126
|
+
*
|
|
127
|
+
* `AsyncQueue` (core/backend) supplies the async-iteration side; the extra
|
|
128
|
+
* synchronous buffer exists because Python's `queue.Queue` offered
|
|
129
|
+
* `get_nowait()`/`empty()` and the daemon's tick loop drains up to 20 events
|
|
130
|
+
* without awaiting.
|
|
131
|
+
*/
|
|
132
|
+
export class EventQueue {
|
|
133
|
+
maxsize;
|
|
134
|
+
_async;
|
|
135
|
+
_buffer = [];
|
|
136
|
+
constructor(maxsize = 0) {
|
|
137
|
+
this.maxsize = maxsize;
|
|
138
|
+
this._async = new AsyncQueue();
|
|
139
|
+
}
|
|
140
|
+
put(item) {
|
|
141
|
+
if (this.maxsize > 0 && this._buffer.length >= this.maxsize)
|
|
142
|
+
return; // drop, never block
|
|
143
|
+
this._buffer.push(item);
|
|
144
|
+
this._async.push(item);
|
|
145
|
+
}
|
|
146
|
+
put_nowait(item) {
|
|
147
|
+
this.put(item);
|
|
148
|
+
}
|
|
149
|
+
get_nowait() {
|
|
150
|
+
return this._buffer.shift();
|
|
151
|
+
}
|
|
152
|
+
empty() {
|
|
153
|
+
return this._buffer.length === 0;
|
|
154
|
+
}
|
|
155
|
+
get qsize() {
|
|
156
|
+
return this._buffer.length;
|
|
157
|
+
}
|
|
158
|
+
[Symbol.asyncIterator]() {
|
|
159
|
+
return this._async[Symbol.asyncIterator]();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Heuristic stand-in for Python's `compile(source, path, "exec")`.
|
|
164
|
+
*
|
|
165
|
+
* It catches unbalanced brackets, unterminated strings and (approximated)
|
|
166
|
+
* triple-quoted strings — the failures that dominate "file saved, does it still
|
|
167
|
+
* parse?" checks. It CANNOT detect real grammar errors (`def f(:` passes) and it
|
|
168
|
+
* can be fooled by exotic literal shapes. `.js`/`.mjs`/`.cjs` files use the real
|
|
169
|
+
* `node:vm` parser instead (`_jsSyntaxIssue`).
|
|
170
|
+
*/
|
|
171
|
+
export function _pySyntaxIssue(source) {
|
|
172
|
+
const lines = source.split(/\r?\n/);
|
|
173
|
+
const stack = [];
|
|
174
|
+
const closerToOpener = { ")": "(", "]": "[", "}": "{" };
|
|
175
|
+
let single = null;
|
|
176
|
+
let triple = null;
|
|
177
|
+
for (let i = 0; i < lines.length; i++) {
|
|
178
|
+
const line = lines[i];
|
|
179
|
+
for (let j = 0; j < line.length; j++) {
|
|
180
|
+
const ch = line[j];
|
|
181
|
+
if (triple) {
|
|
182
|
+
if (line.startsWith(triple, j)) {
|
|
183
|
+
triple = null;
|
|
184
|
+
j += 2;
|
|
185
|
+
}
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (single) {
|
|
189
|
+
if (ch === "\\") {
|
|
190
|
+
j++;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (ch === single)
|
|
194
|
+
single = null;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (ch === "#")
|
|
198
|
+
break;
|
|
199
|
+
if ((ch === '"' || ch === "'") && line.startsWith(ch.repeat(3), j)) {
|
|
200
|
+
triple = ch.repeat(3);
|
|
201
|
+
j += 2;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (ch === '"' || ch === "'") {
|
|
205
|
+
single = ch;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
209
|
+
stack.push({ ch, line: i + 1 });
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
213
|
+
const top = stack.pop();
|
|
214
|
+
if (!top || top.ch !== closerToOpener[ch]) {
|
|
215
|
+
return { error: `unmatched '${ch}'`, line: i + 1 };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (triple)
|
|
221
|
+
return { error: `unterminated ${triple} string`, line: lines.length };
|
|
222
|
+
if (single)
|
|
223
|
+
return { error: `unterminated ${single} string`, line: lines.length };
|
|
224
|
+
const open = stack[stack.length - 1];
|
|
225
|
+
if (open)
|
|
226
|
+
return { error: `unclosed '${open.ch}'`, line: open.line };
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
/** Real syntax check for JavaScript, via the V8 parser. */
|
|
230
|
+
export function _jsSyntaxIssue(source, filename = "file.js") {
|
|
231
|
+
try {
|
|
232
|
+
new vm.Script(source, { filename });
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
const err = e;
|
|
237
|
+
return { error: err.message, line: err.lineNumber ?? 0 };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/* ─── File Watcher ───────────────────────────────────────────────────────────── */
|
|
241
|
+
/**
|
|
242
|
+
* Watches a workspace directory for file changes using mtime polling.
|
|
243
|
+
* No external deps (no watchdog needed).
|
|
244
|
+
* Debounces rapid changes (e.g. editor writing temp files).
|
|
245
|
+
*/
|
|
246
|
+
export class FileWatcher {
|
|
247
|
+
static POLL_INTERVAL = 1.5; // seconds between polls
|
|
248
|
+
static DEBOUNCE_SEC = 2.0; // wait this long after last change before emitting
|
|
249
|
+
static MAX_FILES = 2000;
|
|
250
|
+
static SKIP_DIRS = new Set([
|
|
251
|
+
".git",
|
|
252
|
+
"__pycache__",
|
|
253
|
+
"node_modules",
|
|
254
|
+
".axoniz",
|
|
255
|
+
"dist",
|
|
256
|
+
"build",
|
|
257
|
+
".egg-info",
|
|
258
|
+
"venv",
|
|
259
|
+
"env",
|
|
260
|
+
".venv",
|
|
261
|
+
]);
|
|
262
|
+
static WATCH_EXTS = new Set([
|
|
263
|
+
".py",
|
|
264
|
+
".js",
|
|
265
|
+
".ts",
|
|
266
|
+
".json",
|
|
267
|
+
".yaml",
|
|
268
|
+
".yml",
|
|
269
|
+
".toml",
|
|
270
|
+
".md",
|
|
271
|
+
".txt",
|
|
272
|
+
".html",
|
|
273
|
+
".css",
|
|
274
|
+
]);
|
|
275
|
+
workspace;
|
|
276
|
+
queue;
|
|
277
|
+
_mtimes = new Map();
|
|
278
|
+
_pending = new Map(); // path → time of last change
|
|
279
|
+
_running = false;
|
|
280
|
+
_timer = null;
|
|
281
|
+
constructor(workspace, queue) {
|
|
282
|
+
this.workspace = path.resolve(workspace);
|
|
283
|
+
this.queue = queue;
|
|
284
|
+
}
|
|
285
|
+
start() {
|
|
286
|
+
this._running = true;
|
|
287
|
+
// Initial scan (silent — don't emit for existing files)
|
|
288
|
+
this._scan(false);
|
|
289
|
+
this._timer = setInterval(() => {
|
|
290
|
+
this._loop();
|
|
291
|
+
}, FileWatcher.POLL_INTERVAL * 1000);
|
|
292
|
+
// Python's thread was daemon=True: never block process exit.
|
|
293
|
+
this._timer.unref?.();
|
|
294
|
+
info(`[FileWatcher] Watching ${this.workspace}`);
|
|
295
|
+
}
|
|
296
|
+
stop() {
|
|
297
|
+
this._running = false;
|
|
298
|
+
if (this._timer) {
|
|
299
|
+
clearInterval(this._timer);
|
|
300
|
+
this._timer = null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
_loop() {
|
|
304
|
+
if (!this._running)
|
|
305
|
+
return;
|
|
306
|
+
try {
|
|
307
|
+
this._scan(true);
|
|
308
|
+
this._flush_debounced();
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
debug(`[FileWatcher] scan error: ${errText(e)}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
_scan(emit) {
|
|
315
|
+
let count = 0;
|
|
316
|
+
const walk = (dir) => {
|
|
317
|
+
let entries;
|
|
318
|
+
try {
|
|
319
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
for (const ent of entries) {
|
|
325
|
+
if (ent.isDirectory()) {
|
|
326
|
+
if (FileWatcher.SKIP_DIRS.has(ent.name))
|
|
327
|
+
continue;
|
|
328
|
+
if (walk(path.join(dir, ent.name)))
|
|
329
|
+
return true;
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
if (!FileWatcher.WATCH_EXTS.has(path.extname(ent.name).toLowerCase()))
|
|
333
|
+
continue;
|
|
334
|
+
const fpath = path.join(dir, ent.name);
|
|
335
|
+
count += 1;
|
|
336
|
+
if (count > FileWatcher.MAX_FILES)
|
|
337
|
+
return true;
|
|
338
|
+
try {
|
|
339
|
+
const mtime = fs.statSync(fpath).mtimeMs / 1000;
|
|
340
|
+
const old = this._mtimes.get(fpath);
|
|
341
|
+
if (old === undefined) {
|
|
342
|
+
this._mtimes.set(fpath, mtime);
|
|
343
|
+
if (emit) {
|
|
344
|
+
this._pending.set(fpath, Date.now() / 1000);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
else if (mtime !== old) {
|
|
348
|
+
this._mtimes.set(fpath, mtime);
|
|
349
|
+
this._pending.set(fpath, Date.now() / 1000);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
if (this._mtimes.has(fpath)) {
|
|
354
|
+
this._mtimes.delete(fpath);
|
|
355
|
+
if (emit) {
|
|
356
|
+
this.queue.put(new FileEvent({ path: fpath, event: "deleted" }));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
};
|
|
363
|
+
walk(this.workspace);
|
|
364
|
+
}
|
|
365
|
+
_flush_debounced() {
|
|
366
|
+
const now = Date.now() / 1000;
|
|
367
|
+
const flush = [...this._pending.entries()]
|
|
368
|
+
.filter(([, t]) => now - t >= FileWatcher.DEBOUNCE_SEC)
|
|
369
|
+
.map(([p]) => p);
|
|
370
|
+
for (const fpath of flush) {
|
|
371
|
+
this._pending.delete(fpath);
|
|
372
|
+
const event = this._mtimes.has(fpath) ? "modified" : "created";
|
|
373
|
+
try {
|
|
374
|
+
const size = fs.statSync(fpath).size;
|
|
375
|
+
this.queue.put(new FileEvent({ path: fpath, event, size }));
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
this.queue.put(new FileEvent({ path: fpath, event: "deleted" }));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/* ─── Daemon Loop ────────────────────────────────────────────────────────────── */
|
|
384
|
+
/**
|
|
385
|
+
* Background daemon that watches files, runs scheduled tasks,
|
|
386
|
+
* and reacts to events — all without user intervention.
|
|
387
|
+
*
|
|
388
|
+
* This is the OS layer. It's always running.
|
|
389
|
+
*/
|
|
390
|
+
export class axonizDaemon {
|
|
391
|
+
static DAEMON_STATE_PATH = path.join(AXONIZ_HOME, "daemon_state.json");
|
|
392
|
+
agent;
|
|
393
|
+
workspace;
|
|
394
|
+
on_event;
|
|
395
|
+
_queue;
|
|
396
|
+
_watcher;
|
|
397
|
+
_running = false;
|
|
398
|
+
_event_log = [];
|
|
399
|
+
_tasks;
|
|
400
|
+
_pending_lint = new Set();
|
|
401
|
+
_timer = null;
|
|
402
|
+
_vision_warned = false;
|
|
403
|
+
constructor(a, b, c = null) {
|
|
404
|
+
// Discriminate the options-object form from the positional (agent, workspace)
|
|
405
|
+
// form: only the init object carries an `agent` key.
|
|
406
|
+
const o = b === undefined && a !== null && typeof a === "object" && "agent" in a
|
|
407
|
+
? a
|
|
408
|
+
: { agent: a, workspace: b ?? ".", on_event: c };
|
|
409
|
+
this.agent = o.agent;
|
|
410
|
+
this.workspace = path.resolve(o.workspace);
|
|
411
|
+
this.on_event = o.on_event ?? null;
|
|
412
|
+
this._queue = new EventQueue(500);
|
|
413
|
+
this._watcher = new FileWatcher(this.workspace, this._queue);
|
|
414
|
+
// Scheduled tasks
|
|
415
|
+
this._tasks = [
|
|
416
|
+
new ScheduledTask({
|
|
417
|
+
name: "lint_changed_files",
|
|
418
|
+
interval_sec: 30,
|
|
419
|
+
callback: () => this._task_lint_pending(),
|
|
420
|
+
description: "Auto-lint Python files changed in last 30s",
|
|
421
|
+
}),
|
|
422
|
+
new ScheduledTask({
|
|
423
|
+
name: "git_status_check",
|
|
424
|
+
interval_sec: 120,
|
|
425
|
+
callback: () => this._task_git_status(),
|
|
426
|
+
description: "Check git status and warn about uncommitted changes",
|
|
427
|
+
}),
|
|
428
|
+
new ScheduledTask({
|
|
429
|
+
name: "axodex_shadow_scan",
|
|
430
|
+
interval_sec: 60,
|
|
431
|
+
callback: () => this._task_axodex_refresh(),
|
|
432
|
+
description: "Auto-refresh Axodex graph index on changes",
|
|
433
|
+
}),
|
|
434
|
+
new ScheduledTask({
|
|
435
|
+
name: "beru_heartbeat",
|
|
436
|
+
interval_sec: 300, // 5 minutes
|
|
437
|
+
callback: () => this._task_beru_heartbeat(),
|
|
438
|
+
description: "Proactive codebase health check and fix suggestion",
|
|
439
|
+
}),
|
|
440
|
+
new ScheduledTask({
|
|
441
|
+
name: "vision_sentinel",
|
|
442
|
+
interval_sec: 10, // 10 seconds
|
|
443
|
+
callback: () => this._task_vision_sentinel(),
|
|
444
|
+
description: "Monitor terminal for errors via screenshot/OCR",
|
|
445
|
+
}),
|
|
446
|
+
new ScheduledTask({
|
|
447
|
+
name: "daily_audit",
|
|
448
|
+
interval_sec: 86400, // 24h
|
|
449
|
+
callback: () => this._task_daily_audit(),
|
|
450
|
+
description: "Daily code quality audit",
|
|
451
|
+
}),
|
|
452
|
+
];
|
|
453
|
+
}
|
|
454
|
+
/* ── Public API ──────────────────────────────────────────────────────────── */
|
|
455
|
+
/** Start daemon in background thread. */
|
|
456
|
+
start() {
|
|
457
|
+
this._running = true;
|
|
458
|
+
this._watcher.start();
|
|
459
|
+
this._timer = setInterval(() => {
|
|
460
|
+
this._loop();
|
|
461
|
+
}, 1000);
|
|
462
|
+
this._timer.unref?.();
|
|
463
|
+
info(`[Daemon] Started | workspace=${this.workspace}`);
|
|
464
|
+
}
|
|
465
|
+
stop() {
|
|
466
|
+
this._running = false;
|
|
467
|
+
this._watcher.stop();
|
|
468
|
+
if (this._timer) {
|
|
469
|
+
clearInterval(this._timer);
|
|
470
|
+
this._timer = null;
|
|
471
|
+
}
|
|
472
|
+
info("[Daemon] Stopped");
|
|
473
|
+
}
|
|
474
|
+
is_running() {
|
|
475
|
+
return this._running;
|
|
476
|
+
}
|
|
477
|
+
/** camelCase alias. */
|
|
478
|
+
isRunning() {
|
|
479
|
+
return this._running;
|
|
480
|
+
}
|
|
481
|
+
/** Add a custom scheduled task. */
|
|
482
|
+
add_task(task) {
|
|
483
|
+
this._tasks.push(task);
|
|
484
|
+
}
|
|
485
|
+
/** camelCase alias. */
|
|
486
|
+
addTask(task) {
|
|
487
|
+
this.add_task(task);
|
|
488
|
+
}
|
|
489
|
+
remove_task(name) {
|
|
490
|
+
this._tasks = this._tasks.filter((t) => t.name !== name);
|
|
491
|
+
}
|
|
492
|
+
/** camelCase alias. */
|
|
493
|
+
removeTask(name) {
|
|
494
|
+
this.remove_task(name);
|
|
495
|
+
}
|
|
496
|
+
get_recent_events(n = 20) {
|
|
497
|
+
return this._event_log.slice(-n);
|
|
498
|
+
}
|
|
499
|
+
/** camelCase alias. */
|
|
500
|
+
getRecentEvents(n = 20) {
|
|
501
|
+
return this.get_recent_events(n);
|
|
502
|
+
}
|
|
503
|
+
status() {
|
|
504
|
+
return {
|
|
505
|
+
running: this._running,
|
|
506
|
+
workspace: this.workspace,
|
|
507
|
+
tasks: this._tasks.map((t) => ({ name: t.name, interval: t.interval_sec, enabled: t.enabled })),
|
|
508
|
+
pending_lint: this._pending_lint.size,
|
|
509
|
+
recent_events: this._event_log.length,
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
/* ── Internal loop ───────────────────────────────────────────────────────── */
|
|
513
|
+
_loop() {
|
|
514
|
+
if (!this._running)
|
|
515
|
+
return;
|
|
516
|
+
// 1. Process file events
|
|
517
|
+
this._drain_queue();
|
|
518
|
+
// 2. Run scheduled tasks that are due
|
|
519
|
+
const now = Date.now() / 1000;
|
|
520
|
+
for (const task of this._tasks) {
|
|
521
|
+
if (!task.enabled) {
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
if (now - task.last_run >= task.interval_sec) {
|
|
525
|
+
try {
|
|
526
|
+
const res = task.callback();
|
|
527
|
+
task.last_run = now;
|
|
528
|
+
// Async callbacks (the Node port of the Python callbacks) report
|
|
529
|
+
// their failures out of band; the schedule is marked as run
|
|
530
|
+
// immediately because unlike Python we cannot observe completion
|
|
531
|
+
// synchronously.
|
|
532
|
+
if (res && typeof res.then === "function") {
|
|
533
|
+
void res.catch((e) => {
|
|
534
|
+
error(`[Daemon] Task '${task.name}' failed: ${errText(e)}`);
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
catch (e) {
|
|
539
|
+
error(`[Daemon] Task '${task.name}' failed: ${errText(e)}`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
_drain_queue() {
|
|
545
|
+
// Process all pending file events.
|
|
546
|
+
let processed = 0;
|
|
547
|
+
while (processed < 20) {
|
|
548
|
+
// max 20 per tick to avoid blocking
|
|
549
|
+
const event = this._queue.get_nowait();
|
|
550
|
+
if (event === undefined)
|
|
551
|
+
break;
|
|
552
|
+
this._handle_event(event);
|
|
553
|
+
processed += 1;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/** React to a file change event. */
|
|
557
|
+
_handle_event(event) {
|
|
558
|
+
const p = event.path;
|
|
559
|
+
const ext = path.extname(p).toLowerCase();
|
|
560
|
+
// Queue Python files for linting
|
|
561
|
+
if (ext === ".py" && (event.event === "created" || event.event === "modified")) {
|
|
562
|
+
this._pending_lint.add(p);
|
|
563
|
+
}
|
|
564
|
+
// Log the event
|
|
565
|
+
const daemon_ev = new DaemonEvent({
|
|
566
|
+
kind: "file_change",
|
|
567
|
+
payload: { path: p, event: event.event, size: event.size },
|
|
568
|
+
});
|
|
569
|
+
this._event_log.push(daemon_ev);
|
|
570
|
+
if (this._event_log.length > 500) {
|
|
571
|
+
this._event_log = this._event_log.slice(-400);
|
|
572
|
+
}
|
|
573
|
+
this._emit(daemon_ev);
|
|
574
|
+
debug(`[Daemon] ${event.event}: ${path.relative(this.workspace, p)}`);
|
|
575
|
+
}
|
|
576
|
+
_emit(ev) {
|
|
577
|
+
if (!this.on_event)
|
|
578
|
+
return;
|
|
579
|
+
try {
|
|
580
|
+
const res = this.on_event(ev);
|
|
581
|
+
if (res && typeof res.then === "function") {
|
|
582
|
+
void res.catch(() => undefined);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
catch {
|
|
586
|
+
/* listener errors must not kill the daemon */
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
/* ── Scheduled tasks ─────────────────────────────────────────────────────── */
|
|
590
|
+
/** Lint all Python files that changed recently. */
|
|
591
|
+
_task_lint_pending() {
|
|
592
|
+
const pending = new Set(this._pending_lint);
|
|
593
|
+
this._pending_lint.clear();
|
|
594
|
+
if (pending.size === 0) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
const py_files = [...pending].filter((p) => p.endsWith(".py") && fs.existsSync(p));
|
|
598
|
+
if (py_files.length === 0) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
info(`[Daemon] Auto-linting ${py_files.length} changed file(s)`);
|
|
602
|
+
for (const fpath of py_files.slice(0, 5)) {
|
|
603
|
+
// max 5 per cycle
|
|
604
|
+
const rel = path.relative(this.workspace, fpath);
|
|
605
|
+
try {
|
|
606
|
+
const source = fs.readFileSync(fpath, "utf-8");
|
|
607
|
+
const issue = _pySyntaxIssue(source);
|
|
608
|
+
if (issue) {
|
|
609
|
+
warn(`[Daemon] ✗ syntax error in ${rel}: ${issue.error} (line ${issue.line})`);
|
|
610
|
+
const daemon_ev = new DaemonEvent({
|
|
611
|
+
kind: "syntax_error",
|
|
612
|
+
payload: { file: rel, error: issue.error, line: issue.line },
|
|
613
|
+
});
|
|
614
|
+
this._event_log.push(daemon_ev);
|
|
615
|
+
this._emit(daemon_ev);
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
debug(`[Daemon] ✓ syntax OK: ${rel}`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch {
|
|
622
|
+
/* unreadable file — ignore, as Python did */
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
/** Check git status and emit events for uncommitted changes. */
|
|
627
|
+
async _task_git_status() {
|
|
628
|
+
const gitTools = this.agent.git_tools ?? this.agent.gitTools;
|
|
629
|
+
if (!gitTools || typeof gitTools.status !== "function") {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
try {
|
|
633
|
+
const status = String((await gitTools.status()) ?? "");
|
|
634
|
+
if (status && status.trim() && !status.toLowerCase().includes("nothing to commit")) {
|
|
635
|
+
const lines = status.split(/\r?\n/).filter((l) => l.trim());
|
|
636
|
+
const changed_count = lines.length;
|
|
637
|
+
if (changed_count > 0) {
|
|
638
|
+
const ev = new DaemonEvent({
|
|
639
|
+
kind: "git_uncommitted",
|
|
640
|
+
payload: { count: changed_count, status: status.slice(0, 500) },
|
|
641
|
+
});
|
|
642
|
+
this._event_log.push(ev);
|
|
643
|
+
this._emit(ev);
|
|
644
|
+
debug(`[Daemon] ${changed_count} uncommitted file(s)`);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
/* git unavailable — silent, exactly like Python */
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
/** Daily code quality check — runs lint on all Python files. */
|
|
653
|
+
async _task_daily_audit() {
|
|
654
|
+
info("[Daemon] Running daily code audit");
|
|
655
|
+
try {
|
|
656
|
+
const py_files = [];
|
|
657
|
+
const skip = new Set([".git", "__pycache__", "node_modules", ".axoniz"]);
|
|
658
|
+
const walk = (dir) => {
|
|
659
|
+
let entries;
|
|
660
|
+
try {
|
|
661
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
662
|
+
}
|
|
663
|
+
catch {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
for (const ent of entries) {
|
|
667
|
+
if (ent.isDirectory()) {
|
|
668
|
+
if (skip.has(ent.name))
|
|
669
|
+
continue;
|
|
670
|
+
walk(path.join(dir, ent.name));
|
|
671
|
+
}
|
|
672
|
+
else if (ent.name.endsWith(".py")) {
|
|
673
|
+
py_files.push(path.join(dir, ent.name));
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
walk(this.workspace);
|
|
678
|
+
const errors_found = [];
|
|
679
|
+
for (const fpath of py_files.slice(0, 50)) {
|
|
680
|
+
try {
|
|
681
|
+
const source = fs.readFileSync(fpath, "utf-8");
|
|
682
|
+
const issue = _pySyntaxIssue(source);
|
|
683
|
+
if (issue)
|
|
684
|
+
errors_found.push({ file: fpath, error: `${issue.error} (line ${issue.line})` });
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
/* unreadable — skip */
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
const ev = new DaemonEvent({
|
|
691
|
+
kind: "daily_audit",
|
|
692
|
+
payload: {
|
|
693
|
+
files_checked: py_files.slice(0, 50).length,
|
|
694
|
+
syntax_errors: errors_found.length,
|
|
695
|
+
errors: errors_found.slice(0, 10),
|
|
696
|
+
},
|
|
697
|
+
});
|
|
698
|
+
this._event_log.push(ev);
|
|
699
|
+
this._emit(ev);
|
|
700
|
+
// Store audit results in palace
|
|
701
|
+
const palace = this.agent.memory?.palace;
|
|
702
|
+
const available = Boolean(palace && ((palace.is_available?.() ?? false) || (palace.isAvailable?.() ?? false)));
|
|
703
|
+
if (palace && available && typeof palace.store === "function") {
|
|
704
|
+
const store = palace.store;
|
|
705
|
+
const content = `Audit ${_localDate()}: ${py_files.length} files, ${errors_found.length} errors`;
|
|
706
|
+
try {
|
|
707
|
+
// Python called this with keywords; the surrounding Node ports take
|
|
708
|
+
// positional arguments, so try positional first and fall back to the
|
|
709
|
+
// keyword-object form.
|
|
710
|
+
try {
|
|
711
|
+
await store("wing_axoniz", "daily-audits", content, "daemon");
|
|
712
|
+
}
|
|
713
|
+
catch (e) {
|
|
714
|
+
if (!(e instanceof TypeError))
|
|
715
|
+
throw e;
|
|
716
|
+
await store({
|
|
717
|
+
wing: "wing_axoniz",
|
|
718
|
+
room: "daily-audits",
|
|
719
|
+
content,
|
|
720
|
+
added_by: "daemon",
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
catch (e) {
|
|
725
|
+
debug(`[Daemon] Palace store failed: ${errText(e)}`);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
info(`[Daemon] Daily audit: ${py_files.slice(0, 50).length} files checked, ` +
|
|
729
|
+
`${errors_found.length} syntax errors`);
|
|
730
|
+
}
|
|
731
|
+
catch (e) {
|
|
732
|
+
error(`[Daemon] Daily audit failed: ${errText(e)}`);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
/** Background Axodex refresh. */
|
|
736
|
+
async _task_axodex_refresh() {
|
|
737
|
+
if (!this.agent.axodex)
|
|
738
|
+
return;
|
|
739
|
+
// Only refresh if there are uncommitted changes or recent file events
|
|
740
|
+
if (this._event_log.length > 0) {
|
|
741
|
+
const last_ev = this._event_log[this._event_log.length - 1];
|
|
742
|
+
if (Date.now() / 1000 - last_ev.ts < 60) {
|
|
743
|
+
debug("[Daemon] Triggering Axodex shadow scan...");
|
|
744
|
+
try {
|
|
745
|
+
await this.agent.axodex.analyze?.();
|
|
746
|
+
}
|
|
747
|
+
catch (e) {
|
|
748
|
+
debug(`[Daemon] Axodex refresh failed: ${errText(e)}`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/** Proactive codebase health check and fix suggestion. */
|
|
754
|
+
async _task_beru_heartbeat() {
|
|
755
|
+
if (!this.agent.axodex)
|
|
756
|
+
return;
|
|
757
|
+
info("[Daemon] Beru Heartbeat: Scanning for architectural weaknesses...");
|
|
758
|
+
try {
|
|
759
|
+
// 1. Check for stale index
|
|
760
|
+
const status = String((await this.agent.axodex.status?.()) ?? "");
|
|
761
|
+
if (status.toLowerCase().includes("stale")) {
|
|
762
|
+
await this.agent.axodex.analyze?.();
|
|
763
|
+
}
|
|
764
|
+
// 2. Proactively look for syntax errors in the last edited files
|
|
765
|
+
// This is already handled by _task_lint_pending, but we can add more logic here.
|
|
766
|
+
// 3. Emit a heartbeat event
|
|
767
|
+
const ev = new DaemonEvent({
|
|
768
|
+
kind: "beru_heartbeat",
|
|
769
|
+
payload: { status: "healthy", scanned_at: new Date().toISOString() },
|
|
770
|
+
});
|
|
771
|
+
this._event_log.push(ev);
|
|
772
|
+
this._emit(ev);
|
|
773
|
+
}
|
|
774
|
+
catch (e) {
|
|
775
|
+
error(`[Daemon] Heartbeat failed: ${errText(e)}`);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Monitor terminal/screen for errors via OCR.
|
|
780
|
+
*
|
|
781
|
+
* FIDELITY LOSS: Python used `pyautogui.screenshot()` + `pytesseract` to read
|
|
782
|
+
* the screen and look for critical fail markers. No OCR engine is available in
|
|
783
|
+
* the Node dependency set (and `screenshot-desktop` alone cannot read text), so
|
|
784
|
+
* the sentinel keeps its schedule + guard but cannot perform detection. It
|
|
785
|
+
* warns once per process and then stays silent.
|
|
786
|
+
*/
|
|
787
|
+
async _task_vision_sentinel() {
|
|
788
|
+
if (process.env.AXONIZ_DISABLE_VISION) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (!this._vision_warned) {
|
|
792
|
+
this._vision_warned = true;
|
|
793
|
+
warn("[Vision] OCR-based visual error detection is unavailable in the Node port (no tesseract) — sentinel idle.");
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
/** Persist daemon state for restart. */
|
|
797
|
+
save_state() {
|
|
798
|
+
const state = {
|
|
799
|
+
workspace: this.workspace,
|
|
800
|
+
last_run: Object.fromEntries(this._tasks.map((t) => [t.name, t.last_run])),
|
|
801
|
+
saved_at: Date.now() / 1000,
|
|
802
|
+
};
|
|
803
|
+
try {
|
|
804
|
+
fs.mkdirSync(path.dirname(axonizDaemon.DAEMON_STATE_PATH), { recursive: true });
|
|
805
|
+
fs.writeFileSync(axonizDaemon.DAEMON_STATE_PATH, JSON.stringify(state, null, 2), "utf-8");
|
|
806
|
+
}
|
|
807
|
+
catch {
|
|
808
|
+
/* best effort, mirrors Python's bare except */
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
/** camelCase alias. */
|
|
812
|
+
saveState() {
|
|
813
|
+
this.save_state();
|
|
814
|
+
}
|
|
815
|
+
/** Restore task last_run times from previous session. */
|
|
816
|
+
load_state() {
|
|
817
|
+
try {
|
|
818
|
+
if (!fs.existsSync(axonizDaemon.DAEMON_STATE_PATH))
|
|
819
|
+
return;
|
|
820
|
+
const raw = JSON.parse(fs.readFileSync(axonizDaemon.DAEMON_STATE_PATH, "utf-8"));
|
|
821
|
+
const last_run = raw.last_run ?? {};
|
|
822
|
+
for (const task of this._tasks) {
|
|
823
|
+
if (task.name in last_run) {
|
|
824
|
+
task.last_run = Number(last_run[task.name]);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
catch {
|
|
829
|
+
/* corrupt state — ignore, as Python did */
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
/** camelCase alias. */
|
|
833
|
+
loadState() {
|
|
834
|
+
this.load_state();
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
/** Python's `datetime.now().strftime('%Y-%m-%d')` — local date, not UTC. */
|
|
838
|
+
function _localDate(d = new Date()) {
|
|
839
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
840
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
841
|
+
}
|
|
842
|
+
//# sourceMappingURL=daemon.js.map
|