@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,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Compaction Hook
|
|
3
|
+
*
|
|
4
|
+
* Replaces the default compaction behavior with a full summary of the entire context.
|
|
5
|
+
* Instead of keeping the last 20k tokens of conversation turns, this hook:
|
|
6
|
+
* 1. Summarizes ALL messages (messagesToSummarize + turnPrefixMessages)
|
|
7
|
+
* 2. Discards all old turns completely, keeping only the summary
|
|
8
|
+
*
|
|
9
|
+
* This example also demonstrates using a different model (Gemini Flash) for summarization,
|
|
10
|
+
* which can be cheaper/faster than the main conversation model.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* arcane --hook examples/hooks/custom-compaction.ts
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
17
|
+
import { convertToLlm, serializeConversation } from "@nghyane/arcane";
|
|
18
|
+
import { complete, getModel } from "@nghyane/arcane-ai";
|
|
19
|
+
|
|
20
|
+
export default function (pi: HookAPI) {
|
|
21
|
+
pi.on("session_before_compact", async (event, ctx) => {
|
|
22
|
+
ctx.ui.notify("Custom compaction hook triggered", "info");
|
|
23
|
+
|
|
24
|
+
const { preparation, branchEntries: _, signal } = event;
|
|
25
|
+
const { messagesToSummarize, turnPrefixMessages, tokensBefore, firstKeptEntryId, previousSummary } = preparation;
|
|
26
|
+
|
|
27
|
+
// Use Gemini Flash for summarization (cheaper/faster than most conversation models)
|
|
28
|
+
const model = getModel("google", "gemini-2.5-flash");
|
|
29
|
+
if (!model) {
|
|
30
|
+
ctx.ui.notify(`Could not find Gemini Flash model, using default compaction`, "warning");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Resolve API key for the summarization model
|
|
35
|
+
const apiKey = await ctx.modelRegistry.getApiKey(model);
|
|
36
|
+
if (!apiKey) {
|
|
37
|
+
ctx.ui.notify(`No API key for ${model.provider}, using default compaction`, "warning");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Combine all messages for full summary
|
|
42
|
+
const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
|
|
43
|
+
|
|
44
|
+
ctx.ui.notify(
|
|
45
|
+
`Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${
|
|
46
|
+
model.id
|
|
47
|
+
}...`,
|
|
48
|
+
"info",
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Convert messages to readable text format
|
|
52
|
+
const conversationText = serializeConversation(convertToLlm(allMessages));
|
|
53
|
+
|
|
54
|
+
// Include previous summary context if available
|
|
55
|
+
const previousContext = previousSummary ? `\n\nPrevious session summary for context:\n${previousSummary}` : "";
|
|
56
|
+
|
|
57
|
+
// Build messages that ask for a comprehensive summary
|
|
58
|
+
const summaryMessages = [
|
|
59
|
+
{
|
|
60
|
+
role: "user" as const,
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text" as const,
|
|
64
|
+
text: `You are a conversation summarizer. Create a comprehensive summary of this conversation that captures:${previousContext}
|
|
65
|
+
|
|
66
|
+
1. The main goals and objectives discussed
|
|
67
|
+
2. Key decisions made and their rationale
|
|
68
|
+
3. Important code changes, file modifications, or technical details
|
|
69
|
+
4. Current state of any ongoing work
|
|
70
|
+
5. Any blockers, issues, or open questions
|
|
71
|
+
6. Next steps that were planned or suggested
|
|
72
|
+
|
|
73
|
+
Be thorough but concise. The summary will replace the ENTIRE conversation history, so include all information needed to continue the work effectively.
|
|
74
|
+
|
|
75
|
+
Format the summary as structured markdown with clear sections.
|
|
76
|
+
|
|
77
|
+
<conversation>
|
|
78
|
+
${conversationText}
|
|
79
|
+
</conversation>`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
timestamp: Date.now(),
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
// Pass signal to honor abort requests (e.g., user cancels compaction)
|
|
88
|
+
const response = await complete(model, { messages: summaryMessages }, { apiKey, maxTokens: 8192, signal });
|
|
89
|
+
|
|
90
|
+
const summary = response.content
|
|
91
|
+
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
92
|
+
.map(c => c.text)
|
|
93
|
+
.join("\n");
|
|
94
|
+
|
|
95
|
+
if (!summary.trim()) {
|
|
96
|
+
if (!signal.aborted) ctx.ui.notify("Compaction summary was empty, using default compaction", "warning");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Return compaction content - SessionManager adds id/parentId
|
|
101
|
+
// Use firstKeptEntryId from preparation to keep recent messages
|
|
102
|
+
return {
|
|
103
|
+
compaction: {
|
|
104
|
+
summary,
|
|
105
|
+
firstKeptEntryId,
|
|
106
|
+
tokensBefore,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
+
ctx.ui.notify(`Compaction failed: ${message}`, "error");
|
|
112
|
+
// Fall back to default compaction on error
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dirty Repo Guard Hook
|
|
3
|
+
*
|
|
4
|
+
* Prevents session changes when there are uncommitted git changes.
|
|
5
|
+
* Useful to ensure work is committed before switching context.
|
|
6
|
+
*/
|
|
7
|
+
import type { HookAPI, HookContext } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
async function checkDirtyRepo(pi: HookAPI, ctx: HookContext, action: string): Promise<{ cancel: boolean } | undefined> {
|
|
10
|
+
// Check for uncommitted changes
|
|
11
|
+
const { stdout, code } = await pi.exec("git", ["status", "--porcelain"]);
|
|
12
|
+
|
|
13
|
+
if (code !== 0) {
|
|
14
|
+
// Not a git repo, allow the action
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const hasChanges = stdout.trim().length > 0;
|
|
19
|
+
if (!hasChanges) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!ctx.hasUI) {
|
|
24
|
+
// In non-interactive mode, block by default
|
|
25
|
+
return { cancel: true };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Count changed files
|
|
29
|
+
const changedFiles = stdout.trim().split("\n").filter(Boolean).length;
|
|
30
|
+
|
|
31
|
+
const choice = await ctx.ui.select(`You have ${changedFiles} uncommitted file(s). ${action} anyway?`, [
|
|
32
|
+
"Yes, proceed anyway",
|
|
33
|
+
"No, let me commit first",
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
if (choice !== "Yes, proceed anyway") {
|
|
37
|
+
ctx.ui.notify("Commit your changes first", "warning");
|
|
38
|
+
return { cancel: true };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default function (pi: HookAPI) {
|
|
43
|
+
pi.on("session_before_switch", async (event, ctx) => {
|
|
44
|
+
const action = event.reason === "new" ? "new session" : "switch session";
|
|
45
|
+
return checkDirtyRepo(pi, ctx, action);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
pi.on("session_before_branch", async (_event, ctx) => {
|
|
49
|
+
return checkDirtyRepo(pi, ctx, "branch");
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Trigger Hook
|
|
3
|
+
*
|
|
4
|
+
* Watches a trigger file and injects its contents into the conversation.
|
|
5
|
+
* Useful for external systems to send messages to the agent.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* echo "Run the tests" > /tmp/agent-trigger.txt
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from "node:fs";
|
|
11
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
12
|
+
|
|
13
|
+
export default function (pi: HookAPI) {
|
|
14
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
15
|
+
const triggerFile = "/tmp/agent-trigger.txt";
|
|
16
|
+
|
|
17
|
+
fs.watch(triggerFile, async () => {
|
|
18
|
+
try {
|
|
19
|
+
const content = (await Bun.file(triggerFile).text()).trim();
|
|
20
|
+
if (content) {
|
|
21
|
+
pi.sendMessage(
|
|
22
|
+
{
|
|
23
|
+
customType: "file-trigger",
|
|
24
|
+
content: `External trigger: ${content}`,
|
|
25
|
+
display: true,
|
|
26
|
+
},
|
|
27
|
+
true, // triggerTurn - get LLM to respond
|
|
28
|
+
);
|
|
29
|
+
await Bun.write(triggerFile, ""); // Clear after reading
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// File might not exist yet
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (ctx.hasUI) {
|
|
37
|
+
ctx.ui.notify(`Watching ${triggerFile}`, "info");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Checkpoint Hook
|
|
3
|
+
*
|
|
4
|
+
* Creates git stash checkpoints at each turn so /branch can restore code state.
|
|
5
|
+
* When branching, offers to restore code to that point in history.
|
|
6
|
+
*/
|
|
7
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
export default function (pi: HookAPI) {
|
|
10
|
+
const checkpoints = new Map<string, string>();
|
|
11
|
+
let currentEntryId: string | undefined;
|
|
12
|
+
|
|
13
|
+
// Track the current entry ID when user messages are saved
|
|
14
|
+
pi.on("tool_result", async (_event, ctx) => {
|
|
15
|
+
const leaf = ctx.sessionManager.getLeafEntry();
|
|
16
|
+
if (leaf) currentEntryId = leaf.id;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
pi.on("turn_start", async () => {
|
|
20
|
+
// Create a git stash entry before LLM makes changes
|
|
21
|
+
const { stdout } = await pi.exec("git", ["stash", "create"]);
|
|
22
|
+
const ref = stdout.trim();
|
|
23
|
+
if (ref && currentEntryId) {
|
|
24
|
+
checkpoints.set(currentEntryId, ref);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
pi.on("session_before_branch", async (event, ctx) => {
|
|
29
|
+
const ref = checkpoints.get(event.entryId);
|
|
30
|
+
if (!ref) return;
|
|
31
|
+
|
|
32
|
+
if (!ctx.hasUI) {
|
|
33
|
+
// In non-interactive mode, don't restore automatically
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const choice = await ctx.ui.select("Restore code state?", [
|
|
38
|
+
"Yes, restore code to that point",
|
|
39
|
+
"No, keep current code",
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
if (choice?.startsWith("Yes")) {
|
|
43
|
+
await pi.exec("git", ["stash", "apply", ref]);
|
|
44
|
+
ctx.ui.notify("Code restored to checkpoint", "info");
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
pi.on("agent_end", async () => {
|
|
49
|
+
// Clear checkpoints after agent completes
|
|
50
|
+
checkpoints.clear();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff hook - transfer context to a new focused session
|
|
3
|
+
*
|
|
4
|
+
* Instead of compacting (which is lossy), handoff extracts what matters
|
|
5
|
+
* for your next task and creates a new session with a generated prompt.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* /handoff now implement this for teams as well
|
|
9
|
+
* /handoff execute phase one of the plan
|
|
10
|
+
* /handoff check other places that need this fix
|
|
11
|
+
*
|
|
12
|
+
* The generated prompt appears as a draft in the editor for review/editing.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { HookAPI, SessionEntry } from "@nghyane/arcane";
|
|
16
|
+
import { BorderedLoader, convertToLlm, serializeConversation } from "@nghyane/arcane";
|
|
17
|
+
import { complete, type Message } from "@nghyane/arcane-ai";
|
|
18
|
+
|
|
19
|
+
const SYSTEM_PROMPT = `You are a context transfer assistant. Given a conversation history and the user's goal for a new thread, generate a focused prompt that:
|
|
20
|
+
|
|
21
|
+
1. Summarizes relevant context from the conversation (decisions made, approaches taken, key findings)
|
|
22
|
+
2. Lists any relevant files that were discussed or modified
|
|
23
|
+
3. Clearly states the next task based on the user's goal
|
|
24
|
+
4. Is self-contained - the new thread should be able to proceed without the old conversation
|
|
25
|
+
|
|
26
|
+
Format your response as a prompt the user can send to start the new thread. Be concise but include all necessary context. Do not include any preamble like "Here's the prompt" - just output the prompt itself.
|
|
27
|
+
|
|
28
|
+
Example output format:
|
|
29
|
+
## Context
|
|
30
|
+
We've been working on X. Key decisions:
|
|
31
|
+
- Decision 1
|
|
32
|
+
- Decision 2
|
|
33
|
+
|
|
34
|
+
Files involved:
|
|
35
|
+
- path/to/file1.ts
|
|
36
|
+
- path/to/file2.ts
|
|
37
|
+
|
|
38
|
+
## Task
|
|
39
|
+
[Clear description of what to do next based on user's goal]`;
|
|
40
|
+
|
|
41
|
+
export default function (pi: HookAPI) {
|
|
42
|
+
pi.registerCommand("handoff", {
|
|
43
|
+
description: "Transfer context to a new focused session",
|
|
44
|
+
handler: async (args, ctx) => {
|
|
45
|
+
if (!ctx.hasUI) {
|
|
46
|
+
ctx.ui.notify("handoff requires interactive mode", "error");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!ctx.model) {
|
|
51
|
+
ctx.ui.notify("No model selected", "error");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const goal = args.trim();
|
|
56
|
+
if (!goal) {
|
|
57
|
+
ctx.ui.notify("Usage: /handoff <goal for new thread>", "error");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Gather conversation context from current branch
|
|
62
|
+
const branch = ctx.sessionManager.getBranch();
|
|
63
|
+
const messages = branch
|
|
64
|
+
.filter((entry): entry is SessionEntry & { type: "message" } => entry.type === "message")
|
|
65
|
+
.map(entry => entry.message);
|
|
66
|
+
|
|
67
|
+
if (messages.length === 0) {
|
|
68
|
+
ctx.ui.notify("No conversation to hand off", "error");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Convert to LLM format and serialize
|
|
73
|
+
const llmMessages = convertToLlm(messages);
|
|
74
|
+
const conversationText = serializeConversation(llmMessages);
|
|
75
|
+
const currentSessionFile = ctx.sessionManager.getSessionFile();
|
|
76
|
+
|
|
77
|
+
// Generate the handoff prompt with loader UI
|
|
78
|
+
const result = await ctx.ui.custom<string | null>((tui, theme, done) => {
|
|
79
|
+
const loader = new BorderedLoader(tui, theme, `Generating handoff prompt...`);
|
|
80
|
+
loader.onAbort = () => done(null);
|
|
81
|
+
|
|
82
|
+
const doGenerate = async () => {
|
|
83
|
+
const apiKey = await ctx.modelRegistry.getApiKey(ctx.model!);
|
|
84
|
+
|
|
85
|
+
const userMessage: Message = {
|
|
86
|
+
role: "user",
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: `## Conversation History\n\n${conversationText}\n\n## User's Goal for New Thread\n\n${goal}`,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const response = await complete(
|
|
97
|
+
ctx.model!,
|
|
98
|
+
{ systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
|
|
99
|
+
{ apiKey, signal: loader.signal },
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (response.stopReason === "aborted") {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return response.content
|
|
107
|
+
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
108
|
+
.map(c => c.text)
|
|
109
|
+
.join("\n");
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
doGenerate()
|
|
113
|
+
.then(done)
|
|
114
|
+
.catch(err => {
|
|
115
|
+
console.error("Handoff generation failed:", err);
|
|
116
|
+
done(null);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return loader;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (result === null) {
|
|
123
|
+
ctx.ui.notify("Cancelled", "info");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Let user edit the generated prompt
|
|
128
|
+
const editedPrompt = await ctx.ui.editor("Edit handoff prompt (ctrl+enter to submit, esc to cancel)", result);
|
|
129
|
+
|
|
130
|
+
if (editedPrompt === undefined) {
|
|
131
|
+
ctx.ui.notify("Cancelled", "info");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Create new session with parent tracking
|
|
136
|
+
const newSessionResult = await ctx.newSession({
|
|
137
|
+
parentSession: currentSessionFile,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (newSessionResult.cancelled) {
|
|
141
|
+
ctx.ui.notify("New session cancelled", "info");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Set the edited prompt in the main editor for submission
|
|
146
|
+
ctx.ui.setEditorText(editedPrompt);
|
|
147
|
+
ctx.ui.notify("Handoff ready. Submit when ready.", "info");
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Gate Hook
|
|
3
|
+
*
|
|
4
|
+
* Prompts for confirmation before running potentially dangerous bash commands.
|
|
5
|
+
* Patterns checked: rm -rf, sudo, chmod/chown 777
|
|
6
|
+
*/
|
|
7
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
export default function (pi: HookAPI) {
|
|
10
|
+
const dangerousPatterns = [/\brm\s+(-rf?|--recursive)/i, /\bsudo\b/i, /\b(chmod|chown)\b.*777/i];
|
|
11
|
+
|
|
12
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
13
|
+
if (event.toolName !== "bash") return undefined;
|
|
14
|
+
|
|
15
|
+
const command = event.input.command as string;
|
|
16
|
+
const isDangerous = dangerousPatterns.some(p => p.test(command));
|
|
17
|
+
|
|
18
|
+
if (isDangerous) {
|
|
19
|
+
if (!ctx.hasUI) {
|
|
20
|
+
// In non-interactive mode, block by default
|
|
21
|
+
return { block: true, reason: "Dangerous command blocked (no UI for confirmation)" };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const choice = await ctx.ui.select(`⚠️ Dangerous command:\n\n ${command}\n\nAllow?`, ["Yes", "No"]);
|
|
25
|
+
|
|
26
|
+
if (choice !== "Yes") {
|
|
27
|
+
return { block: true, reason: "Blocked by user" };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return undefined;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protected Paths Hook
|
|
3
|
+
*
|
|
4
|
+
* Blocks write and edit operations to protected paths.
|
|
5
|
+
* Useful for preventing accidental modifications to sensitive files.
|
|
6
|
+
*/
|
|
7
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
export default function (pi: HookAPI) {
|
|
10
|
+
const protectedPaths = [".env", ".git/", "node_modules/"];
|
|
11
|
+
|
|
12
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
13
|
+
if (event.toolName !== "write" && event.toolName !== "edit") {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const path = event.input.path as string;
|
|
18
|
+
const isProtected = protectedPaths.some(p => path.includes(p));
|
|
19
|
+
|
|
20
|
+
if (isProtected) {
|
|
21
|
+
if (ctx.hasUI) {
|
|
22
|
+
ctx.ui.notify(`Blocked write to protected path: ${path}`, "warning");
|
|
23
|
+
}
|
|
24
|
+
return { block: true, reason: `Path "${path}" is protected` };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return undefined;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Q&A extraction hook - extracts questions from assistant responses
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the "prompt generator" pattern:
|
|
5
|
+
* 1. /qna command gets the last assistant message
|
|
6
|
+
* 2. Shows a spinner while extracting (hides editor)
|
|
7
|
+
* 3. Loads the result into the editor for user to fill in answers
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
11
|
+
import { BorderedLoader } from "@nghyane/arcane";
|
|
12
|
+
import { complete, type UserMessage } from "@nghyane/arcane-ai";
|
|
13
|
+
|
|
14
|
+
const SYSTEM_PROMPT = `You are a question extractor. Given text from a conversation, extract any questions that need answering and format them for the user to fill in.
|
|
15
|
+
|
|
16
|
+
Output format:
|
|
17
|
+
- List each question on its own line, prefixed with "Q: "
|
|
18
|
+
- After each question, add a blank line for the answer prefixed with "A: "
|
|
19
|
+
- If no questions are found, output "No questions found in the last message."
|
|
20
|
+
|
|
21
|
+
Example output:
|
|
22
|
+
Q: What is your preferred database?
|
|
23
|
+
A:
|
|
24
|
+
|
|
25
|
+
Q: Should we use TypeScript or JavaScript?
|
|
26
|
+
A:
|
|
27
|
+
|
|
28
|
+
Keep questions in the order they appeared. Be concise.`;
|
|
29
|
+
|
|
30
|
+
export default function (pi: HookAPI) {
|
|
31
|
+
pi.registerCommand("qna", {
|
|
32
|
+
description: "Extract questions from last assistant message into editor",
|
|
33
|
+
handler: async (_args, ctx) => {
|
|
34
|
+
if (!ctx.hasUI) {
|
|
35
|
+
ctx.ui.notify("qna requires interactive mode", "error");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!ctx.model) {
|
|
40
|
+
ctx.ui.notify("No model selected", "error");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Find the last assistant message on the current branch
|
|
45
|
+
const branch = ctx.sessionManager.getBranch();
|
|
46
|
+
let lastAssistantText: string | undefined;
|
|
47
|
+
|
|
48
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
49
|
+
const entry = branch[i];
|
|
50
|
+
if (entry.type === "message") {
|
|
51
|
+
const msg = entry.message;
|
|
52
|
+
if ("role" in msg && msg.role === "assistant") {
|
|
53
|
+
if (msg.stopReason !== "stop") {
|
|
54
|
+
ctx.ui.notify(`Last assistant message incomplete (${msg.stopReason})`, "error");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const textParts = msg.content
|
|
58
|
+
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
59
|
+
.map(c => c.text);
|
|
60
|
+
if (textParts.length > 0) {
|
|
61
|
+
lastAssistantText = textParts.join("\n");
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!lastAssistantText) {
|
|
69
|
+
ctx.ui.notify("No assistant messages found", "error");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Run extraction with loader UI
|
|
74
|
+
const result = await ctx.ui.custom<string | null>((tui, theme, done) => {
|
|
75
|
+
const loader = new BorderedLoader(tui, theme, `Extracting questions using ${ctx.model!.id}…`);
|
|
76
|
+
loader.onAbort = () => done(null);
|
|
77
|
+
|
|
78
|
+
// Do the work
|
|
79
|
+
const doExtract = async () => {
|
|
80
|
+
const apiKey = await ctx.modelRegistry.getApiKey(ctx.model!);
|
|
81
|
+
const userMessage: UserMessage = {
|
|
82
|
+
role: "user",
|
|
83
|
+
content: [{ type: "text", text: lastAssistantText! }],
|
|
84
|
+
timestamp: Date.now(),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const response = await complete(
|
|
88
|
+
ctx.model!,
|
|
89
|
+
{ systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
|
|
90
|
+
{ apiKey, signal: loader.signal },
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (response.stopReason === "aborted") {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return response.content
|
|
98
|
+
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
99
|
+
.map(c => c.text)
|
|
100
|
+
.join("\n");
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
doExtract()
|
|
104
|
+
.then(done)
|
|
105
|
+
.catch(() => done(null));
|
|
106
|
+
|
|
107
|
+
return loader;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (result === null) {
|
|
111
|
+
ctx.ui.notify("Cancelled", "info");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
ctx.ui.setEditorText(result);
|
|
116
|
+
ctx.ui.notify("Questions loaded. Edit and submit when ready.", "info");
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Line Hook
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates ctx.ui.setStatus() for displaying persistent status text in the footer.
|
|
5
|
+
* Shows turn progress with themed colors.
|
|
6
|
+
*/
|
|
7
|
+
import type { HookAPI } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
export default function (pi: HookAPI) {
|
|
10
|
+
let turnCount = 0;
|
|
11
|
+
|
|
12
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
13
|
+
const theme = ctx.ui.theme;
|
|
14
|
+
ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
pi.on("turn_start", async (_event, ctx) => {
|
|
18
|
+
turnCount++;
|
|
19
|
+
const theme = ctx.ui.theme;
|
|
20
|
+
const spinner = theme.fg("accent", "●");
|
|
21
|
+
const text = theme.fg("dim", ` Turn ${turnCount}…`);
|
|
22
|
+
ctx.ui.setStatus("status-demo", spinner + text);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
pi.on("turn_end", async (_event, ctx) => {
|
|
26
|
+
const theme = ctx.ui.theme;
|
|
27
|
+
const check = theme.fg("success", "✓");
|
|
28
|
+
const text = theme.fg("dim", ` Turn ${turnCount} complete`);
|
|
29
|
+
ctx.ui.setStatus("status-demo", check + text);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
pi.on("session_switch", async (event, ctx) => {
|
|
33
|
+
if (event.reason === "new") {
|
|
34
|
+
turnCount = 0;
|
|
35
|
+
const theme = ctx.ui.theme;
|
|
36
|
+
ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SDK Usage
|
|
3
|
+
*
|
|
4
|
+
* Uses all defaults: discovers skills, hooks, tools, context files
|
|
5
|
+
* from cwd and ~/.arcane/agent. Model chosen from settings or first available.
|
|
6
|
+
*/
|
|
7
|
+
import { createAgentSession } from "@nghyane/arcane";
|
|
8
|
+
|
|
9
|
+
const { session } = await createAgentSession();
|
|
10
|
+
|
|
11
|
+
session.subscribe(event => {
|
|
12
|
+
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
|
13
|
+
process.stdout.write(event.assistantMessageEvent.delta);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
await session.prompt("What files are in the current directory?");
|
|
18
|
+
session.state.messages.forEach(msg => {
|
|
19
|
+
console.log(msg);
|
|
20
|
+
});
|
|
21
|
+
console.log();
|