@neurocode-ai/core 1.18.8
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/bin/neurocode +199 -0
- package/bunfig.toml +2 -0
- package/drizzle.config.ts +10 -0
- package/package.json +131 -0
- package/schema.json +2071 -0
- package/script/fix-node-pty.ts +28 -0
- package/script/migration.ts +196 -0
- package/src/account/sql.ts +39 -0
- package/src/account.ts +101 -0
- package/src/agent.ts +111 -0
- package/src/aisdk.ts +235 -0
- package/src/background-job.ts +365 -0
- package/src/catalog.ts +301 -0
- package/src/command.ts +64 -0
- package/src/config/agent.ts +25 -0
- package/src/config/attachments.ts +15 -0
- package/src/config/command.ts +12 -0
- package/src/config/compaction.ts +15 -0
- package/src/config/experimental.ts +18 -0
- package/src/config/formatter.ts +12 -0
- package/src/config/lsp.ts +18 -0
- package/src/config/markdown.ts +36 -0
- package/src/config/mcp.ts +48 -0
- package/src/config/plugin/agent.ts +179 -0
- package/src/config/plugin/command.ts +83 -0
- package/src/config/plugin/external.ts +91 -0
- package/src/config/plugin/provider.ts +113 -0
- package/src/config/plugin/reference.ts +70 -0
- package/src/config/plugin/skill.ts +50 -0
- package/src/config/plugin.ts +13 -0
- package/src/config/provider.ts +71 -0
- package/src/config/reference.ts +22 -0
- package/src/config/tool-output.ts +9 -0
- package/src/config/watcher.ts +7 -0
- package/src/config.ts +227 -0
- package/src/control-plane/move-session.ts +148 -0
- package/src/control-plane/workspace.sql.ts +20 -0
- package/src/credential/sql.ts +14 -0
- package/src/credential.ts +138 -0
- package/src/cross-spawn-spawner.ts +507 -0
- package/src/data-migration.sql.ts +6 -0
- package/src/database/database.ts +57 -0
- package/src/database/migration/20260127222353_familiar_lady_ursula.ts +107 -0
- package/src/database/migration/20260211171708_add_project_commands.ts +11 -0
- package/src/database/migration/20260213144116_wakeful_the_professor.ts +23 -0
- package/src/database/migration/20260225215848_workspace.ts +19 -0
- package/src/database/migration/20260227213759_add_session_workspace_id.ts +12 -0
- package/src/database/migration/20260228203230_blue_harpoon.ts +30 -0
- package/src/database/migration/20260303231226_add_workspace_fields.ts +15 -0
- package/src/database/migration/20260309230000_move_org_to_state.ts +15 -0
- package/src/database/migration/20260312043431_session_message_cursor.ts +16 -0
- package/src/database/migration/20260323234822_events.ts +26 -0
- package/src/database/migration/20260410174513_workspace-name.ts +29 -0
- package/src/database/migration/20260413175956_chief_energizer.ts +24 -0
- package/src/database/migration/20260423070820_add_icon_url_override.ts +14 -0
- package/src/database/migration/20260427172553_slow_nightmare.ts +30 -0
- package/src/database/migration/20260428004200_add_session_path.ts +11 -0
- package/src/database/migration/20260501142318_next_venus.ts +12 -0
- package/src/database/migration/20260504145000_add_sync_owner.ts +11 -0
- package/src/database/migration/20260507164347_add_workspace_time.ts +11 -0
- package/src/database/migration/20260510033149_session_usage.ts +56 -0
- package/src/database/migration/20260511000411_data_migration_state.ts +16 -0
- package/src/database/migration/20260511173437_session-metadata.ts +16 -0
- package/src/database/migration/20260601010001_normalize_storage_paths.ts +22 -0
- package/src/database/migration/20260601202201_amazing_prowler.ts +11 -0
- package/src/database/migration/20260602002951_lowly_union_jack.ts +24 -0
- package/src/database/migration/20260602182828_add_project_directories.ts +20 -0
- package/src/database/migration/20260603001617_session_message_projection_indexes.ts +19 -0
- package/src/database/migration/20260603040000_session_message_projection_order.ts +19 -0
- package/src/database/migration/20260603141458_session_input_inbox.ts +25 -0
- package/src/database/migration/20260603160727_jittery_ezekiel_stane.ts +20 -0
- package/src/database/migration/20260604172448_event_sourced_session_input.ts +47 -0
- package/src/database/migration/20260605003541_add_session_context_snapshot.ts +21 -0
- package/src/database/migration/20260605042240_add_context_epoch_agent.ts +11 -0
- package/src/database/migration/20260611035744_credential.ts +25 -0
- package/src/database/migration/20260611192811_lush_chimera.ts +25 -0
- package/src/database/migration/20260612174303_project_dir_strategy.ts +29 -0
- package/src/database/migration/20260622142730_simplify_session_context_epoch.ts +13 -0
- package/src/database/migration/20260622170816_reset_v2_session_state.ts +17 -0
- package/src/database/migration/20260622202450_simplify_session_input.ts +17 -0
- package/src/database/migration.gen.ts +44 -0
- package/src/database/migration.ts +81 -0
- package/src/database/path.ts +91 -0
- package/src/database/schema.gen.ts +274 -0
- package/src/database/schema.sql.ts +10 -0
- package/src/database/sqlite.bun.ts +183 -0
- package/src/database/sqlite.node.ts +178 -0
- package/src/database/sqlite.ts +8 -0
- package/src/effect/app-node-builder.ts +23 -0
- package/src/effect/app-node-platform.ts +18 -0
- package/src/effect/app-node.ts +14 -0
- package/src/effect/dfdf +1 -0
- package/src/effect/keyed-mutex.ts +45 -0
- package/src/effect/layer-node.ts +333 -0
- package/src/effect/memo-map.ts +3 -0
- package/src/effect/runtime.ts +21 -0
- package/src/effect/service-use.ts +43 -0
- package/src/event/sql.ts +25 -0
- package/src/event.ts +638 -0
- package/src/file-mutation.ts +207 -0
- package/src/file.ts +6 -0
- package/src/filesystem/fff.bun.ts +140 -0
- package/src/filesystem/fff.node.ts +138 -0
- package/src/filesystem/ignore.ts +67 -0
- package/src/filesystem/protected.ts +53 -0
- package/src/filesystem/search.ts +239 -0
- package/src/filesystem/watcher.ts +140 -0
- package/src/filesystem.ts +118 -0
- package/src/flag/flag.ts +78 -0
- package/src/fs-util.ts +274 -0
- package/src/git.ts +987 -0
- package/src/github-copilot/README.md +5 -0
- package/src/github-copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
- package/src/github-copilot/chat/get-response-metadata.ts +15 -0
- package/src/github-copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
- package/src/github-copilot/chat/openai-compatible-api-types.ts +64 -0
- package/src/github-copilot/chat/openai-compatible-chat-language-model.ts +815 -0
- package/src/github-copilot/chat/openai-compatible-chat-options.ts +28 -0
- package/src/github-copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
- package/src/github-copilot/chat/openai-compatible-prepare-tools.ts +83 -0
- package/src/github-copilot/copilot-provider.ts +100 -0
- package/src/github-copilot/openai-compatible-error.ts +27 -0
- package/src/github-copilot/responses/convert-to-openai-responses-input.ts +335 -0
- package/src/github-copilot/responses/map-openai-responses-finish-reason.ts +22 -0
- package/src/github-copilot/responses/openai-config.ts +18 -0
- package/src/github-copilot/responses/openai-error.ts +22 -0
- package/src/github-copilot/responses/openai-responses-api-types.ts +214 -0
- package/src/github-copilot/responses/openai-responses-language-model.ts +1770 -0
- package/src/github-copilot/responses/openai-responses-prepare-tools.ts +173 -0
- package/src/github-copilot/responses/openai-responses-settings.ts +1 -0
- package/src/github-copilot/responses/tool/code-interpreter.ts +87 -0
- package/src/github-copilot/responses/tool/file-search.ts +127 -0
- package/src/github-copilot/responses/tool/image-generation.ts +114 -0
- package/src/github-copilot/responses/tool/local-shell.ts +64 -0
- package/src/github-copilot/responses/tool/web-search-preview.ts +103 -0
- package/src/github-copilot/responses/tool/web-search.ts +102 -0
- package/src/global.ts +87 -0
- package/src/id/id.ts +47 -0
- package/src/image/photon.ts +94 -0
- package/src/image.ts +81 -0
- package/src/installation/version.ts +8 -0
- package/src/instruction-context.ts +101 -0
- package/src/integration/connection.ts +12 -0
- package/src/integration.ts +520 -0
- package/src/location-mutation.ts +162 -0
- package/src/location-service-map.ts +18 -0
- package/src/location-services.ts +115 -0
- package/src/location.ts +39 -0
- package/src/markdown.d.ts +4 -0
- package/src/model.ts +41 -0
- package/src/models-dev.ts +260 -0
- package/src/npm-config.ts +40 -0
- package/src/npm.ts +269 -0
- package/src/oauth/page.ts +276 -0
- package/src/observability/logging.ts +71 -0
- package/src/observability/otlp.ts +79 -0
- package/src/observability/shared.ts +1 -0
- package/src/observability.ts +24 -0
- package/src/patch.ts +197 -0
- package/src/permission/saved.ts +79 -0
- package/src/permission/sql.ts +20 -0
- package/src/permission.ts +310 -0
- package/src/plugin/agent.ts +206 -0
- package/src/plugin/command/initialize.txt +65 -0
- package/src/plugin/command/review.txt +100 -0
- package/src/plugin/command.ts +25 -0
- package/src/plugin/host.ts +219 -0
- package/src/plugin/internal.ts +153 -0
- package/src/plugin/layer-map.example.ts +94 -0
- package/src/plugin/models-dev.ts +183 -0
- package/src/plugin/promise.ts +93 -0
- package/src/plugin/provider/alibaba.ts +15 -0
- package/src/plugin/provider/amazon-bedrock.ts +126 -0
- package/src/plugin/provider/anthropic.ts +27 -0
- package/src/plugin/provider/azure.ts +82 -0
- package/src/plugin/provider/cerebras.ts +26 -0
- package/src/plugin/provider/cloudflare-ai-gateway.ts +81 -0
- package/src/plugin/provider/cloudflare-workers-ai.ts +81 -0
- package/src/plugin/provider/cohere.ts +15 -0
- package/src/plugin/provider/deepinfra.ts +15 -0
- package/src/plugin/provider/dynamic.ts +31 -0
- package/src/plugin/provider/gateway.ts +15 -0
- package/src/plugin/provider/github-copilot.ts +52 -0
- package/src/plugin/provider/gitlab.ts +65 -0
- package/src/plugin/provider/google-vertex.ts +173 -0
- package/src/plugin/provider/google.ts +15 -0
- package/src/plugin/provider/groq.ts +15 -0
- package/src/plugin/provider/kilo.ts +21 -0
- package/src/plugin/provider/llmgateway.ts +26 -0
- package/src/plugin/provider/mistral.ts +15 -0
- package/src/plugin/provider/nvidia.ts +22 -0
- package/src/plugin/provider/openai-compatible.ts +17 -0
- package/src/plugin/provider/openai.ts +292 -0
- package/src/plugin/provider/opencode.ts +311 -0
- package/src/plugin/provider/openrouter.ts +36 -0
- package/src/plugin/provider/perplexity.ts +15 -0
- package/src/plugin/provider/sap-ai-core.ts +46 -0
- package/src/plugin/provider/snowflake-cortex.ts +89 -0
- package/src/plugin/provider/togetherai.ts +15 -0
- package/src/plugin/provider/venice.ts +15 -0
- package/src/plugin/provider/vercel.ts +27 -0
- package/src/plugin/provider/xai.ts +22 -0
- package/src/plugin/provider/zenmux.ts +21 -0
- package/src/plugin/provider.ts +71 -0
- package/src/plugin/skill/customize-neurocode.md +452 -0
- package/src/plugin/skill.ts +31 -0
- package/src/plugin/variant.ts +39 -0
- package/src/plugin.ts +167 -0
- package/src/policy.ts +49 -0
- package/src/process.ts +261 -0
- package/src/project/copy-strategies.ts +35 -0
- package/src/project/copy.ts +292 -0
- package/src/project/directories.ts +158 -0
- package/src/project/schema.ts +16 -0
- package/src/project/sql.ts +35 -0
- package/src/project.ts +136 -0
- package/src/provider.ts +25 -0
- package/src/pty/protocol.ts +37 -0
- package/src/pty/pty.bun.ts +26 -0
- package/src/pty/pty.node.ts +29 -0
- package/src/pty/pty.ts +25 -0
- package/src/pty/schema.ts +1 -0
- package/src/pty/ticket.ts +56 -0
- package/src/pty.ts +318 -0
- package/src/public-event-manifest.ts +7 -0
- package/src/question.ts +153 -0
- package/src/reference/guidance.ts +69 -0
- package/src/reference.ts +125 -0
- package/src/repository-cache.ts +259 -0
- package/src/repository.ts +214 -0
- package/src/ripgrep/binary.ts +132 -0
- package/src/ripgrep.ts +281 -0
- package/src/schema.ts +79 -0
- package/src/session/compaction.ts +241 -0
- package/src/session/context-epoch.ts +174 -0
- package/src/session/error.ts +24 -0
- package/src/session/event.ts +2 -0
- package/src/session/execution/local.ts +46 -0
- package/src/session/execution.ts +34 -0
- package/src/session/history.ts +101 -0
- package/src/session/info.ts +50 -0
- package/src/session/input.ts +288 -0
- package/src/session/message-updater.ts +397 -0
- package/src/session/message.ts +2 -0
- package/src/session/projector.ts +458 -0
- package/src/session/prompt.ts +1 -0
- package/src/session/revert.ts +121 -0
- package/src/session/run-coordinator.ts +104 -0
- package/src/session/runner/index.ts +28 -0
- package/src/session/runner/llm.ts +432 -0
- package/src/session/runner/max-steps.ts +16 -0
- package/src/session/runner/model.ts +218 -0
- package/src/session/runner/publish-llm-event.ts +423 -0
- package/src/session/runner/to-llm-message.ts +171 -0
- package/src/session/schema.ts +9 -0
- package/src/session/sql.ts +176 -0
- package/src/session/store.ts +63 -0
- package/src/session/todo.ts +78 -0
- package/src/session.ts +486 -0
- package/src/share/sql.ts +13 -0
- package/src/shell.ts +226 -0
- package/src/skill/discovery.ts +213 -0
- package/src/skill/guidance.ts +76 -0
- package/src/skill.ts +132 -0
- package/src/snapshot.ts +266 -0
- package/src/state.ts +128 -0
- package/src/system-context/builtins.ts +50 -0
- package/src/system-context/index.ts +320 -0
- package/src/system-context/registry.ts +49 -0
- package/src/tool/AGENTS.md +59 -0
- package/src/tool/application-tools.ts +57 -0
- package/src/tool/apply-patch.ts +219 -0
- package/src/tool/bash.ts +207 -0
- package/src/tool/builtins.ts +48 -0
- package/src/tool/edit.ts +223 -0
- package/src/tool/glob.ts +105 -0
- package/src/tool/grep.ts +137 -0
- package/src/tool/http-body.ts +30 -0
- package/src/tool/question.ts +94 -0
- package/src/tool/read-filesystem.ts +366 -0
- package/src/tool/read.ts +117 -0
- package/src/tool/registry.ts +147 -0
- package/src/tool/skill.ts +109 -0
- package/src/tool/todowrite.ts +62 -0
- package/src/tool/tool.ts +162 -0
- package/src/tool/tools.ts +13 -0
- package/src/tool/webfetch.ts +218 -0
- package/src/tool/websearch.ts +260 -0
- package/src/tool/write.ts +101 -0
- package/src/tool-output-store.ts +211 -0
- package/src/util/array.ts +10 -0
- package/src/util/binary.ts +41 -0
- package/src/util/effect-flock.ts +284 -0
- package/src/util/encode.ts +51 -0
- package/src/util/error.ts +70 -0
- package/src/util/flock.ts +358 -0
- package/src/util/glob.ts +34 -0
- package/src/util/hash.ts +11 -0
- package/src/util/identifier.ts +1 -0
- package/src/util/iife.ts +3 -0
- package/src/util/lazy.ts +11 -0
- package/src/util/module.ts +10 -0
- package/src/util/path.ts +37 -0
- package/src/util/retry.ts +42 -0
- package/src/util/slug.ts +74 -0
- package/src/util/token.ts +5 -0
- package/src/util/which.ts +14 -0
- package/src/util/wildcard.ts +14 -0
- package/src/v1/config/agent.ts +89 -0
- package/src/v1/config/attachment.ts +25 -0
- package/src/v1/config/command.ts +13 -0
- package/src/v1/config/config.ts +192 -0
- package/src/v1/config/console-state.ts +16 -0
- package/src/v1/config/error.ts +39 -0
- package/src/v1/config/formatter.ts +13 -0
- package/src/v1/config/layout.ts +6 -0
- package/src/v1/config/lsp.ts +80 -0
- package/src/v1/config/mcp.ts +63 -0
- package/src/v1/config/migrate.ts +254 -0
- package/src/v1/config/permission.ts +50 -0
- package/src/v1/config/plugin.ts +9 -0
- package/src/v1/config/provider-options.ts +227 -0
- package/src/v1/config/provider.ts +121 -0
- package/src/v1/config/server.ts +19 -0
- package/src/v1/config/skills.ts +13 -0
- package/src/v1/permission.ts +33 -0
- package/src/v1/session.ts +68 -0
- package/src/v2-schema.ts +3 -0
- package/src/workspace.ts +6 -0
- package/sst-env.d.ts +10 -0
- package/test/agent.test.ts +131 -0
- package/test/application-tools.test.ts +287 -0
- package/test/background-job.test.ts +106 -0
- package/test/catalog.test.ts +353 -0
- package/test/command.test.ts +56 -0
- package/test/config/agent.test.ts +349 -0
- package/test/config/command.test.ts +83 -0
- package/test/config/config.test.ts +798 -0
- package/test/config/fixtures/plugin/directory-plugin.ts +13 -0
- package/test/config/plugin.test.ts +248 -0
- package/test/config/provider-options.test.ts +224 -0
- package/test/config/provider.test.ts +269 -0
- package/test/config/skill.test.ts +80 -0
- package/test/credential.test.ts +36 -0
- package/test/database-migration.test.ts +644 -0
- package/test/effect/cross-spawn-spawner.test.ts +426 -0
- package/test/effect/keyed-mutex.test.ts +73 -0
- package/test/effect/layer-node/layer-node-types.test.ts +143 -0
- package/test/effect/layer-node/layer-node.test.ts +261 -0
- package/test/effect/layer-node/node-build.test.ts +125 -0
- package/test/effect/observability.test.ts +109 -0
- package/test/event.test.ts +1124 -0
- package/test/file-mutation.test.ts +368 -0
- package/test/filesystem/filesystem.test.ts +387 -0
- package/test/filesystem/ignore.test.ts +10 -0
- package/test/filesystem/search.test.ts +44 -0
- package/test/filesystem/watcher.test.ts +266 -0
- package/test/fixture/effect-flock-worker.ts +60 -0
- package/test/fixture/flock-worker.ts +72 -0
- package/test/fixture/git.ts +49 -0
- package/test/fixture/location.ts +26 -0
- package/test/fixture/tmpdir.ts +25 -0
- package/test/fixtures/recordings/session-runner/openai-chat-streams-text.json +27 -0
- package/test/git.test.ts +164 -0
- package/test/github-copilot/convert-to-copilot-messages.test.ts +523 -0
- package/test/github-copilot/copilot-chat-model.test.ts +592 -0
- package/test/github-copilot/openai-responses-language-model.test.ts +206 -0
- package/test/global.test.ts +16 -0
- package/test/instruction-context.test.ts +323 -0
- package/test/integration.test.ts +349 -0
- package/test/legacy-event-schema.test.ts +16 -0
- package/test/lib/effect.ts +53 -0
- package/test/lib/tool.ts +20 -0
- package/test/location-filesystem.test.ts +69 -0
- package/test/location-layer.test.ts +226 -0
- package/test/location-mutation.test.ts +178 -0
- package/test/location.test.ts +42 -0
- package/test/model.test.ts +23 -0
- package/test/models.test.ts +290 -0
- package/test/move-session.test.ts +235 -0
- package/test/npm-config.test.ts +51 -0
- package/test/npm.test.ts +84 -0
- package/test/oauth-page.test.ts +15 -0
- package/test/patch.test.ts +68 -0
- package/test/permission.test.ts +315 -0
- package/test/plugin/command.test.ts +47 -0
- package/test/plugin/fixture.ts +52 -0
- package/test/plugin/fixtures/config-effect-plugin.ts +15 -0
- package/test/plugin/fixtures/config-promise-plugin.ts +13 -0
- package/test/plugin/fixtures/invalid-plugin.ts +1 -0
- package/test/plugin/fixtures/models-dev.json +14 -0
- package/test/plugin/fixtures/provider-factory.ts +9 -0
- package/test/plugin/host.ts +303 -0
- package/test/plugin/models-dev.test.ts +170 -0
- package/test/plugin/promise.test.ts +67 -0
- package/test/plugin/provider-alibaba.test.ts +92 -0
- package/test/plugin/provider-amazon-bedrock.test.ts +622 -0
- package/test/plugin/provider-anthropic.test.ts +94 -0
- package/test/plugin/provider-azure-cognitive-services.test.ts +199 -0
- package/test/plugin/provider-azure.test.ts +293 -0
- package/test/plugin/provider-cerebras.test.ts +136 -0
- package/test/plugin/provider-cloudflare-ai-gateway.test.ts +426 -0
- package/test/plugin/provider-cloudflare-workers-ai.test.ts +279 -0
- package/test/plugin/provider-cohere.test.ts +123 -0
- package/test/plugin/provider-deepinfra.test.ts +159 -0
- package/test/plugin/provider-dynamic.test.ts +184 -0
- package/test/plugin/provider-gateway.test.ts +115 -0
- package/test/plugin/provider-github-copilot.test.ts +278 -0
- package/test/plugin/provider-gitlab.test.ts +308 -0
- package/test/plugin/provider-google-vertex-anthropic.test.ts +264 -0
- package/test/plugin/provider-google-vertex.test.ts +387 -0
- package/test/plugin/provider-google.test.ts +80 -0
- package/test/plugin/provider-groq.test.ts +121 -0
- package/test/plugin/provider-kilo.test.ts +99 -0
- package/test/plugin/provider-llmgateway.test.ts +80 -0
- package/test/plugin/provider-mistral.test.ts +129 -0
- package/test/plugin/provider-nvidia.test.ts +97 -0
- package/test/plugin/provider-openai-compatible.test.ts +107 -0
- package/test/plugin/provider-openai.test.ts +176 -0
- package/test/plugin/provider-opencode.test.ts +423 -0
- package/test/plugin/provider-openrouter.test.ts +113 -0
- package/test/plugin/provider-perplexity.test.ts +122 -0
- package/test/plugin/provider-sap-ai-core.test.ts +159 -0
- package/test/plugin/provider-snowflake-cortex.test.ts +261 -0
- package/test/plugin/provider-togetherai.test.ts +129 -0
- package/test/plugin/provider-venice.test.ts +115 -0
- package/test/plugin/provider-vercel.test.ts +83 -0
- package/test/plugin/provider-xai.test.ts +125 -0
- package/test/plugin/provider-zenmux.test.ts +110 -0
- package/test/plugin/skill.test.ts +25 -0
- package/test/plugin/variant.test.ts +67 -0
- package/test/plugin.test.ts +71 -0
- package/test/policy.test.ts +85 -0
- package/test/preload.ts +5 -0
- package/test/process/process.test.ts +368 -0
- package/test/project-copy.test.ts +400 -0
- package/test/project-directories.test.ts +61 -0
- package/test/project.test.ts +221 -0
- package/test/provider-mistral.test.ts +282 -0
- package/test/provider-xai-responses.test.ts +32 -0
- package/test/pty/info-schema.test.ts +32 -0
- package/test/pty/protocol.test.ts +27 -0
- package/test/pty/pty-session.test.ts +240 -0
- package/test/pty/ticket.test.ts +62 -0
- package/test/question.test.ts +114 -0
- package/test/reference-guidance.test.ts +76 -0
- package/test/reference.test.ts +78 -0
- package/test/repository-cache.test.ts +153 -0
- package/test/repository.test.ts +71 -0
- package/test/ripgrep.test.ts +65 -0
- package/test/session-compaction.test.ts +27 -0
- package/test/session-create.test.ts +425 -0
- package/test/session-history.test.ts +165 -0
- package/test/session-projector.test.ts +533 -0
- package/test/session-prompt.test.ts +584 -0
- package/test/session-run-coordinator.test.ts +418 -0
- package/test/session-runner-message.test.ts +501 -0
- package/test/session-runner-model.test.ts +347 -0
- package/test/session-runner-recorded.test.ts +193 -0
- package/test/session-runner-tool-events.test.ts +136 -0
- package/test/session-runner-tool-registry.test.ts +452 -0
- package/test/session-runner.test.ts +3365 -0
- package/test/session-todo.test.ts +94 -0
- package/test/session-tool-progress.test.ts +158 -0
- package/test/shared-schema.test.ts +206 -0
- package/test/shell.test.ts +108 -0
- package/test/skill/guidance.test.ts +144 -0
- package/test/skill-discovery.test.ts +165 -0
- package/test/skill.test.ts +125 -0
- package/test/snapshot.test.ts +178 -0
- package/test/state.test.ts +115 -0
- package/test/system-context/builtins.test.ts +129 -0
- package/test/system-context/index.test.ts +307 -0
- package/test/system-context/registry.test.ts +114 -0
- package/test/tool-apply-patch.test.ts +436 -0
- package/test/tool-bash.test.ts +437 -0
- package/test/tool-edit.test.ts +434 -0
- package/test/tool-output-store.test.ts +247 -0
- package/test/tool-question.test.ts +162 -0
- package/test/tool-read-filesystem.test.ts +118 -0
- package/test/tool-read.test.ts +674 -0
- package/test/tool-skill.test.ts +149 -0
- package/test/tool-todowrite.test.ts +125 -0
- package/test/tool-webfetch.test.ts +281 -0
- package/test/tool-websearch.test.ts +316 -0
- package/test/tool-write.test.ts +305 -0
- package/test/util/effect-flock.test.ts +392 -0
- package/test/util/flock.test.ts +428 -0
- package/test/util/which.test.ts +100 -0
- package/tsconfig.json +7 -0
package/src/snapshot.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
export * as Snapshot from "./snapshot"
|
|
2
|
+
|
|
3
|
+
import { makeLocationNode } from "./effect/app-node"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import { Context, Effect, Layer, Schema } from "effect"
|
|
6
|
+
import { Config } from "./config"
|
|
7
|
+
import { File } from "./file"
|
|
8
|
+
import { FSUtil } from "./fs-util"
|
|
9
|
+
import { Git } from "./git"
|
|
10
|
+
import { Global } from "./global"
|
|
11
|
+
import { Location } from "./location"
|
|
12
|
+
import { AbsolutePath, RelativePath } from "./schema"
|
|
13
|
+
import { Hash } from "./util/hash"
|
|
14
|
+
|
|
15
|
+
export const ID = Schema.String.pipe(Schema.brand("Snapshot.ID"))
|
|
16
|
+
export type ID = typeof ID.Type
|
|
17
|
+
|
|
18
|
+
export class Error extends Schema.TaggedErrorClass<Error>()("Snapshot.Error", {
|
|
19
|
+
operation: Schema.Literals(["capture", "files", "diff", "preview", "restore"]),
|
|
20
|
+
message: Schema.String,
|
|
21
|
+
cause: Schema.optional(Schema.Defect()),
|
|
22
|
+
}) {}
|
|
23
|
+
|
|
24
|
+
export interface CompareInput {
|
|
25
|
+
readonly from: ID
|
|
26
|
+
readonly to: ID
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface DiffInput extends CompareInput {
|
|
30
|
+
readonly context?: number
|
|
31
|
+
readonly paths?: readonly RelativePath[]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface RestoreInput {
|
|
35
|
+
/** Paths are relative to the project root. */
|
|
36
|
+
readonly files: ReadonlyMap<RelativePath, ID>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PreviewInput extends RestoreInput {
|
|
40
|
+
readonly context?: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface Interface {
|
|
44
|
+
/**
|
|
45
|
+
* Capture the current Location-scoped filesystem state as a content-addressed
|
|
46
|
+
* tree. Returns `undefined` when snapshots are disabled, unsupported, or the
|
|
47
|
+
* best-effort capture fails.
|
|
48
|
+
*/
|
|
49
|
+
readonly capture: () => Effect.Effect<ID | undefined>
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* List project-relative paths changed between two captured trees without
|
|
53
|
+
* loading file contents or generating patches.
|
|
54
|
+
*/
|
|
55
|
+
readonly files: (input: CompareInput) => Effect.Effect<readonly RelativePath[], Error>
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Generate structured per-file diffs between two captured trees. `context`
|
|
59
|
+
* controls unchanged lines around each unified diff hunk.
|
|
60
|
+
*/
|
|
61
|
+
readonly diff: (input: DiffInput) => Effect.Effect<readonly File.Diff[], Error>
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Preview the filesystem result of a selective restore without modifying the
|
|
65
|
+
* worktree. Each project-relative path maps to the tree it would be restored
|
|
66
|
+
* from.
|
|
67
|
+
*/
|
|
68
|
+
readonly preview: (input: PreviewInput) => Effect.Effect<readonly File.Diff[], Error>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Restore selected project-relative paths from their associated trees. A path
|
|
72
|
+
* absent from its selected tree is removed; paths outside the map are untouched.
|
|
73
|
+
*/
|
|
74
|
+
readonly restore: (input: RestoreInput) => Effect.Effect<void, Error>
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Replace the snapshot index with a captured tree and check out all its entries.
|
|
78
|
+
* Files absent from the tree remain untouched. Prefer selective `restore` when
|
|
79
|
+
* only known paths should change.
|
|
80
|
+
*/
|
|
81
|
+
readonly checkout: (snapshot: ID) => Effect.Effect<void, Error>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class Service extends Context.Service<Service, Interface>()("@neurocode/v2/Snapshot") {}
|
|
85
|
+
|
|
86
|
+
const layer = Layer.effect(
|
|
87
|
+
Service,
|
|
88
|
+
Effect.gen(function* () {
|
|
89
|
+
const config = yield* Config.Service
|
|
90
|
+
const fs = yield* FSUtil.Service
|
|
91
|
+
const git = yield* Git.Service
|
|
92
|
+
const global = yield* Global.Service
|
|
93
|
+
const location = yield* Location.Service
|
|
94
|
+
const source = yield* git.repo.discover(location.project.directory)
|
|
95
|
+
const worktree = source
|
|
96
|
+
? AbsolutePath.make(yield* fs.realPath(source.worktree).pipe(Effect.orDie))
|
|
97
|
+
: location.project.directory
|
|
98
|
+
const gitDirectory = AbsolutePath.make(path.join(global.data, "snapshot", location.project.id, Hash.fast(worktree)))
|
|
99
|
+
|
|
100
|
+
const scope = Effect.fnUntraced(function* () {
|
|
101
|
+
const relative = path.relative(worktree, location.directory)
|
|
102
|
+
if (relative.startsWith("..") || path.isAbsolute(relative))
|
|
103
|
+
return yield* new Error({ operation: "capture", message: "Location is outside the project" })
|
|
104
|
+
return RelativePath.make(relative.replaceAll("\\", "/") || ".")
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const repository = Effect.fnUntraced(function* () {
|
|
108
|
+
if (!source) return yield* new Error({ operation: "capture", message: "Project is not a Git repository" })
|
|
109
|
+
if (yield* fs.existsSafe(path.join(gitDirectory, "HEAD")))
|
|
110
|
+
return new Git.Repository({
|
|
111
|
+
worktree,
|
|
112
|
+
gitDirectory,
|
|
113
|
+
commonDirectory: gitDirectory,
|
|
114
|
+
})
|
|
115
|
+
return yield* git.repo
|
|
116
|
+
.create({
|
|
117
|
+
worktree,
|
|
118
|
+
gitDirectory,
|
|
119
|
+
seed: source,
|
|
120
|
+
})
|
|
121
|
+
.pipe(Effect.mapError((cause) => failure("capture", cause)))
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const enabled = Effect.fnUntraced(function* () {
|
|
125
|
+
if (location.vcs?.type !== "git") return false
|
|
126
|
+
return Config.latest(yield* config.entries(), "snapshots") !== false
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const capture = Effect.fn("Snapshot.capture")(function* () {
|
|
130
|
+
if (!(yield* enabled())) return undefined
|
|
131
|
+
return yield* Effect.gen(function* () {
|
|
132
|
+
const repo = yield* repository()
|
|
133
|
+
return ID.make(
|
|
134
|
+
yield* git.tree.capture({
|
|
135
|
+
repository: repo,
|
|
136
|
+
scopes: [yield* scope()],
|
|
137
|
+
ignores: source,
|
|
138
|
+
maximumUntrackedFileBytes: 2 * 1024 * 1024,
|
|
139
|
+
}),
|
|
140
|
+
)
|
|
141
|
+
}).pipe(
|
|
142
|
+
Effect.catch((cause) => Effect.logWarning("failed to capture snapshot", { cause }).pipe(Effect.as(undefined))),
|
|
143
|
+
)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
const compare = Effect.fnUntraced(function* (operation: "files" | "diff", input: CompareInput) {
|
|
147
|
+
const repo = yield* repository().pipe(Effect.mapError((cause) => failure(operation, cause)))
|
|
148
|
+
return { repository: repo, from: Git.TreeID.make(input.from), to: Git.TreeID.make(input.to) }
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const files = Effect.fn("Snapshot.files")(function* (input: CompareInput) {
|
|
152
|
+
const comparison = yield* compare("files", input)
|
|
153
|
+
const files = yield* git.tree.files(comparison).pipe(Effect.mapError((cause) => failure("files", cause)))
|
|
154
|
+
if (!source) return files
|
|
155
|
+
const ignored = yield* git.index
|
|
156
|
+
.ignored({ repository: source, paths: files })
|
|
157
|
+
.pipe(Effect.mapError((cause) => failure("files", cause)))
|
|
158
|
+
return files.filter((file) => !ignored.has(file))
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const diff = Effect.fn("Snapshot.diff")(function* (input: DiffInput) {
|
|
162
|
+
const comparison = yield* compare("diff", input)
|
|
163
|
+
const files = yield* git.tree.files(comparison).pipe(Effect.mapError((cause) => failure("diff", cause)))
|
|
164
|
+
const ignored = source
|
|
165
|
+
? yield* git.index
|
|
166
|
+
.ignored({ repository: source, paths: files })
|
|
167
|
+
.pipe(Effect.mapError((cause) => failure("diff", cause)))
|
|
168
|
+
: new Set<RelativePath>()
|
|
169
|
+
return yield* git.tree
|
|
170
|
+
.diff({
|
|
171
|
+
...comparison,
|
|
172
|
+
context: input.context,
|
|
173
|
+
paths: (input.paths ?? files).filter((file) => !ignored.has(file)),
|
|
174
|
+
})
|
|
175
|
+
.pipe(Effect.mapError((cause) => failure("diff", cause)))
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const plan = Effect.fnUntraced(function* (operation: "preview" | "restore", input: RestoreInput) {
|
|
179
|
+
const files = new Map<RelativePath, Git.TreeID>()
|
|
180
|
+
for (const [file, snapshot] of input.files) {
|
|
181
|
+
const absolute = path.resolve(worktree, file)
|
|
182
|
+
if (!FSUtil.contains(worktree, absolute))
|
|
183
|
+
return yield* new Error({ operation, message: `Path escapes the project: ${file}` })
|
|
184
|
+
files.set(file, Git.TreeID.make(snapshot))
|
|
185
|
+
}
|
|
186
|
+
return files
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
const preview = Effect.fn("Snapshot.preview")(function* (input: PreviewInput) {
|
|
190
|
+
if (!(yield* enabled())) return yield* new Error({ operation: "preview", message: "Snapshots are disabled" })
|
|
191
|
+
const repo = yield* repository().pipe(Effect.mapError((cause) => failure("preview", cause)))
|
|
192
|
+
const files = yield* plan("preview", input)
|
|
193
|
+
const current = yield* git.tree
|
|
194
|
+
.capture({
|
|
195
|
+
repository: repo,
|
|
196
|
+
scopes: Array.from(files.keys()),
|
|
197
|
+
ignores: source,
|
|
198
|
+
maximumUntrackedFileBytes: 2 * 1024 * 1024,
|
|
199
|
+
})
|
|
200
|
+
.pipe(Effect.mapError((cause) => failure("preview", cause)))
|
|
201
|
+
return yield* git.tree
|
|
202
|
+
.preview({
|
|
203
|
+
repository: repo,
|
|
204
|
+
current,
|
|
205
|
+
files,
|
|
206
|
+
context: input.context,
|
|
207
|
+
})
|
|
208
|
+
.pipe(Effect.mapError((cause) => failure("preview", cause)))
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
const restore = Effect.fn("Snapshot.restore")(function* (input: RestoreInput) {
|
|
212
|
+
if (!(yield* enabled())) return yield* new Error({ operation: "restore", message: "Snapshots are disabled" })
|
|
213
|
+
const repo = yield* repository().pipe(Effect.mapError((cause) => failure("restore", cause)))
|
|
214
|
+
yield* git.tree
|
|
215
|
+
.restore({ repository: repo, files: yield* plan("restore", input) })
|
|
216
|
+
.pipe(Effect.mapError((cause) => failure("restore", cause)))
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const checkout = Effect.fn("Snapshot.checkout")(function* (snapshot: ID) {
|
|
220
|
+
const repo = yield* repository().pipe(Effect.mapError((cause) => failure("restore", cause)))
|
|
221
|
+
yield* git.tree
|
|
222
|
+
.checkout({ repository: repo, tree: Git.TreeID.make(snapshot) })
|
|
223
|
+
.pipe(Effect.mapError((cause) => failure("restore", cause)))
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
return Service.of({ capture, files, diff, preview, restore, checkout })
|
|
227
|
+
}),
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
export const locationLayer = layer.pipe(Layer.provideMerge(Config.locationLayer))
|
|
231
|
+
|
|
232
|
+
export const node = makeLocationNode({
|
|
233
|
+
service: Service,
|
|
234
|
+
layer,
|
|
235
|
+
deps: [Config.node, FSUtil.node, Git.node, Global.node, Location.node],
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
export const noopLayer = Layer.succeed(
|
|
239
|
+
Service,
|
|
240
|
+
Service.of({
|
|
241
|
+
capture: () => Effect.succeed(undefined),
|
|
242
|
+
files: () => Effect.succeed([]),
|
|
243
|
+
diff: () => Effect.succeed([]),
|
|
244
|
+
preview: () => Effect.succeed([]),
|
|
245
|
+
restore: () => Effect.void,
|
|
246
|
+
checkout: () => Effect.void,
|
|
247
|
+
}),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
function failure(operation: Error["operation"], cause: unknown) {
|
|
251
|
+
if (cause instanceof Error && cause.operation === operation) return cause
|
|
252
|
+
return new Error({
|
|
253
|
+
operation,
|
|
254
|
+
message: cause instanceof globalThis.Error ? cause.message : String(cause),
|
|
255
|
+
cause,
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Legacy persisted session diff shape. */
|
|
260
|
+
export type LegacyFileDiff = {
|
|
261
|
+
file?: string
|
|
262
|
+
patch?: string
|
|
263
|
+
additions: number
|
|
264
|
+
deletions: number
|
|
265
|
+
status?: "added" | "deleted" | "modified"
|
|
266
|
+
}
|
package/src/state.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export * as State from "./state"
|
|
2
|
+
|
|
3
|
+
import { Context, Effect, Scope, Semaphore } from "effect"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A replayable transform applied to a draft during reload.
|
|
7
|
+
*
|
|
8
|
+
* Domain drafts expose readable and writable state while preserving concise
|
|
9
|
+
* plugin/config code. Transforms may perform Effects before returning.
|
|
10
|
+
*/
|
|
11
|
+
type TransformCallback<DraftApi> = (draft: DraftApi) => Effect.Effect<void> | void
|
|
12
|
+
export type MakeDraft<State, DraftApi> = (state: State) => DraftApi
|
|
13
|
+
|
|
14
|
+
export interface Registration {
|
|
15
|
+
readonly dispose: Effect.Effect<void>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type Transform<DraftApi> = (
|
|
19
|
+
transform: TransformCallback<DraftApi>,
|
|
20
|
+
) => Effect.Effect<Registration, never, Scope.Scope>
|
|
21
|
+
|
|
22
|
+
export type Reload = () => Effect.Effect<void>
|
|
23
|
+
|
|
24
|
+
export interface Transformable<DraftApi> {
|
|
25
|
+
readonly transform: Transform<DraftApi>
|
|
26
|
+
readonly reload: Reload
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const CurrentBatch = Context.Reference<Set<Reload> | undefined>("@neurocode/State/CurrentBatch", {
|
|
30
|
+
defaultValue: () => undefined,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export function batch<A, E, R>(effect: Effect.Effect<A, E, R>) {
|
|
34
|
+
return Effect.gen(function* () {
|
|
35
|
+
const current = yield* CurrentBatch
|
|
36
|
+
if (current) return yield* effect
|
|
37
|
+
const reloads = new Set<Reload>()
|
|
38
|
+
const result = yield* effect.pipe(Effect.provideService(CurrentBatch, reloads))
|
|
39
|
+
yield* Effect.forEach(reloads, (reload) => reload(), { discard: true })
|
|
40
|
+
return result
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Options<State, DraftApi> {
|
|
45
|
+
/** Creates the base value for initial state and every scoped-transform reload. */
|
|
46
|
+
readonly initial: () => State
|
|
47
|
+
/** Wraps mutable state in a domain-specific draft API. */
|
|
48
|
+
readonly draft: MakeDraft<State, DraftApi>
|
|
49
|
+
/** Runs after all active transforms and before the rebuilt state becomes visible. */
|
|
50
|
+
readonly finalize?: (draft: DraftApi) => Effect.Effect<void>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface Interface<State, DraftApi> extends Transformable<DraftApi> {
|
|
54
|
+
readonly get: () => State
|
|
55
|
+
/**
|
|
56
|
+
* Registers and applies a scoped transform. Closing the owning Scope removes
|
|
57
|
+
* the transform and reloads the materialized state.
|
|
58
|
+
*/
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function create<State, DraftApi>(options: Options<State, DraftApi>): Interface<State, DraftApi> {
|
|
62
|
+
let state = options.initial()
|
|
63
|
+
let transforms: { run: TransformCallback<DraftApi> }[] = []
|
|
64
|
+
const semaphore = Semaphore.makeUnsafe(1)
|
|
65
|
+
|
|
66
|
+
const commit = Effect.fn("State.commit")(function* (next: State) {
|
|
67
|
+
const api = options.draft(next)
|
|
68
|
+
if (options.finalize) yield* options.finalize(api)
|
|
69
|
+
state = next
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const apply = (transform: TransformCallback<DraftApi>, draft: DraftApi) =>
|
|
73
|
+
Effect.suspend(() => {
|
|
74
|
+
const result = transform(draft)
|
|
75
|
+
return Effect.isEffect(result) ? Effect.asVoid(result).pipe(Effect.orDie) : Effect.void
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const materialize = Effect.fnUntraced(function* () {
|
|
79
|
+
const next = options.initial()
|
|
80
|
+
const api = options.draft(next)
|
|
81
|
+
for (const transform of transforms) yield* apply(transform.run, api).pipe(Effect.withSpan("State.reload.update"))
|
|
82
|
+
yield* commit(next)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const reload = () => semaphore.withPermit(materialize())
|
|
86
|
+
|
|
87
|
+
const result: Interface<State, DraftApi> = {
|
|
88
|
+
get: () => state,
|
|
89
|
+
transform: Effect.fn("State.transform")(function* (update) {
|
|
90
|
+
const scope = yield* Scope.Scope
|
|
91
|
+
return yield* Effect.uninterruptible(
|
|
92
|
+
Effect.gen(function* () {
|
|
93
|
+
const transform = { run: update }
|
|
94
|
+
let active = true
|
|
95
|
+
const dispose = Effect.uninterruptible(
|
|
96
|
+
semaphore.withPermit(
|
|
97
|
+
Effect.suspend(() => {
|
|
98
|
+
if (!active) return Effect.void
|
|
99
|
+
active = false
|
|
100
|
+
transforms = transforms.filter((item) => item !== transform)
|
|
101
|
+
return Effect.gen(function* () {
|
|
102
|
+
const batch = yield* CurrentBatch
|
|
103
|
+
if (batch) {
|
|
104
|
+
batch.add(reload)
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
yield* materialize()
|
|
108
|
+
})
|
|
109
|
+
}),
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
yield* semaphore.withPermit(
|
|
113
|
+
Effect.sync(() => {
|
|
114
|
+
transforms = [...transforms, transform]
|
|
115
|
+
}),
|
|
116
|
+
)
|
|
117
|
+
yield* Scope.addFinalizer(scope, dispose)
|
|
118
|
+
const batch = yield* CurrentBatch
|
|
119
|
+
if (batch) batch.add(reload)
|
|
120
|
+
else yield* reload()
|
|
121
|
+
return { dispose }
|
|
122
|
+
}),
|
|
123
|
+
)
|
|
124
|
+
}),
|
|
125
|
+
reload,
|
|
126
|
+
}
|
|
127
|
+
return result
|
|
128
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export * as SystemContextBuiltIns from "./builtins"
|
|
2
|
+
|
|
3
|
+
import { makeLocationNode } from "../effect/app-node"
|
|
4
|
+
import { DateTime, Effect, Layer, Schema } from "effect"
|
|
5
|
+
import { Location } from "../location"
|
|
6
|
+
import { SystemContext } from "./index"
|
|
7
|
+
import { InstructionContext } from "../instruction-context"
|
|
8
|
+
import { SystemContextRegistry } from "./registry"
|
|
9
|
+
import { FSUtil } from "../fs-util"
|
|
10
|
+
import { Global } from "../global"
|
|
11
|
+
|
|
12
|
+
const builtIns = Layer.effectDiscard(
|
|
13
|
+
Effect.gen(function* () {
|
|
14
|
+
const location = yield* Location.Service
|
|
15
|
+
const registry = yield* SystemContextRegistry.Service
|
|
16
|
+
const environment = [
|
|
17
|
+
"<env>",
|
|
18
|
+
` Working directory: ${location.directory}`,
|
|
19
|
+
` Workspace root folder: ${location.project.directory}`,
|
|
20
|
+
` Is directory a git repo: ${location.vcs?.type === "git" ? "yes" : "no"}`,
|
|
21
|
+
` Platform: ${process.platform}`,
|
|
22
|
+
"</env>",
|
|
23
|
+
].join("\n")
|
|
24
|
+
const context = SystemContext.combine([
|
|
25
|
+
SystemContext.make({
|
|
26
|
+
key: SystemContext.Key.make("core/environment"),
|
|
27
|
+
codec: Schema.toCodecJson(Schema.String),
|
|
28
|
+
load: Effect.succeed(environment),
|
|
29
|
+
baseline: (environment) =>
|
|
30
|
+
["Here is some useful information about the environment you are running in:", environment].join("\n"),
|
|
31
|
+
update: (_previous, environment) => ["The environment you are running in is now:", environment].join("\n"),
|
|
32
|
+
}),
|
|
33
|
+
SystemContext.make({
|
|
34
|
+
key: SystemContext.Key.make("core/date"),
|
|
35
|
+
codec: Schema.toCodecJson(Schema.String),
|
|
36
|
+
load: DateTime.nowAsDate.pipe(Effect.map((date) => date.toDateString())),
|
|
37
|
+
baseline: (date) => `Today's date: ${date}`,
|
|
38
|
+
update: (_previous, date) => `Today's date is now: ${date}`,
|
|
39
|
+
}),
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
yield* registry.register({ key: SystemContext.Key.make("core/builtins"), load: Effect.succeed(context) })
|
|
43
|
+
}),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export const node = makeLocationNode({
|
|
47
|
+
name: "system-context-builtins",
|
|
48
|
+
layer: builtIns,
|
|
49
|
+
deps: [Location.node, SystemContextRegistry.node, InstructionContext.node, FSUtil.node, Global.node],
|
|
50
|
+
})
|