bonecode 1.0.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/ARCHITECTURE.md +183 -0
- package/README.md +71 -0
- package/bin/bonecode +62 -0
- package/bone/migrations/rag_vectors.sql +258 -0
- package/bone/output/agent/.dockerignore +7 -0
- package/bone/output/agent/.env.example +36 -0
- package/bone/output/agent/.github/workflows/ci.yaml +58 -0
- package/bone/output/agent/AgentDomain.bone.map +350 -0
- package/bone/output/agent/AgentDomain.postman_collection.json +958 -0
- package/bone/output/agent/Dockerfile +22 -0
- package/bone/output/agent/README.md +47 -0
- package/bone/output/agent/admin/index.html +740 -0
- package/bone/output/agent/docker-compose.yaml +22 -0
- package/bone/output/agent/k8s/deployment.yaml +75 -0
- package/bone/output/agent/migrations/agent.sql +36 -0
- package/bone/output/agent/migrations/agent_instance.sql +36 -0
- package/bone/output/agent/migrations/audit_log.sql +18 -0
- package/bone/output/agent/migrations/build_step.sql +34 -0
- package/bone/output/agent/migrations/event_outbox.sql +31 -0
- package/bone/output/agent/migrations/plan.sql +30 -0
- package/bone/output/agent/migrations/task.sql +30 -0
- package/bone/output/agent/migrations/tool_call.sql +33 -0
- package/bone/output/agent/openapi.yaml +1116 -0
- package/bone/output/agent/package.json +36 -0
- package/bone/output/agent/schema.graphql +233 -0
- package/bone/output/agent/sdk/client.ts +231 -0
- package/bone/output/agent/src/algorithms.ts +2 -0
- package/bone/output/agent/src/audit.ts +44 -0
- package/bone/output/agent/src/auth.ts +57 -0
- package/bone/output/agent/src/cron.ts +12 -0
- package/bone/output/agent/src/db.ts +32 -0
- package/bone/output/agent/src/debug.ts +66 -0
- package/bone/output/agent/src/events.ts +243 -0
- package/bone/output/agent/src/extensions.ts +54 -0
- package/bone/output/agent/src/failure_rules.ts +323 -0
- package/bone/output/agent/src/flows.ts +168 -0
- package/bone/output/agent/src/health.ts +43 -0
- package/bone/output/agent/src/index.ts +100 -0
- package/bone/output/agent/src/logger.ts +66 -0
- package/bone/output/agent/src/metrics.ts +75 -0
- package/bone/output/agent/src/migrate.ts +352 -0
- package/bone/output/agent/src/migration_diff.ts +108 -0
- package/bone/output/agent/src/notify.ts +125 -0
- package/bone/output/agent/src/routes/agent_instance.ts +234 -0
- package/bone/output/agent/src/routes/build_step.ts +105 -0
- package/bone/output/agent/src/routes/plan.ts +91 -0
- package/bone/output/agent/src/routes/task.ts +105 -0
- package/bone/output/agent/src/routes/tool_call.ts +166 -0
- package/bone/output/agent/src/schemas.ts +384 -0
- package/bone/output/agent/src/state_machines/agent_instance.ts +24 -0
- package/bone/output/agent/src/state_machines/build_step.ts +22 -0
- package/bone/output/agent/src/state_machines/plan.ts +22 -0
- package/bone/output/agent/src/state_machines/task.ts +22 -0
- package/bone/output/agent/src/state_machines/tool_call.ts +22 -0
- package/bone/output/agent/src/tests.ts +362 -0
- package/bone/output/agent/src/websocket.ts +201 -0
- package/bone/output/agent/tsconfig.json +25 -0
- package/bone/output/rag/.dockerignore +7 -0
- package/bone/output/rag/.env.example +36 -0
- package/bone/output/rag/.github/workflows/ci.yaml +58 -0
- package/bone/output/rag/Dockerfile +22 -0
- package/bone/output/rag/RAGDomain.bone.map +287 -0
- package/bone/output/rag/RAGDomain.postman_collection.json +923 -0
- package/bone/output/rag/README.md +47 -0
- package/bone/output/rag/admin/index.html +818 -0
- package/bone/output/rag/docker-compose.yaml +22 -0
- package/bone/output/rag/k8s/deployment.yaml +75 -0
- package/bone/output/rag/migrations/audit_log.sql +18 -0
- package/bone/output/rag/migrations/code_chunk.sql +34 -0
- package/bone/output/rag/migrations/code_file.sql +33 -0
- package/bone/output/rag/migrations/event_outbox.sql +31 -0
- package/bone/output/rag/migrations/indexing_job.sql +33 -0
- package/bone/output/rag/migrations/knowledge_base.sql +35 -0
- package/bone/output/rag/migrations/memory_entry.sql +34 -0
- package/bone/output/rag/openapi.yaml +1097 -0
- package/bone/output/rag/package.json +36 -0
- package/bone/output/rag/schema.graphql +245 -0
- package/bone/output/rag/sdk/client.ts +234 -0
- package/bone/output/rag/src/algorithms.ts +2 -0
- package/bone/output/rag/src/audit.ts +37 -0
- package/bone/output/rag/src/auth.ts +57 -0
- package/bone/output/rag/src/cron.ts +12 -0
- package/bone/output/rag/src/db.ts +32 -0
- package/bone/output/rag/src/debug.ts +66 -0
- package/bone/output/rag/src/events.ts +243 -0
- package/bone/output/rag/src/extensions.ts +350 -0
- package/bone/output/rag/src/failure_rules.ts +315 -0
- package/bone/output/rag/src/flows.ts +239 -0
- package/bone/output/rag/src/health.ts +43 -0
- package/bone/output/rag/src/index.ts +95 -0
- package/bone/output/rag/src/logger.ts +66 -0
- package/bone/output/rag/src/metrics.ts +75 -0
- package/bone/output/rag/src/migrate.ts +364 -0
- package/bone/output/rag/src/migration_diff.ts +108 -0
- package/bone/output/rag/src/notify.ts +99 -0
- package/bone/output/rag/src/routes/code_chunk.ts +75 -0
- package/bone/output/rag/src/routes/code_file.ts +101 -0
- package/bone/output/rag/src/routes/indexing_job.ts +87 -0
- package/bone/output/rag/src/routes/knowledge_base.ts +230 -0
- package/bone/output/rag/src/routes/memory_entry.ts +87 -0
- package/bone/output/rag/src/schemas.ts +394 -0
- package/bone/output/rag/src/state_machines/code_file.ts +23 -0
- package/bone/output/rag/src/state_machines/indexing_job.ts +22 -0
- package/bone/output/rag/src/state_machines/knowledge_base.ts +23 -0
- package/bone/output/rag/src/state_machines/memory_entry.ts +20 -0
- package/bone/output/rag/src/tests.ts +340 -0
- package/bone/output/rag/tsconfig.json +25 -0
- package/bone/output/session/.dockerignore +7 -0
- package/bone/output/session/.env.example +36 -0
- package/bone/output/session/.github/workflows/ci.yaml +58 -0
- package/bone/output/session/Dockerfile +22 -0
- package/bone/output/session/README.md +47 -0
- package/bone/output/session/SessionDomain.bone.map +350 -0
- package/bone/output/session/SessionDomain.postman_collection.json +958 -0
- package/bone/output/session/admin/index.html +667 -0
- package/bone/output/session/docker-compose.yaml +22 -0
- package/bone/output/session/k8s/deployment.yaml +75 -0
- package/bone/output/session/migrations/audit_log.sql +18 -0
- package/bone/output/session/migrations/event_outbox.sql +31 -0
- package/bone/output/session/migrations/message.sql +31 -0
- package/bone/output/session/migrations/part.sql +28 -0
- package/bone/output/session/migrations/permission.sql +28 -0
- package/bone/output/session/migrations/project.sql +28 -0
- package/bone/output/session/migrations/session.sql +38 -0
- package/bone/output/session/openapi.yaml +1101 -0
- package/bone/output/session/package.json +36 -0
- package/bone/output/session/schema.graphql +222 -0
- package/bone/output/session/sdk/client.ts +225 -0
- package/bone/output/session/src/algorithms.ts +2 -0
- package/bone/output/session/src/audit.ts +44 -0
- package/bone/output/session/src/auth.ts +57 -0
- package/bone/output/session/src/cron.ts +12 -0
- package/bone/output/session/src/db.ts +32 -0
- package/bone/output/session/src/debug.ts +66 -0
- package/bone/output/session/src/events.ts +270 -0
- package/bone/output/session/src/extensions.ts +215 -0
- package/bone/output/session/src/failure_rules.ts +284 -0
- package/bone/output/session/src/flows.ts +168 -0
- package/bone/output/session/src/health.ts +43 -0
- package/bone/output/session/src/index.ts +100 -0
- package/bone/output/session/src/logger.ts +66 -0
- package/bone/output/session/src/metrics.ts +75 -0
- package/bone/output/session/src/migrate.ts +332 -0
- package/bone/output/session/src/migration_diff.ts +108 -0
- package/bone/output/session/src/notify.ts +112 -0
- package/bone/output/session/src/routes/message.ts +93 -0
- package/bone/output/session/src/routes/part.ts +79 -0
- package/bone/output/session/src/routes/permission.ts +79 -0
- package/bone/output/session/src/routes/project.ts +79 -0
- package/bone/output/session/src/routes/session.ts +294 -0
- package/bone/output/session/src/schemas.ts +357 -0
- package/bone/output/session/src/state_machines/session.ts +23 -0
- package/bone/output/session/src/tests.ts +326 -0
- package/bone/output/session/src/websocket.ts +201 -0
- package/bone/output/session/tsconfig.json +25 -0
- package/bone/output/workspace/.dockerignore +7 -0
- package/bone/output/workspace/.env.example +36 -0
- package/bone/output/workspace/.github/workflows/ci.yaml +58 -0
- package/bone/output/workspace/Dockerfile +22 -0
- package/bone/output/workspace/README.md +45 -0
- package/bone/output/workspace/WorkspaceDomain.bone.map +189 -0
- package/bone/output/workspace/WorkspaceDomain.postman_collection.json +621 -0
- package/bone/output/workspace/admin/index.html +485 -0
- package/bone/output/workspace/docker-compose.yaml +22 -0
- package/bone/output/workspace/k8s/deployment.yaml +75 -0
- package/bone/output/workspace/migrations/audit_log.sql +18 -0
- package/bone/output/workspace/migrations/codebase.sql +34 -0
- package/bone/output/workspace/migrations/event_outbox.sql +31 -0
- package/bone/output/workspace/migrations/snapshot.sql +32 -0
- package/bone/output/workspace/migrations/workspace.sql +33 -0
- package/bone/output/workspace/openapi.yaml +721 -0
- package/bone/output/workspace/package.json +36 -0
- package/bone/output/workspace/schema.graphql +153 -0
- package/bone/output/workspace/sdk/client.ts +155 -0
- package/bone/output/workspace/src/algorithms.ts +2 -0
- package/bone/output/workspace/src/audit.ts +37 -0
- package/bone/output/workspace/src/auth.ts +57 -0
- package/bone/output/workspace/src/cron.ts +12 -0
- package/bone/output/workspace/src/db.ts +32 -0
- package/bone/output/workspace/src/debug.ts +66 -0
- package/bone/output/workspace/src/events.ts +243 -0
- package/bone/output/workspace/src/extensions.ts +44 -0
- package/bone/output/workspace/src/failure_rules.ts +153 -0
- package/bone/output/workspace/src/health.ts +43 -0
- package/bone/output/workspace/src/index.ts +89 -0
- package/bone/output/workspace/src/logger.ts +66 -0
- package/bone/output/workspace/src/metrics.ts +75 -0
- package/bone/output/workspace/src/migrate.ts +220 -0
- package/bone/output/workspace/src/migration_diff.ts +108 -0
- package/bone/output/workspace/src/notify.ts +73 -0
- package/bone/output/workspace/src/routes/codebase.ts +87 -0
- package/bone/output/workspace/src/routes/snapshot.ts +127 -0
- package/bone/output/workspace/src/routes/workspace.ts +190 -0
- package/bone/output/workspace/src/schemas.ts +231 -0
- package/bone/output/workspace/src/state_machines/codebase.ts +21 -0
- package/bone/output/workspace/src/state_machines/snapshot.ts +20 -0
- package/bone/output/workspace/src/state_machines/workspace.ts +21 -0
- package/bone/output/workspace/src/tests.ts +249 -0
- package/bone/output/workspace/tsconfig.json +25 -0
- package/compat/opencode_adapter.ts +410 -0
- package/package.json +69 -0
- package/scripts/check_benchmark_session.js +34 -0
- package/scripts/check_finish_event.js +24 -0
- package/scripts/check_parts.js +15 -0
- package/scripts/compile.js +79 -0
- package/scripts/copy_opencode.ps1 +53 -0
- package/scripts/create_functions.sql +129 -0
- package/scripts/migrate.js +85 -0
- package/scripts/migrate_from_opencode.ts +218 -0
- package/scripts/test_agent_loop.js +101 -0
- package/scripts/test_api.ps1 +116 -0
- package/scripts/test_context_builder.js +136 -0
- package/scripts/test_context_builder.ts +97 -0
- package/scripts/test_rag.js +189 -0
- package/scripts/test_stream_events.js +36 -0
- package/scripts/test_websocket_and_saga.js +216 -0
- package/src/cli.ts +475 -0
- package/src/config.ts +162 -0
- package/src/context_builder.ts +598 -0
- package/src/engine/account/account.sql.ts +39 -0
- package/src/engine/account/account.ts +456 -0
- package/src/engine/account/repo.ts +166 -0
- package/src/engine/account/schema.ts +99 -0
- package/src/engine/account/url.ts +8 -0
- package/src/engine/acp/README.md +174 -0
- package/src/engine/acp/agent.ts +1968 -0
- package/src/engine/acp/runtime.ts +22 -0
- package/src/engine/acp/session.ts +122 -0
- package/src/engine/acp/types.ts +24 -0
- package/src/engine/agent/agent.ts +463 -0
- package/src/engine/agent/generate.txt +75 -0
- package/src/engine/agent/prompt/compaction.txt +9 -0
- package/src/engine/agent/prompt/explore.txt +18 -0
- package/src/engine/agent/prompt/scout.txt +36 -0
- package/src/engine/agent/prompt/summary.txt +11 -0
- package/src/engine/agent/prompt/title.txt +44 -0
- package/src/engine/agent/subagent-permissions.ts +34 -0
- package/src/engine/auth/index.ts +96 -0
- package/src/engine/background/background/job.ts +200 -0
- package/src/engine/background/job.ts +200 -0
- package/src/engine/bus/bus-event.ts +45 -0
- package/src/engine/bus/global.ts +22 -0
- package/src/engine/bus/index.ts +203 -0
- package/src/engine/command/command/index.ts +181 -0
- package/src/engine/command/command/template/initialize.txt +66 -0
- package/src/engine/command/command/template/review.txt +101 -0
- package/src/engine/command/index.ts +181 -0
- package/src/engine/command/template/initialize.txt +66 -0
- package/src/engine/command/template/review.txt +101 -0
- package/src/engine/config/agent.ts +172 -0
- package/src/engine/config/attachment.ts +25 -0
- package/src/engine/config/command.ts +62 -0
- package/src/engine/config/config.ts +833 -0
- package/src/engine/config/console-state.ts +14 -0
- package/src/engine/config/entry-name.ts +16 -0
- package/src/engine/config/error.ts +23 -0
- package/src/engine/config/formatter.ts +13 -0
- package/src/engine/config/layout.ts +6 -0
- package/src/engine/config/lsp.ts +43 -0
- package/src/engine/config/managed.ts +71 -0
- package/src/engine/config/markdown.ts +96 -0
- package/src/engine/config/mcp.ts +56 -0
- package/src/engine/config/model-id.ts +5 -0
- package/src/engine/config/parse.ts +79 -0
- package/src/engine/config/paths.ts +45 -0
- package/src/engine/config/permission.ts +58 -0
- package/src/engine/config/plugin.ts +84 -0
- package/src/engine/config/provider.ts +111 -0
- package/src/engine/config/reference.ts +23 -0
- package/src/engine/config/server.ts +19 -0
- package/src/engine/config/skills.ts +14 -0
- package/src/engine/config/variable.ts +90 -0
- package/src/engine/control-plane/adapters/index.ts +41 -0
- package/src/engine/control-plane/adapters/worktree.ts +96 -0
- package/src/engine/control-plane/dev/README.md +19 -0
- package/src/engine/control-plane/dev/debug-workspace-plugin.ts +73 -0
- package/src/engine/control-plane/schema.ts +14 -0
- package/src/engine/control-plane/types.ts +59 -0
- package/src/engine/control-plane/util.ts +39 -0
- package/src/engine/control-plane/workspace-adapter-runtime.ts +51 -0
- package/src/engine/control-plane/workspace-context.ts +26 -0
- package/src/engine/control-plane/workspace.sql.ts +20 -0
- package/src/engine/control-plane/workspace.ts +1072 -0
- package/src/engine/data-migration.ts +161 -0
- package/src/engine/effect/app-runtime.ts +143 -0
- package/src/engine/effect/bootstrap-runtime.ts +29 -0
- package/src/engine/effect/bridge.ts +84 -0
- package/src/engine/effect/config-service.ts +67 -0
- package/src/engine/effect/instance-ref.ts +11 -0
- package/src/engine/effect/instance-registry.ts +12 -0
- package/src/engine/effect/instance-state.ts +72 -0
- package/src/engine/effect/promise.ts +17 -0
- package/src/engine/effect/run-service.ts +47 -0
- package/src/engine/effect/runner.ts +217 -0
- package/src/engine/effect/runtime-flags.ts +74 -0
- package/src/engine/effect/service-use.ts +38 -0
- package/src/engine/env/index.ts +37 -0
- package/src/engine/event-v2-bridge.ts +89 -0
- package/src/engine/file/file/ignore.ts +81 -0
- package/src/engine/file/file/index.ts +651 -0
- package/src/engine/file/file/protected.ts +59 -0
- package/src/engine/file/file/ripgrep.ts +481 -0
- package/src/engine/file/file/watcher.ts +167 -0
- package/src/engine/file/ignore.ts +81 -0
- package/src/engine/file/index.ts +651 -0
- package/src/engine/file/protected.ts +59 -0
- package/src/engine/file/ripgrep.ts +481 -0
- package/src/engine/file/watcher.ts +167 -0
- package/src/engine/format/format/formatter.ts +404 -0
- package/src/engine/format/format/index.ts +209 -0
- package/src/engine/format/formatter.ts +404 -0
- package/src/engine/format/index.ts +209 -0
- package/src/engine/git/git/index.ts +347 -0
- package/src/engine/git/index.ts +347 -0
- package/src/engine/id/id.ts +80 -0
- package/src/engine/ide/index.ts +70 -0
- package/src/engine/image/image/image.ts +176 -0
- package/src/engine/image/image.ts +176 -0
- package/src/engine/index.ts +251 -0
- package/src/engine/installation/index.ts +327 -0
- package/src/engine/lsp/client.ts +707 -0
- package/src/engine/lsp/diagnostic.ts +29 -0
- package/src/engine/lsp/language.ts +121 -0
- package/src/engine/lsp/launch.ts +21 -0
- package/src/engine/lsp/lsp/client.ts +707 -0
- package/src/engine/lsp/lsp/diagnostic.ts +29 -0
- package/src/engine/lsp/lsp/language.ts +121 -0
- package/src/engine/lsp/lsp/launch.ts +21 -0
- package/src/engine/lsp/lsp/lsp.ts +507 -0
- package/src/engine/lsp/lsp/server.ts +2064 -0
- package/src/engine/lsp/lsp.ts +507 -0
- package/src/engine/lsp/server.ts +2064 -0
- package/src/engine/mcp/auth.ts +146 -0
- package/src/engine/mcp/index.ts +958 -0
- package/src/engine/mcp/mcp/auth.ts +146 -0
- package/src/engine/mcp/mcp/index.ts +958 -0
- package/src/engine/mcp/mcp/oauth-callback.ts +232 -0
- package/src/engine/mcp/mcp/oauth-provider.ts +214 -0
- package/src/engine/mcp/oauth-callback.ts +232 -0
- package/src/engine/mcp/oauth-provider.ts +214 -0
- package/src/engine/node.ts +6 -0
- package/src/engine/patch/index.ts +689 -0
- package/src/engine/patch/patch/index.ts +689 -0
- package/src/engine/permission/arity.ts +163 -0
- package/src/engine/permission/evaluate.ts +15 -0
- package/src/engine/permission/index.ts +306 -0
- package/src/engine/permission/permission/arity.ts +163 -0
- package/src/engine/permission/permission/evaluate.ts +15 -0
- package/src/engine/permission/permission/index.ts +306 -0
- package/src/engine/permission/permission/schema.ts +13 -0
- package/src/engine/permission/schema.ts +13 -0
- package/src/engine/plugin/azure.ts +26 -0
- package/src/engine/plugin/cloudflare.ts +76 -0
- package/src/engine/plugin/codex.ts +622 -0
- package/src/engine/plugin/digitalocean.ts +411 -0
- package/src/engine/plugin/github-copilot/copilot.ts +394 -0
- package/src/engine/plugin/github-copilot/models.ts +196 -0
- package/src/engine/plugin/index.ts +295 -0
- package/src/engine/plugin/install.ts +439 -0
- package/src/engine/plugin/loader.ts +216 -0
- package/src/engine/plugin/meta.ts +188 -0
- package/src/engine/plugin/shared.ts +323 -0
- package/src/engine/project/bootstrap-service.ts +9 -0
- package/src/engine/project/bootstrap.ts +75 -0
- package/src/engine/project/instance-context.ts +24 -0
- package/src/engine/project/instance-layer.ts +11 -0
- package/src/engine/project/instance-runtime.ts +16 -0
- package/src/engine/project/instance-store.ts +193 -0
- package/src/engine/project/project.sql.ts +17 -0
- package/src/engine/project/project.ts +537 -0
- package/src/engine/project/schema.ts +13 -0
- package/src/engine/project/vcs.ts +405 -0
- package/src/engine/provider/auth.ts +225 -0
- package/src/engine/provider/error.ts +204 -0
- package/src/engine/provider/model-status.ts +8 -0
- package/src/engine/provider/provider.ts +1843 -0
- package/src/engine/provider/schema.ts +30 -0
- package/src/engine/provider/sdk/copilot/AGENTS.md +1 -0
- package/src/engine/provider/transform.ts +1376 -0
- package/src/engine/pty/index.ts +365 -0
- package/src/engine/pty/input.ts +24 -0
- package/src/engine/pty/pty/index.ts +365 -0
- package/src/engine/pty/pty/input.ts +24 -0
- package/src/engine/pty/pty/pty.bun.ts +26 -0
- package/src/engine/pty/pty/pty.node.ts +27 -0
- package/src/engine/pty/pty/pty.ts +25 -0
- package/src/engine/pty/pty/schema.ts +14 -0
- package/src/engine/pty/pty/ticket.ts +68 -0
- package/src/engine/pty/pty.bun.ts +26 -0
- package/src/engine/pty/pty.node.ts +27 -0
- package/src/engine/pty/pty.ts +25 -0
- package/src/engine/pty/schema.ts +14 -0
- package/src/engine/pty/ticket.ts +68 -0
- package/src/engine/question/index.ts +213 -0
- package/src/engine/question/question/index.ts +213 -0
- package/src/engine/question/question/schema.ts +10 -0
- package/src/engine/question/schema.ts +10 -0
- package/src/engine/reference/reference/reference.ts +241 -0
- package/src/engine/reference/reference/repository-cache.ts +147 -0
- package/src/engine/reference/reference.ts +241 -0
- package/src/engine/reference/repository-cache.ts +147 -0
- package/src/engine/session/compaction.ts +651 -0
- package/src/engine/session/compaction_logic.ts +120 -0
- package/src/engine/session/instruction.ts +238 -0
- package/src/engine/session/instruction_loader.ts +54 -0
- package/src/engine/session/llm.ts +459 -0
- package/src/engine/session/message-error.ts +14 -0
- package/src/engine/session/message-v2.ts +1202 -0
- package/src/engine/session/message.ts +146 -0
- package/src/engine/session/overflow.ts +32 -0
- package/src/engine/session/overflow_check.ts +46 -0
- package/src/engine/session/processor.ts +823 -0
- package/src/engine/session/prompt/anthropic.txt +105 -0
- package/src/engine/session/prompt/beast.txt +147 -0
- package/src/engine/session/prompt/build-switch.txt +5 -0
- package/src/engine/session/prompt/codex.txt +79 -0
- package/src/engine/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/engine/session/prompt/default.txt +105 -0
- package/src/engine/session/prompt/gemini.txt +155 -0
- package/src/engine/session/prompt/gpt.txt +107 -0
- package/src/engine/session/prompt/kimi.txt +95 -0
- package/src/engine/session/prompt/max-steps.txt +16 -0
- package/src/engine/session/prompt/plan-reminder-anthropic.txt +67 -0
- package/src/engine/session/prompt/plan.txt +26 -0
- package/src/engine/session/prompt/trinity.txt +97 -0
- package/src/engine/session/prompt.ts +671 -0
- package/src/engine/session/provider_transform.ts +187 -0
- package/src/engine/session/retry.ts +200 -0
- package/src/engine/session/retry_logic.ts +65 -0
- package/src/engine/session/revert.ts +162 -0
- package/src/engine/session/run-state.ts +153 -0
- package/src/engine/session/schema.ts +26 -0
- package/src/engine/session/session.sql.ts +137 -0
- package/src/engine/session/session.ts +1011 -0
- package/src/engine/session/status.ts +94 -0
- package/src/engine/session/summary.ts +164 -0
- package/src/engine/session/system.ts +84 -0
- package/src/engine/session/system_prompt.ts +65 -0
- package/src/engine/session/todo.ts +81 -0
- package/src/engine/session/tool_registry.ts +162 -0
- package/src/engine/share/session.ts +61 -0
- package/src/engine/share/share-next.ts +376 -0
- package/src/engine/share/share.sql.ts +13 -0
- package/src/engine/shell/shell/shell.ts +215 -0
- package/src/engine/shell/shell.ts +215 -0
- package/src/engine/skill/discovery.ts +116 -0
- package/src/engine/skill/index.ts +336 -0
- package/src/engine/skill/prompt/customize-opencode.md +377 -0
- package/src/engine/skill/skill/discovery.ts +116 -0
- package/src/engine/skill/skill/index.ts +336 -0
- package/src/engine/skill/skill/prompt/customize-opencode.md +377 -0
- package/src/engine/snapshot/index.ts +762 -0
- package/src/engine/snapshot/snapshot/index.ts +762 -0
- package/src/engine/sync/README.md +179 -0
- package/src/engine/sync/event.sql.ts +17 -0
- package/src/engine/sync/index.ts +410 -0
- package/src/engine/sync/schema.ts +11 -0
- package/src/engine/temporary.ts +33 -0
- package/src/engine/tool/apply_patch.ts +313 -0
- package/src/engine/tool/apply_patch.txt +33 -0
- package/src/engine/tool/edit.ts +711 -0
- package/src/engine/tool/edit.txt +10 -0
- package/src/engine/tool/external-directory.ts +49 -0
- package/src/engine/tool/glob.ts +103 -0
- package/src/engine/tool/glob.txt +6 -0
- package/src/engine/tool/grep.ts +156 -0
- package/src/engine/tool/grep.txt +8 -0
- package/src/engine/tool/invalid.ts +21 -0
- package/src/engine/tool/json-schema.ts +164 -0
- package/src/engine/tool/lsp.ts +113 -0
- package/src/engine/tool/lsp.txt +24 -0
- package/src/engine/tool/mcp-websearch.ts +96 -0
- package/src/engine/tool/plan-enter.txt +14 -0
- package/src/engine/tool/plan-exit.txt +13 -0
- package/src/engine/tool/plan.ts +78 -0
- package/src/engine/tool/question.ts +44 -0
- package/src/engine/tool/question.txt +10 -0
- package/src/engine/tool/read.ts +337 -0
- package/src/engine/tool/read.txt +14 -0
- package/src/engine/tool/registry.ts +472 -0
- package/src/engine/tool/repo_clone.ts +80 -0
- package/src/engine/tool/repo_clone.txt +5 -0
- package/src/engine/tool/repo_overview.ts +279 -0
- package/src/engine/tool/repo_overview.txt +4 -0
- package/src/engine/tool/schema.ts +14 -0
- package/src/engine/tool/shell/id.ts +19 -0
- package/src/engine/tool/shell/prompt.ts +295 -0
- package/src/engine/tool/shell/shell.txt +77 -0
- package/src/engine/tool/shell.ts +647 -0
- package/src/engine/tool/skill.ts +75 -0
- package/src/engine/tool/skill.txt +5 -0
- package/src/engine/tool/task.ts +337 -0
- package/src/engine/tool/task.txt +58 -0
- package/src/engine/tool/task_status.ts +179 -0
- package/src/engine/tool/task_status.txt +13 -0
- package/src/engine/tool/todo.ts +57 -0
- package/src/engine/tool/todowrite.txt +167 -0
- package/src/engine/tool/tool/apply_patch.ts +313 -0
- package/src/engine/tool/tool/apply_patch.txt +33 -0
- package/src/engine/tool/tool/edit.ts +711 -0
- package/src/engine/tool/tool/edit.txt +10 -0
- package/src/engine/tool/tool/external-directory.ts +49 -0
- package/src/engine/tool/tool/glob.ts +103 -0
- package/src/engine/tool/tool/glob.txt +6 -0
- package/src/engine/tool/tool/grep.ts +156 -0
- package/src/engine/tool/tool/grep.txt +8 -0
- package/src/engine/tool/tool/invalid.ts +21 -0
- package/src/engine/tool/tool/json-schema.ts +164 -0
- package/src/engine/tool/tool/lsp.ts +113 -0
- package/src/engine/tool/tool/lsp.txt +24 -0
- package/src/engine/tool/tool/mcp-websearch.ts +96 -0
- package/src/engine/tool/tool/plan-enter.txt +14 -0
- package/src/engine/tool/tool/plan-exit.txt +13 -0
- package/src/engine/tool/tool/plan.ts +78 -0
- package/src/engine/tool/tool/question.ts +44 -0
- package/src/engine/tool/tool/question.txt +10 -0
- package/src/engine/tool/tool/read.ts +337 -0
- package/src/engine/tool/tool/read.txt +14 -0
- package/src/engine/tool/tool/registry.ts +472 -0
- package/src/engine/tool/tool/repo_clone.ts +80 -0
- package/src/engine/tool/tool/repo_clone.txt +5 -0
- package/src/engine/tool/tool/repo_overview.ts +279 -0
- package/src/engine/tool/tool/repo_overview.txt +4 -0
- package/src/engine/tool/tool/schema.ts +14 -0
- package/src/engine/tool/tool/shell/id.ts +19 -0
- package/src/engine/tool/tool/shell/prompt.ts +295 -0
- package/src/engine/tool/tool/shell/shell.txt +77 -0
- package/src/engine/tool/tool/shell.ts +647 -0
- package/src/engine/tool/tool/skill.ts +75 -0
- package/src/engine/tool/tool/skill.txt +5 -0
- package/src/engine/tool/tool/task.ts +337 -0
- package/src/engine/tool/tool/task.txt +58 -0
- package/src/engine/tool/tool/task_status.ts +179 -0
- package/src/engine/tool/tool/task_status.txt +13 -0
- package/src/engine/tool/tool/todo.ts +57 -0
- package/src/engine/tool/tool/todowrite.txt +167 -0
- package/src/engine/tool/tool/tool.ts +164 -0
- package/src/engine/tool/tool/truncate.ts +160 -0
- package/src/engine/tool/tool/truncation-dir.ts +4 -0
- package/src/engine/tool/tool/webfetch.ts +192 -0
- package/src/engine/tool/tool/webfetch.txt +13 -0
- package/src/engine/tool/tool/websearch.ts +143 -0
- package/src/engine/tool/tool/websearch.txt +14 -0
- package/src/engine/tool/tool/write.ts +104 -0
- package/src/engine/tool/tool/write.txt +8 -0
- package/src/engine/tool/tool.ts +164 -0
- package/src/engine/tool/truncate.ts +160 -0
- package/src/engine/tool/truncation-dir.ts +4 -0
- package/src/engine/tool/webfetch.ts +192 -0
- package/src/engine/tool/webfetch.txt +13 -0
- package/src/engine/tool/websearch.ts +143 -0
- package/src/engine/tool/websearch.txt +14 -0
- package/src/engine/tool/write.ts +104 -0
- package/src/engine/tool/write.txt +8 -0
- package/src/engine/util/archive.ts +17 -0
- package/src/engine/util/bom.ts +31 -0
- package/src/engine/util/data-url.ts +9 -0
- package/src/engine/util/defer.ts +10 -0
- package/src/engine/util/effect-http-client.ts +11 -0
- package/src/engine/util/error.ts +88 -0
- package/src/engine/util/filesystem.ts +252 -0
- package/src/engine/util/format.ts +20 -0
- package/src/engine/util/iife.ts +3 -0
- package/src/engine/util/lazy.ts +20 -0
- package/src/engine/util/local-context.ts +25 -0
- package/src/engine/util/locale.ts +86 -0
- package/src/engine/util/media.ts +26 -0
- package/src/engine/util/process.ts +176 -0
- package/src/engine/util/queue.ts +32 -0
- package/src/engine/util/record.ts +3 -0
- package/src/engine/util/repository.ts +158 -0
- package/src/engine/util/rpc.ts +66 -0
- package/src/engine/util/signal.ts +12 -0
- package/src/engine/util/timeout.ts +13 -0
- package/src/engine/util/token.ts +7 -0
- package/src/engine/util/util/archive.ts +17 -0
- package/src/engine/util/util/bom.ts +31 -0
- package/src/engine/util/util/data-url.ts +9 -0
- package/src/engine/util/util/defer.ts +10 -0
- package/src/engine/util/util/effect-http-client.ts +11 -0
- package/src/engine/util/util/error.ts +88 -0
- package/src/engine/util/util/filesystem.ts +252 -0
- package/src/engine/util/util/format.ts +20 -0
- package/src/engine/util/util/iife.ts +3 -0
- package/src/engine/util/util/lazy.ts +20 -0
- package/src/engine/util/util/local-context.ts +25 -0
- package/src/engine/util/util/locale.ts +86 -0
- package/src/engine/util/util/media.ts +26 -0
- package/src/engine/util/util/process.ts +176 -0
- package/src/engine/util/util/queue.ts +32 -0
- package/src/engine/util/util/record.ts +3 -0
- package/src/engine/util/util/repository.ts +158 -0
- package/src/engine/util/util/rpc.ts +66 -0
- package/src/engine/util/util/signal.ts +12 -0
- package/src/engine/util/util/timeout.ts +13 -0
- package/src/engine/util/util/token.ts +7 -0
- package/src/engine/util/util/which.ts +14 -0
- package/src/engine/util/util/wildcard.ts +59 -0
- package/src/engine/util/which.ts +14 -0
- package/src/engine/util/wildcard.ts +59 -0
- package/src/engine/worktree/index.ts +621 -0
- package/src/rag_worker.ts +519 -0
- package/src/server.ts +201 -0
- package/src/tui.ts +637 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Effect } from "effect"
|
|
2
|
+
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
|
3
|
+
|
|
4
|
+
const BOM_CODE = 0xfeff
|
|
5
|
+
const BOM = String.fromCharCode(BOM_CODE)
|
|
6
|
+
|
|
7
|
+
export function split(text: string) {
|
|
8
|
+
if (text.charCodeAt(0) !== BOM_CODE) return { bom: false, text }
|
|
9
|
+
return { bom: true, text: text.slice(1) }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function join(text: string, bom: boolean) {
|
|
13
|
+
const stripped = split(text).text
|
|
14
|
+
if (!bom) return stripped
|
|
15
|
+
return BOM + stripped
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const readFile = Effect.fn("Bom.readFile")(function* (fs: AppFileSystem.Interface, filePath: string) {
|
|
19
|
+
return split(new TextDecoder("utf-8", { ignoreBOM: true }).decode(yield* fs.readFile(filePath)))
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export const syncFile = Effect.fn("Bom.syncFile")(function* (
|
|
23
|
+
fs: AppFileSystem.Interface,
|
|
24
|
+
filePath: string,
|
|
25
|
+
bom: boolean,
|
|
26
|
+
) {
|
|
27
|
+
const current = yield* readFile(fs, filePath)
|
|
28
|
+
if (current.bom === bom) return current.text
|
|
29
|
+
yield* fs.writeWithDirs(filePath, join(current.text, bom))
|
|
30
|
+
return current.text
|
|
31
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function decodeDataUrl(url: string) {
|
|
2
|
+
const idx = url.indexOf(",")
|
|
3
|
+
if (idx === -1) return ""
|
|
4
|
+
|
|
5
|
+
const head = url.slice(0, idx)
|
|
6
|
+
const body = url.slice(idx + 1)
|
|
7
|
+
if (head.includes(";base64")) return Buffer.from(body, "base64").toString("utf8")
|
|
8
|
+
return decodeURIComponent(body)
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Schedule } from "effect"
|
|
2
|
+
import { HttpClient } from "effect/unstable/http"
|
|
3
|
+
|
|
4
|
+
export const withTransientReadRetry = <E, R>(client: HttpClient.HttpClient.With<E, R>) =>
|
|
5
|
+
client.pipe(
|
|
6
|
+
HttpClient.retryTransient({
|
|
7
|
+
retryOn: "errors-and-responses",
|
|
8
|
+
times: 2,
|
|
9
|
+
schedule: Schedule.exponential(200).pipe(Schedule.jittered),
|
|
10
|
+
}),
|
|
11
|
+
)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { isRecord } from "./record"
|
|
2
|
+
|
|
3
|
+
export function errorFormat(error: unknown): string {
|
|
4
|
+
if (error instanceof Error) {
|
|
5
|
+
return error.stack ?? `${error.name}: ${error.message}`
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (typeof error === "object" && error !== null) {
|
|
9
|
+
try {
|
|
10
|
+
const json = JSON.stringify(error, null, 2)
|
|
11
|
+
// Plain objects whose own properties are all non-enumerable (or empty)
|
|
12
|
+
// serialize to "{}", which prints as a useless bare `{}` on stderr.
|
|
13
|
+
// Fall back to a custom toString first, then to ctor name + own prop names.
|
|
14
|
+
if (json === "{}") {
|
|
15
|
+
const str = String(error)
|
|
16
|
+
if (str && str !== "[object Object]") return str
|
|
17
|
+
const ctor = error.constructor?.name
|
|
18
|
+
const prefix = ctor && ctor !== "Object" ? ctor : "Error"
|
|
19
|
+
const names = Object.getOwnPropertyNames(error)
|
|
20
|
+
return names.length === 0 ? `${prefix} (no message)` : `${prefix} { ${names.join(", ")} }`
|
|
21
|
+
}
|
|
22
|
+
return json
|
|
23
|
+
} catch {
|
|
24
|
+
return "Unexpected error (unserializable)"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return String(error)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function errorMessage(error: unknown): string {
|
|
32
|
+
if (error instanceof Error) {
|
|
33
|
+
if (error.message) return error.message
|
|
34
|
+
if (error.name) return error.name
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isRecord(error) && typeof error.message === "string" && error.message) {
|
|
38
|
+
return error.message
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isRecord(error) && isRecord(error.data) && typeof error.data.message === "string" && error.data.message) {
|
|
42
|
+
return error.data.message
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const text = String(error)
|
|
46
|
+
if (text && text !== "[object Object]") return text
|
|
47
|
+
|
|
48
|
+
const formatted = errorFormat(error)
|
|
49
|
+
if (formatted) return formatted
|
|
50
|
+
return "unknown error"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function errorData(error: unknown) {
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
return {
|
|
56
|
+
type: error.name,
|
|
57
|
+
message: errorMessage(error),
|
|
58
|
+
stack: error.stack,
|
|
59
|
+
cause: error.cause === undefined ? undefined : errorFormat(error.cause),
|
|
60
|
+
formatted: errorFormat(error),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!isRecord(error)) {
|
|
65
|
+
return {
|
|
66
|
+
type: typeof error,
|
|
67
|
+
message: errorMessage(error),
|
|
68
|
+
formatted: errorFormat(error),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const data = Object.getOwnPropertyNames(error).reduce<Record<string, unknown>>((acc, key) => {
|
|
73
|
+
const value = error[key]
|
|
74
|
+
if (value === undefined) return acc
|
|
75
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
76
|
+
acc[key] = value
|
|
77
|
+
return acc
|
|
78
|
+
}
|
|
79
|
+
// oxlint-disable-next-line no-base-to-string -- intentional coercion of arbitrary error properties
|
|
80
|
+
acc[key] = value instanceof Error ? value.message : String(value)
|
|
81
|
+
return acc
|
|
82
|
+
}, {})
|
|
83
|
+
|
|
84
|
+
if (typeof data.message !== "string") data.message = errorMessage(error)
|
|
85
|
+
if (typeof data.type !== "string") data.type = error.constructor?.name
|
|
86
|
+
data.formatted = errorFormat(error)
|
|
87
|
+
return data
|
|
88
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, stat as statFile, writeFile } from "fs/promises"
|
|
2
|
+
import { createWriteStream, existsSync, statSync } from "fs"
|
|
3
|
+
import { realpathSync } from "fs"
|
|
4
|
+
import { dirname, isAbsolute, join, relative, resolve as pathResolve, win32 } from "path"
|
|
5
|
+
import { Readable } from "stream"
|
|
6
|
+
import { pipeline } from "stream/promises"
|
|
7
|
+
import { Glob } from "@opencode-ai/core/util/glob"
|
|
8
|
+
import { fileURLToPath } from "url"
|
|
9
|
+
|
|
10
|
+
// Fast sync version for metadata checks
|
|
11
|
+
export async function exists(p: string): Promise<boolean> {
|
|
12
|
+
return existsSync(p)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function isDir(p: string): Promise<boolean> {
|
|
16
|
+
try {
|
|
17
|
+
return statSync(p).isDirectory()
|
|
18
|
+
} catch {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function stat(p: string): ReturnType<typeof statSync> | undefined {
|
|
24
|
+
return statSync(p, { throwIfNoEntry: false }) ?? undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function statAsync(p: string): Promise<ReturnType<typeof statSync> | undefined> {
|
|
28
|
+
return statFile(p).catch((e) => {
|
|
29
|
+
if (isEnoent(e)) return undefined
|
|
30
|
+
throw e
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function size(p: string): Promise<number> {
|
|
35
|
+
const s = stat(p)?.size ?? 0
|
|
36
|
+
return typeof s === "bigint" ? Number(s) : s
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function readText(p: string): Promise<string> {
|
|
40
|
+
return readFile(p, "utf-8")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function readJson<T = unknown>(p: string): Promise<T> {
|
|
44
|
+
return JSON.parse(await readFile(p, "utf-8"))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function readBytes(p: string): Promise<Buffer> {
|
|
48
|
+
return readFile(p)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function readArrayBuffer(p: string): Promise<ArrayBuffer> {
|
|
52
|
+
const buf = await readFile(p)
|
|
53
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isEnoent(e: unknown): e is { code: "ENOENT" } {
|
|
57
|
+
return typeof e === "object" && e !== null && "code" in e && (e as { code: string }).code === "ENOENT"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function write(p: string, content: string | Buffer | Uint8Array, mode?: number): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
if (mode) {
|
|
63
|
+
await writeFile(p, content, { mode })
|
|
64
|
+
} else {
|
|
65
|
+
await writeFile(p, content)
|
|
66
|
+
}
|
|
67
|
+
} catch (e) {
|
|
68
|
+
if (isEnoent(e)) {
|
|
69
|
+
await mkdir(dirname(p), { recursive: true })
|
|
70
|
+
if (mode) {
|
|
71
|
+
await writeFile(p, content, { mode })
|
|
72
|
+
} else {
|
|
73
|
+
await writeFile(p, content)
|
|
74
|
+
}
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
throw e
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function writeJson(p: string, data: unknown, mode?: number): Promise<void> {
|
|
82
|
+
return write(p, JSON.stringify(data, null, 2), mode)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function writeStream(
|
|
86
|
+
p: string,
|
|
87
|
+
stream: ReadableStream<Uint8Array> | Readable,
|
|
88
|
+
mode?: number,
|
|
89
|
+
): Promise<void> {
|
|
90
|
+
const dir = dirname(p)
|
|
91
|
+
if (!existsSync(dir)) {
|
|
92
|
+
await mkdir(dir, { recursive: true })
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const nodeStream = stream instanceof ReadableStream ? Readable.fromWeb(stream as any) : stream
|
|
96
|
+
const writeStream = createWriteStream(p)
|
|
97
|
+
await pipeline(nodeStream, writeStream)
|
|
98
|
+
|
|
99
|
+
if (mode) {
|
|
100
|
+
await chmod(p, mode)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function mimeType(p: string): Promise<string> {
|
|
105
|
+
const { lookup } = await import("mime-types")
|
|
106
|
+
return lookup(p) || "application/octet-stream"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* On Windows, normalize a path to its canonical casing using the filesystem.
|
|
111
|
+
* This is needed because Windows paths are case-insensitive but LSP servers
|
|
112
|
+
* may return paths with different casing than what we send them.
|
|
113
|
+
*/
|
|
114
|
+
export function normalizePath(p: string): string {
|
|
115
|
+
if (process.platform !== "win32") return p
|
|
116
|
+
const resolved = win32.normalize(win32.resolve(windowsPath(p)))
|
|
117
|
+
try {
|
|
118
|
+
return realpathSync.native(resolved)
|
|
119
|
+
} catch {
|
|
120
|
+
return resolved
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function normalizePathPattern(p: string): string {
|
|
125
|
+
if (process.platform !== "win32") return p
|
|
126
|
+
if (p === "*") return p
|
|
127
|
+
const match = p.match(/^(.*)[\\/]\*$/)
|
|
128
|
+
if (!match) return normalizePath(p)
|
|
129
|
+
const dir = /^[A-Za-z]:$/.test(match[1]) ? match[1] + "\\" : match[1]
|
|
130
|
+
return join(normalizePath(dir), "*")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// We cannot rely on path.resolve() here because git.exe may come from Git Bash, Cygwin, or MSYS2, so we need to translate these paths at the boundary.
|
|
134
|
+
// Also resolves symlinks so that callers using the result as a cache key
|
|
135
|
+
// always get the same canonical path for a given physical directory.
|
|
136
|
+
export function resolve(p: string): string {
|
|
137
|
+
const resolved = pathResolve(windowsPath(p))
|
|
138
|
+
try {
|
|
139
|
+
return normalizePath(realpathSync(resolved))
|
|
140
|
+
} catch (e) {
|
|
141
|
+
if (isEnoent(e)) return normalizePath(resolved)
|
|
142
|
+
throw e
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function resolveFilePath(root: string, file: string): string {
|
|
147
|
+
const raw = file.startsWith("file://") ? fileURLToPath(file) : file
|
|
148
|
+
if (isAbsolute(raw)) return raw
|
|
149
|
+
return pathResolve(root, raw)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function windowsPath(p: string): string {
|
|
153
|
+
if (process.platform !== "win32") return p
|
|
154
|
+
return (
|
|
155
|
+
p
|
|
156
|
+
.replace(/^\/([a-zA-Z]):(?:[\\/]|$)/, (_, drive) => `${drive.toUpperCase()}:/`)
|
|
157
|
+
// Git Bash for Windows paths are typically /<drive>/...
|
|
158
|
+
.replace(/^\/([a-zA-Z])(?:\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)
|
|
159
|
+
// Cygwin git paths are typically /cygdrive/<drive>/...
|
|
160
|
+
.replace(/^\/cygdrive\/([a-zA-Z])(?:\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)
|
|
161
|
+
// WSL paths are typically /mnt/<drive>/...
|
|
162
|
+
.replace(/^\/mnt\/([a-zA-Z])(?:\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
export function overlaps(a: string, b: string) {
|
|
166
|
+
const relA = relative(a, b)
|
|
167
|
+
const relB = relative(b, a)
|
|
168
|
+
return !relA || !relA.startsWith("..") || !relB || !relB.startsWith("..")
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function contains(parent: string, child: string) {
|
|
172
|
+
return !relative(parent, child).startsWith("..")
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function findUp(
|
|
176
|
+
target: string,
|
|
177
|
+
start: string,
|
|
178
|
+
stop?: string,
|
|
179
|
+
options?: { rootFirst?: boolean },
|
|
180
|
+
): Promise<string[]>
|
|
181
|
+
export async function findUp(
|
|
182
|
+
target: string[],
|
|
183
|
+
start: string,
|
|
184
|
+
stop?: string,
|
|
185
|
+
options?: { rootFirst?: boolean },
|
|
186
|
+
): Promise<string[]>
|
|
187
|
+
export async function findUp(
|
|
188
|
+
target: string | string[],
|
|
189
|
+
start: string,
|
|
190
|
+
stop?: string,
|
|
191
|
+
options?: { rootFirst?: boolean },
|
|
192
|
+
) {
|
|
193
|
+
const dirs = [start]
|
|
194
|
+
let current = start
|
|
195
|
+
while (true) {
|
|
196
|
+
if (stop === current) break
|
|
197
|
+
const parent = dirname(current)
|
|
198
|
+
if (parent === current) break
|
|
199
|
+
dirs.push(parent)
|
|
200
|
+
current = parent
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const targets = Array.isArray(target) ? target : [target]
|
|
204
|
+
const result = []
|
|
205
|
+
for (const dir of options?.rootFirst ? dirs.toReversed() : dirs) {
|
|
206
|
+
for (const item of targets) {
|
|
207
|
+
const search = join(dir, item)
|
|
208
|
+
if (await exists(search)) result.push(search)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return result
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export async function* up(options: { targets: string[]; start: string; stop?: string }) {
|
|
215
|
+
const { targets, start, stop } = options
|
|
216
|
+
let current = start
|
|
217
|
+
while (true) {
|
|
218
|
+
for (const target of targets) {
|
|
219
|
+
const search = join(current, target)
|
|
220
|
+
if (await exists(search)) yield search
|
|
221
|
+
}
|
|
222
|
+
if (stop === current) break
|
|
223
|
+
const parent = dirname(current)
|
|
224
|
+
if (parent === current) break
|
|
225
|
+
current = parent
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export async function globUp(pattern: string, start: string, stop?: string) {
|
|
230
|
+
let current = start
|
|
231
|
+
const result = []
|
|
232
|
+
while (true) {
|
|
233
|
+
try {
|
|
234
|
+
const matches = await Glob.scan(pattern, {
|
|
235
|
+
cwd: current,
|
|
236
|
+
absolute: true,
|
|
237
|
+
include: "file",
|
|
238
|
+
dot: true,
|
|
239
|
+
})
|
|
240
|
+
result.push(...matches)
|
|
241
|
+
} catch {
|
|
242
|
+
// Skip invalid glob patterns
|
|
243
|
+
}
|
|
244
|
+
if (stop === current) break
|
|
245
|
+
const parent = dirname(current)
|
|
246
|
+
if (parent === current) break
|
|
247
|
+
current = parent
|
|
248
|
+
}
|
|
249
|
+
return result
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export * as Filesystem from "./filesystem"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function formatDuration(secs: number) {
|
|
2
|
+
if (secs <= 0) return ""
|
|
3
|
+
if (secs < 60) return `${secs}s`
|
|
4
|
+
if (secs < 3600) {
|
|
5
|
+
const mins = Math.floor(secs / 60)
|
|
6
|
+
const remaining = secs % 60
|
|
7
|
+
return remaining > 0 ? `${mins}m ${remaining}s` : `${mins}m`
|
|
8
|
+
}
|
|
9
|
+
if (secs < 86400) {
|
|
10
|
+
const hours = Math.floor(secs / 3600)
|
|
11
|
+
const remaining = Math.floor((secs % 3600) / 60)
|
|
12
|
+
return remaining > 0 ? `${hours}h ${remaining}m` : `${hours}h`
|
|
13
|
+
}
|
|
14
|
+
if (secs < 604800) {
|
|
15
|
+
const days = Math.floor(secs / 86400)
|
|
16
|
+
return days === 1 ? "~1 day" : `~${days} days`
|
|
17
|
+
}
|
|
18
|
+
const weeks = Math.floor(secs / 604800)
|
|
19
|
+
return weeks === 1 ? "~1 week" : `~${weeks} weeks`
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function lazy<T>(fn: () => T) {
|
|
2
|
+
let value: T | undefined
|
|
3
|
+
let loaded = false
|
|
4
|
+
|
|
5
|
+
const result = (): T => {
|
|
6
|
+
if (loaded) return value as T
|
|
7
|
+
value = fn()
|
|
8
|
+
loaded = true
|
|
9
|
+
return value as T
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
result.reset = () => {
|
|
13
|
+
loaded = false
|
|
14
|
+
value = undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
result.loaded = () => loaded
|
|
18
|
+
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "async_hooks"
|
|
2
|
+
|
|
3
|
+
export class NotFound extends Error {
|
|
4
|
+
constructor(public override readonly name: string) {
|
|
5
|
+
super(`No context found for ${name}`)
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function create<T>(name: string) {
|
|
10
|
+
const storage = new AsyncLocalStorage<T>()
|
|
11
|
+
return {
|
|
12
|
+
use() {
|
|
13
|
+
const result = storage.getStore()
|
|
14
|
+
if (!result) {
|
|
15
|
+
throw new NotFound(name)
|
|
16
|
+
}
|
|
17
|
+
return result
|
|
18
|
+
},
|
|
19
|
+
provide<R>(value: T, fn: () => R) {
|
|
20
|
+
return storage.run(value, fn)
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export * as LocalContext from "./local-context"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export function titlecase(str: string) {
|
|
2
|
+
return str.replace(/\b\w/g, (c) => c.toUpperCase())
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function time(input: number): string {
|
|
6
|
+
const date = new Date(input)
|
|
7
|
+
return date.toLocaleTimeString(undefined, { timeStyle: "short" })
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function datetime(input: number): string {
|
|
11
|
+
const date = new Date(input)
|
|
12
|
+
const localTime = time(input)
|
|
13
|
+
const localDate = date.toLocaleDateString()
|
|
14
|
+
return `${localTime} · ${localDate}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function todayTimeOrDateTime(input: number): string {
|
|
18
|
+
const date = new Date(input)
|
|
19
|
+
const now = new Date()
|
|
20
|
+
const isToday =
|
|
21
|
+
date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()
|
|
22
|
+
|
|
23
|
+
if (isToday) {
|
|
24
|
+
return time(input)
|
|
25
|
+
} else {
|
|
26
|
+
return datetime(input)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function number(num: number): string {
|
|
31
|
+
if (num >= 1000000) {
|
|
32
|
+
return (num / 1000000).toFixed(1) + "M"
|
|
33
|
+
} else if (num >= 1000) {
|
|
34
|
+
return (num / 1000).toFixed(1) + "K"
|
|
35
|
+
}
|
|
36
|
+
return num.toString()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function duration(input: number) {
|
|
40
|
+
if (input < 1000) {
|
|
41
|
+
return `${input}ms`
|
|
42
|
+
}
|
|
43
|
+
if (input < 60000) {
|
|
44
|
+
return `${(input / 1000).toFixed(1)}s`
|
|
45
|
+
}
|
|
46
|
+
if (input < 3600000) {
|
|
47
|
+
const minutes = Math.floor(input / 60000)
|
|
48
|
+
const seconds = Math.floor((input % 60000) / 1000)
|
|
49
|
+
return `${minutes}m ${seconds}s`
|
|
50
|
+
}
|
|
51
|
+
if (input < 86400000) {
|
|
52
|
+
const hours = Math.floor(input / 3600000)
|
|
53
|
+
const minutes = Math.floor((input % 3600000) / 60000)
|
|
54
|
+
return `${hours}h ${minutes}m`
|
|
55
|
+
}
|
|
56
|
+
const hours = Math.floor(input / 3600000)
|
|
57
|
+
const days = Math.floor((input % 3600000) / 86400000)
|
|
58
|
+
return `${days}d ${hours}h`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function truncate(str: string, len: number): string {
|
|
62
|
+
if (str.length <= len) return str
|
|
63
|
+
return str.slice(0, len - 1) + "…"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function truncateLeft(str: string, len: number): string {
|
|
67
|
+
if (str.length <= len) return str
|
|
68
|
+
return "…" + str.slice(-(len - 1))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function truncateMiddle(str: string, maxLength: number = 35): string {
|
|
72
|
+
if (str.length <= maxLength) return str
|
|
73
|
+
|
|
74
|
+
const ellipsis = "…"
|
|
75
|
+
const keepStart = Math.ceil((maxLength - ellipsis.length) / 2)
|
|
76
|
+
const keepEnd = Math.floor((maxLength - ellipsis.length) / 2)
|
|
77
|
+
|
|
78
|
+
return str.slice(0, keepStart) + ellipsis + str.slice(-keepEnd)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function pluralize(count: number, singular: string, plural: string): string {
|
|
82
|
+
const template = count === 1 ? singular : plural
|
|
83
|
+
return template.replace("{}", count.toString())
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export * as Locale from "./locale"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const startsWith = (bytes: Uint8Array, prefix: number[]) => prefix.every((value, index) => bytes[index] === value)
|
|
2
|
+
|
|
3
|
+
export function isPdfAttachment(mime: string) {
|
|
4
|
+
return mime === "application/pdf"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function isMedia(mime: string) {
|
|
8
|
+
return mime.startsWith("image/") || isPdfAttachment(mime)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isImageAttachment(mime: string) {
|
|
12
|
+
return mime.startsWith("image/") && mime !== "image/svg+xml" && mime !== "image/vnd.fastbidsheet"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function sniffAttachmentMime(bytes: Uint8Array, fallback: string) {
|
|
16
|
+
if (startsWith(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) return "image/png"
|
|
17
|
+
if (startsWith(bytes, [0xff, 0xd8, 0xff])) return "image/jpeg"
|
|
18
|
+
if (startsWith(bytes, [0x47, 0x49, 0x46, 0x38])) return "image/gif"
|
|
19
|
+
if (startsWith(bytes, [0x42, 0x4d])) return "image/bmp"
|
|
20
|
+
if (startsWith(bytes, [0x25, 0x50, 0x44, 0x46, 0x2d])) return "application/pdf"
|
|
21
|
+
if (startsWith(bytes, [0x52, 0x49, 0x46, 0x46]) && startsWith(bytes.subarray(8), [0x57, 0x45, 0x42, 0x50])) {
|
|
22
|
+
return "image/webp"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return fallback
|
|
26
|
+
}
|