@nghyane/arcane 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/CHANGELOG.md +3 -0
- package/README.md +12 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +109 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/todo/index.ts +206 -0
- package/examples/extensions/README.md +143 -0
- package/examples/extensions/api-demo.ts +89 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +32 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +550 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/todo.ts +296 -0
- package/examples/extensions/tools.ts +144 -0
- package/examples/extensions/with-deps/index.ts +35 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +16 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +116 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +43 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +80 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +36 -0
- package/examples/sdk/08-slash-commands.ts +41 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/README.md +150 -0
- package/package.json +464 -0
- package/scripts/format-prompts.ts +184 -0
- package/scripts/generate-docs-index.ts +40 -0
- package/scripts/generate-template.ts +32 -0
- package/src/bun-imports.d.ts +22 -0
- package/src/capability/context-file.ts +39 -0
- package/src/capability/extension-module.ts +33 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +89 -0
- package/src/capability/hook.ts +39 -0
- package/src/capability/index.ts +432 -0
- package/src/capability/instruction.ts +36 -0
- package/src/capability/mcp.ts +60 -0
- package/src/capability/prompt.ts +34 -0
- package/src/capability/rule.ts +223 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +48 -0
- package/src/capability/slash-command.ts +39 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +37 -0
- package/src/capability/types.ts +156 -0
- package/src/cli/args.ts +259 -0
- package/src/cli/config-cli.ts +357 -0
- package/src/cli/file-processor.ts +124 -0
- package/src/cli/grep-cli.ts +152 -0
- package/src/cli/jupyter-cli.ts +106 -0
- package/src/cli/list-models.ts +103 -0
- package/src/cli/plugin-cli.ts +661 -0
- package/src/cli/session-picker.ts +42 -0
- package/src/cli/setup-cli.ts +376 -0
- package/src/cli/shell-cli.ts +174 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/stats-cli.ts +197 -0
- package/src/cli/update-cli.ts +286 -0
- package/src/cli/web-search-cli.ts +143 -0
- package/src/cli.ts +65 -0
- package/src/commands/commit.ts +36 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/grep.ts +41 -0
- package/src/commands/jupyter.ts +32 -0
- package/src/commands/launch.ts +139 -0
- package/src/commands/plugin.ts +70 -0
- package/src/commands/setup.ts +42 -0
- package/src/commands/shell.ts +29 -0
- package/src/commands/ssh.ts +60 -0
- package/src/commands/stats.ts +29 -0
- package/src/commands/update.ts +21 -0
- package/src/commands/web-search.ts +42 -0
- package/src/commit/agentic/agent.ts +311 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +359 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +118 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +37 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +9 -0
- package/src/commit/git/index.ts +211 -0
- package/src/commit/git/operations.ts +54 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +64 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +69 -0
- package/src/commit/pipeline.ts +243 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +280 -0
- package/src/config/model-registry.ts +1140 -0
- package/src/config/model-resolver.ts +812 -0
- package/src/config/prompt-templates.ts +526 -0
- package/src/config/resolve-config-value.ts +92 -0
- package/src/config/settings-schema.ts +1236 -0
- package/src/config/settings.ts +706 -0
- package/src/config.ts +414 -0
- package/src/cursor.ts +239 -0
- package/src/debug/index.ts +431 -0
- package/src/debug/log-formatting.ts +60 -0
- package/src/debug/log-viewer.ts +903 -0
- package/src/debug/profiler.ts +158 -0
- package/src/debug/report-bundle.ts +366 -0
- package/src/debug/system-info.ts +112 -0
- package/src/discovery/agents-md.ts +68 -0
- package/src/discovery/agents.ts +199 -0
- package/src/discovery/builtin.ts +815 -0
- package/src/discovery/claude-plugins.ts +205 -0
- package/src/discovery/claude.ts +506 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +532 -0
- package/src/discovery/cursor.ts +218 -0
- package/src/discovery/gemini.ts +395 -0
- package/src/discovery/github.ts +117 -0
- package/src/discovery/helpers.ts +698 -0
- package/src/discovery/index.ts +89 -0
- package/src/discovery/mcp-json.ts +156 -0
- package/src/discovery/opencode.ts +394 -0
- package/src/discovery/ssh.ts +160 -0
- package/src/discovery/vscode.ts +103 -0
- package/src/discovery/windsurf.ts +145 -0
- package/src/exa/company.ts +57 -0
- package/src/exa/index.ts +62 -0
- package/src/exa/linkedin.ts +57 -0
- package/src/exa/mcp-client.ts +289 -0
- package/src/exa/render.ts +244 -0
- package/src/exa/researcher.ts +89 -0
- package/src/exa/search.ts +330 -0
- package/src/exa/types.ts +166 -0
- package/src/exa/websets.ts +247 -0
- package/src/exec/bash-executor.ts +184 -0
- package/src/exec/exec.ts +53 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/index.ts +162 -0
- package/src/export/html/template.css +889 -0
- package/src/export/html/template.generated.ts +2 -0
- package/src/export/html/template.html +45 -0
- package/src/export/html/template.js +1329 -0
- package/src/export/html/template.macro.ts +24 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/ttsr.ts +434 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +433 -0
- package/src/extensibility/custom-commands/index.ts +15 -0
- package/src/extensibility/custom-commands/loader.ts +231 -0
- package/src/extensibility/custom-commands/types.ts +111 -0
- package/src/extensibility/custom-tools/index.ts +22 -0
- package/src/extensibility/custom-tools/loader.ts +235 -0
- package/src/extensibility/custom-tools/types.ts +226 -0
- package/src/extensibility/custom-tools/wrapper.ts +45 -0
- package/src/extensibility/extensions/index.ts +136 -0
- package/src/extensibility/extensions/loader.ts +520 -0
- package/src/extensibility/extensions/runner.ts +774 -0
- package/src/extensibility/extensions/types.ts +1293 -0
- package/src/extensibility/extensions/wrapper.ts +188 -0
- package/src/extensibility/hooks/index.ts +16 -0
- package/src/extensibility/hooks/loader.ts +273 -0
- package/src/extensibility/hooks/runner.ts +441 -0
- package/src/extensibility/hooks/tool-wrapper.ts +106 -0
- package/src/extensibility/hooks/types.ts +817 -0
- package/src/extensibility/plugins/doctor.ts +65 -0
- package/src/extensibility/plugins/git-url.ts +281 -0
- package/src/extensibility/plugins/index.ts +33 -0
- package/src/extensibility/plugins/installer.ts +192 -0
- package/src/extensibility/plugins/loader.ts +338 -0
- package/src/extensibility/plugins/manager.ts +716 -0
- package/src/extensibility/plugins/parser.ts +105 -0
- package/src/extensibility/plugins/types.ts +190 -0
- package/src/extensibility/skills.ts +385 -0
- package/src/extensibility/slash-commands.ts +287 -0
- package/src/extensibility/tool-proxy.ts +25 -0
- package/src/index.ts +275 -0
- package/src/internal-urls/agent-protocol.ts +136 -0
- package/src/internal-urls/artifact-protocol.ts +97 -0
- package/src/internal-urls/docs-index.generated.ts +54 -0
- package/src/internal-urls/docs-protocol.ts +84 -0
- package/src/internal-urls/index.ts +31 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/memory-protocol.ts +133 -0
- package/src/internal-urls/router.ts +70 -0
- package/src/internal-urls/rule-protocol.ts +55 -0
- package/src/internal-urls/skill-protocol.ts +111 -0
- package/src/internal-urls/types.ts +52 -0
- package/src/ipy/executor.ts +556 -0
- package/src/ipy/gateway-coordinator.ts +426 -0
- package/src/ipy/kernel.ts +892 -0
- package/src/ipy/modules.ts +109 -0
- package/src/ipy/prelude.py +831 -0
- package/src/ipy/prelude.ts +3 -0
- package/src/ipy/runtime.ts +222 -0
- package/src/lsp/client.ts +867 -0
- package/src/lsp/clients/biome-client.ts +202 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +93 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +397 -0
- package/src/lsp/defaults.json +464 -0
- package/src/lsp/edits.ts +109 -0
- package/src/lsp/index.ts +1268 -0
- package/src/lsp/lspmux.ts +250 -0
- package/src/lsp/render.ts +689 -0
- package/src/lsp/types.ts +414 -0
- package/src/lsp/utils.ts +549 -0
- package/src/main.ts +773 -0
- package/src/mcp/client.ts +239 -0
- package/src/mcp/config-writer.ts +215 -0
- package/src/mcp/config.ts +363 -0
- package/src/mcp/index.ts +55 -0
- package/src/mcp/json-rpc.ts +84 -0
- package/src/mcp/loader.ts +124 -0
- package/src/mcp/manager.ts +490 -0
- package/src/mcp/oauth-discovery.ts +274 -0
- package/src/mcp/oauth-flow.ts +229 -0
- package/src/mcp/render.ts +123 -0
- package/src/mcp/tool-bridge.ts +372 -0
- package/src/mcp/tool-cache.ts +121 -0
- package/src/mcp/transports/http.ts +332 -0
- package/src/mcp/transports/index.ts +6 -0
- package/src/mcp/transports/stdio.ts +281 -0
- package/src/mcp/types.ts +248 -0
- package/src/memories/index.ts +1099 -0
- package/src/memories/storage.ts +563 -0
- package/src/modes/components/agent-dashboard.ts +1130 -0
- package/src/modes/components/assistant-message.ts +144 -0
- package/src/modes/components/bash-execution.ts +218 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/branch-summary-message.ts +45 -0
- package/src/modes/components/codemode-group.ts +369 -0
- package/src/modes/components/compaction-summary-message.ts +51 -0
- package/src/modes/components/countdown-timer.ts +46 -0
- package/src/modes/components/custom-editor.ts +181 -0
- package/src/modes/components/custom-message.ts +91 -0
- package/src/modes/components/diff.ts +186 -0
- package/src/modes/components/dynamic-border.ts +25 -0
- package/src/modes/components/extensions/extension-dashboard.ts +325 -0
- package/src/modes/components/extensions/extension-list.ts +484 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +321 -0
- package/src/modes/components/extensions/state-manager.ts +586 -0
- package/src/modes/components/extensions/types.ts +191 -0
- package/src/modes/components/footer.ts +315 -0
- package/src/modes/components/history-search.ts +157 -0
- package/src/modes/components/hook-editor.ts +101 -0
- package/src/modes/components/hook-input.ts +72 -0
- package/src/modes/components/hook-message.ts +100 -0
- package/src/modes/components/hook-selector.ts +155 -0
- package/src/modes/components/index.ts +41 -0
- package/src/modes/components/keybinding-hints.ts +65 -0
- package/src/modes/components/login-dialog.ts +164 -0
- package/src/modes/components/mcp-add-wizard.ts +1295 -0
- package/src/modes/components/model-selector.ts +625 -0
- package/src/modes/components/oauth-selector.ts +210 -0
- package/src/modes/components/plugin-settings.ts +477 -0
- package/src/modes/components/python-execution.ts +196 -0
- package/src/modes/components/queue-mode-selector.ts +56 -0
- package/src/modes/components/read-tool-group.ts +119 -0
- package/src/modes/components/session-selector.ts +242 -0
- package/src/modes/components/settings-defs.ts +340 -0
- package/src/modes/components/settings-selector.ts +529 -0
- package/src/modes/components/show-images-selector.ts +45 -0
- package/src/modes/components/skill-message.ts +90 -0
- package/src/modes/components/status-line/index.ts +4 -0
- package/src/modes/components/status-line/presets.ts +94 -0
- package/src/modes/components/status-line/segments.ts +352 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/types.ts +75 -0
- package/src/modes/components/status-line-segment-editor.ts +354 -0
- package/src/modes/components/status-line.ts +421 -0
- package/src/modes/components/theme-selector.ts +63 -0
- package/src/modes/components/thinking-selector.ts +64 -0
- package/src/modes/components/todo-display.ts +115 -0
- package/src/modes/components/todo-reminder.ts +40 -0
- package/src/modes/components/tool-execution.ts +703 -0
- package/src/modes/components/tree-selector.ts +904 -0
- package/src/modes/components/ttsr-notification.ts +80 -0
- package/src/modes/components/user-message-selector.ts +146 -0
- package/src/modes/components/user-message.ts +22 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +247 -0
- package/src/modes/controllers/command-controller.ts +1120 -0
- package/src/modes/controllers/event-controller.ts +479 -0
- package/src/modes/controllers/extension-ui-controller.ts +778 -0
- package/src/modes/controllers/input-controller.ts +671 -0
- package/src/modes/controllers/mcp-command-controller.ts +1315 -0
- package/src/modes/controllers/selector-controller.ts +712 -0
- package/src/modes/controllers/ssh-command-controller.ts +452 -0
- package/src/modes/index.ts +15 -0
- package/src/modes/interactive-mode.ts +1027 -0
- package/src/modes/print-mode.ts +191 -0
- package/src/modes/rpc/rpc-client.ts +583 -0
- package/src/modes/rpc/rpc-mode.ts +700 -0
- package/src/modes/rpc/rpc-types.ts +236 -0
- package/src/modes/theme/dark.json +95 -0
- package/src/modes/theme/defaults/alabaster.json +93 -0
- package/src/modes/theme/defaults/amethyst.json +96 -0
- package/src/modes/theme/defaults/anthracite.json +93 -0
- package/src/modes/theme/defaults/basalt.json +91 -0
- package/src/modes/theme/defaults/birch.json +95 -0
- package/src/modes/theme/defaults/dark-abyss.json +91 -0
- package/src/modes/theme/defaults/dark-arctic.json +104 -0
- package/src/modes/theme/defaults/dark-aurora.json +95 -0
- package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
- package/src/modes/theme/defaults/dark-cavern.json +91 -0
- package/src/modes/theme/defaults/dark-copper.json +95 -0
- package/src/modes/theme/defaults/dark-cosmos.json +90 -0
- package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/modes/theme/defaults/dark-dracula.json +98 -0
- package/src/modes/theme/defaults/dark-eclipse.json +91 -0
- package/src/modes/theme/defaults/dark-ember.json +95 -0
- package/src/modes/theme/defaults/dark-equinox.json +90 -0
- package/src/modes/theme/defaults/dark-forest.json +96 -0
- package/src/modes/theme/defaults/dark-github.json +105 -0
- package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
- package/src/modes/theme/defaults/dark-lavender.json +95 -0
- package/src/modes/theme/defaults/dark-lunar.json +89 -0
- package/src/modes/theme/defaults/dark-midnight.json +95 -0
- package/src/modes/theme/defaults/dark-monochrome.json +94 -0
- package/src/modes/theme/defaults/dark-monokai.json +98 -0
- package/src/modes/theme/defaults/dark-nebula.json +90 -0
- package/src/modes/theme/defaults/dark-nord.json +97 -0
- package/src/modes/theme/defaults/dark-ocean.json +101 -0
- package/src/modes/theme/defaults/dark-one.json +100 -0
- package/src/modes/theme/defaults/dark-rainforest.json +91 -0
- package/src/modes/theme/defaults/dark-reef.json +91 -0
- package/src/modes/theme/defaults/dark-retro.json +92 -0
- package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
- package/src/modes/theme/defaults/dark-sakura.json +95 -0
- package/src/modes/theme/defaults/dark-slate.json +95 -0
- package/src/modes/theme/defaults/dark-solarized.json +97 -0
- package/src/modes/theme/defaults/dark-solstice.json +90 -0
- package/src/modes/theme/defaults/dark-starfall.json +91 -0
- package/src/modes/theme/defaults/dark-sunset.json +99 -0
- package/src/modes/theme/defaults/dark-swamp.json +90 -0
- package/src/modes/theme/defaults/dark-synthwave.json +103 -0
- package/src/modes/theme/defaults/dark-taiga.json +91 -0
- package/src/modes/theme/defaults/dark-terminal.json +95 -0
- package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/modes/theme/defaults/dark-tundra.json +91 -0
- package/src/modes/theme/defaults/dark-twilight.json +91 -0
- package/src/modes/theme/defaults/dark-volcanic.json +91 -0
- package/src/modes/theme/defaults/graphite.json +92 -0
- package/src/modes/theme/defaults/index.ts +195 -0
- package/src/modes/theme/defaults/light-arctic.json +107 -0
- package/src/modes/theme/defaults/light-aurora-day.json +91 -0
- package/src/modes/theme/defaults/light-canyon.json +91 -0
- package/src/modes/theme/defaults/light-catppuccin.json +106 -0
- package/src/modes/theme/defaults/light-cirrus.json +90 -0
- package/src/modes/theme/defaults/light-coral.json +95 -0
- package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
- package/src/modes/theme/defaults/light-dawn.json +90 -0
- package/src/modes/theme/defaults/light-dunes.json +91 -0
- package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
- package/src/modes/theme/defaults/light-forest.json +100 -0
- package/src/modes/theme/defaults/light-frost.json +95 -0
- package/src/modes/theme/defaults/light-github.json +115 -0
- package/src/modes/theme/defaults/light-glacier.json +91 -0
- package/src/modes/theme/defaults/light-gruvbox.json +108 -0
- package/src/modes/theme/defaults/light-haze.json +90 -0
- package/src/modes/theme/defaults/light-honeycomb.json +95 -0
- package/src/modes/theme/defaults/light-lagoon.json +91 -0
- package/src/modes/theme/defaults/light-lavender.json +95 -0
- package/src/modes/theme/defaults/light-meadow.json +91 -0
- package/src/modes/theme/defaults/light-mint.json +95 -0
- package/src/modes/theme/defaults/light-monochrome.json +101 -0
- package/src/modes/theme/defaults/light-ocean.json +99 -0
- package/src/modes/theme/defaults/light-one.json +99 -0
- package/src/modes/theme/defaults/light-opal.json +91 -0
- package/src/modes/theme/defaults/light-orchard.json +91 -0
- package/src/modes/theme/defaults/light-paper.json +95 -0
- package/src/modes/theme/defaults/light-prism.json +90 -0
- package/src/modes/theme/defaults/light-retro.json +98 -0
- package/src/modes/theme/defaults/light-sand.json +95 -0
- package/src/modes/theme/defaults/light-savanna.json +91 -0
- package/src/modes/theme/defaults/light-solarized.json +102 -0
- package/src/modes/theme/defaults/light-soleil.json +90 -0
- package/src/modes/theme/defaults/light-sunset.json +99 -0
- package/src/modes/theme/defaults/light-synthwave.json +98 -0
- package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
- package/src/modes/theme/defaults/light-wetland.json +91 -0
- package/src/modes/theme/defaults/light-zenith.json +89 -0
- package/src/modes/theme/defaults/limestone.json +94 -0
- package/src/modes/theme/defaults/mahogany.json +97 -0
- package/src/modes/theme/defaults/marble.json +93 -0
- package/src/modes/theme/defaults/obsidian.json +91 -0
- package/src/modes/theme/defaults/onyx.json +91 -0
- package/src/modes/theme/defaults/pearl.json +93 -0
- package/src/modes/theme/defaults/porcelain.json +91 -0
- package/src/modes/theme/defaults/quartz.json +96 -0
- package/src/modes/theme/defaults/sandstone.json +95 -0
- package/src/modes/theme/defaults/titanium.json +90 -0
- package/src/modes/theme/light.json +93 -0
- package/src/modes/theme/mermaid-cache.ts +111 -0
- package/src/modes/theme/theme-schema.json +429 -0
- package/src/modes/theme/theme.ts +2333 -0
- package/src/modes/types.ts +216 -0
- package/src/modes/utils/ui-helpers.ts +529 -0
- package/src/patch/applicator.ts +1482 -0
- package/src/patch/diff.ts +425 -0
- package/src/patch/fuzzy.ts +784 -0
- package/src/patch/hashline.ts +972 -0
- package/src/patch/index.ts +964 -0
- package/src/patch/normalize.ts +397 -0
- package/src/patch/normative.ts +72 -0
- package/src/patch/parser.ts +532 -0
- package/src/patch/shared.ts +400 -0
- package/src/patch/types.ts +292 -0
- package/src/priority.json +35 -0
- package/src/prompts/agents/explore.md +48 -0
- package/src/prompts/agents/frontmatter.md +9 -0
- package/src/prompts/agents/init.md +36 -0
- package/src/prompts/agents/librarian.md +53 -0
- package/src/prompts/agents/oracle.md +51 -0
- package/src/prompts/agents/reviewer.md +70 -0
- package/src/prompts/agents/task.md +14 -0
- package/src/prompts/compaction/branch-summary-context.md +5 -0
- package/src/prompts/compaction/branch-summary-preamble.md +2 -0
- package/src/prompts/compaction/branch-summary.md +30 -0
- package/src/prompts/compaction/compaction-short-summary.md +9 -0
- package/src/prompts/compaction/compaction-summary-context.md +5 -0
- package/src/prompts/compaction/compaction-summary.md +38 -0
- package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
- package/src/prompts/compaction/compaction-update-summary.md +45 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/read_path.md +11 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-request.md +64 -0
- package/src/prompts/system/agent-creation-architect.md +65 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/custom-system-prompt.md +68 -0
- package/src/prompts/system/file-operations.md +10 -0
- package/src/prompts/system/subagent-submit-reminder.md +11 -0
- package/src/prompts/system/subagent-system-prompt.md +31 -0
- package/src/prompts/system/subagent-user-prompt.md +8 -0
- package/src/prompts/system/summarization-system.md +3 -0
- package/src/prompts/system/system-prompt.md +300 -0
- package/src/prompts/system/title-system.md +2 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/web-search.md +28 -0
- package/src/prompts/tools/ask.md +44 -0
- package/src/prompts/tools/bash.md +24 -0
- package/src/prompts/tools/browser.md +33 -0
- package/src/prompts/tools/calculator.md +12 -0
- package/src/prompts/tools/explore.md +29 -0
- package/src/prompts/tools/fetch.md +16 -0
- package/src/prompts/tools/find.md +18 -0
- package/src/prompts/tools/gemini-image.md +23 -0
- package/src/prompts/tools/grep.md +28 -0
- package/src/prompts/tools/hashline.md +232 -0
- package/src/prompts/tools/librarian.md +24 -0
- package/src/prompts/tools/lsp.md +28 -0
- package/src/prompts/tools/oracle.md +26 -0
- package/src/prompts/tools/patch.md +74 -0
- package/src/prompts/tools/python.md +66 -0
- package/src/prompts/tools/read.md +36 -0
- package/src/prompts/tools/replace.md +38 -0
- package/src/prompts/tools/reviewer.md +41 -0
- package/src/prompts/tools/ssh.md +51 -0
- package/src/prompts/tools/task-summary.md +28 -0
- package/src/prompts/tools/task.md +275 -0
- package/src/prompts/tools/todo-write.md +65 -0
- package/src/prompts/tools/undo-edit.md +7 -0
- package/src/prompts/tools/web-search.md +19 -0
- package/src/prompts/tools/write.md +18 -0
- package/src/sdk.ts +1287 -0
- package/src/secrets/index.ts +116 -0
- package/src/secrets/obfuscator.ts +269 -0
- package/src/secrets/regex.ts +21 -0
- package/src/session/agent-session.ts +4669 -0
- package/src/session/agent-storage.ts +621 -0
- package/src/session/artifacts.ts +132 -0
- package/src/session/auth-storage.ts +1433 -0
- package/src/session/blob-store.ts +103 -0
- package/src/session/compaction/branch-summarization.ts +315 -0
- package/src/session/compaction/compaction.ts +864 -0
- package/src/session/compaction/index.ts +7 -0
- package/src/session/compaction/pruning.ts +91 -0
- package/src/session/compaction/utils.ts +171 -0
- package/src/session/history-storage.ts +170 -0
- package/src/session/messages.ts +317 -0
- package/src/session/session-manager.ts +2276 -0
- package/src/session/session-storage.ts +342 -0
- package/src/session/streaming-output.ts +565 -0
- package/src/slash-commands/builtin-registry.ts +439 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +444 -0
- package/src/ssh/ssh-executor.ts +127 -0
- package/src/ssh/sshfs-mount.ts +135 -0
- package/src/stt/downloader.ts +71 -0
- package/src/stt/index.ts +3 -0
- package/src/stt/recorder.ts +351 -0
- package/src/stt/setup.ts +52 -0
- package/src/stt/stt-controller.ts +160 -0
- package/src/stt/transcribe.py +70 -0
- package/src/stt/transcriber.ts +91 -0
- package/src/system-prompt.ts +685 -0
- package/src/task/agents.ts +155 -0
- package/src/task/batch.ts +102 -0
- package/src/task/commands.ts +134 -0
- package/src/task/discovery.ts +126 -0
- package/src/task/executor.ts +908 -0
- package/src/task/index.ts +223 -0
- package/src/task/output-manager.ts +107 -0
- package/src/task/parallel.ts +84 -0
- package/src/task/render.ts +326 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/template.ts +32 -0
- package/src/task/types.ts +144 -0
- package/src/tools/ask.ts +523 -0
- package/src/tools/bash-interactive.ts +419 -0
- package/src/tools/bash-interceptor.ts +105 -0
- package/src/tools/bash-normalize.ts +107 -0
- package/src/tools/bash-skill-urls.ts +177 -0
- package/src/tools/bash.ts +347 -0
- package/src/tools/browser.ts +1374 -0
- package/src/tools/calculator.ts +537 -0
- package/src/tools/context.ts +39 -0
- package/src/tools/explore.ts +23 -0
- package/src/tools/fetch.ts +1091 -0
- package/src/tools/find.ts +540 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gemini-image.ts +907 -0
- package/src/tools/grep.ts +489 -0
- package/src/tools/index.ts +337 -0
- package/src/tools/json-tree.ts +231 -0
- package/src/tools/jtd-to-json-schema.ts +247 -0
- package/src/tools/jtd-to-typescript.ts +198 -0
- package/src/tools/librarian.ts +33 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/notebook.ts +287 -0
- package/src/tools/oracle.ts +40 -0
- package/src/tools/output-meta.ts +459 -0
- package/src/tools/output-utils.ts +63 -0
- package/src/tools/path-utils.ts +116 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
- package/src/tools/python.ts +1118 -0
- package/src/tools/read.ts +1193 -0
- package/src/tools/render-utils.ts +680 -0
- package/src/tools/renderers.ts +60 -0
- package/src/tools/reviewer-tool.ts +41 -0
- package/src/tools/ssh.ts +326 -0
- package/src/tools/subagent-tool.ts +169 -0
- package/src/tools/submit-result.ts +152 -0
- package/src/tools/todo-write.ts +255 -0
- package/src/tools/tool-errors.ts +92 -0
- package/src/tools/tool-result.ts +86 -0
- package/src/tools/undo-edit.ts +145 -0
- package/src/tools/undo-history.ts +22 -0
- package/src/tools/write.ts +274 -0
- package/src/tui/code-cell.ts +108 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +144 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +53 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +116 -0
- package/src/utils/changelog.ts +98 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +59 -0
- package/src/utils/file-display-mode.ts +36 -0
- package/src/utils/file-mentions.ts +384 -0
- package/src/utils/frontmatter.ts +101 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/ignore-files.ts +119 -0
- package/src/utils/image-convert.ts +27 -0
- package/src/utils/image-resize.ts +236 -0
- package/src/utils/mime.ts +30 -0
- package/src/utils/open.ts +20 -0
- package/src/utils/shell-snapshot.ts +199 -0
- package/src/utils/timings.ts +26 -0
- package/src/utils/title-generator.ts +167 -0
- package/src/utils/tools-manager.ts +362 -0
- package/src/web/scrapers/artifacthub.ts +215 -0
- package/src/web/scrapers/arxiv.ts +88 -0
- package/src/web/scrapers/aur.ts +175 -0
- package/src/web/scrapers/biorxiv.ts +141 -0
- package/src/web/scrapers/bluesky.ts +284 -0
- package/src/web/scrapers/brew.ts +177 -0
- package/src/web/scrapers/cheatsh.ts +78 -0
- package/src/web/scrapers/chocolatey.ts +158 -0
- package/src/web/scrapers/choosealicense.ts +110 -0
- package/src/web/scrapers/cisa-kev.ts +100 -0
- package/src/web/scrapers/clojars.ts +180 -0
- package/src/web/scrapers/coingecko.ts +184 -0
- package/src/web/scrapers/crates-io.ts +128 -0
- package/src/web/scrapers/crossref.ts +149 -0
- package/src/web/scrapers/devto.ts +177 -0
- package/src/web/scrapers/discogs.ts +307 -0
- package/src/web/scrapers/discourse.ts +221 -0
- package/src/web/scrapers/dockerhub.ts +160 -0
- package/src/web/scrapers/fdroid.ts +158 -0
- package/src/web/scrapers/firefox-addons.ts +214 -0
- package/src/web/scrapers/flathub.ts +239 -0
- package/src/web/scrapers/github-gist.ts +68 -0
- package/src/web/scrapers/github.ts +490 -0
- package/src/web/scrapers/gitlab.ts +456 -0
- package/src/web/scrapers/go-pkg.ts +275 -0
- package/src/web/scrapers/hackage.ts +94 -0
- package/src/web/scrapers/hackernews.ts +208 -0
- package/src/web/scrapers/hex.ts +121 -0
- package/src/web/scrapers/huggingface.ts +385 -0
- package/src/web/scrapers/iacr.ts +86 -0
- package/src/web/scrapers/index.ts +249 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +169 -0
- package/src/web/scrapers/lemmy.ts +220 -0
- package/src/web/scrapers/lobsters.ts +186 -0
- package/src/web/scrapers/mastodon.ts +310 -0
- package/src/web/scrapers/maven.ts +152 -0
- package/src/web/scrapers/mdn.ts +172 -0
- package/src/web/scrapers/metacpan.ts +253 -0
- package/src/web/scrapers/musicbrainz.ts +272 -0
- package/src/web/scrapers/npm.ts +114 -0
- package/src/web/scrapers/nuget.ts +205 -0
- package/src/web/scrapers/nvd.ts +243 -0
- package/src/web/scrapers/ollama.ts +265 -0
- package/src/web/scrapers/open-vsx.ts +119 -0
- package/src/web/scrapers/opencorporates.ts +275 -0
- package/src/web/scrapers/openlibrary.ts +319 -0
- package/src/web/scrapers/orcid.ts +298 -0
- package/src/web/scrapers/osv.ts +192 -0
- package/src/web/scrapers/packagist.ts +174 -0
- package/src/web/scrapers/pub-dev.ts +185 -0
- package/src/web/scrapers/pubmed.ts +177 -0
- package/src/web/scrapers/pypi.ts +129 -0
- package/src/web/scrapers/rawg.ts +124 -0
- package/src/web/scrapers/readthedocs.ts +125 -0
- package/src/web/scrapers/reddit.ts +104 -0
- package/src/web/scrapers/repology.ts +262 -0
- package/src/web/scrapers/rfc.ts +209 -0
- package/src/web/scrapers/rubygems.ts +117 -0
- package/src/web/scrapers/searchcode.ts +217 -0
- package/src/web/scrapers/sec-edgar.ts +274 -0
- package/src/web/scrapers/semantic-scholar.ts +190 -0
- package/src/web/scrapers/snapcraft.ts +200 -0
- package/src/web/scrapers/sourcegraph.ts +373 -0
- package/src/web/scrapers/spdx.ts +121 -0
- package/src/web/scrapers/spotify.ts +217 -0
- package/src/web/scrapers/stackoverflow.ts +124 -0
- package/src/web/scrapers/terraform.ts +304 -0
- package/src/web/scrapers/tldr.ts +51 -0
- package/src/web/scrapers/twitter.ts +97 -0
- package/src/web/scrapers/types.ts +200 -0
- package/src/web/scrapers/utils.ts +142 -0
- package/src/web/scrapers/vimeo.ts +152 -0
- package/src/web/scrapers/vscode-marketplace.ts +195 -0
- package/src/web/scrapers/w3c.ts +163 -0
- package/src/web/scrapers/wikidata.ts +357 -0
- package/src/web/scrapers/wikipedia.ts +95 -0
- package/src/web/scrapers/youtube.ts +312 -0
- package/src/web/search/auth.ts +178 -0
- package/src/web/search/index.ts +598 -0
- package/src/web/search/provider.ts +77 -0
- package/src/web/search/providers/anthropic.ts +284 -0
- package/src/web/search/providers/base.ts +22 -0
- package/src/web/search/providers/brave.ts +165 -0
- package/src/web/search/providers/codex.ts +377 -0
- package/src/web/search/providers/exa.ts +158 -0
- package/src/web/search/providers/gemini.ts +437 -0
- package/src/web/search/providers/jina.ts +99 -0
- package/src/web/search/providers/kimi.ts +196 -0
- package/src/web/search/providers/perplexity.ts +546 -0
- package/src/web/search/providers/synthetic.ts +136 -0
- package/src/web/search/providers/zai.ts +352 -0
- package/src/web/search/render.ts +299 -0
- package/src/web/search/types.ts +437 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CPU and heap profiling wrappers for debug reports.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface CpuProfile {
|
|
6
|
+
data: string;
|
|
7
|
+
markdown: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ProfilerSession {
|
|
11
|
+
/** Stop profiling and return the profile data */
|
|
12
|
+
stop(): Promise<CpuProfile>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** V8 CPU Profile node structure */
|
|
16
|
+
interface CpuProfileNode {
|
|
17
|
+
id: number;
|
|
18
|
+
callFrame?: {
|
|
19
|
+
functionName?: string;
|
|
20
|
+
url?: string;
|
|
21
|
+
lineNumber?: number;
|
|
22
|
+
};
|
|
23
|
+
hitCount?: number;
|
|
24
|
+
children?: number[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** V8 CPU Profile structure */
|
|
28
|
+
interface CpuProfileData {
|
|
29
|
+
nodes?: CpuProfileNode[];
|
|
30
|
+
samples?: number[];
|
|
31
|
+
timeDeltas?: number[];
|
|
32
|
+
startTime?: number;
|
|
33
|
+
endTime?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Format CPU profile data as markdown for LLM analysis.
|
|
38
|
+
* Extracts top functions by self time and call counts.
|
|
39
|
+
*/
|
|
40
|
+
function formatProfileAsMarkdown(profileJson: string): string {
|
|
41
|
+
try {
|
|
42
|
+
const profile = JSON.parse(profileJson) as CpuProfileData;
|
|
43
|
+
const nodes = profile.nodes ?? [];
|
|
44
|
+
|
|
45
|
+
interface NodeInfo {
|
|
46
|
+
id: number;
|
|
47
|
+
functionName: string;
|
|
48
|
+
url: string;
|
|
49
|
+
lineNumber: number;
|
|
50
|
+
selfTime: number;
|
|
51
|
+
hitCount: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const nodeMap = new Map<number, NodeInfo>();
|
|
55
|
+
for (const node of nodes) {
|
|
56
|
+
nodeMap.set(node.id, {
|
|
57
|
+
id: node.id,
|
|
58
|
+
functionName: node.callFrame?.functionName ?? "(anonymous)",
|
|
59
|
+
url: node.callFrame?.url ?? "",
|
|
60
|
+
lineNumber: node.callFrame?.lineNumber ?? 0,
|
|
61
|
+
selfTime: 0,
|
|
62
|
+
hitCount: node.hitCount ?? 0,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Distribute sample times to nodes
|
|
67
|
+
const samples = profile.samples ?? [];
|
|
68
|
+
const timeDeltas = profile.timeDeltas ?? [];
|
|
69
|
+
for (let i = 0; i < samples.length; i++) {
|
|
70
|
+
const nodeId = samples[i];
|
|
71
|
+
const info = nodeId !== undefined ? nodeMap.get(nodeId) : undefined;
|
|
72
|
+
const delta = timeDeltas[i] ?? 0;
|
|
73
|
+
if (info) {
|
|
74
|
+
info.selfTime += delta;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Sort by self time and get top functions
|
|
79
|
+
const sorted = Array.from(nodeMap.values())
|
|
80
|
+
.filter(n => n.selfTime > 0 && n.functionName !== "(root)" && n.functionName !== "(idle)")
|
|
81
|
+
.sort((a, b) => b.selfTime - a.selfTime)
|
|
82
|
+
.slice(0, 30);
|
|
83
|
+
|
|
84
|
+
if (sorted.length === 0) {
|
|
85
|
+
return "# CPU Profile Summary\n\nNo significant CPU activity recorded.";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const totalTime = sorted.reduce((sum, n) => sum + n.selfTime, 0);
|
|
89
|
+
|
|
90
|
+
const lines = ["# CPU Profile Summary", ""];
|
|
91
|
+
lines.push(`Total profiled time: ${(totalTime / 1000).toFixed(1)}ms`);
|
|
92
|
+
lines.push("");
|
|
93
|
+
lines.push("## Top Functions by Self Time");
|
|
94
|
+
lines.push("");
|
|
95
|
+
lines.push("| Function | Self Time (ms) | % | Location |");
|
|
96
|
+
lines.push("|----------|----------------|---|----------|");
|
|
97
|
+
|
|
98
|
+
for (const node of sorted) {
|
|
99
|
+
const selfMs = (node.selfTime / 1000).toFixed(1);
|
|
100
|
+
const pct = ((node.selfTime / totalTime) * 100).toFixed(1);
|
|
101
|
+
const location = node.url ? `${node.url}:${node.lineNumber}` : "-";
|
|
102
|
+
lines.push(`| ${node.functionName} | ${selfMs} | ${pct}% | ${location} |`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return lines.join("\n");
|
|
106
|
+
} catch {
|
|
107
|
+
return "# CPU Profile Summary\n\nFailed to parse profile data.";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Start CPU profiling.
|
|
113
|
+
* Returns a session that can be stopped to get the profile data.
|
|
114
|
+
*/
|
|
115
|
+
export async function startCpuProfile(): Promise<ProfilerSession> {
|
|
116
|
+
const v8 = await import("node:v8");
|
|
117
|
+
v8.setFlagsFromString("--allow-natives-syntax");
|
|
118
|
+
|
|
119
|
+
const { Session } = await import("node:inspector/promises");
|
|
120
|
+
const session = new Session();
|
|
121
|
+
session.connect();
|
|
122
|
+
|
|
123
|
+
await session.post("Profiler.enable");
|
|
124
|
+
await session.post("Profiler.start");
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
async stop(): Promise<CpuProfile> {
|
|
128
|
+
const result = await session.post("Profiler.stop");
|
|
129
|
+
await session.post("Profiler.disable");
|
|
130
|
+
session.disconnect();
|
|
131
|
+
|
|
132
|
+
const data = JSON.stringify(result.profile, null, 2);
|
|
133
|
+
const markdown = formatProfileAsMarkdown(data);
|
|
134
|
+
|
|
135
|
+
return { data, markdown };
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface HeapSnapshot {
|
|
141
|
+
data: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generate a heap snapshot.
|
|
146
|
+
* Uses Bun's built-in generateHeapSnapshot.
|
|
147
|
+
*/
|
|
148
|
+
export function generateHeapSnapshotData(): HeapSnapshot {
|
|
149
|
+
// Force GC before snapshot
|
|
150
|
+
Bun.gc(true);
|
|
151
|
+
|
|
152
|
+
// Use V8 format for Chrome DevTools compatibility
|
|
153
|
+
const snapshot = Bun.generateHeapSnapshot("v8");
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
data: snapshot,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug report bundle creation.
|
|
3
|
+
*
|
|
4
|
+
* Creates a .tar.gz archive with session data, logs, system info, and optional profiling data.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from "node:fs/promises";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import type { WorkProfile } from "@nghyane/arcane-natives";
|
|
9
|
+
import { isEnoent } from "@nghyane/arcane-utils";
|
|
10
|
+
import { APP_NAME, getLogPath, getLogsDir, getReportsDir } from "@nghyane/arcane-utils/dirs";
|
|
11
|
+
import type { CpuProfile, HeapSnapshot } from "./profiler";
|
|
12
|
+
import { collectSystemInfo, sanitizeEnv } from "./system-info";
|
|
13
|
+
|
|
14
|
+
/** Maximum number of log lines to load into memory at once. */
|
|
15
|
+
const MAX_LOG_LINES = 5000;
|
|
16
|
+
|
|
17
|
+
/** Maximum bytes to read from the tail of a log file (2 MB). */
|
|
18
|
+
const MAX_LOG_BYTES = 2 * 1024 * 1024;
|
|
19
|
+
/** Read last N lines from a file, reading at most `maxBytes` from the tail. */
|
|
20
|
+
async function readLastLines(filePath: string, n: number, maxBytes = MAX_LOG_BYTES): Promise<string> {
|
|
21
|
+
try {
|
|
22
|
+
const file = Bun.file(filePath);
|
|
23
|
+
const size = file.size;
|
|
24
|
+
const start = Math.max(0, size - maxBytes);
|
|
25
|
+
const content = start > 0 ? await file.slice(start, size).text() : await file.text();
|
|
26
|
+
const lines = content.split("\n");
|
|
27
|
+
// If we sliced mid-file, drop the first (partial) line
|
|
28
|
+
if (start > 0 && lines.length > 0) {
|
|
29
|
+
lines.shift();
|
|
30
|
+
}
|
|
31
|
+
return lines.slice(-n).join("\n");
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (isEnoent(err)) return "";
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ReportBundleOptions {
|
|
39
|
+
/** Session file path */
|
|
40
|
+
sessionFile: string | undefined;
|
|
41
|
+
/** Settings to include */
|
|
42
|
+
settings?: Record<string, unknown>;
|
|
43
|
+
/** CPU profile (for performance reports) */
|
|
44
|
+
cpuProfile?: CpuProfile;
|
|
45
|
+
/** Heap snapshot (for memory reports) */
|
|
46
|
+
heapSnapshot?: HeapSnapshot;
|
|
47
|
+
/** Work profile (for work scheduling reports) */
|
|
48
|
+
workProfile?: WorkProfile;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ReportBundleResult {
|
|
52
|
+
path: string;
|
|
53
|
+
files: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface DebugLogSource {
|
|
57
|
+
getInitialText(): Promise<string>;
|
|
58
|
+
hasOlderLogs(): boolean;
|
|
59
|
+
loadOlderLogs(limitDays?: number): Promise<string>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create a debug report bundle.
|
|
64
|
+
*
|
|
65
|
+
* Bundle contents:
|
|
66
|
+
* - session.jsonl: Current session transcript
|
|
67
|
+
* - artifacts/: Session artifacts directory
|
|
68
|
+
* - subagents/: Subagent sessions + artifacts
|
|
69
|
+
* - logs.txt: Recent log entries
|
|
70
|
+
* - system.json: OS, arch, CPU, memory, versions
|
|
71
|
+
* - env.json: Sanitized environment variables
|
|
72
|
+
* - config.json: Resolved settings
|
|
73
|
+
* - profile.cpuprofile: CPU profile (performance report only)
|
|
74
|
+
* - profile.md: Markdown CPU profile (performance report only)
|
|
75
|
+
* - heap.heapsnapshot: Heap snapshot (memory report only)
|
|
76
|
+
* - work.folded: Work profile folded stacks (work report only)
|
|
77
|
+
* - work.md: Work profile summary (work report only)
|
|
78
|
+
* - work.svg: Work profile flamegraph (work report only)
|
|
79
|
+
*/
|
|
80
|
+
export async function createReportBundle(options: ReportBundleOptions): Promise<ReportBundleResult> {
|
|
81
|
+
const reportsDir = getReportsDir();
|
|
82
|
+
await fs.mkdir(reportsDir, { recursive: true });
|
|
83
|
+
|
|
84
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
85
|
+
const outputPath = path.join(reportsDir, `arc-report-${timestamp}.tar.gz`);
|
|
86
|
+
|
|
87
|
+
const data: Record<string, string> = {};
|
|
88
|
+
const files: string[] = [];
|
|
89
|
+
|
|
90
|
+
// Collect system info
|
|
91
|
+
const systemInfo = await collectSystemInfo();
|
|
92
|
+
data["system.json"] = JSON.stringify(systemInfo, null, 2);
|
|
93
|
+
files.push("system.json");
|
|
94
|
+
|
|
95
|
+
// Sanitized environment
|
|
96
|
+
data["env.json"] = JSON.stringify(sanitizeEnv(Bun.env as Record<string, string>), null, 2);
|
|
97
|
+
files.push("env.json");
|
|
98
|
+
|
|
99
|
+
// Settings/config
|
|
100
|
+
if (options.settings) {
|
|
101
|
+
data["config.json"] = JSON.stringify(options.settings, null, 2);
|
|
102
|
+
files.push("config.json");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Recent logs (last 1000 lines)
|
|
106
|
+
const logPath = getLogPath();
|
|
107
|
+
const logs = await readLastLines(logPath, 1000);
|
|
108
|
+
if (logs) {
|
|
109
|
+
data["logs.txt"] = logs;
|
|
110
|
+
files.push("logs.txt");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Session file
|
|
114
|
+
if (options.sessionFile) {
|
|
115
|
+
try {
|
|
116
|
+
const sessionContent = await Bun.file(options.sessionFile).text();
|
|
117
|
+
data["session.jsonl"] = sessionContent;
|
|
118
|
+
files.push("session.jsonl");
|
|
119
|
+
} catch {
|
|
120
|
+
// Session file might not exist yet
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Artifacts directory (same path without .jsonl)
|
|
124
|
+
const artifactsDir = options.sessionFile.slice(0, -6);
|
|
125
|
+
await addDirectoryToArchive(data, files, artifactsDir, "artifacts");
|
|
126
|
+
|
|
127
|
+
// Look for subagent sessions in the same directory
|
|
128
|
+
const sessionDir = path.dirname(options.sessionFile);
|
|
129
|
+
const sessionBasename = path.basename(options.sessionFile, ".jsonl");
|
|
130
|
+
await addSubagentSessions(data, files, sessionDir, sessionBasename);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// CPU profile
|
|
134
|
+
if (options.cpuProfile) {
|
|
135
|
+
data["profile.cpuprofile"] = options.cpuProfile.data;
|
|
136
|
+
files.push("profile.cpuprofile");
|
|
137
|
+
data["profile.md"] = options.cpuProfile.markdown;
|
|
138
|
+
files.push("profile.md");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Heap snapshot
|
|
142
|
+
if (options.heapSnapshot) {
|
|
143
|
+
data["heap.heapsnapshot"] = options.heapSnapshot.data;
|
|
144
|
+
files.push("heap.heapsnapshot");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Work profile
|
|
148
|
+
if (options.workProfile) {
|
|
149
|
+
data["work.folded"] = options.workProfile.folded;
|
|
150
|
+
files.push("work.folded");
|
|
151
|
+
data["work.md"] = options.workProfile.summary;
|
|
152
|
+
files.push("work.md");
|
|
153
|
+
if (options.workProfile.svg) {
|
|
154
|
+
data["work.svg"] = options.workProfile.svg;
|
|
155
|
+
files.push("work.svg");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Write archive
|
|
160
|
+
await Bun.Archive.write(outputPath, data, { compress: "gzip" });
|
|
161
|
+
|
|
162
|
+
return { path: outputPath, files };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Add all files from a directory to the archive */
|
|
166
|
+
async function addDirectoryToArchive(
|
|
167
|
+
data: Record<string, string>,
|
|
168
|
+
files: string[],
|
|
169
|
+
dirPath: string,
|
|
170
|
+
archivePrefix: string,
|
|
171
|
+
): Promise<void> {
|
|
172
|
+
try {
|
|
173
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
174
|
+
for (const entry of entries) {
|
|
175
|
+
if (!entry.isFile()) continue;
|
|
176
|
+
const filePath = path.join(dirPath, entry.name);
|
|
177
|
+
const archivePath = `${archivePrefix}/${entry.name}`;
|
|
178
|
+
try {
|
|
179
|
+
const content = await Bun.file(filePath).text();
|
|
180
|
+
data[archivePath] = content;
|
|
181
|
+
files.push(archivePath);
|
|
182
|
+
} catch {
|
|
183
|
+
// Skip files we can't read
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch {
|
|
187
|
+
// Directory doesn't exist
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Find and add subagent session files */
|
|
192
|
+
async function addSubagentSessions(
|
|
193
|
+
data: Record<string, string>,
|
|
194
|
+
files: string[],
|
|
195
|
+
sessionDir: string,
|
|
196
|
+
parentBasename: string,
|
|
197
|
+
): Promise<void> {
|
|
198
|
+
// Subagent sessions are named with task IDs in the same directory
|
|
199
|
+
// They follow the pattern: {timestamp}_{sessionId}.jsonl
|
|
200
|
+
// We look for any sessions created after the parent session
|
|
201
|
+
try {
|
|
202
|
+
const entries = await fs.readdir(sessionDir, { withFileTypes: true });
|
|
203
|
+
const sessionFiles = entries
|
|
204
|
+
.filter(e => e.isFile() && e.name.endsWith(".jsonl") && e.name !== `${parentBasename}.jsonl`)
|
|
205
|
+
.map(e => e.name);
|
|
206
|
+
|
|
207
|
+
// Limit to most recent 10 subagent sessions
|
|
208
|
+
const sortedFiles = sessionFiles.sort().slice(-10);
|
|
209
|
+
|
|
210
|
+
for (const filename of sortedFiles) {
|
|
211
|
+
const filePath = path.join(sessionDir, filename);
|
|
212
|
+
const archivePath = `subagents/${filename}`;
|
|
213
|
+
try {
|
|
214
|
+
const content = await Bun.file(filePath).text();
|
|
215
|
+
data[archivePath] = content;
|
|
216
|
+
files.push(archivePath);
|
|
217
|
+
|
|
218
|
+
// Also add artifacts for this subagent session
|
|
219
|
+
const artifactsDir = filePath.slice(0, -6);
|
|
220
|
+
await addDirectoryToArchive(data, files, artifactsDir, `subagents/${filename.slice(0, -6)}`);
|
|
221
|
+
} catch {
|
|
222
|
+
// Skip files we can't read
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
} catch {
|
|
226
|
+
// Directory doesn't exist
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Get recent log entries for display (tail-limited to avoid OOM on large files). */
|
|
231
|
+
export async function getLogText(): Promise<string> {
|
|
232
|
+
return readLastLines(getLogPath(), MAX_LOG_LINES);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const LOG_FILE_PATTERN = new RegExp(`^${APP_NAME}\\.(\\d{4}-\\d{2}-\\d{2})\\.log$`);
|
|
236
|
+
|
|
237
|
+
export async function createDebugLogSource(): Promise<DebugLogSource> {
|
|
238
|
+
const logsDir = getLogsDir();
|
|
239
|
+
const todayPath = getLogPath();
|
|
240
|
+
const todayName = path.basename(todayPath);
|
|
241
|
+
let olderFiles: string[] = [];
|
|
242
|
+
try {
|
|
243
|
+
const entries = await fs.readdir(logsDir, { withFileTypes: true });
|
|
244
|
+
const datedFiles = entries
|
|
245
|
+
.filter(entry => entry.isFile())
|
|
246
|
+
.map(entry => {
|
|
247
|
+
const match = LOG_FILE_PATTERN.exec(entry.name);
|
|
248
|
+
return match ? { name: entry.name, date: match[1] } : undefined;
|
|
249
|
+
})
|
|
250
|
+
.filter((entry): entry is { name: string; date: string } => entry !== undefined)
|
|
251
|
+
.filter(entry => entry.name !== todayName)
|
|
252
|
+
.sort((a, b) => b.date.localeCompare(a.date));
|
|
253
|
+
olderFiles = datedFiles.map(entry => entry.name);
|
|
254
|
+
} catch {
|
|
255
|
+
olderFiles = [];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
let cursor = 0;
|
|
259
|
+
|
|
260
|
+
const getInitialText = async (): Promise<string> => {
|
|
261
|
+
return readLastLines(todayPath, MAX_LOG_LINES);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const hasOlderLogs = (): boolean => cursor < olderFiles.length;
|
|
265
|
+
|
|
266
|
+
const loadOlderLogs = async (limitDays: number = 1): Promise<string> => {
|
|
267
|
+
if (!hasOlderLogs()) {
|
|
268
|
+
return "";
|
|
269
|
+
}
|
|
270
|
+
const count = Math.max(1, limitDays);
|
|
271
|
+
const slice = olderFiles.slice(cursor, cursor + count);
|
|
272
|
+
cursor += slice.length;
|
|
273
|
+
const chunks: string[] = [];
|
|
274
|
+
for (const filename of slice.reverse()) {
|
|
275
|
+
const filePath = path.join(logsDir, filename);
|
|
276
|
+
try {
|
|
277
|
+
const content = await readLastLines(filePath, MAX_LOG_LINES);
|
|
278
|
+
if (content.length > 0) {
|
|
279
|
+
chunks.push(content);
|
|
280
|
+
}
|
|
281
|
+
} catch (err) {
|
|
282
|
+
if (!isEnoent(err)) {
|
|
283
|
+
throw err;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return chunks.filter(chunk => chunk.length > 0).join("\n");
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
getInitialText,
|
|
292
|
+
hasOlderLogs,
|
|
293
|
+
loadOlderLogs,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Calculate total size of artifact cache */
|
|
298
|
+
export async function getArtifactCacheStats(
|
|
299
|
+
sessionsDir: string,
|
|
300
|
+
): Promise<{ count: number; totalSize: number; oldestDate: Date | null }> {
|
|
301
|
+
let count = 0;
|
|
302
|
+
let totalSize = 0;
|
|
303
|
+
let oldestDate: Date | null = null;
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
const sessions = await fs.readdir(sessionsDir, { withFileTypes: true });
|
|
307
|
+
|
|
308
|
+
for (const session of sessions) {
|
|
309
|
+
// Artifact directories don't have .jsonl extension
|
|
310
|
+
if (session.isDirectory()) {
|
|
311
|
+
const dirPath = path.join(sessionsDir, session.name);
|
|
312
|
+
try {
|
|
313
|
+
const stat = await fs.stat(dirPath);
|
|
314
|
+
const files = await fs.readdir(dirPath);
|
|
315
|
+
for (const file of files) {
|
|
316
|
+
const filePath = path.join(dirPath, file);
|
|
317
|
+
const fileStat = await fs.stat(filePath);
|
|
318
|
+
if (fileStat.isFile()) {
|
|
319
|
+
count++;
|
|
320
|
+
totalSize += fileStat.size;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (!oldestDate || stat.mtime < oldestDate) {
|
|
324
|
+
oldestDate = stat.mtime;
|
|
325
|
+
}
|
|
326
|
+
} catch {
|
|
327
|
+
// Skip inaccessible directories
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch {
|
|
332
|
+
// Directory doesn't exist
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return { count, totalSize, oldestDate };
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Clear artifact cache older than N days */
|
|
339
|
+
export async function clearArtifactCache(sessionsDir: string, daysOld: number = 30): Promise<{ removed: number }> {
|
|
340
|
+
const cutoff = new Date();
|
|
341
|
+
cutoff.setDate(cutoff.getDate() - daysOld);
|
|
342
|
+
let removed = 0;
|
|
343
|
+
|
|
344
|
+
try {
|
|
345
|
+
const sessions = await fs.readdir(sessionsDir, { withFileTypes: true });
|
|
346
|
+
|
|
347
|
+
for (const session of sessions) {
|
|
348
|
+
if (session.isDirectory()) {
|
|
349
|
+
const dirPath = path.join(sessionsDir, session.name);
|
|
350
|
+
try {
|
|
351
|
+
const stat = await fs.stat(dirPath);
|
|
352
|
+
if (stat.mtime < cutoff) {
|
|
353
|
+
await fs.rm(dirPath, { recursive: true, force: true });
|
|
354
|
+
removed++;
|
|
355
|
+
}
|
|
356
|
+
} catch {
|
|
357
|
+
// Skip inaccessible directories
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} catch {
|
|
362
|
+
// Directory doesn't exist
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return { removed };
|
|
366
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System information collection for debug reports.
|
|
3
|
+
*/
|
|
4
|
+
import * as os from "node:os";
|
|
5
|
+
import { getProjectDir, VERSION } from "@nghyane/arcane-utils/dirs";
|
|
6
|
+
|
|
7
|
+
export interface SystemInfo {
|
|
8
|
+
os: string;
|
|
9
|
+
arch: string;
|
|
10
|
+
cpu: string;
|
|
11
|
+
memory: {
|
|
12
|
+
total: number;
|
|
13
|
+
free: number;
|
|
14
|
+
};
|
|
15
|
+
versions: {
|
|
16
|
+
app: string;
|
|
17
|
+
bun: string;
|
|
18
|
+
node: string;
|
|
19
|
+
};
|
|
20
|
+
cwd: string;
|
|
21
|
+
shell: string;
|
|
22
|
+
terminal: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Map Darwin kernel major version to macOS marketing name. */
|
|
26
|
+
function macosMarketingName(release: string): string | undefined {
|
|
27
|
+
const major = Number.parseInt(release.split(".")[0] ?? "", 10);
|
|
28
|
+
if (Number.isNaN(major)) return undefined;
|
|
29
|
+
const names: Record<number, string> = {
|
|
30
|
+
25: "Tahoe",
|
|
31
|
+
24: "Sequoia",
|
|
32
|
+
23: "Sonoma",
|
|
33
|
+
22: "Ventura",
|
|
34
|
+
21: "Monterey",
|
|
35
|
+
20: "Big Sur",
|
|
36
|
+
};
|
|
37
|
+
return names[major];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Collect system information */
|
|
41
|
+
export async function collectSystemInfo(): Promise<SystemInfo> {
|
|
42
|
+
const cpus = os.cpus();
|
|
43
|
+
const cpuModel = cpus[0]?.model ?? "Unknown CPU";
|
|
44
|
+
|
|
45
|
+
// Try to get shell from environment
|
|
46
|
+
const shell = Bun.env.SHELL ?? Bun.env.ComSpec ?? "unknown";
|
|
47
|
+
const terminal = Bun.env.TERM_PROGRAM ?? Bun.env.TERM ?? undefined;
|
|
48
|
+
|
|
49
|
+
let osStr = `${os.type()} ${os.release()} (${os.platform()})`;
|
|
50
|
+
if (os.platform() === "darwin") {
|
|
51
|
+
const name = macosMarketingName(os.release());
|
|
52
|
+
if (name) osStr = `${osStr} ${name}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
os: osStr,
|
|
57
|
+
arch: os.arch(),
|
|
58
|
+
cpu: cpuModel,
|
|
59
|
+
memory: {
|
|
60
|
+
total: os.totalmem(),
|
|
61
|
+
free: os.freemem(),
|
|
62
|
+
},
|
|
63
|
+
versions: {
|
|
64
|
+
app: VERSION,
|
|
65
|
+
bun: Bun.version,
|
|
66
|
+
node: process.version,
|
|
67
|
+
},
|
|
68
|
+
cwd: getProjectDir(),
|
|
69
|
+
shell,
|
|
70
|
+
terminal,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Format bytes to human-readable string */
|
|
75
|
+
function formatBytes(bytes: number): string {
|
|
76
|
+
const gb = bytes / (1024 * 1024 * 1024);
|
|
77
|
+
return `${gb.toFixed(1)} GB`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Format system info for display */
|
|
81
|
+
export function formatSystemInfo(info: SystemInfo): string {
|
|
82
|
+
const lines = [
|
|
83
|
+
"System Information",
|
|
84
|
+
"━━━━━━━━━━━━━━━━━━",
|
|
85
|
+
`OS: ${info.os}`,
|
|
86
|
+
`Arch: ${info.arch}`,
|
|
87
|
+
`CPU: ${info.cpu}`,
|
|
88
|
+
`Memory: ${formatBytes(info.memory.total)} (${formatBytes(info.memory.free)} free)`,
|
|
89
|
+
`Bun: ${info.versions.bun}`,
|
|
90
|
+
`App: arcane ${info.versions.app}`,
|
|
91
|
+
`Node: ${info.versions.node} (compat)`,
|
|
92
|
+
`CWD: ${info.cwd}`,
|
|
93
|
+
`Shell: ${info.shell}`,
|
|
94
|
+
];
|
|
95
|
+
if (info.terminal) {
|
|
96
|
+
lines.push(`Terminal: ${info.terminal}`);
|
|
97
|
+
}
|
|
98
|
+
return lines.join("\n");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Sanitize environment variables by redacting sensitive values */
|
|
102
|
+
export function sanitizeEnv(env: Record<string, string | undefined>): Record<string, string> {
|
|
103
|
+
const SENSITIVE_PATTERNS = [/key/i, /secret/i, /token/i, /pass/i, /auth/i, /credential/i, /api/i, /private/i];
|
|
104
|
+
|
|
105
|
+
const result: Record<string, string> = {};
|
|
106
|
+
for (const [k, v] of Object.entries(env)) {
|
|
107
|
+
if (v === undefined) continue;
|
|
108
|
+
const isSensitive = SENSITIVE_PATTERNS.some(p => p.test(k));
|
|
109
|
+
result[k] = isSensitive ? "[REDACTED]" : v;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AGENTS.md Provider
|
|
3
|
+
*
|
|
4
|
+
* Discovers standalone AGENTS.md files by walking up from cwd.
|
|
5
|
+
* This handles AGENTS.md files that live in project root (not in config directories
|
|
6
|
+
* like .codex/ or .gemini/, which are handled by their respective providers).
|
|
7
|
+
*/
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { registerProvider } from "../capability";
|
|
10
|
+
import { type ContextFile, contextFileCapability } from "../capability/context-file";
|
|
11
|
+
import { readFile } from "../capability/fs";
|
|
12
|
+
import type { LoadContext, LoadResult } from "../capability/types";
|
|
13
|
+
import { calculateDepth, createSourceMeta } from "./helpers";
|
|
14
|
+
|
|
15
|
+
const PROVIDER_ID = "agents-md";
|
|
16
|
+
const DISPLAY_NAME = "AGENTS.md";
|
|
17
|
+
const MAX_DEPTH = 20; // Prevent walking up excessively far from cwd
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Load standalone AGENTS.md files.
|
|
21
|
+
*/
|
|
22
|
+
async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<ContextFile>> {
|
|
23
|
+
const items: ContextFile[] = [];
|
|
24
|
+
const warnings: string[] = [];
|
|
25
|
+
|
|
26
|
+
// Walk up from cwd looking for AGENTS.md files
|
|
27
|
+
let current = ctx.cwd;
|
|
28
|
+
let depth = 0;
|
|
29
|
+
|
|
30
|
+
while (depth < MAX_DEPTH) {
|
|
31
|
+
const candidate = path.join(current, "AGENTS.md");
|
|
32
|
+
const content = await readFile(candidate);
|
|
33
|
+
|
|
34
|
+
if (content !== null) {
|
|
35
|
+
const parent = path.dirname(candidate);
|
|
36
|
+
const baseName = parent.split(path.sep).pop() ?? "";
|
|
37
|
+
|
|
38
|
+
if (!baseName.startsWith(".")) {
|
|
39
|
+
const fileDir = path.dirname(candidate);
|
|
40
|
+
const calculatedDepth = calculateDepth(ctx.cwd, fileDir, path.sep);
|
|
41
|
+
|
|
42
|
+
items.push({
|
|
43
|
+
path: candidate,
|
|
44
|
+
content,
|
|
45
|
+
level: "project",
|
|
46
|
+
depth: calculatedDepth,
|
|
47
|
+
_source: createSourceMeta(PROVIDER_ID, candidate, "project"),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Move to parent directory
|
|
53
|
+
const parent = path.dirname(current);
|
|
54
|
+
if (parent === current) break; // Reached filesystem root
|
|
55
|
+
current = parent;
|
|
56
|
+
depth++;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { items, warnings };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
registerProvider(contextFileCapability.id, {
|
|
63
|
+
id: PROVIDER_ID,
|
|
64
|
+
displayName: DISPLAY_NAME,
|
|
65
|
+
description: "Standalone AGENTS.md files (Codex/Gemini style)",
|
|
66
|
+
priority: 10,
|
|
67
|
+
load: loadAgentsMd,
|
|
68
|
+
});
|