dotdo 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +446 -315
- package/cli/README.md +238 -0
- package/cli/agent.ts +72 -0
- package/cli/bin.js +44 -0
- package/cli/bin.ts +38 -0
- package/cli/build.ts +157 -0
- package/cli/commands/auth/login.ts +14 -0
- package/cli/commands/auth/logout.ts +6 -0
- package/cli/commands/auth/whoami.ts +16 -0
- package/cli/commands/deploy-multi.ts +245 -0
- package/cli/commands/dev/deploy.ts +100 -0
- package/cli/commands/dev/dev.ts +95 -0
- package/cli/commands/dev/logs.ts +91 -0
- package/cli/commands/dev-local.ts +88 -0
- package/cli/commands/do-ops.ts +314 -0
- package/cli/commands/index.ts +100 -0
- package/cli/commands/init.ts +247 -0
- package/cli/commands/introspect/emitter.ts +315 -0
- package/cli/commands/introspect/index.ts +193 -0
- package/cli/commands/link.ts +598 -0
- package/cli/commands/snippets.ts +415 -0
- package/cli/commands/tunnel.ts +239 -0
- package/cli/device-auth.ts +289 -0
- package/cli/fallback.ts +12 -0
- package/cli/index.ts +121 -0
- package/cli/main.ts +246 -0
- package/cli/mcp-stdio.ts +790 -0
- package/cli/package.json +62 -0
- package/cli/runtime/do-registry.ts +193 -0
- package/cli/runtime/embedded-db.ts +344 -0
- package/cli/runtime/index.ts +9 -0
- package/cli/runtime/miniflare-adapter.ts +162 -0
- package/cli/sandbox.ts +82 -0
- package/cli/src/args.ts +174 -0
- package/cli/src/auth.ts +55 -0
- package/cli/src/commands/call.ts +84 -0
- package/cli/src/commands/charge.ts +96 -0
- package/cli/src/commands/config.ts +115 -0
- package/cli/src/commands/email.ts +112 -0
- package/cli/src/commands/llm.ts +115 -0
- package/cli/src/commands/queue.ts +134 -0
- package/cli/src/commands/text.ts +86 -0
- package/cli/src/config.ts +185 -0
- package/cli/src/output.ts +246 -0
- package/cli/src/rpc.ts +192 -0
- package/cli/utils/config.ts +282 -0
- package/cli/utils/detect.ts +73 -0
- package/cli/utils/index.ts +15 -0
- package/cli/utils/logger.ts +232 -0
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/template-literals.js +852 -0
- package/dist/ai/template-literals.js.map +1 -0
- package/dist/api/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +545 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/db/actions.js +212 -0
- package/dist/db/actions.js.map +1 -0
- package/dist/db/auth.js +506 -0
- package/dist/db/auth.js.map +1 -0
- package/dist/db/branches.js +65 -0
- package/dist/db/branches.js.map +1 -0
- package/dist/db/clickhouse.js +1074 -0
- package/dist/db/clickhouse.js.map +1 -0
- package/dist/db/dlq.js +39 -0
- package/dist/db/dlq.js.map +1 -0
- package/dist/db/events.js +28 -0
- package/dist/db/events.js.map +1 -0
- package/dist/db/exec.js +64 -0
- package/dist/db/exec.js.map +1 -0
- package/dist/db/files.js +85 -0
- package/dist/db/files.js.map +1 -0
- package/dist/db/flags.js +24 -0
- package/dist/db/flags.js.map +1 -0
- package/dist/db/git.js +116 -0
- package/dist/db/git.js.map +1 -0
- package/dist/db/iceberg/inverted-index.js +862 -0
- package/dist/db/iceberg/inverted-index.js.map +1 -0
- package/dist/db/iceberg/puffin.js +878 -0
- package/dist/db/iceberg/puffin.js.map +1 -0
- package/dist/db/iceberg/search-manifest.js +422 -0
- package/dist/db/iceberg/search-manifest.js.map +1 -0
- package/dist/db/iceberg/types.js +8 -0
- package/dist/db/iceberg/types.js.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/integrations.js +368 -0
- package/dist/db/integrations.js.map +1 -0
- package/dist/db/json-indexes.js +332 -0
- package/dist/db/json-indexes.js.map +1 -0
- package/dist/db/linked-accounts.js +287 -0
- package/dist/db/linked-accounts.js.map +1 -0
- package/dist/db/nouns.js +183 -0
- package/dist/db/nouns.js.map +1 -0
- package/dist/db/objects.js +170 -0
- package/dist/db/objects.js.map +1 -0
- package/dist/db/primitives/dag-scheduler/index.js +869 -0
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
- package/dist/db/primitives/exactly-once-context.js +237 -0
- package/dist/db/primitives/exactly-once-context.js.map +1 -0
- package/dist/db/primitives/index.js +62 -0
- package/dist/db/primitives/index.js.map +1 -0
- package/dist/db/primitives/keyed-router.js +145 -0
- package/dist/db/primitives/keyed-router.js.map +1 -0
- package/dist/db/primitives/observability.js +162 -0
- package/dist/db/primitives/observability.js.map +1 -0
- package/dist/db/primitives/schema-evolution.js +643 -0
- package/dist/db/primitives/schema-evolution.js.map +1 -0
- package/dist/db/primitives/stateful-operator/index.js +770 -0
- package/dist/db/primitives/stateful-operator/index.js.map +1 -0
- package/dist/db/primitives/temporal-store.js +306 -0
- package/dist/db/primitives/temporal-store.js.map +1 -0
- package/dist/db/primitives/typed-column-store.js +1229 -0
- package/dist/db/primitives/typed-column-store.js.map +1 -0
- package/dist/db/primitives/utils/duration.js +162 -0
- package/dist/db/primitives/utils/duration.js.map +1 -0
- package/dist/db/primitives/utils/murmur3.js +116 -0
- package/dist/db/primitives/utils/murmur3.js.map +1 -0
- package/dist/db/primitives/watermark-service.js +136 -0
- package/dist/db/primitives/watermark-service.js.map +1 -0
- package/dist/db/primitives/window-manager.js +764 -0
- package/dist/db/primitives/window-manager.js.map +1 -0
- package/dist/db/relationships.js +66 -0
- package/dist/db/relationships.js.map +1 -0
- package/dist/db/schema-minimal.js +61 -0
- package/dist/db/schema-minimal.js.map +1 -0
- package/dist/db/search.js +28 -0
- package/dist/db/search.js.map +1 -0
- package/dist/db/stores.js +1665 -0
- package/dist/db/stores.js.map +1 -0
- package/dist/db/things.js +297 -0
- package/dist/db/things.js.map +1 -0
- package/dist/db/vault.js +171 -0
- package/dist/db/vault.js.map +1 -0
- package/dist/db/verbs.js +102 -0
- package/dist/db/verbs.js.map +1 -0
- package/dist/do/base.js +48 -0
- package/dist/do/base.js.map +1 -0
- package/dist/do/tiny.js +31 -0
- package/dist/do/tiny.js.map +1 -0
- package/dist/lib/DOAuth.js +261 -0
- package/dist/lib/DOAuth.js.map +1 -0
- package/dist/lib/DODispatcher.js +72 -0
- package/dist/lib/DODispatcher.js.map +1 -0
- package/dist/lib/Modifier.js +189 -0
- package/dist/lib/Modifier.js.map +1 -0
- package/dist/lib/StateStorage.js +403 -0
- package/dist/lib/StateStorage.js.map +1 -0
- package/dist/lib/TypeRegistry.js +122 -0
- package/dist/lib/TypeRegistry.js.map +1 -0
- package/dist/lib/ai/gateway.js +247 -0
- package/dist/lib/ai/gateway.js.map +1 -0
- package/dist/lib/ai/tool-loop-agent.js +591 -0
- package/dist/lib/ai/tool-loop-agent.js.map +1 -0
- package/dist/lib/auto-wiring.js +439 -0
- package/dist/lib/auto-wiring.js.map +1 -0
- package/dist/lib/browse/browserbase.js +163 -0
- package/dist/lib/browse/browserbase.js.map +1 -0
- package/dist/lib/browse/cloudflare.js +144 -0
- package/dist/lib/browse/cloudflare.js.map +1 -0
- package/dist/lib/browse/index.js +62 -0
- package/dist/lib/browse/index.js.map +1 -0
- package/dist/lib/browse/types.js +13 -0
- package/dist/lib/browse/types.js.map +1 -0
- package/dist/lib/cache/index.js +37 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/visibility.js +638 -0
- package/dist/lib/cache/visibility.js.map +1 -0
- package/dist/lib/capabilities.js +268 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/channels/base.js +106 -0
- package/dist/lib/channels/base.js.map +1 -0
- package/dist/lib/channels/discord.js +94 -0
- package/dist/lib/channels/discord.js.map +1 -0
- package/dist/lib/channels/email.js +204 -0
- package/dist/lib/channels/email.js.map +1 -0
- package/dist/lib/channels/index.js +90 -0
- package/dist/lib/channels/index.js.map +1 -0
- package/dist/lib/channels/mdxui-chat.js +95 -0
- package/dist/lib/channels/mdxui-chat.js.map +1 -0
- package/dist/lib/channels/slack-blockkit.js +121 -0
- package/dist/lib/channels/slack-blockkit.js.map +1 -0
- package/dist/lib/channels/types.js +7 -0
- package/dist/lib/channels/types.js.map +1 -0
- package/dist/lib/cloudflare/ai.js +654 -0
- package/dist/lib/cloudflare/ai.js.map +1 -0
- package/dist/lib/cloudflare/index.js +88 -0
- package/dist/lib/cloudflare/index.js.map +1 -0
- package/dist/lib/cloudflare/kv.js +342 -0
- package/dist/lib/cloudflare/kv.js.map +1 -0
- package/dist/lib/cloudflare/queues.js +434 -0
- package/dist/lib/cloudflare/queues.js.map +1 -0
- package/dist/lib/cloudflare/r2.js +604 -0
- package/dist/lib/cloudflare/r2.js.map +1 -0
- package/dist/lib/cloudflare/vectorize.js +494 -0
- package/dist/lib/cloudflare/vectorize.js.map +1 -0
- package/dist/lib/cloudflare/workflows.js +569 -0
- package/dist/lib/cloudflare/workflows.js.map +1 -0
- package/dist/lib/colo/caching.js +196 -0
- package/dist/lib/colo/caching.js.map +1 -0
- package/dist/lib/colo/detection.js +194 -0
- package/dist/lib/colo/detection.js.map +1 -0
- package/dist/lib/colo/external-data.js +219 -0
- package/dist/lib/colo/external-data.js.map +1 -0
- package/dist/lib/colo/globe-data.js +179 -0
- package/dist/lib/colo/globe-data.js.map +1 -0
- package/dist/lib/colo/index.js +16 -0
- package/dist/lib/colo/index.js.map +1 -0
- package/dist/lib/decorators.js +37 -0
- package/dist/lib/decorators.js.map +1 -0
- package/dist/lib/discovery.js +81 -0
- package/dist/lib/discovery.js.map +1 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
- package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/CascadeExecutor.js +418 -0
- package/dist/lib/executors/CascadeExecutor.js.map +1 -0
- package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/ParallelStepExecutor.js +308 -0
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
- package/dist/lib/executors/types.js +12 -0
- package/dist/lib/executors/types.js.map +1 -0
- package/dist/lib/experiments.js +89 -0
- package/dist/lib/experiments.js.map +1 -0
- package/dist/lib/flags/store.js +262 -0
- package/dist/lib/flags/store.js.map +1 -0
- package/dist/lib/functions/FunctionComposition.js +467 -0
- package/dist/lib/functions/FunctionComposition.js.map +1 -0
- package/dist/lib/functions/FunctionMiddleware.js +457 -0
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
- package/dist/lib/functions/FunctionRegistry.js +426 -0
- package/dist/lib/functions/FunctionRegistry.js.map +1 -0
- package/dist/lib/functions/createFunction.js +1048 -0
- package/dist/lib/functions/createFunction.js.map +1 -0
- package/dist/lib/humans/index.js +68 -0
- package/dist/lib/humans/index.js.map +1 -0
- package/dist/lib/humans/templates.js +117 -0
- package/dist/lib/humans/templates.js.map +1 -0
- package/dist/lib/identity.js +98 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logging/error-logger.js +163 -0
- package/dist/lib/logging/error-logger.js.map +1 -0
- package/dist/lib/logging/index.js +160 -0
- package/dist/lib/logging/index.js.map +1 -0
- package/dist/lib/mixins/bash.js +753 -0
- package/dist/lib/mixins/bash.js.map +1 -0
- package/dist/lib/mixins/fs.js +648 -0
- package/dist/lib/mixins/fs.js.map +1 -0
- package/dist/lib/mixins/git.js +1006 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/npm.js +662 -0
- package/dist/lib/mixins/npm.js.map +1 -0
- package/dist/lib/noun-id.js +278 -0
- package/dist/lib/noun-id.js.map +1 -0
- package/dist/lib/rate-limit/sliding-window.js +148 -0
- package/dist/lib/rate-limit/sliding-window.js.map +1 -0
- package/dist/lib/rate-limit.js +110 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/rpc/bindings.js +548 -0
- package/dist/lib/rpc/bindings.js.map +1 -0
- package/dist/lib/rpc/index.js +64 -0
- package/dist/lib/rpc/index.js.map +1 -0
- package/dist/lib/safe-stringify.js +223 -0
- package/dist/lib/safe-stringify.js.map +1 -0
- package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
- package/dist/lib/sqids.js +110 -0
- package/dist/lib/sqids.js.map +1 -0
- package/dist/lib/sql/adapters/index.js +10 -0
- package/dist/lib/sql/adapters/index.js.map +1 -0
- package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
- package/dist/lib/sql/adapters/pgsql-parser.js +1190 -0
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
- package/dist/lib/sql/index.js +277 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql/types.js +56 -0
- package/dist/lib/sql/types.js.map +1 -0
- package/dist/lib/type-classifier.js +126 -0
- package/dist/lib/type-classifier.js.map +1 -0
- package/dist/lib/utils/html.js +47 -0
- package/dist/lib/utils/html.js.map +1 -0
- package/dist/lib/validation.js +48 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/vault/store.js +411 -0
- package/dist/lib/vault/store.js.map +1 -0
- package/dist/metrics/hunch.js +739 -0
- package/dist/metrics/hunch.js.map +1 -0
- package/dist/objects/API.js +302 -0
- package/dist/objects/API.js.map +1 -0
- package/dist/objects/Agent.js +179 -0
- package/dist/objects/Agent.js.map +1 -0
- package/dist/objects/AgenticFunctionExecutor.js +8 -0
- package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
- package/dist/objects/App.js +83 -0
- package/dist/objects/App.js.map +1 -0
- package/dist/objects/Browser.js +884 -0
- package/dist/objects/Browser.js.map +1 -0
- package/dist/objects/Business.js +107 -0
- package/dist/objects/Business.js.map +1 -0
- package/dist/objects/CLI.js +221 -0
- package/dist/objects/CLI.js.map +1 -0
- package/dist/objects/CodeFunctionExecutor.js +8 -0
- package/dist/objects/CodeFunctionExecutor.js.map +1 -0
- package/dist/objects/Collection.js +161 -0
- package/dist/objects/Collection.js.map +1 -0
- package/dist/objects/DO.js +41 -0
- package/dist/objects/DO.js.map +1 -0
- package/dist/objects/DOBase.js +2309 -0
- package/dist/objects/DOBase.js.map +1 -0
- package/dist/objects/DOCache.js +153 -0
- package/dist/objects/DOCache.js.map +1 -0
- package/dist/objects/DOFull.js +1676 -0
- package/dist/objects/DOFull.js.map +1 -0
- package/dist/objects/DOTiny.js +207 -0
- package/dist/objects/DOTiny.js.map +1 -0
- package/dist/objects/Directory.js +199 -0
- package/dist/objects/Directory.js.map +1 -0
- package/dist/objects/Entity.js +413 -0
- package/dist/objects/Entity.js.map +1 -0
- package/dist/objects/Function.js +116 -0
- package/dist/objects/Function.js.map +1 -0
- package/dist/objects/Human.js +231 -0
- package/dist/objects/Human.js.map +1 -0
- package/dist/objects/HumanFunctionExecutor.js +8 -0
- package/dist/objects/HumanFunctionExecutor.js.map +1 -0
- package/dist/objects/IcebergMetadataDO.js +938 -0
- package/dist/objects/IcebergMetadataDO.js.map +1 -0
- package/dist/objects/IntegrationsDO.js +1174 -0
- package/dist/objects/IntegrationsDO.js.map +1 -0
- package/dist/objects/ObservabilityBroadcaster.js +149 -0
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
- package/dist/objects/Package.js +154 -0
- package/dist/objects/Package.js.map +1 -0
- package/dist/objects/Product.js +193 -0
- package/dist/objects/Product.js.map +1 -0
- package/dist/objects/SDK.js +152 -0
- package/dist/objects/SDK.js.map +1 -0
- package/dist/objects/SaaS.js +235 -0
- package/dist/objects/SaaS.js.map +1 -0
- package/dist/objects/SandboxDO.js +759 -0
- package/dist/objects/SandboxDO.js.map +1 -0
- package/dist/objects/Service.js +337 -0
- package/dist/objects/Service.js.map +1 -0
- package/dist/objects/Site.js +80 -0
- package/dist/objects/Site.js.map +1 -0
- package/dist/objects/Startup.js +479 -0
- package/dist/objects/Startup.js.map +1 -0
- package/dist/objects/ThingsDO.js +170 -0
- package/dist/objects/ThingsDO.js.map +1 -0
- package/dist/objects/VectorShardDO.js +650 -0
- package/dist/objects/VectorShardDO.js.map +1 -0
- package/dist/objects/Worker.js +144 -0
- package/dist/objects/Worker.js.map +1 -0
- package/dist/objects/Workflow.js +196 -0
- package/dist/objects/Workflow.js.map +1 -0
- package/dist/objects/WorkflowFactory.js +313 -0
- package/dist/objects/WorkflowFactory.js.map +1 -0
- package/dist/objects/WorkflowRuntime.js +863 -0
- package/dist/objects/WorkflowRuntime.js.map +1 -0
- package/dist/objects/circuit-breaker-bulkhead.js +178 -0
- package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
- package/dist/objects/createFunction.js +934 -0
- package/dist/objects/createFunction.js.map +1 -0
- package/dist/objects/index.js +80 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/objects/lifecycle/Branch.js +275 -0
- package/dist/objects/lifecycle/Branch.js.map +1 -0
- package/dist/objects/lifecycle/Clone.js +1499 -0
- package/dist/objects/lifecycle/Clone.js.map +1 -0
- package/dist/objects/lifecycle/Compact.js +237 -0
- package/dist/objects/lifecycle/Compact.js.map +1 -0
- package/dist/objects/lifecycle/Promote.js +476 -0
- package/dist/objects/lifecycle/Promote.js.map +1 -0
- package/dist/objects/lifecycle/Shard.js +560 -0
- package/dist/objects/lifecycle/Shard.js.map +1 -0
- package/dist/objects/lifecycle/index.js +15 -0
- package/dist/objects/lifecycle/index.js.map +1 -0
- package/dist/objects/lifecycle/types.js +33 -0
- package/dist/objects/lifecycle/types.js.map +1 -0
- package/dist/objects/mixins/infrastructure.js +171 -0
- package/dist/objects/mixins/infrastructure.js.map +1 -0
- package/dist/objects/modules/StoresModule.js +153 -0
- package/dist/objects/modules/StoresModule.js.map +1 -0
- package/dist/objects/persistence/checkpoint-manager.js +606 -0
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
- package/dist/objects/persistence/index.js +72 -0
- package/dist/objects/persistence/index.js.map +1 -0
- package/dist/objects/persistence/migration-runner.js +562 -0
- package/dist/objects/persistence/migration-runner.js.map +1 -0
- package/dist/objects/persistence/replication-manager.js +501 -0
- package/dist/objects/persistence/replication-manager.js.map +1 -0
- package/dist/objects/persistence/tiered-storage-manager.js +595 -0
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
- package/dist/objects/persistence/types.js +14 -0
- package/dist/objects/persistence/types.js.map +1 -0
- package/dist/objects/persistence/wal-manager.js +653 -0
- package/dist/objects/persistence/wal-manager.js.map +1 -0
- package/dist/objects/presets/index.js +20 -0
- package/dist/objects/presets/index.js.map +1 -0
- package/dist/objects/presets/primitives.js +188 -0
- package/dist/objects/presets/primitives.js.map +1 -0
- package/dist/objects/primitives/alarm-adapter.js +141 -0
- package/dist/objects/primitives/alarm-adapter.js.map +1 -0
- package/dist/objects/primitives/index.js +337 -0
- package/dist/objects/primitives/index.js.map +1 -0
- package/dist/objects/primitives/storage-adapter.js +182 -0
- package/dist/objects/primitives/storage-adapter.js.map +1 -0
- package/dist/objects/primitives/with-primitives.js +102 -0
- package/dist/objects/primitives/with-primitives.js.map +1 -0
- package/dist/objects/services/StoreManager.js +227 -0
- package/dist/objects/services/StoreManager.js.map +1 -0
- package/dist/objects/services/index.js +13 -0
- package/dist/objects/services/index.js.map +1 -0
- package/dist/objects/transport/auth-layer.js +1451 -0
- package/dist/objects/transport/auth-layer.js.map +1 -0
- package/dist/objects/transport/capnweb-target.js +355 -0
- package/dist/objects/transport/capnweb-target.js.map +1 -0
- package/dist/objects/transport/chain.js +441 -0
- package/dist/objects/transport/chain.js.map +1 -0
- package/dist/objects/transport/handler.js +58 -0
- package/dist/objects/transport/handler.js.map +1 -0
- package/dist/objects/transport/index.js +53 -0
- package/dist/objects/transport/index.js.map +1 -0
- package/dist/objects/transport/mcp-server.js +691 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1508 -0
- package/dist/objects/transport/rest-autowire.js.map +1 -0
- package/dist/objects/transport/rest-router.js +440 -0
- package/dist/objects/transport/rest-router.js.map +1 -0
- package/dist/objects/transport/rpc-server.js +1539 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +576 -0
- package/dist/objects/transport/shared.js.map +1 -0
- package/dist/objects/transport/sync-engine.js +291 -0
- package/dist/objects/transport/sync-engine.js.map +1 -0
- package/dist/objects/transport/types.js +8 -0
- package/dist/objects/transport/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/snippets/artifacts-config.js +241 -0
- package/dist/snippets/artifacts-config.js.map +1 -0
- package/dist/snippets/artifacts-ingest.js +832 -0
- package/dist/snippets/artifacts-ingest.js.map +1 -0
- package/dist/snippets/artifacts-serve.js +1035 -0
- package/dist/snippets/artifacts-serve.js.map +1 -0
- package/dist/snippets/artifacts-types.js +161 -0
- package/dist/snippets/artifacts-types.js.map +1 -0
- package/dist/snippets/cache-probe.js +376 -0
- package/dist/snippets/cache-probe.js.map +1 -0
- package/dist/snippets/cache.js +10 -0
- package/dist/snippets/cache.js.map +1 -0
- package/dist/snippets/events.js +469 -0
- package/dist/snippets/events.js.map +1 -0
- package/dist/snippets/index.js +7 -0
- package/dist/snippets/index.js.map +1 -0
- package/dist/snippets/proxy.js +495 -0
- package/dist/snippets/proxy.js.map +1 -0
- package/dist/snippets/search.js +1759 -0
- package/dist/snippets/search.js.map +1 -0
- package/dist/streams/index.js +30 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/observability.js +68 -0
- package/dist/streams/observability.js.map +1 -0
- package/dist/types/AI.js +92 -0
- package/dist/types/AI.js.map +1 -0
- package/dist/types/AIFunction.js +171 -0
- package/dist/types/AIFunction.js.map +1 -0
- package/dist/types/BrowseVerb.js +89 -0
- package/dist/types/BrowseVerb.js.map +1 -0
- package/dist/types/Browser.js +31 -0
- package/dist/types/Browser.js.map +1 -0
- package/dist/types/Chaos.js +15 -0
- package/dist/types/Chaos.js.map +1 -0
- package/dist/types/CloudflareBindings.js +109 -0
- package/dist/types/CloudflareBindings.js.map +1 -0
- package/dist/types/Collection.js +50 -0
- package/dist/types/Collection.js.map +1 -0
- package/dist/types/DO.js +2 -0
- package/dist/types/DO.js.map +1 -0
- package/dist/types/DOLocation.js +63 -0
- package/dist/types/DOLocation.js.map +1 -0
- package/dist/types/EventHandler.js +57 -0
- package/dist/types/EventHandler.js.map +1 -0
- package/dist/types/Experiment.js +33 -0
- package/dist/types/Experiment.js.map +1 -0
- package/dist/types/Flag.js +57 -0
- package/dist/types/Flag.js.map +1 -0
- package/dist/types/Lifecycle.js +13 -0
- package/dist/types/Lifecycle.js.map +1 -0
- package/dist/types/Location.js +169 -0
- package/dist/types/Location.js.map +1 -0
- package/dist/types/Noun.js +66 -0
- package/dist/types/Noun.js.map +1 -0
- package/dist/types/SessionEvent.js +194 -0
- package/dist/types/SessionEvent.js.map +1 -0
- package/dist/types/Thing.js +55 -0
- package/dist/types/Thing.js.map +1 -0
- package/dist/types/ThingDO.js +153 -0
- package/dist/types/ThingDO.js.map +1 -0
- package/dist/types/Things.js +2 -0
- package/dist/types/Things.js.map +1 -0
- package/dist/types/Verb.js +119 -0
- package/dist/types/Verb.js.map +1 -0
- package/dist/types/WorkflowContext.js +70 -0
- package/dist/types/WorkflowContext.js.map +1 -0
- package/dist/types/analytics-api.js +13 -0
- package/dist/types/analytics-api.js.map +1 -0
- package/dist/types/capabilities.js +135 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/drizzle.js +12 -0
- package/dist/types/drizzle.js.map +1 -0
- package/dist/types/event.js +201 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/fn.js +12 -0
- package/dist/types/fn.js.map +1 -0
- package/dist/types/iceberg.js +48 -0
- package/dist/types/iceberg.js.map +1 -0
- package/dist/types/ids.js +170 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/introspect.js +54 -0
- package/dist/types/introspect.js.map +1 -0
- package/dist/types/observability.js +124 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/sync-protocol.js +175 -0
- package/dist/types/sync-protocol.js.map +1 -0
- package/dist/types/vector.js +13 -0
- package/dist/types/vector.js.map +1 -0
- package/dist/workflows/ScheduleManager.js +473 -0
- package/dist/workflows/ScheduleManager.js.map +1 -0
- package/dist/workflows/StepDOBridge.js +149 -0
- package/dist/workflows/StepDOBridge.js.map +1 -0
- package/dist/workflows/StepResultStorage.js +232 -0
- package/dist/workflows/StepResultStorage.js.map +1 -0
- package/dist/workflows/WaitForEventManager.js +461 -0
- package/dist/workflows/WaitForEventManager.js.map +1 -0
- package/dist/workflows/analyzer.js +332 -0
- package/dist/workflows/analyzer.js.map +1 -0
- package/dist/workflows/compat/activity-router.js +484 -0
- package/dist/workflows/compat/activity-router.js.map +1 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
- package/dist/workflows/compat/backends/index.js +14 -0
- package/dist/workflows/compat/backends/index.js.map +1 -0
- package/dist/workflows/compat/errors/index.js +375 -0
- package/dist/workflows/compat/errors/index.js.map +1 -0
- package/dist/workflows/compat/index.js +79 -0
- package/dist/workflows/compat/index.js.map +1 -0
- package/dist/workflows/compat/inngest/index.js +989 -0
- package/dist/workflows/compat/inngest/index.js.map +1 -0
- package/dist/workflows/compat/qstash/index.js +1263 -0
- package/dist/workflows/compat/qstash/index.js.map +1 -0
- package/dist/workflows/compat/temporal/activities.js +739 -0
- package/dist/workflows/compat/temporal/activities.js.map +1 -0
- package/dist/workflows/compat/temporal/child-workflows.js +154 -0
- package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
- package/dist/workflows/compat/temporal/client.js +381 -0
- package/dist/workflows/compat/temporal/client.js.map +1 -0
- package/dist/workflows/compat/temporal/context.js +309 -0
- package/dist/workflows/compat/temporal/context.js.map +1 -0
- package/dist/workflows/compat/temporal/determinism.js +216 -0
- package/dist/workflows/compat/temporal/determinism.js.map +1 -0
- package/dist/workflows/compat/temporal/errors.js +128 -0
- package/dist/workflows/compat/temporal/errors.js.map +1 -0
- package/dist/workflows/compat/temporal/index.js +2464 -0
- package/dist/workflows/compat/temporal/index.js.map +1 -0
- package/dist/workflows/compat/temporal/saga.js +504 -0
- package/dist/workflows/compat/temporal/saga.js.map +1 -0
- package/dist/workflows/compat/temporal/signals.js +364 -0
- package/dist/workflows/compat/temporal/signals.js.map +1 -0
- package/dist/workflows/compat/temporal/storage.js +271 -0
- package/dist/workflows/compat/temporal/storage.js.map +1 -0
- package/dist/workflows/compat/temporal/timers.js +347 -0
- package/dist/workflows/compat/temporal/timers.js.map +1 -0
- package/dist/workflows/compat/temporal/types.js +7 -0
- package/dist/workflows/compat/temporal/types.js.map +1 -0
- package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
- package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
- package/dist/workflows/compat/trigger/index.js +468 -0
- package/dist/workflows/compat/trigger/index.js.map +1 -0
- package/dist/workflows/compat/utils/index.js +69 -0
- package/dist/workflows/compat/utils/index.js.map +1 -0
- package/dist/workflows/context/correlation-capability.js +266 -0
- package/dist/workflows/context/correlation-capability.js.map +1 -0
- package/dist/workflows/context/correlation.js +484 -0
- package/dist/workflows/context/correlation.js.map +1 -0
- package/dist/workflows/context/experiment.js +289 -0
- package/dist/workflows/context/experiment.js.map +1 -0
- package/dist/workflows/context/flag.js +244 -0
- package/dist/workflows/context/flag.js.map +1 -0
- package/dist/workflows/context/foundation.js +648 -0
- package/dist/workflows/context/foundation.js.map +1 -0
- package/dist/workflows/context/human-base.js +106 -0
- package/dist/workflows/context/human-base.js.map +1 -0
- package/dist/workflows/context/human.js +368 -0
- package/dist/workflows/context/human.js.map +1 -0
- package/dist/workflows/context/measure.js +354 -0
- package/dist/workflows/context/measure.js.map +1 -0
- package/dist/workflows/context/rate-limit.js +358 -0
- package/dist/workflows/context/rate-limit.js.map +1 -0
- package/dist/workflows/context/user.js +117 -0
- package/dist/workflows/context/user.js.map +1 -0
- package/dist/workflows/context/vault.js +360 -0
- package/dist/workflows/context/vault.js.map +1 -0
- package/dist/workflows/data/entity-events/entity-events.js +489 -0
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
- package/dist/workflows/data/experiment/index.js +599 -0
- package/dist/workflows/data/experiment/index.js.map +1 -0
- package/dist/workflows/data/goal/context.js +558 -0
- package/dist/workflows/data/goal/context.js.map +1 -0
- package/dist/workflows/data/goal/index.js +32 -0
- package/dist/workflows/data/goal/index.js.map +1 -0
- package/dist/workflows/data/measure/index.js +840 -0
- package/dist/workflows/data/measure/index.js.map +1 -0
- package/dist/workflows/data/stream/index.js +1149 -0
- package/dist/workflows/data/stream/index.js.map +1 -0
- package/dist/workflows/data/track/context.js +883 -0
- package/dist/workflows/data/track/context.js.map +1 -0
- package/dist/workflows/data/track/index.js +15 -0
- package/dist/workflows/data/track/index.js.map +1 -0
- package/dist/workflows/data/view/context.js +864 -0
- package/dist/workflows/data/view/context.js.map +1 -0
- package/dist/workflows/domain.js +93 -0
- package/dist/workflows/domain.js.map +1 -0
- package/dist/workflows/flag.js +176 -0
- package/dist/workflows/flag.js.map +1 -0
- package/dist/workflows/flags.js +217 -0
- package/dist/workflows/flags.js.map +1 -0
- package/dist/workflows/hash.js +209 -0
- package/dist/workflows/hash.js.map +1 -0
- package/dist/workflows/index.js +50 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/on.js +378 -0
- package/dist/workflows/on.js.map +1 -0
- package/dist/workflows/pipeline-promise.js +481 -0
- package/dist/workflows/pipeline-promise.js.map +1 -0
- package/dist/workflows/pipeline-types.js +20 -0
- package/dist/workflows/pipeline-types.js.map +1 -0
- package/dist/workflows/proxy.js +76 -0
- package/dist/workflows/proxy.js.map +1 -0
- package/dist/workflows/runtime.js +310 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/schedule-builder.js +327 -0
- package/dist/workflows/schedule-builder.js.map +1 -0
- package/dist/workflows/visibility/index.js +146 -0
- package/dist/workflows/visibility/index.js.map +1 -0
- package/dist/workflows/visibility/query-parser.js +150 -0
- package/dist/workflows/visibility/query-parser.js.map +1 -0
- package/dist/workflows/visibility/store.js +223 -0
- package/dist/workflows/visibility/store.js.map +1 -0
- package/dist/workflows/visibility/types.js +30 -0
- package/dist/workflows/visibility/types.js.map +1 -0
- package/dist/workflows/workflow.js +53 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/package.json +294 -46
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* withBash Mixin - Shell Execution Capability
|
|
3
|
+
*
|
|
4
|
+
* Adds $.bash to the WorkflowContext with shell operations:
|
|
5
|
+
* - Tagged template execution: $.bash`command`
|
|
6
|
+
* - exec, run, spawn methods
|
|
7
|
+
* - parse, analyze, isDangerous utilities
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { withBash } from 'dotdo/mixins'
|
|
12
|
+
* import { withFs } from 'dotdo/mixins'
|
|
13
|
+
* import { DO } from 'dotdo'
|
|
14
|
+
*
|
|
15
|
+
* // Basic usage with executor
|
|
16
|
+
* class MyDO extends withBash(DO, {
|
|
17
|
+
* executor: () => ({
|
|
18
|
+
* execute: async (cmd, opts) => {
|
|
19
|
+
* // Execute via Containers, RPC, etc.
|
|
20
|
+
* return await containerExecutor.run(cmd, opts)
|
|
21
|
+
* }
|
|
22
|
+
* })
|
|
23
|
+
* }) {
|
|
24
|
+
* async deploy() {
|
|
25
|
+
* const result = await this.$.bash.exec('npm', ['run', 'build'])
|
|
26
|
+
* return result.exitCode === 0
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* // With FsCapability integration for native file ops
|
|
31
|
+
* class MyDO extends withBash(withFs(DO), {
|
|
32
|
+
* executor: () => containerExecutor,
|
|
33
|
+
* fs: (instance) => instance.$.fs // 'cat' uses $.fs.read() natively
|
|
34
|
+
* }) {
|
|
35
|
+
* async readConfig() {
|
|
36
|
+
* // 'cat config.json' uses $.fs.read() - Tier 1, fast!
|
|
37
|
+
* const result = await this.$.bash.exec('cat', ['config.json'])
|
|
38
|
+
* return result.stdout
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @module dotdo/mixins/bash
|
|
44
|
+
*/
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// NATIVE FS COMMANDS
|
|
47
|
+
// ============================================================================
|
|
48
|
+
const NATIVE_FS_COMMANDS = new Set(['cat', 'head', 'tail', 'ls', 'test']);
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// DANGEROUS COMMAND PATTERNS
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Patterns that indicate critically dangerous commands.
|
|
54
|
+
*/
|
|
55
|
+
const DANGEROUS_PATTERNS = [
|
|
56
|
+
{ pattern: /\brm\s+(-[rfvdi]*\s+)*\/($|\s|[^\/])/, reason: 'Dangerous: rm targeting root directory is blocked' },
|
|
57
|
+
{ pattern: /\brm\s+(-[rfvdi]*\s+)*\/\*/, reason: 'Dangerous: rm targeting root directory contents is blocked' },
|
|
58
|
+
{ pattern: /\brm\s+(-[rfvdi]*\s+)*~\//, reason: 'Dangerous: rm targeting home directory is blocked' },
|
|
59
|
+
{ pattern: /\bchmod\s+[0-7]{3,4}\s+\/($|\s)/, reason: 'Dangerous: chmod on root directory is blocked' },
|
|
60
|
+
{ pattern: /\bchmod\s+-[rR]\s+[0-7]{3,4}\s+\//, reason: 'Dangerous: recursive chmod on root is blocked' },
|
|
61
|
+
{ pattern: /\bdd\s+.*\bof=\/dev\/[hs]d[a-z]/, reason: 'Dangerous: dd writing to disk device is blocked' },
|
|
62
|
+
{ pattern: /\bmkfs\b/, reason: 'Dangerous: filesystem formatting command is blocked' },
|
|
63
|
+
{ pattern: /\bshutdown\b/, reason: 'Dangerous: system shutdown command is blocked' },
|
|
64
|
+
{ pattern: /\breboot\b/, reason: 'Dangerous: system reboot command is blocked' },
|
|
65
|
+
{ pattern: /:\(\)\s*\{\s*:\|\:&\s*\}\s*;\s*:/, reason: 'Dangerous: fork bomb is blocked' },
|
|
66
|
+
{ pattern: /\bsudo\b.*\brm\s+-rf\s+\//, reason: 'Dangerous: sudo rm -rf / is blocked' },
|
|
67
|
+
];
|
|
68
|
+
/**
|
|
69
|
+
* Commands that require network access.
|
|
70
|
+
*/
|
|
71
|
+
const NETWORK_COMMANDS = new Set([
|
|
72
|
+
'curl', 'wget', 'ssh', 'scp', 'rsync', 'nc', 'netcat', 'telnet', 'ftp', 'sftp',
|
|
73
|
+
'git push', 'git pull', 'git fetch', 'git clone', 'npm publish', 'pip upload',
|
|
74
|
+
]);
|
|
75
|
+
/**
|
|
76
|
+
* Commands that indicate elevated privileges.
|
|
77
|
+
*/
|
|
78
|
+
const ELEVATED_COMMANDS = new Set(['sudo', 'doas', 'su', 'pkexec']);
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// SHELL ESCAPING
|
|
81
|
+
// ============================================================================
|
|
82
|
+
function escapeForShell(value) {
|
|
83
|
+
const str = String(value);
|
|
84
|
+
if (str === '') {
|
|
85
|
+
return "''";
|
|
86
|
+
}
|
|
87
|
+
if (/^[a-zA-Z0-9_\-./:=@]+$/.test(str)) {
|
|
88
|
+
return str;
|
|
89
|
+
}
|
|
90
|
+
return "'" + str.replace(/'/g, "'\"'\"'") + "'";
|
|
91
|
+
}
|
|
92
|
+
function buildEscapedCommand(strings, values) {
|
|
93
|
+
return strings.reduce((acc, str, i) => acc + str + (values[i] !== undefined ? escapeForShell(values[i]) : ''), '');
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// LOCAL PARSING & ANALYSIS
|
|
97
|
+
// ============================================================================
|
|
98
|
+
/**
|
|
99
|
+
* Simple parser for bash commands (returns basic AST structure).
|
|
100
|
+
*/
|
|
101
|
+
function parse(input) {
|
|
102
|
+
// Extract command parts
|
|
103
|
+
const trimmed = input.trim();
|
|
104
|
+
const commands = [];
|
|
105
|
+
// Split on pipes and operators
|
|
106
|
+
const parts = trimmed.split(/\s*(\||&&|\|\||;)\s*/);
|
|
107
|
+
for (const part of parts) {
|
|
108
|
+
const cmd = part.trim().split(/\s+/)[0];
|
|
109
|
+
if (cmd && !['|', '&&', '||', ';'].includes(cmd)) {
|
|
110
|
+
commands.push(cmd);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
type: 'Program',
|
|
115
|
+
body: [{
|
|
116
|
+
type: 'Command',
|
|
117
|
+
name: commands[0] || '',
|
|
118
|
+
commands,
|
|
119
|
+
raw: trimmed,
|
|
120
|
+
}],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Analyze a command for safety classification.
|
|
125
|
+
*/
|
|
126
|
+
function analyze(ast) {
|
|
127
|
+
const raw = ast.body[0]?.raw || '';
|
|
128
|
+
const commands = ast.body[0]?.commands || [];
|
|
129
|
+
// Determine type
|
|
130
|
+
let type = 'read';
|
|
131
|
+
let impact = 'none';
|
|
132
|
+
let reversible = true;
|
|
133
|
+
let reason = 'Command analyzed';
|
|
134
|
+
// Extract info for intent
|
|
135
|
+
const reads = [];
|
|
136
|
+
const writes = [];
|
|
137
|
+
const deletes = [];
|
|
138
|
+
let network = false;
|
|
139
|
+
let elevated = false;
|
|
140
|
+
// Check for elevated commands
|
|
141
|
+
for (const cmd of commands) {
|
|
142
|
+
if (ELEVATED_COMMANDS.has(cmd)) {
|
|
143
|
+
elevated = true;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Check for network commands
|
|
147
|
+
for (const cmd of commands) {
|
|
148
|
+
if (NETWORK_COMMANDS.has(cmd)) {
|
|
149
|
+
network = true;
|
|
150
|
+
type = 'network';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Check for specific command types
|
|
154
|
+
const firstCmd = commands[0]?.toLowerCase() || '';
|
|
155
|
+
if (['ls', 'cat', 'head', 'tail', 'less', 'more', 'find', 'grep', 'wc', 'pwd', 'echo', 'date', 'whoami', 'id', 'env', 'printenv'].includes(firstCmd)) {
|
|
156
|
+
type = 'read';
|
|
157
|
+
impact = 'none';
|
|
158
|
+
reason = 'Read-only command';
|
|
159
|
+
// Extract read paths from arguments
|
|
160
|
+
const match = raw.match(/\s+([\/~][\w\/.-]+)/g);
|
|
161
|
+
if (match) {
|
|
162
|
+
reads.push(...match.map(m => m.trim()));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else if (['rm', 'rmdir', 'unlink'].includes(firstCmd)) {
|
|
166
|
+
type = 'delete';
|
|
167
|
+
reversible = false;
|
|
168
|
+
reason = 'Delete operation';
|
|
169
|
+
// Check for recursive flag
|
|
170
|
+
if (raw.includes('-r') || raw.includes('-R') || raw.includes('-rf') || raw.includes('-fr')) {
|
|
171
|
+
impact = 'high';
|
|
172
|
+
reason = 'Recursive delete operation';
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
impact = 'medium';
|
|
176
|
+
}
|
|
177
|
+
// Check for root path
|
|
178
|
+
if (/\s+\/($|\s)/.test(raw) || raw.includes('/*')) {
|
|
179
|
+
impact = 'critical';
|
|
180
|
+
reason = 'Delete targeting root or all files';
|
|
181
|
+
}
|
|
182
|
+
// Extract delete paths
|
|
183
|
+
const pathMatch = raw.match(/\s+([\/~\w][\w\/.-]*)/g);
|
|
184
|
+
if (pathMatch) {
|
|
185
|
+
deletes.push(...pathMatch.map(m => m.trim()).filter(p => !p.startsWith('-')));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (['mv', 'cp', 'touch', 'mkdir', 'tee'].includes(firstCmd)) {
|
|
189
|
+
type = 'write';
|
|
190
|
+
impact = 'low';
|
|
191
|
+
reversible = true;
|
|
192
|
+
reason = 'Write operation';
|
|
193
|
+
// Extract write paths
|
|
194
|
+
const pathMatch = raw.match(/\s+([\/~\w][\w\/.-]*)/g);
|
|
195
|
+
if (pathMatch) {
|
|
196
|
+
const paths = pathMatch.map(m => m.trim()).filter(p => !p.startsWith('-'));
|
|
197
|
+
if (firstCmd === 'mv' || firstCmd === 'cp') {
|
|
198
|
+
// Last path is destination
|
|
199
|
+
if (paths.length >= 2) {
|
|
200
|
+
reads.push(...paths.slice(0, -1));
|
|
201
|
+
writes.push(paths[paths.length - 1]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
writes.push(...paths);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (['chmod', 'chown', 'chgrp'].includes(firstCmd)) {
|
|
210
|
+
type = 'system';
|
|
211
|
+
impact = 'medium';
|
|
212
|
+
reversible = true;
|
|
213
|
+
reason = 'Permission/ownership change';
|
|
214
|
+
if (raw.includes('-R') || raw.includes('-r')) {
|
|
215
|
+
impact = 'high';
|
|
216
|
+
reason = 'Recursive permission change';
|
|
217
|
+
}
|
|
218
|
+
if (/\s+\/($|\s)/.test(raw)) {
|
|
219
|
+
impact = 'critical';
|
|
220
|
+
reason = 'Permission change on root directory';
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (['curl', 'wget', 'ssh', 'scp', 'rsync'].includes(firstCmd)) {
|
|
224
|
+
type = 'network';
|
|
225
|
+
network = true;
|
|
226
|
+
impact = 'low';
|
|
227
|
+
reversible = true;
|
|
228
|
+
reason = 'Network operation';
|
|
229
|
+
if (raw.includes('-X POST') || raw.includes('--data') || raw.includes('-d ')) {
|
|
230
|
+
impact = 'medium';
|
|
231
|
+
reason = 'Network request with data';
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else if (['git'].includes(firstCmd)) {
|
|
235
|
+
if (raw.includes('push')) {
|
|
236
|
+
type = 'network';
|
|
237
|
+
network = true;
|
|
238
|
+
impact = 'medium';
|
|
239
|
+
reason = 'Git push operation';
|
|
240
|
+
}
|
|
241
|
+
else if (raw.includes('pull') || raw.includes('fetch') || raw.includes('clone')) {
|
|
242
|
+
type = 'network';
|
|
243
|
+
network = true;
|
|
244
|
+
impact = 'low';
|
|
245
|
+
reason = 'Git network operation';
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
type = 'read';
|
|
249
|
+
impact = 'none';
|
|
250
|
+
reason = 'Git local operation';
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else if (['npm', 'yarn', 'pnpm'].includes(firstCmd)) {
|
|
254
|
+
if (raw.includes('install') || raw.includes('add')) {
|
|
255
|
+
type = 'write';
|
|
256
|
+
impact = 'low';
|
|
257
|
+
reason = 'Package installation';
|
|
258
|
+
}
|
|
259
|
+
else if (raw.includes('publish')) {
|
|
260
|
+
type = 'network';
|
|
261
|
+
network = true;
|
|
262
|
+
impact = 'high';
|
|
263
|
+
reason = 'Package publish operation';
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
type = 'execute';
|
|
267
|
+
impact = 'low';
|
|
268
|
+
reason = 'Package manager operation';
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else if (['dd', 'mkfs', 'fdisk', 'parted'].includes(firstCmd)) {
|
|
272
|
+
type = 'system';
|
|
273
|
+
impact = 'critical';
|
|
274
|
+
reversible = false;
|
|
275
|
+
reason = 'Low-level disk operation';
|
|
276
|
+
}
|
|
277
|
+
else if (['shutdown', 'reboot', 'halt', 'poweroff'].includes(firstCmd)) {
|
|
278
|
+
type = 'system';
|
|
279
|
+
impact = 'critical';
|
|
280
|
+
reversible = false;
|
|
281
|
+
reason = 'System shutdown/reboot';
|
|
282
|
+
}
|
|
283
|
+
else if (elevated) {
|
|
284
|
+
type = 'system';
|
|
285
|
+
impact = 'high';
|
|
286
|
+
reason = 'Elevated privilege command';
|
|
287
|
+
}
|
|
288
|
+
// Check for dangerous patterns (strip quoted content first to avoid false positives)
|
|
289
|
+
const unquotedForPatterns = stripQuotedContent(raw);
|
|
290
|
+
for (const { pattern, reason: dangerReason } of DANGEROUS_PATTERNS) {
|
|
291
|
+
if (pattern.test(unquotedForPatterns)) {
|
|
292
|
+
impact = 'critical';
|
|
293
|
+
reason = dangerReason;
|
|
294
|
+
reversible = false;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
classification: { type, impact, reversible, reason },
|
|
300
|
+
intent: { commands, reads, writes, deletes, network, elevated },
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Strip quoted content from a command for safety analysis.
|
|
305
|
+
* This removes content within single/double quotes to avoid false positives
|
|
306
|
+
* when dangerous patterns appear as literal strings (e.g., echo '; rm -rf /').
|
|
307
|
+
*/
|
|
308
|
+
function stripQuotedContent(cmd) {
|
|
309
|
+
// Replace single-quoted strings with placeholder
|
|
310
|
+
let result = cmd.replace(/'[^']*'/g, "'QUOTED'");
|
|
311
|
+
// Replace double-quoted strings with placeholder
|
|
312
|
+
result = result.replace(/"[^"]*"/g, '"QUOTED"');
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Check if a command is dangerous.
|
|
317
|
+
*/
|
|
318
|
+
function isDangerous(ast) {
|
|
319
|
+
const raw = ast.body[0]?.raw || '';
|
|
320
|
+
// Strip quoted content before checking patterns
|
|
321
|
+
// This prevents false positives when dangerous patterns appear as arguments
|
|
322
|
+
const unquoted = stripQuotedContent(raw);
|
|
323
|
+
for (const { pattern, reason } of DANGEROUS_PATTERNS) {
|
|
324
|
+
if (pattern.test(unquoted)) {
|
|
325
|
+
return { dangerous: true, reason };
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const analysis = analyze(ast);
|
|
329
|
+
if (analysis.classification.impact === 'critical') {
|
|
330
|
+
return { dangerous: true, reason: analysis.classification.reason };
|
|
331
|
+
}
|
|
332
|
+
return { dangerous: false };
|
|
333
|
+
}
|
|
334
|
+
// ============================================================================
|
|
335
|
+
// BASH CAPABILITY IMPLEMENTATION
|
|
336
|
+
// ============================================================================
|
|
337
|
+
function createBashCapability(executor, fsCapability, useNativeOps = true) {
|
|
338
|
+
function performSafetyAnalysis(command, options) {
|
|
339
|
+
const ast = parse(command);
|
|
340
|
+
const { classification, intent } = analyze(ast);
|
|
341
|
+
const dangerCheck = isDangerous(ast);
|
|
342
|
+
const requiresConfirm = classification.impact === 'critical' || classification.impact === 'high';
|
|
343
|
+
if (requiresConfirm && !options?.confirm) {
|
|
344
|
+
return createBlockedResult(command, classification, intent, dangerCheck.reason);
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
function createBlockedResult(command, classification, intent, reason) {
|
|
349
|
+
const blockReason = reason || classification.reason || 'Command blocked due to safety concerns';
|
|
350
|
+
return {
|
|
351
|
+
input: command,
|
|
352
|
+
command,
|
|
353
|
+
valid: true,
|
|
354
|
+
generated: false,
|
|
355
|
+
stdout: '',
|
|
356
|
+
stderr: '',
|
|
357
|
+
exitCode: 0,
|
|
358
|
+
intent,
|
|
359
|
+
classification,
|
|
360
|
+
blocked: true,
|
|
361
|
+
requiresConfirm: true,
|
|
362
|
+
blockReason,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
function createNativeResult(command, stdout, stderr = '', exitCode = 0) {
|
|
366
|
+
return {
|
|
367
|
+
input: command,
|
|
368
|
+
command,
|
|
369
|
+
valid: true,
|
|
370
|
+
generated: false,
|
|
371
|
+
stdout,
|
|
372
|
+
stderr,
|
|
373
|
+
exitCode,
|
|
374
|
+
intent: {
|
|
375
|
+
commands: [command.split(' ')[0]],
|
|
376
|
+
reads: [],
|
|
377
|
+
writes: [],
|
|
378
|
+
deletes: [],
|
|
379
|
+
network: false,
|
|
380
|
+
elevated: false,
|
|
381
|
+
},
|
|
382
|
+
classification: {
|
|
383
|
+
type: 'read',
|
|
384
|
+
impact: 'none',
|
|
385
|
+
reversible: true,
|
|
386
|
+
reason: 'Native filesystem operation',
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
async function nativeCat(args) {
|
|
391
|
+
if (!fsCapability || args.length === 0)
|
|
392
|
+
return null;
|
|
393
|
+
const files = args.filter((arg) => !arg.startsWith('-'));
|
|
394
|
+
if (files.length === 0)
|
|
395
|
+
return null;
|
|
396
|
+
try {
|
|
397
|
+
const contents = await Promise.all(files.map((file) => fsCapability.read(file)));
|
|
398
|
+
const stdout = contents.join('');
|
|
399
|
+
return createNativeResult(`cat ${args.join(' ')}`, stdout);
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
const stderr = error instanceof Error ? error.message : String(error);
|
|
403
|
+
return createNativeResult(`cat ${args.join(' ')}`, '', stderr, 1);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
async function nativeLs(args) {
|
|
407
|
+
if (!fsCapability)
|
|
408
|
+
return null;
|
|
409
|
+
const paths = args.filter((arg) => !arg.startsWith('-'));
|
|
410
|
+
const path = paths[0] || '.';
|
|
411
|
+
try {
|
|
412
|
+
const entries = await fsCapability.list(path);
|
|
413
|
+
const stdout = entries
|
|
414
|
+
.map((e) => (e.isDirectory ? `${e.name}/` : e.name))
|
|
415
|
+
.join('\n') + '\n';
|
|
416
|
+
return createNativeResult(`ls ${args.join(' ')}`, stdout);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
const stderr = error instanceof Error ? error.message : String(error);
|
|
420
|
+
return createNativeResult(`ls ${args.join(' ')}`, '', stderr, 1);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
async function nativeHead(args) {
|
|
424
|
+
if (!fsCapability)
|
|
425
|
+
return null;
|
|
426
|
+
let lines = 10;
|
|
427
|
+
let file;
|
|
428
|
+
for (let i = 0; i < args.length; i++) {
|
|
429
|
+
if (args[i] === '-n' && args[i + 1]) {
|
|
430
|
+
lines = parseInt(args[i + 1], 10);
|
|
431
|
+
i++;
|
|
432
|
+
}
|
|
433
|
+
else if (/^-\d+$/.test(args[i])) {
|
|
434
|
+
lines = parseInt(args[i].slice(1), 10);
|
|
435
|
+
}
|
|
436
|
+
else if (!args[i].startsWith('-')) {
|
|
437
|
+
file = args[i];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (!file)
|
|
441
|
+
return null;
|
|
442
|
+
try {
|
|
443
|
+
const content = await fsCapability.read(file);
|
|
444
|
+
const allLines = content.split('\n');
|
|
445
|
+
const stdout = allLines.slice(0, lines).join('\n');
|
|
446
|
+
return createNativeResult(`head ${args.join(' ')}`, stdout);
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
const stderr = error instanceof Error ? error.message : String(error);
|
|
450
|
+
return createNativeResult(`head ${args.join(' ')}`, '', stderr, 1);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
async function nativeTail(args) {
|
|
454
|
+
if (!fsCapability)
|
|
455
|
+
return null;
|
|
456
|
+
let lines = 10;
|
|
457
|
+
let file;
|
|
458
|
+
for (let i = 0; i < args.length; i++) {
|
|
459
|
+
if (args[i] === '-n' && args[i + 1]) {
|
|
460
|
+
lines = parseInt(args[i + 1], 10);
|
|
461
|
+
i++;
|
|
462
|
+
}
|
|
463
|
+
else if (/^-\d+$/.test(args[i])) {
|
|
464
|
+
lines = parseInt(args[i].slice(1), 10);
|
|
465
|
+
}
|
|
466
|
+
else if (!args[i].startsWith('-')) {
|
|
467
|
+
file = args[i];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!file)
|
|
471
|
+
return null;
|
|
472
|
+
try {
|
|
473
|
+
const content = await fsCapability.read(file);
|
|
474
|
+
const allLines = content.split('\n');
|
|
475
|
+
const effectiveLines = allLines[allLines.length - 1] === '' ? allLines.slice(0, -1) : allLines;
|
|
476
|
+
const stdout = effectiveLines.slice(-lines).join('\n') + '\n';
|
|
477
|
+
return createNativeResult(`tail ${args.join(' ')}`, stdout);
|
|
478
|
+
}
|
|
479
|
+
catch (error) {
|
|
480
|
+
const stderr = error instanceof Error ? error.message : String(error);
|
|
481
|
+
return createNativeResult(`tail ${args.join(' ')}`, '', stderr, 1);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
async function tryNativeExec(command, args) {
|
|
485
|
+
if (!fsCapability || !useNativeOps)
|
|
486
|
+
return null;
|
|
487
|
+
switch (command) {
|
|
488
|
+
case 'cat':
|
|
489
|
+
return nativeCat(args);
|
|
490
|
+
case 'ls':
|
|
491
|
+
return nativeLs(args);
|
|
492
|
+
case 'head':
|
|
493
|
+
return nativeHead(args);
|
|
494
|
+
case 'tail':
|
|
495
|
+
return nativeTail(args);
|
|
496
|
+
default:
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async function exec(command, args, options) {
|
|
501
|
+
const fullCommand = args && args.length > 0 ? `${command} ${args.join(' ')}` : command;
|
|
502
|
+
if (options?.dryRun) {
|
|
503
|
+
const ast = parse(fullCommand);
|
|
504
|
+
const { classification, intent } = analyze(ast);
|
|
505
|
+
return {
|
|
506
|
+
input: fullCommand,
|
|
507
|
+
command: fullCommand,
|
|
508
|
+
valid: true,
|
|
509
|
+
generated: false,
|
|
510
|
+
stdout: `[DRY RUN] Would execute: ${fullCommand}`,
|
|
511
|
+
stderr: '',
|
|
512
|
+
exitCode: 0,
|
|
513
|
+
intent,
|
|
514
|
+
classification,
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
const safetyResult = performSafetyAnalysis(fullCommand, options);
|
|
518
|
+
if (safetyResult) {
|
|
519
|
+
return safetyResult;
|
|
520
|
+
}
|
|
521
|
+
const ast = parse(fullCommand);
|
|
522
|
+
const { classification, intent } = analyze(ast);
|
|
523
|
+
if (useNativeOps && fsCapability && NATIVE_FS_COMMANDS.has(command)) {
|
|
524
|
+
const nativeResult = await tryNativeExec(command, args || []);
|
|
525
|
+
if (nativeResult) {
|
|
526
|
+
return nativeResult;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
const result = await executor.execute(fullCommand, options);
|
|
530
|
+
// Always use our local analysis, overriding the executor's default classification
|
|
531
|
+
// This ensures consistent behavior regardless of the executor implementation
|
|
532
|
+
result.classification = classification;
|
|
533
|
+
result.intent = intent;
|
|
534
|
+
return result;
|
|
535
|
+
}
|
|
536
|
+
async function spawn(command, args, options) {
|
|
537
|
+
if (!executor.spawn) {
|
|
538
|
+
throw new Error('Spawn not supported by this executor');
|
|
539
|
+
}
|
|
540
|
+
return executor.spawn(command, args, options);
|
|
541
|
+
}
|
|
542
|
+
async function run(script, options) {
|
|
543
|
+
const safetyResult = performSafetyAnalysis(script, options);
|
|
544
|
+
if (safetyResult) {
|
|
545
|
+
throw new Error(safetyResult.blockReason || 'Command blocked due to safety concerns');
|
|
546
|
+
}
|
|
547
|
+
const result = await executor.execute(script, options);
|
|
548
|
+
if (result.exitCode !== 0) {
|
|
549
|
+
throw new Error(result.stderr || `Command failed with exit code ${result.exitCode}`);
|
|
550
|
+
}
|
|
551
|
+
return result;
|
|
552
|
+
}
|
|
553
|
+
function bashParse(input) {
|
|
554
|
+
return parse(input);
|
|
555
|
+
}
|
|
556
|
+
function bashAnalyze(input) {
|
|
557
|
+
const ast = parse(input);
|
|
558
|
+
return analyze(ast);
|
|
559
|
+
}
|
|
560
|
+
function bashIsDangerous(input) {
|
|
561
|
+
const ast = parse(input);
|
|
562
|
+
return isDangerous(ast);
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Handle output redirection natively using fs capability.
|
|
566
|
+
* Matches patterns like: echo "content" > /path/to/file
|
|
567
|
+
* Returns null if no redirection or fs not available.
|
|
568
|
+
*/
|
|
569
|
+
async function handleNativeRedirection(command) {
|
|
570
|
+
if (!fsCapability || !useNativeOps)
|
|
571
|
+
return null;
|
|
572
|
+
// Match echo "content" > /path or echo 'content' > /path
|
|
573
|
+
const redirectMatch = command.match(/^echo\s+["'](.*)["']\s*>\s*(.+)$/);
|
|
574
|
+
if (redirectMatch) {
|
|
575
|
+
const content = redirectMatch[1];
|
|
576
|
+
const filePath = redirectMatch[2].trim();
|
|
577
|
+
try {
|
|
578
|
+
await fsCapability.write(filePath, content);
|
|
579
|
+
return {
|
|
580
|
+
input: command,
|
|
581
|
+
command,
|
|
582
|
+
valid: true,
|
|
583
|
+
generated: false,
|
|
584
|
+
stdout: '',
|
|
585
|
+
stderr: '',
|
|
586
|
+
exitCode: 0,
|
|
587
|
+
intent: {
|
|
588
|
+
commands: ['echo'],
|
|
589
|
+
reads: [],
|
|
590
|
+
writes: [filePath],
|
|
591
|
+
deletes: [],
|
|
592
|
+
network: false,
|
|
593
|
+
elevated: false,
|
|
594
|
+
},
|
|
595
|
+
classification: {
|
|
596
|
+
type: 'write',
|
|
597
|
+
impact: 'low',
|
|
598
|
+
reversible: true,
|
|
599
|
+
reason: 'Native filesystem write via redirection',
|
|
600
|
+
},
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
catch (error) {
|
|
604
|
+
const stderr = error instanceof Error ? error.message : String(error);
|
|
605
|
+
return {
|
|
606
|
+
input: command,
|
|
607
|
+
command,
|
|
608
|
+
valid: true,
|
|
609
|
+
generated: false,
|
|
610
|
+
stdout: '',
|
|
611
|
+
stderr,
|
|
612
|
+
exitCode: 1,
|
|
613
|
+
intent: {
|
|
614
|
+
commands: ['echo'],
|
|
615
|
+
reads: [],
|
|
616
|
+
writes: [filePath],
|
|
617
|
+
deletes: [],
|
|
618
|
+
network: false,
|
|
619
|
+
elevated: false,
|
|
620
|
+
},
|
|
621
|
+
classification: {
|
|
622
|
+
type: 'write',
|
|
623
|
+
impact: 'low',
|
|
624
|
+
reversible: true,
|
|
625
|
+
reason: 'Native filesystem write failed',
|
|
626
|
+
},
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
const taggedTemplate = async function (strings, ...values) {
|
|
633
|
+
const command = buildEscapedCommand(strings, values);
|
|
634
|
+
const ast = parse(command);
|
|
635
|
+
const dangerCheck = isDangerous(ast);
|
|
636
|
+
const { classification, intent } = analyze(ast);
|
|
637
|
+
if (dangerCheck.dangerous) {
|
|
638
|
+
throw new Error(dangerCheck.reason || 'Dangerous command blocked');
|
|
639
|
+
}
|
|
640
|
+
if (classification.impact === 'critical' || classification.impact === 'high') {
|
|
641
|
+
throw new Error(classification.reason || 'Critical/high impact command blocked');
|
|
642
|
+
}
|
|
643
|
+
// Try native redirection handling first
|
|
644
|
+
const nativeRedirectResult = await handleNativeRedirection(command);
|
|
645
|
+
if (nativeRedirectResult) {
|
|
646
|
+
return nativeRedirectResult;
|
|
647
|
+
}
|
|
648
|
+
// Pass empty object when no options to satisfy expect.anything() in tests
|
|
649
|
+
const result = await executor.execute(command, {});
|
|
650
|
+
// Always use our local analysis for consistency
|
|
651
|
+
result.classification = classification;
|
|
652
|
+
result.intent = intent;
|
|
653
|
+
return result;
|
|
654
|
+
};
|
|
655
|
+
const capability = taggedTemplate;
|
|
656
|
+
capability.exec = exec;
|
|
657
|
+
capability.spawn = spawn;
|
|
658
|
+
capability.run = run;
|
|
659
|
+
capability.parse = bashParse;
|
|
660
|
+
capability.analyze = bashAnalyze;
|
|
661
|
+
capability.isDangerous = bashIsDangerous;
|
|
662
|
+
return capability;
|
|
663
|
+
}
|
|
664
|
+
// ============================================================================
|
|
665
|
+
// MIXIN IMPLEMENTATION
|
|
666
|
+
// ============================================================================
|
|
667
|
+
const BASH_CAPABILITY_CACHE = Symbol('bashCapabilityCache');
|
|
668
|
+
export function withBash(Base, config) {
|
|
669
|
+
return class WithBash extends Base {
|
|
670
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
671
|
+
static capabilities = [...(Base.capabilities || []), 'bash'];
|
|
672
|
+
hasCapability(name) {
|
|
673
|
+
if (name === 'bash')
|
|
674
|
+
return true;
|
|
675
|
+
const baseProto = Base.prototype;
|
|
676
|
+
if (baseProto && typeof baseProto.hasCapability === 'function') {
|
|
677
|
+
return baseProto.hasCapability.call(this, name);
|
|
678
|
+
}
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
[BASH_CAPABILITY_CACHE];
|
|
682
|
+
get bashCapability() {
|
|
683
|
+
if (!this[BASH_CAPABILITY_CACHE]) {
|
|
684
|
+
const executor = config.executor(this);
|
|
685
|
+
const fs = config.fs?.(this);
|
|
686
|
+
this[BASH_CAPABILITY_CACHE] = createBashCapability(executor, fs, config.useNativeOps ?? true);
|
|
687
|
+
}
|
|
688
|
+
return this[BASH_CAPABILITY_CACHE];
|
|
689
|
+
}
|
|
690
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
691
|
+
constructor(...args) {
|
|
692
|
+
super(...args);
|
|
693
|
+
if (config.requireFs) {
|
|
694
|
+
const hasFs = Base.capabilities?.includes('fs') ||
|
|
695
|
+
this.hasCapability?.('fs');
|
|
696
|
+
if (!hasFs) {
|
|
697
|
+
throw new Error('withBash requires withFs capability when requireFs is true. Apply withFs(Base) first.');
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
const originalContext = this.$;
|
|
701
|
+
const self = this;
|
|
702
|
+
this.$ = new Proxy(originalContext, {
|
|
703
|
+
get(target, prop) {
|
|
704
|
+
if (prop === 'bash') {
|
|
705
|
+
return self.bashCapability;
|
|
706
|
+
}
|
|
707
|
+
const value = target[prop];
|
|
708
|
+
if (typeof value === 'function') {
|
|
709
|
+
// Only bind if it has a bind method (not a Proxy or capability object)
|
|
710
|
+
if (typeof value.bind === 'function') {
|
|
711
|
+
// Don't bind capability functions that have custom properties
|
|
712
|
+
const customProps = Object.getOwnPropertyNames(value).filter((p) => p !== 'length' && p !== 'name' && p !== 'prototype');
|
|
713
|
+
if (customProps.length > 0) {
|
|
714
|
+
return value;
|
|
715
|
+
}
|
|
716
|
+
return value.bind(target);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return value;
|
|
720
|
+
},
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
// ============================================================================
|
|
726
|
+
// LEGACY EXPORTS (for backward compatibility)
|
|
727
|
+
// ============================================================================
|
|
728
|
+
/** @deprecated Use createBashCapability instead */
|
|
729
|
+
export class BashModule {
|
|
730
|
+
capability;
|
|
731
|
+
constructor(executor, options) {
|
|
732
|
+
this.capability = createBashCapability(executor, options?.fs, options?.useNativeOps ?? true);
|
|
733
|
+
}
|
|
734
|
+
async exec(command, args, options) {
|
|
735
|
+
return this.capability.exec(command, args, options);
|
|
736
|
+
}
|
|
737
|
+
async spawn(command, args, options) {
|
|
738
|
+
return this.capability.spawn(command, args, options);
|
|
739
|
+
}
|
|
740
|
+
async run(script, options) {
|
|
741
|
+
return this.capability.run(script, options);
|
|
742
|
+
}
|
|
743
|
+
parse(input) {
|
|
744
|
+
return this.capability.parse(input);
|
|
745
|
+
}
|
|
746
|
+
analyze(input) {
|
|
747
|
+
return this.capability.analyze(input);
|
|
748
|
+
}
|
|
749
|
+
isDangerous(input) {
|
|
750
|
+
return this.capability.isDangerous(input);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
//# sourceMappingURL=bash.js.map
|