dotdo 0.0.1 → 0.0.2
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/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/analytics/router.js +601 -0
- package/dist/api/analytics/router.js.map +1 -0
- package/dist/api/index.js +158 -0
- package/dist/api/index.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 +544 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/api/middleware/error-handling.js +176 -0
- package/dist/api/middleware/error-handling.js.map +1 -0
- package/dist/api/middleware/request-id.js +21 -0
- package/dist/api/middleware/request-id.js.map +1 -0
- package/dist/api/pages.js +1180 -0
- package/dist/api/pages.js.map +1 -0
- package/dist/api/routes/api.js +612 -0
- package/dist/api/routes/api.js.map +1 -0
- package/dist/api/routes/browsers.js +471 -0
- package/dist/api/routes/browsers.js.map +1 -0
- package/dist/api/routes/do.js +188 -0
- package/dist/api/routes/do.js.map +1 -0
- package/dist/api/routes/mcp.js +459 -0
- package/dist/api/routes/mcp.js.map +1 -0
- package/dist/api/routes/obs.js +445 -0
- package/dist/api/routes/obs.js.map +1 -0
- package/dist/api/routes/openapi.js +794 -0
- package/dist/api/routes/openapi.js.map +1 -0
- package/dist/api/routes/rpc.js +1103 -0
- package/dist/api/routes/rpc.js.map +1 -0
- package/dist/api/routes/sandboxes.js +389 -0
- package/dist/api/routes/sandboxes.js.map +1 -0
- package/dist/api/test-do.js +38 -0
- package/dist/api/test-do.js.map +1 -0
- package/dist/api/types.js +11 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli/bin.js +2 -0
- package/dist/cli/main.js +52342 -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 +118 -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/bash.js +35 -0
- package/dist/do/bash.js.map +1 -0
- package/dist/do/fs.js +25 -0
- package/dist/do/fs.js.map +1 -0
- package/dist/do/full.js +61 -0
- package/dist/do/full.js.map +1 -0
- package/dist/do/git.js +28 -0
- package/dist/do/git.js.map +1 -0
- package/dist/do/index.js +52 -0
- package/dist/do/index.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/agent/tools/bash.js +336 -0
- package/dist/lib/agent/tools/bash.js.map +1 -0
- package/dist/lib/agent/tools/edit.js +157 -0
- package/dist/lib/agent/tools/edit.js.map +1 -0
- package/dist/lib/agent/tools/glob.js +137 -0
- package/dist/lib/agent/tools/glob.js.map +1 -0
- package/dist/lib/agent/tools/grep.js +315 -0
- package/dist/lib/agent/tools/grep.js.map +1 -0
- package/dist/lib/agent/tools/index.js +71 -0
- package/dist/lib/agent/tools/index.js.map +1 -0
- package/dist/lib/agent/tools/read.js +212 -0
- package/dist/lib/agent/tools/read.js.map +1 -0
- package/dist/lib/agent/tools/types.js +197 -0
- package/dist/lib/agent/tools/types.js.map +1 -0
- package/dist/lib/agent/tools/write.js +159 -0
- package/dist/lib/agent/tools/write.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 +825 -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 +1011 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/index.js +29 -0
- package/dist/lib/mixins/index.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 +1189 -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/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 +648 -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 +690 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1507 -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 +1536 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +575 -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/primitives/bashx/src/ast/analyze.js +1472 -0
- package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
- package/dist/primitives/bashx/src/ast/parser.js +1488 -0
- package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/container-executor.js +429 -0
- package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/index.js +668 -0
- package/dist/primitives/bashx/src/do/index.js.map +1 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/worker.js +352 -0
- package/dist/primitives/bashx/src/do/worker.js.map +1 -0
- package/dist/primitives/bashx/src/types.js +10 -0
- package/dist/primitives/bashx/src/types.js.map +1 -0
- package/dist/primitives/fsx/core/backend.js +480 -0
- package/dist/primitives/fsx/core/backend.js.map +1 -0
- package/dist/primitives/fsx/core/constants.js +140 -0
- package/dist/primitives/fsx/core/constants.js.map +1 -0
- package/dist/primitives/fsx/core/fsx.js +1184 -0
- package/dist/primitives/fsx/core/fsx.js.map +1 -0
- package/dist/primitives/fsx/core/glob/glob.js +438 -0
- package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
- package/dist/primitives/fsx/core/glob/index.js +8 -0
- package/dist/primitives/fsx/core/glob/index.js.map +1 -0
- package/dist/primitives/fsx/core/glob/match.js +392 -0
- package/dist/primitives/fsx/core/glob/match.js.map +1 -0
- package/dist/primitives/fsx/core/types.js +307 -0
- package/dist/primitives/fsx/core/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sdk/capnweb-compat.js +42 -0
- package/dist/sdk/capnweb-compat.js.map +1 -0
- package/dist/sdk/client.js +20 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/index.js +17 -0
- package/dist/sdk/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 +1215 -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 +148 -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 +279 -46
|
@@ -0,0 +1,1122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Math & Control Commands
|
|
3
|
+
*
|
|
4
|
+
* Native implementations for math and control flow commands:
|
|
5
|
+
* - bc: arbitrary precision calculator
|
|
6
|
+
* - expr: expression evaluator
|
|
7
|
+
* - seq: sequence generator
|
|
8
|
+
* - shuf: shuffle/randomize
|
|
9
|
+
* - sleep: delay execution
|
|
10
|
+
* - timeout: run with time limit
|
|
11
|
+
*
|
|
12
|
+
* @module bashx/do/commands/math-control
|
|
13
|
+
*/
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// TIMING UTILITIES
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Time unit multipliers in milliseconds.
|
|
19
|
+
* Used for parsing duration strings with suffixes.
|
|
20
|
+
*/
|
|
21
|
+
const TIME_UNIT_MS = {
|
|
22
|
+
s: 1000,
|
|
23
|
+
m: 60 * 1000,
|
|
24
|
+
h: 60 * 60 * 1000,
|
|
25
|
+
d: 24 * 60 * 60 * 1000,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Signal name to number mapping for timeout command.
|
|
29
|
+
* Supports both short (TERM) and long (SIGTERM) forms.
|
|
30
|
+
*/
|
|
31
|
+
const SIGNAL_MAP = {
|
|
32
|
+
TERM: 15,
|
|
33
|
+
SIGTERM: 15,
|
|
34
|
+
KILL: 9,
|
|
35
|
+
SIGKILL: 9,
|
|
36
|
+
INT: 2,
|
|
37
|
+
SIGINT: 2,
|
|
38
|
+
HUP: 1,
|
|
39
|
+
SIGHUP: 1,
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Timing utilities for duration parsing and delay operations.
|
|
43
|
+
* Provides a unified interface for all time-related operations.
|
|
44
|
+
*/
|
|
45
|
+
export const TimingUtils = {
|
|
46
|
+
/**
|
|
47
|
+
* Parse a duration string into milliseconds.
|
|
48
|
+
*
|
|
49
|
+
* @param duration - Duration string with optional unit suffix
|
|
50
|
+
* @returns Duration in milliseconds (may be Infinity)
|
|
51
|
+
* @throws Error if duration format is invalid
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* TimingUtils.parseDuration('5') // 5000 (seconds)
|
|
56
|
+
* TimingUtils.parseDuration('100ms') // Invalid - only s/m/h/d supported
|
|
57
|
+
* TimingUtils.parseDuration('1.5s') // 1500
|
|
58
|
+
* TimingUtils.parseDuration('2m') // 120000
|
|
59
|
+
* TimingUtils.parseDuration('1h') // 3600000
|
|
60
|
+
* TimingUtils.parseDuration('1d') // 86400000
|
|
61
|
+
* TimingUtils.parseDuration('infinity') // Infinity
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
parseDuration(duration) {
|
|
65
|
+
if (duration === 'infinity') {
|
|
66
|
+
return Infinity;
|
|
67
|
+
}
|
|
68
|
+
const match = duration.match(/^(\d+(?:\.\d+)?)(s|m|h|d)?$/);
|
|
69
|
+
if (!match) {
|
|
70
|
+
throw new Error(`Invalid duration: ${duration}`);
|
|
71
|
+
}
|
|
72
|
+
const value = parseFloat(match[1]);
|
|
73
|
+
const unit = match[2] || 's';
|
|
74
|
+
return value * (TIME_UNIT_MS[unit] ?? 1000);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Create a delay promise that resolves after the specified milliseconds.
|
|
78
|
+
*
|
|
79
|
+
* @param ms - Delay in milliseconds
|
|
80
|
+
* @returns Promise that resolves after delay
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* await TimingUtils.delay(1000) // Wait 1 second
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
delay(ms) {
|
|
88
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* Create an infinite wait promise (never resolves).
|
|
92
|
+
* Useful for "sleep infinity" semantics.
|
|
93
|
+
*
|
|
94
|
+
* @returns Promise that never resolves
|
|
95
|
+
*/
|
|
96
|
+
waitForever() {
|
|
97
|
+
return new Promise(() => { });
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Parse a signal specification into a signal number.
|
|
101
|
+
*
|
|
102
|
+
* @param signal - Signal name (e.g., "TERM", "SIGKILL") or number
|
|
103
|
+
* @returns Signal number
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* TimingUtils.parseSignal('TERM') // 15
|
|
108
|
+
* TimingUtils.parseSignal('SIGKILL') // 9
|
|
109
|
+
* TimingUtils.parseSignal(9) // 9
|
|
110
|
+
* TimingUtils.parseSignal('15') // 15
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
parseSignal(signal) {
|
|
114
|
+
if (typeof signal === 'number') {
|
|
115
|
+
return signal;
|
|
116
|
+
}
|
|
117
|
+
return SIGNAL_MAP[signal.toUpperCase()] ?? (parseInt(signal, 10) || 15);
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
// Backward compatibility export
|
|
121
|
+
export const parseDuration = TimingUtils.parseDuration;
|
|
122
|
+
/**
|
|
123
|
+
* Operator precedence levels (higher = binds tighter).
|
|
124
|
+
*/
|
|
125
|
+
const OPERATOR_PRECEDENCE = {
|
|
126
|
+
'|': 1,
|
|
127
|
+
'&': 2,
|
|
128
|
+
'=': 3, '!=': 3, '<': 3, '>': 3, '<=': 3, '>=': 3,
|
|
129
|
+
'+': 4, '-': 4,
|
|
130
|
+
'*': 5, '/': 5, '%': 5,
|
|
131
|
+
'^': 6, '**': 6,
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* ExpressionEngine provides a reusable expression parsing and evaluation system.
|
|
135
|
+
* Supports both bc-style and expr-style expression evaluation.
|
|
136
|
+
*/
|
|
137
|
+
export class ExpressionEngine {
|
|
138
|
+
variables = new Map();
|
|
139
|
+
scale = 0;
|
|
140
|
+
ibase = 10;
|
|
141
|
+
obase = 10;
|
|
142
|
+
mathLib = false;
|
|
143
|
+
/**
|
|
144
|
+
* Create a new ExpressionEngine instance.
|
|
145
|
+
*
|
|
146
|
+
* @param options - Configuration options
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* const engine = new ExpressionEngine({ mathLib: true, scale: 10 })
|
|
151
|
+
* const result = engine.evaluate('sqrt(2)')
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
constructor(options = {}) {
|
|
155
|
+
this.mathLib = options.mathLib ?? false;
|
|
156
|
+
this.scale = options.mathLib ? 20 : (options.scale ?? 0);
|
|
157
|
+
this.ibase = options.ibase ?? 10;
|
|
158
|
+
this.obase = options.obase ?? 10;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Set the decimal scale (number of decimal places).
|
|
162
|
+
*
|
|
163
|
+
* @param scale - Number of decimal places for division results
|
|
164
|
+
*/
|
|
165
|
+
setScale(scale) {
|
|
166
|
+
this.scale = scale;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Set the input base for number parsing.
|
|
170
|
+
*
|
|
171
|
+
* @param base - Input base (2-16)
|
|
172
|
+
*/
|
|
173
|
+
setInputBase(base) {
|
|
174
|
+
this.ibase = base;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Set the output base for result formatting.
|
|
178
|
+
*
|
|
179
|
+
* @param base - Output base (2-16)
|
|
180
|
+
*/
|
|
181
|
+
setOutputBase(base) {
|
|
182
|
+
this.obase = base;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Set a variable value.
|
|
186
|
+
*
|
|
187
|
+
* @param name - Variable name
|
|
188
|
+
* @param value - Numeric value
|
|
189
|
+
*/
|
|
190
|
+
setVariable(name, value) {
|
|
191
|
+
this.variables.set(name, value);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get the operator precedence for comparison.
|
|
195
|
+
*
|
|
196
|
+
* @param op - Operator string
|
|
197
|
+
* @returns Precedence level (higher binds tighter)
|
|
198
|
+
*/
|
|
199
|
+
getOperatorPrecedence(op) {
|
|
200
|
+
return OPERATOR_PRECEDENCE[op] ?? 0;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if an operator is right-associative.
|
|
204
|
+
*
|
|
205
|
+
* @param op - Operator string
|
|
206
|
+
* @returns True if right-associative
|
|
207
|
+
*/
|
|
208
|
+
isRightAssociative(op) {
|
|
209
|
+
return op === '^' || op === '**';
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Evaluate a bc-style expression.
|
|
213
|
+
*
|
|
214
|
+
* @param expr - Expression string
|
|
215
|
+
* @returns Numeric result
|
|
216
|
+
* @throws Error on syntax errors or invalid operations
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* engine.evaluate('2+3*4') // 14
|
|
221
|
+
* engine.evaluate('(2+3)*4') // 20
|
|
222
|
+
* engine.evaluate('2^10') // 1024
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
evaluate(expr) {
|
|
226
|
+
// Substitute variables
|
|
227
|
+
let processedExpr = expr;
|
|
228
|
+
for (const [name, value] of this.variables) {
|
|
229
|
+
processedExpr = processedExpr.replace(new RegExp(`\\b${name}\\b`, 'g'), String(value));
|
|
230
|
+
}
|
|
231
|
+
// Process math functions
|
|
232
|
+
processedExpr = this.processMathFunctions(processedExpr);
|
|
233
|
+
// Convert from input base if needed
|
|
234
|
+
if (this.ibase !== 10) {
|
|
235
|
+
processedExpr = processedExpr.replace(/\b([0-9A-F]+)\b/g, match => {
|
|
236
|
+
return String(parseInt(match, this.ibase));
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// Convert ^ to ** for JavaScript exponentiation
|
|
240
|
+
processedExpr = processedExpr.replace(/\^/g, '**');
|
|
241
|
+
// Check for division by zero
|
|
242
|
+
if (/\/\s*0(?![0-9])/.test(processedExpr)) {
|
|
243
|
+
throw new Error('divide by zero');
|
|
244
|
+
}
|
|
245
|
+
// Check for syntax errors (consecutive operators excluding **)
|
|
246
|
+
if (/[+\-*/%]{2,}/.test(processedExpr.replace(/\*\*/g, 'POW'))) {
|
|
247
|
+
throw new Error('syntax error');
|
|
248
|
+
}
|
|
249
|
+
// Evaluate using safe Function constructor
|
|
250
|
+
try {
|
|
251
|
+
const fn = new Function(`return (${processedExpr})`);
|
|
252
|
+
const result = fn();
|
|
253
|
+
if (typeof result !== 'number' || !isFinite(result)) {
|
|
254
|
+
throw new Error('invalid result');
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
throw new Error('syntax error');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Process math library functions in the expression.
|
|
264
|
+
*
|
|
265
|
+
* @param expr - Expression with function calls
|
|
266
|
+
* @returns Expression with functions evaluated
|
|
267
|
+
*/
|
|
268
|
+
processMathFunctions(expr) {
|
|
269
|
+
let result = expr;
|
|
270
|
+
// Always handle sqrt
|
|
271
|
+
result = this.processFunction(result, 'sqrt', (val) => {
|
|
272
|
+
if (val < 0)
|
|
273
|
+
throw new Error('square root of negative number');
|
|
274
|
+
return Math.sqrt(val);
|
|
275
|
+
});
|
|
276
|
+
// Math library functions
|
|
277
|
+
if (this.mathLib) {
|
|
278
|
+
result = this.processFunction(result, 's', Math.sin);
|
|
279
|
+
result = this.processFunction(result, 'c', Math.cos);
|
|
280
|
+
result = this.processFunction(result, 'a', Math.atan);
|
|
281
|
+
result = this.processFunction(result, 'l', Math.log);
|
|
282
|
+
result = this.processFunction(result, 'e', Math.exp);
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Process a single function in the expression.
|
|
288
|
+
*
|
|
289
|
+
* @param expr - Expression string
|
|
290
|
+
* @param name - Function name
|
|
291
|
+
* @param fn - JavaScript function to apply
|
|
292
|
+
* @returns Expression with function evaluated
|
|
293
|
+
*/
|
|
294
|
+
processFunction(expr, name, fn) {
|
|
295
|
+
const pattern = new RegExp(`\\b${name}\\(([^)]+)\\)`, 'g');
|
|
296
|
+
return expr.replace(pattern, (_, arg) => {
|
|
297
|
+
const val = this.evaluate(arg);
|
|
298
|
+
return String(fn(val));
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Format a numeric result according to current settings.
|
|
303
|
+
*
|
|
304
|
+
* @param value - Numeric value to format
|
|
305
|
+
* @returns Formatted string representation
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```ts
|
|
309
|
+
* engine.setScale(2)
|
|
310
|
+
* engine.format(3.14159) // "3.14"
|
|
311
|
+
*
|
|
312
|
+
* engine.setOutputBase(16)
|
|
313
|
+
* engine.format(255) // "FF"
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
format(value) {
|
|
317
|
+
// Handle decimal scale
|
|
318
|
+
if (this.scale > 0 && !Number.isInteger(value)) {
|
|
319
|
+
// bc truncates, doesn't round
|
|
320
|
+
const factor = Math.pow(10, this.scale);
|
|
321
|
+
const truncated = Math.trunc(value * factor) / factor;
|
|
322
|
+
let formatted = truncated.toFixed(this.scale);
|
|
323
|
+
// bc compatibility: remove leading zero for |value| < 1
|
|
324
|
+
if (Math.abs(truncated) < 1 && truncated !== 0) {
|
|
325
|
+
formatted = formatted.replace(/^-?0\./, match => match.startsWith('-') ? '-.' : '.');
|
|
326
|
+
}
|
|
327
|
+
return formatted;
|
|
328
|
+
}
|
|
329
|
+
// Integer output
|
|
330
|
+
const intValue = Math.trunc(value);
|
|
331
|
+
// Convert to output base
|
|
332
|
+
if (this.obase !== 10) {
|
|
333
|
+
return intValue.toString(this.obase).toUpperCase();
|
|
334
|
+
}
|
|
335
|
+
return String(intValue);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// ============================================================================
|
|
339
|
+
// FORMAT UTILITIES
|
|
340
|
+
// ============================================================================
|
|
341
|
+
/**
|
|
342
|
+
* Format utilities for number output formatting.
|
|
343
|
+
*/
|
|
344
|
+
export const FormatUtils = {
|
|
345
|
+
/**
|
|
346
|
+
* Simple sprintf implementation for format strings.
|
|
347
|
+
* Supports %g, %f, %e format specifiers.
|
|
348
|
+
*
|
|
349
|
+
* @param format - Format string with % specifiers
|
|
350
|
+
* @param value - Numeric value to format
|
|
351
|
+
* @returns Formatted string
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```ts
|
|
355
|
+
* FormatUtils.sprintf('%.2f', 3.14159) // "3.14"
|
|
356
|
+
* FormatUtils.sprintf('%03g', 5) // "005"
|
|
357
|
+
* FormatUtils.sprintf('%.2e', 1000) // "1.00e+03"
|
|
358
|
+
* FormatUtils.sprintf('Value: %g%%', 50) // "Value: 50%"
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
sprintf(format, value) {
|
|
362
|
+
return format
|
|
363
|
+
.replace(/%(\d+)?(?:\.(\d+))?(g|f|e)/, (_, width, precision, type) => {
|
|
364
|
+
let result;
|
|
365
|
+
const prec = precision !== undefined ? parseInt(precision, 10) : undefined;
|
|
366
|
+
switch (type) {
|
|
367
|
+
case 'f':
|
|
368
|
+
result = prec !== undefined ? value.toFixed(prec) : String(value);
|
|
369
|
+
break;
|
|
370
|
+
case 'e': {
|
|
371
|
+
const expStr = prec !== undefined
|
|
372
|
+
? value.toExponential(prec)
|
|
373
|
+
: value.toExponential();
|
|
374
|
+
// Ensure exponent has at least 2 digits (e+03 not e+3)
|
|
375
|
+
result = expStr.replace(/e([+-])(\d)$/, 'e$10$2');
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
case 'g':
|
|
379
|
+
default:
|
|
380
|
+
if (prec !== undefined) {
|
|
381
|
+
result = value.toPrecision(prec).replace(/\.?0+$/, '');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
result = String(value);
|
|
385
|
+
}
|
|
386
|
+
// Pad with zeros if width specified
|
|
387
|
+
if (width) {
|
|
388
|
+
const w = parseInt(width, 10);
|
|
389
|
+
result = result.padStart(w, '0');
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
return result;
|
|
394
|
+
})
|
|
395
|
+
.replace(/%%/g, '%');
|
|
396
|
+
},
|
|
397
|
+
/**
|
|
398
|
+
* Calculate the decimal precision of a number.
|
|
399
|
+
*
|
|
400
|
+
* @param n - Number to analyze
|
|
401
|
+
* @returns Number of decimal places
|
|
402
|
+
*/
|
|
403
|
+
getPrecision(n) {
|
|
404
|
+
const str = String(n);
|
|
405
|
+
const dot = str.indexOf('.');
|
|
406
|
+
return dot >= 0 ? str.length - dot - 1 : 0;
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
// ============================================================================
|
|
410
|
+
// RANDOM UTILITIES
|
|
411
|
+
// ============================================================================
|
|
412
|
+
/**
|
|
413
|
+
* Random number utilities for shuffling and sampling.
|
|
414
|
+
*/
|
|
415
|
+
export const RandomUtils = {
|
|
416
|
+
/**
|
|
417
|
+
* Generate a random integer in the range [0, max).
|
|
418
|
+
*
|
|
419
|
+
* @param max - Exclusive upper bound
|
|
420
|
+
* @returns Random integer
|
|
421
|
+
*/
|
|
422
|
+
randomInt(max) {
|
|
423
|
+
return Math.floor(Math.random() * max);
|
|
424
|
+
},
|
|
425
|
+
/**
|
|
426
|
+
* Fisher-Yates shuffle algorithm for in-place array shuffling.
|
|
427
|
+
*
|
|
428
|
+
* @param array - Array to shuffle (mutates in place)
|
|
429
|
+
* @returns The shuffled array (same reference)
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```ts
|
|
433
|
+
* const arr = [1, 2, 3, 4, 5]
|
|
434
|
+
* RandomUtils.shuffle(arr)
|
|
435
|
+
* // arr is now shuffled
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
shuffle(array) {
|
|
439
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
440
|
+
const j = this.randomInt(i + 1);
|
|
441
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
442
|
+
}
|
|
443
|
+
return array;
|
|
444
|
+
},
|
|
445
|
+
/**
|
|
446
|
+
* Sample n items from an array without replacement.
|
|
447
|
+
*
|
|
448
|
+
* @param array - Source array
|
|
449
|
+
* @param n - Number of items to sample
|
|
450
|
+
* @returns Array of sampled items
|
|
451
|
+
*/
|
|
452
|
+
sample(array, n) {
|
|
453
|
+
const shuffled = this.shuffle([...array]);
|
|
454
|
+
return shuffled.slice(0, Math.min(n, shuffled.length));
|
|
455
|
+
},
|
|
456
|
+
/**
|
|
457
|
+
* Sample n items from an array with replacement.
|
|
458
|
+
*
|
|
459
|
+
* @param array - Source array
|
|
460
|
+
* @param n - Number of items to sample
|
|
461
|
+
* @returns Array of sampled items (may contain duplicates)
|
|
462
|
+
*/
|
|
463
|
+
sampleWithReplacement(array, n) {
|
|
464
|
+
const result = [];
|
|
465
|
+
for (let i = 0; i < n; i++) {
|
|
466
|
+
result.push(array[this.randomInt(array.length)]);
|
|
467
|
+
}
|
|
468
|
+
return result;
|
|
469
|
+
},
|
|
470
|
+
};
|
|
471
|
+
// ============================================================================
|
|
472
|
+
// BC - ARBITRARY PRECISION CALCULATOR
|
|
473
|
+
// ============================================================================
|
|
474
|
+
/**
|
|
475
|
+
* Execute bc expression.
|
|
476
|
+
*
|
|
477
|
+
* bc is a calculator language supporting arbitrary precision arithmetic.
|
|
478
|
+
* This implementation provides compatibility with GNU bc for common operations.
|
|
479
|
+
*
|
|
480
|
+
* @param expression - The bc expression to evaluate
|
|
481
|
+
* @param options - Options including math library flag
|
|
482
|
+
* @returns Result object with result string or error
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* ```ts
|
|
486
|
+
* executeBc('2+2') // { result: '4', exitCode: 0, stderr: '' }
|
|
487
|
+
* executeBc('scale=2; 10/3') // { result: '3.33', exitCode: 0, stderr: '' }
|
|
488
|
+
* executeBc('sqrt(16)', { mathLib: true }) // { result: '4.00...', exitCode: 0, stderr: '' }
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
export function executeBc(expression, options = {}) {
|
|
492
|
+
const engine = new ExpressionEngine({
|
|
493
|
+
mathLib: options.mathLib,
|
|
494
|
+
});
|
|
495
|
+
try {
|
|
496
|
+
// Split by semicolons or newlines
|
|
497
|
+
const lines = expression
|
|
498
|
+
.split(/[;\n]/)
|
|
499
|
+
.map(l => l.trim())
|
|
500
|
+
.filter(l => l.length > 0);
|
|
501
|
+
const results = [];
|
|
502
|
+
for (const line of lines) {
|
|
503
|
+
// Handle scale setting
|
|
504
|
+
if (line.startsWith('scale=')) {
|
|
505
|
+
engine.setScale(parseInt(line.slice(6), 10));
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
// Handle ibase setting
|
|
509
|
+
if (line.startsWith('ibase=')) {
|
|
510
|
+
engine.setInputBase(parseInt(line.slice(6), 10));
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
// Handle obase setting
|
|
514
|
+
if (line.startsWith('obase=')) {
|
|
515
|
+
engine.setOutputBase(parseInt(line.slice(6), 10));
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
// Handle variable assignment
|
|
519
|
+
const assignMatch = line.match(/^([a-z_][a-z0-9_]*)=(.+)$/i);
|
|
520
|
+
if (assignMatch) {
|
|
521
|
+
const [, varName, expr] = assignMatch;
|
|
522
|
+
const value = engine.evaluate(expr);
|
|
523
|
+
engine.setVariable(varName, value);
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
// Evaluate expression and collect result
|
|
527
|
+
const value = engine.evaluate(line);
|
|
528
|
+
results.push(engine.format(value));
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
result: results.join('\n'),
|
|
532
|
+
exitCode: 0,
|
|
533
|
+
stderr: '',
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
538
|
+
return {
|
|
539
|
+
result: '',
|
|
540
|
+
exitCode: 1,
|
|
541
|
+
stderr: `bc: ${message}`,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// ============================================================================
|
|
546
|
+
// EXPR - EXPRESSION EVALUATOR
|
|
547
|
+
// ============================================================================
|
|
548
|
+
/**
|
|
549
|
+
* Execute expr command.
|
|
550
|
+
*
|
|
551
|
+
* expr is a command-line expression evaluator that follows POSIX semantics.
|
|
552
|
+
* It handles arithmetic, string operations, and pattern matching.
|
|
553
|
+
*
|
|
554
|
+
* @param args - Arguments to expr (space-separated expression parts)
|
|
555
|
+
* @returns Result with string output and exit code
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```ts
|
|
559
|
+
* executeExpr(['2', '+', '2']) // { result: '4', exitCode: 0, stderr: '' }
|
|
560
|
+
* executeExpr(['hello', ':', '.*']) // { result: '5', exitCode: 0, stderr: '' }
|
|
561
|
+
* executeExpr(['length', 'hello']) // { result: '5', exitCode: 0, stderr: '' }
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
export function executeExpr(args) {
|
|
565
|
+
if (args.length === 0) {
|
|
566
|
+
return { result: '', exitCode: 2, stderr: 'expr: missing operand' };
|
|
567
|
+
}
|
|
568
|
+
try {
|
|
569
|
+
const result = evaluateExprTokens(args);
|
|
570
|
+
const exitCode = result === '0' || result === '' ? 1 : 0;
|
|
571
|
+
return { result, exitCode, stderr: '' };
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
575
|
+
return { result: '', exitCode: 2, stderr: `expr: ${message}` };
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Evaluate expr tokens with proper precedence.
|
|
580
|
+
* Follows POSIX expr operator precedence:
|
|
581
|
+
* OR < AND < comparisons < addition/subtraction < multiplication/division/modulo
|
|
582
|
+
*
|
|
583
|
+
* @param tokens - Array of expression tokens
|
|
584
|
+
* @returns Evaluated result as string
|
|
585
|
+
*/
|
|
586
|
+
function evaluateExprTokens(tokens) {
|
|
587
|
+
// Handle parentheses first (highest precedence)
|
|
588
|
+
tokens = processParentheses(tokens);
|
|
589
|
+
// Handle string operations: match, substr, index, length
|
|
590
|
+
if (tokens[0] === 'match' && tokens.length >= 3) {
|
|
591
|
+
return exprMatch(tokens[1], tokens[2]);
|
|
592
|
+
}
|
|
593
|
+
if (tokens[0] === 'substr' && tokens.length >= 4) {
|
|
594
|
+
const str = tokens[1];
|
|
595
|
+
const pos = parseInt(tokens[2], 10);
|
|
596
|
+
const len = parseInt(tokens[3], 10);
|
|
597
|
+
return str.substring(pos - 1, pos - 1 + len);
|
|
598
|
+
}
|
|
599
|
+
if (tokens[0] === 'index' && tokens.length >= 3) {
|
|
600
|
+
const str = tokens[1];
|
|
601
|
+
const chars = tokens[2];
|
|
602
|
+
for (let idx = 0; idx < str.length; idx++) {
|
|
603
|
+
if (chars.includes(str[idx])) {
|
|
604
|
+
return String(idx + 1);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return '0';
|
|
608
|
+
}
|
|
609
|
+
if (tokens[0] === 'length' && tokens.length >= 2) {
|
|
610
|
+
return String(tokens[1].length);
|
|
611
|
+
}
|
|
612
|
+
// Handle : operator (pattern matching, anchored at start)
|
|
613
|
+
const colonIdx = tokens.indexOf(':');
|
|
614
|
+
if (colonIdx > 0) {
|
|
615
|
+
const str = tokens[colonIdx - 1];
|
|
616
|
+
const pattern = tokens[colonIdx + 1];
|
|
617
|
+
const result = exprMatch(str, pattern);
|
|
618
|
+
tokens = [
|
|
619
|
+
...tokens.slice(0, colonIdx - 1),
|
|
620
|
+
result,
|
|
621
|
+
...tokens.slice(colonIdx + 2),
|
|
622
|
+
];
|
|
623
|
+
if (tokens.length === 1)
|
|
624
|
+
return tokens[0];
|
|
625
|
+
}
|
|
626
|
+
// Handle operators by precedence (lowest to highest)
|
|
627
|
+
// OR (|) - lowest precedence
|
|
628
|
+
const orIdx = findOperator(tokens, ['|', '\\|']);
|
|
629
|
+
if (orIdx >= 0) {
|
|
630
|
+
const left = evaluateExprTokens(tokens.slice(0, orIdx));
|
|
631
|
+
if (left !== '0' && left !== '')
|
|
632
|
+
return left;
|
|
633
|
+
return evaluateExprTokens(tokens.slice(orIdx + 1));
|
|
634
|
+
}
|
|
635
|
+
// AND (&)
|
|
636
|
+
const andIdx = findOperator(tokens, ['&', '\\&']);
|
|
637
|
+
if (andIdx >= 0) {
|
|
638
|
+
const left = evaluateExprTokens(tokens.slice(0, andIdx));
|
|
639
|
+
if (left === '0' || left === '')
|
|
640
|
+
return '0';
|
|
641
|
+
const right = evaluateExprTokens(tokens.slice(andIdx + 1));
|
|
642
|
+
if (right === '0' || right === '')
|
|
643
|
+
return '0';
|
|
644
|
+
return left;
|
|
645
|
+
}
|
|
646
|
+
// Comparison operators
|
|
647
|
+
const compOps = ['=', '!=', '<', '>', '<=', '>=', '\\<', '\\>', '\\<=', '\\>='];
|
|
648
|
+
const compIdx = findOperator(tokens, compOps);
|
|
649
|
+
if (compIdx >= 0) {
|
|
650
|
+
return evaluateComparison(tokens, compIdx);
|
|
651
|
+
}
|
|
652
|
+
// Addition/Subtraction (search from right for left-to-right associativity)
|
|
653
|
+
const addSubIdx = findOperator(tokens, ['+', '-'], true);
|
|
654
|
+
if (addSubIdx >= 0 && addSubIdx > 0) {
|
|
655
|
+
return evaluateArithmetic(tokens, addSubIdx, ['+', '-']);
|
|
656
|
+
}
|
|
657
|
+
// Multiplication/Division/Modulo (highest arithmetic precedence)
|
|
658
|
+
const mulDivIdx = findOperator(tokens, ['*', '\\*', '/', '%']);
|
|
659
|
+
if (mulDivIdx >= 0) {
|
|
660
|
+
return evaluateArithmetic(tokens, mulDivIdx, ['*', '/', '%']);
|
|
661
|
+
}
|
|
662
|
+
// Single value
|
|
663
|
+
if (tokens.length === 1) {
|
|
664
|
+
return tokens[0];
|
|
665
|
+
}
|
|
666
|
+
throw new Error('syntax error');
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Process parentheses in token array.
|
|
670
|
+
*
|
|
671
|
+
* @param tokens - Token array
|
|
672
|
+
* @returns Token array with parenthesized expressions evaluated
|
|
673
|
+
*/
|
|
674
|
+
function processParentheses(tokens) {
|
|
675
|
+
let result = [...tokens];
|
|
676
|
+
let i = 0;
|
|
677
|
+
while (i < result.length) {
|
|
678
|
+
if (result[i] === '(' || result[i] === '\\(') {
|
|
679
|
+
let depth = 1;
|
|
680
|
+
let j = i + 1;
|
|
681
|
+
while (j < result.length && depth > 0) {
|
|
682
|
+
if (result[j] === '(' || result[j] === '\\(')
|
|
683
|
+
depth++;
|
|
684
|
+
if (result[j] === ')' || result[j] === '\\)')
|
|
685
|
+
depth--;
|
|
686
|
+
j++;
|
|
687
|
+
}
|
|
688
|
+
const subResult = evaluateExprTokens(result.slice(i + 1, j - 1));
|
|
689
|
+
result = [...result.slice(0, i), subResult, ...result.slice(j)];
|
|
690
|
+
}
|
|
691
|
+
i++;
|
|
692
|
+
}
|
|
693
|
+
return result;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Evaluate a comparison operation.
|
|
697
|
+
*
|
|
698
|
+
* @param tokens - Token array
|
|
699
|
+
* @param idx - Index of comparison operator
|
|
700
|
+
* @returns '1' for true, '0' for false
|
|
701
|
+
*/
|
|
702
|
+
function evaluateComparison(tokens, idx) {
|
|
703
|
+
const left = evaluateExprTokens(tokens.slice(0, idx));
|
|
704
|
+
const op = tokens[idx].replace(/^\\/, '');
|
|
705
|
+
const right = evaluateExprTokens(tokens.slice(idx + 1));
|
|
706
|
+
// Try numeric comparison first
|
|
707
|
+
const leftNum = parseFloat(left);
|
|
708
|
+
const rightNum = parseFloat(right);
|
|
709
|
+
const isNumeric = !isNaN(leftNum) && !isNaN(rightNum);
|
|
710
|
+
let result;
|
|
711
|
+
switch (op) {
|
|
712
|
+
case '=':
|
|
713
|
+
result = isNumeric ? leftNum === rightNum : left === right;
|
|
714
|
+
break;
|
|
715
|
+
case '!=':
|
|
716
|
+
result = isNumeric ? leftNum !== rightNum : left !== right;
|
|
717
|
+
break;
|
|
718
|
+
case '<':
|
|
719
|
+
result = isNumeric ? leftNum < rightNum : left < right;
|
|
720
|
+
break;
|
|
721
|
+
case '>':
|
|
722
|
+
result = isNumeric ? leftNum > rightNum : left > right;
|
|
723
|
+
break;
|
|
724
|
+
case '<=':
|
|
725
|
+
result = isNumeric ? leftNum <= rightNum : left <= right;
|
|
726
|
+
break;
|
|
727
|
+
case '>=':
|
|
728
|
+
result = isNumeric ? leftNum >= rightNum : left >= right;
|
|
729
|
+
break;
|
|
730
|
+
default:
|
|
731
|
+
result = false;
|
|
732
|
+
}
|
|
733
|
+
return result ? '1' : '0';
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Evaluate an arithmetic operation.
|
|
737
|
+
*
|
|
738
|
+
* @param tokens - Token array
|
|
739
|
+
* @param idx - Index of arithmetic operator
|
|
740
|
+
* @param ops - Valid operators for this evaluation
|
|
741
|
+
* @returns Result as string
|
|
742
|
+
*/
|
|
743
|
+
function evaluateArithmetic(tokens, idx, _ops) {
|
|
744
|
+
const left = evaluateExprTokens(tokens.slice(0, idx));
|
|
745
|
+
const op = tokens[idx].replace(/^\\/, '');
|
|
746
|
+
const right = evaluateExprTokens(tokens.slice(idx + 1));
|
|
747
|
+
const leftNum = parseInt(left, 10);
|
|
748
|
+
const rightNum = parseInt(right, 10);
|
|
749
|
+
if (isNaN(leftNum) || isNaN(rightNum)) {
|
|
750
|
+
throw new Error('non-numeric argument');
|
|
751
|
+
}
|
|
752
|
+
switch (op) {
|
|
753
|
+
case '+':
|
|
754
|
+
return String(leftNum + rightNum);
|
|
755
|
+
case '-':
|
|
756
|
+
return String(leftNum - rightNum);
|
|
757
|
+
case '*':
|
|
758
|
+
return String(leftNum * rightNum);
|
|
759
|
+
case '/':
|
|
760
|
+
if (rightNum === 0)
|
|
761
|
+
throw new Error('division by zero');
|
|
762
|
+
return String(Math.trunc(leftNum / rightNum));
|
|
763
|
+
case '%':
|
|
764
|
+
if (rightNum === 0)
|
|
765
|
+
throw new Error('division by zero');
|
|
766
|
+
return String(leftNum % rightNum);
|
|
767
|
+
default:
|
|
768
|
+
throw new Error('syntax error');
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Find operator in tokens array.
|
|
773
|
+
*
|
|
774
|
+
* @param tokens - Token array to search
|
|
775
|
+
* @param ops - Operators to find
|
|
776
|
+
* @param fromRight - Search from right (for left-to-right associativity)
|
|
777
|
+
* @returns Index of operator or -1 if not found
|
|
778
|
+
*/
|
|
779
|
+
function findOperator(tokens, ops, fromRight = false) {
|
|
780
|
+
if (fromRight) {
|
|
781
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
782
|
+
if (ops.includes(tokens[i]))
|
|
783
|
+
return i;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
788
|
+
if (ops.includes(tokens[i]))
|
|
789
|
+
return i;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return -1;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* Pattern matching for expr (anchored at start).
|
|
796
|
+
*
|
|
797
|
+
* @param str - String to match against
|
|
798
|
+
* @param pattern - Regex pattern (automatically anchored at start)
|
|
799
|
+
* @returns Captured group, match length, or '0' if no match
|
|
800
|
+
*/
|
|
801
|
+
function exprMatch(str, pattern) {
|
|
802
|
+
// Check for capture group
|
|
803
|
+
const captureMatch = pattern.match(/\\?\((.+?)\\?\)/);
|
|
804
|
+
// Build regex (anchored at start)
|
|
805
|
+
const regexPattern = pattern
|
|
806
|
+
.replace(/\\?\(/g, '(')
|
|
807
|
+
.replace(/\\?\)/g, ')');
|
|
808
|
+
try {
|
|
809
|
+
const regex = new RegExp('^' + regexPattern);
|
|
810
|
+
const match = str.match(regex);
|
|
811
|
+
if (!match) {
|
|
812
|
+
return '0';
|
|
813
|
+
}
|
|
814
|
+
// If there's a capture group, return captured string
|
|
815
|
+
if (captureMatch && match[1] !== undefined) {
|
|
816
|
+
return match[1];
|
|
817
|
+
}
|
|
818
|
+
// Otherwise return match length
|
|
819
|
+
return String(match[0].length);
|
|
820
|
+
}
|
|
821
|
+
catch {
|
|
822
|
+
return '0';
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Execute seq command.
|
|
827
|
+
*
|
|
828
|
+
* seq prints a sequence of numbers with optional formatting.
|
|
829
|
+
*
|
|
830
|
+
* @param args - Numeric arguments: [last], [first, last], or [first, increment, last]
|
|
831
|
+
* @param options - Formatting options
|
|
832
|
+
* @returns Sequence string
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```ts
|
|
836
|
+
* executeSeq([5]) // "1\n2\n3\n4\n5"
|
|
837
|
+
* executeSeq([2, 5]) // "2\n3\n4\n5"
|
|
838
|
+
* executeSeq([1, 2, 10]) // "1\n3\n5\n7\n9"
|
|
839
|
+
* executeSeq([5], { separator: ', ' }) // "1, 2, 3, 4, 5"
|
|
840
|
+
* ```
|
|
841
|
+
*/
|
|
842
|
+
export function executeSeq(args, options = {}) {
|
|
843
|
+
// Parse arguments into first, increment, last
|
|
844
|
+
let first = 1;
|
|
845
|
+
let increment = 1;
|
|
846
|
+
let last;
|
|
847
|
+
if (args.length === 1) {
|
|
848
|
+
last = args[0];
|
|
849
|
+
}
|
|
850
|
+
else if (args.length === 2) {
|
|
851
|
+
first = args[0];
|
|
852
|
+
last = args[1];
|
|
853
|
+
}
|
|
854
|
+
else if (args.length === 3) {
|
|
855
|
+
first = args[0];
|
|
856
|
+
increment = args[1];
|
|
857
|
+
last = args[2];
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
return { result: '', exitCode: 1 };
|
|
861
|
+
}
|
|
862
|
+
// Handle impossible ranges (empty output)
|
|
863
|
+
if ((increment > 0 && first > last) ||
|
|
864
|
+
(increment < 0 && first < last) ||
|
|
865
|
+
increment === 0) {
|
|
866
|
+
return { result: '', exitCode: 0 };
|
|
867
|
+
}
|
|
868
|
+
const results = [];
|
|
869
|
+
const separator = options.separator ?? '\n';
|
|
870
|
+
// Calculate width for equal-width option
|
|
871
|
+
const firstStr = String(first);
|
|
872
|
+
const lastStr = String(last);
|
|
873
|
+
const totalWidth = Math.max(firstStr.length, lastStr.length);
|
|
874
|
+
const maxWidth = first < 0 || last < 0 ? totalWidth : totalWidth;
|
|
875
|
+
// Determine if we're dealing with floats
|
|
876
|
+
const isFloat = !Number.isInteger(first) ||
|
|
877
|
+
!Number.isInteger(increment) ||
|
|
878
|
+
!Number.isInteger(last);
|
|
879
|
+
// Calculate precision for floating point
|
|
880
|
+
const precision = Math.max(FormatUtils.getPrecision(first), FormatUtils.getPrecision(increment), FormatUtils.getPrecision(last));
|
|
881
|
+
// Generate sequence
|
|
882
|
+
for (let i = first; increment > 0 ? i <= last + Number.EPSILON * 10 : i >= last - Number.EPSILON * 10; i += increment) {
|
|
883
|
+
// Avoid floating point errors
|
|
884
|
+
const value = Math.round(i * Math.pow(10, precision + 2)) / Math.pow(10, precision + 2);
|
|
885
|
+
// Stop if we've passed the last value
|
|
886
|
+
if (increment > 0 && value > last + Number.EPSILON)
|
|
887
|
+
break;
|
|
888
|
+
if (increment < 0 && value < last - Number.EPSILON)
|
|
889
|
+
break;
|
|
890
|
+
let formatted;
|
|
891
|
+
if (options.format) {
|
|
892
|
+
formatted = FormatUtils.sprintf(options.format, value);
|
|
893
|
+
}
|
|
894
|
+
else if (options.equalWidth) {
|
|
895
|
+
if (value < 0) {
|
|
896
|
+
formatted = String(Math.round(value));
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
const absStr = String(Math.abs(Math.round(value)));
|
|
900
|
+
formatted = absStr.padStart(maxWidth, '0');
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
else if (isFloat) {
|
|
904
|
+
formatted = precision > 0 ? value.toFixed(precision) : String(value);
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
formatted = String(value);
|
|
908
|
+
}
|
|
909
|
+
results.push(formatted);
|
|
910
|
+
}
|
|
911
|
+
return {
|
|
912
|
+
result: results.length > 0 ? results.join(separator) : '',
|
|
913
|
+
exitCode: 0,
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Execute shuf command.
|
|
918
|
+
*
|
|
919
|
+
* shuf shuffles input lines or generates random permutations.
|
|
920
|
+
*
|
|
921
|
+
* @param lines - Input lines to shuffle (from stdin)
|
|
922
|
+
* @param options - Shuffle options
|
|
923
|
+
* @returns Shuffled output
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* ```ts
|
|
927
|
+
* executeShuf(['a', 'b', 'c']) // Random order of a, b, c
|
|
928
|
+
* executeShuf([], { inputRange: { start: 1, end: 10 } }) // Random order of 1-10
|
|
929
|
+
* executeShuf([], { echoArgs: ['red', 'green', 'blue'] }) // Random color
|
|
930
|
+
* ```
|
|
931
|
+
*/
|
|
932
|
+
export function executeShuf(lines, options = {}) {
|
|
933
|
+
let items;
|
|
934
|
+
// Determine input source
|
|
935
|
+
if (options.inputRange) {
|
|
936
|
+
const { start, end } = options.inputRange;
|
|
937
|
+
items = [];
|
|
938
|
+
for (let i = start; i <= end; i++) {
|
|
939
|
+
items.push(String(i));
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
else if (options.echoArgs && options.echoArgs.length > 0) {
|
|
943
|
+
items = options.echoArgs;
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
items = lines.filter(l => l.length > 0);
|
|
947
|
+
}
|
|
948
|
+
// Handle -n 0
|
|
949
|
+
if (options.count === 0) {
|
|
950
|
+
return { result: '', exitCode: 0 };
|
|
951
|
+
}
|
|
952
|
+
let result;
|
|
953
|
+
if (options.replacement) {
|
|
954
|
+
// With replacement - can pick same item multiple times
|
|
955
|
+
const count = options.count ?? items.length;
|
|
956
|
+
result = RandomUtils.sampleWithReplacement(items, count);
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
// Without replacement - Fisher-Yates shuffle
|
|
960
|
+
result = RandomUtils.shuffle([...items]);
|
|
961
|
+
// Limit to count if specified
|
|
962
|
+
if (options.count !== undefined) {
|
|
963
|
+
result = result.slice(0, Math.min(options.count, result.length));
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return {
|
|
967
|
+
result: result.join('\n'),
|
|
968
|
+
exitCode: 0,
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
// ============================================================================
|
|
972
|
+
// SLEEP - DELAY EXECUTION
|
|
973
|
+
// ============================================================================
|
|
974
|
+
/**
|
|
975
|
+
* Execute sleep command.
|
|
976
|
+
*
|
|
977
|
+
* sleep delays execution for a specified duration.
|
|
978
|
+
*
|
|
979
|
+
* @param durations - One or more duration strings
|
|
980
|
+
* @returns Promise that resolves after delay
|
|
981
|
+
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```ts
|
|
984
|
+
* await executeSleep(['1']) // Sleep 1 second
|
|
985
|
+
* await executeSleep(['0.5']) // Sleep 500ms
|
|
986
|
+
* await executeSleep(['1m']) // Sleep 1 minute
|
|
987
|
+
* await executeSleep(['1', '2']) // Sleep 3 seconds total
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
export async function executeSleep(durations) {
|
|
991
|
+
if (durations.length === 0) {
|
|
992
|
+
return { exitCode: 1, stderr: 'sleep: missing operand' };
|
|
993
|
+
}
|
|
994
|
+
try {
|
|
995
|
+
let totalMs = 0;
|
|
996
|
+
for (const duration of durations) {
|
|
997
|
+
const ms = TimingUtils.parseDuration(duration);
|
|
998
|
+
if (ms < 0) {
|
|
999
|
+
return { exitCode: 1, stderr: 'sleep: invalid time interval' };
|
|
1000
|
+
}
|
|
1001
|
+
if (!isFinite(ms)) {
|
|
1002
|
+
// Infinity - sleep forever (will be interrupted by timeout)
|
|
1003
|
+
await TimingUtils.waitForever();
|
|
1004
|
+
return { exitCode: 0, stderr: '' };
|
|
1005
|
+
}
|
|
1006
|
+
totalMs += ms;
|
|
1007
|
+
}
|
|
1008
|
+
await TimingUtils.delay(totalMs);
|
|
1009
|
+
return { exitCode: 0, stderr: '' };
|
|
1010
|
+
}
|
|
1011
|
+
catch (error) {
|
|
1012
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1013
|
+
return { exitCode: 1, stderr: `sleep: ${message}` };
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Execute timeout command.
|
|
1018
|
+
*
|
|
1019
|
+
* timeout runs a command with a time limit, sending a signal if it exceeds the limit.
|
|
1020
|
+
*
|
|
1021
|
+
* @param options - Timeout options
|
|
1022
|
+
* @param command - Command to execute
|
|
1023
|
+
* @param commandExecutor - Function to execute the command
|
|
1024
|
+
* @returns Result with exit code and timeout status
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* ```ts
|
|
1028
|
+
* await executeTimeout(
|
|
1029
|
+
* { duration: '5s' },
|
|
1030
|
+
* 'sleep 10',
|
|
1031
|
+
* (cmd) => executor.execute(cmd)
|
|
1032
|
+
* )
|
|
1033
|
+
* // Returns { exitCode: 124, timedOut: true, ... }
|
|
1034
|
+
* ```
|
|
1035
|
+
*/
|
|
1036
|
+
export async function executeTimeout(options, command, commandExecutor) {
|
|
1037
|
+
// Parse timeout duration
|
|
1038
|
+
let timeoutMs;
|
|
1039
|
+
try {
|
|
1040
|
+
timeoutMs = TimingUtils.parseDuration(options.duration);
|
|
1041
|
+
}
|
|
1042
|
+
catch {
|
|
1043
|
+
return {
|
|
1044
|
+
exitCode: 125,
|
|
1045
|
+
stdout: '',
|
|
1046
|
+
stderr: `timeout: invalid time interval '${options.duration}'`,
|
|
1047
|
+
timedOut: false,
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
// Determine signal to use
|
|
1051
|
+
const signalNum = options.signal
|
|
1052
|
+
? TimingUtils.parseSignal(options.signal)
|
|
1053
|
+
: 15; // SIGTERM default
|
|
1054
|
+
// Create abort controller for timeout
|
|
1055
|
+
const controller = new AbortController();
|
|
1056
|
+
let timedOut = false;
|
|
1057
|
+
const timer = setTimeout(() => {
|
|
1058
|
+
timedOut = true;
|
|
1059
|
+
controller.abort();
|
|
1060
|
+
}, timeoutMs);
|
|
1061
|
+
try {
|
|
1062
|
+
// Execute command with race against timeout
|
|
1063
|
+
const result = await Promise.race([
|
|
1064
|
+
commandExecutor(command),
|
|
1065
|
+
new Promise((_, reject) => {
|
|
1066
|
+
controller.signal.addEventListener('abort', () => {
|
|
1067
|
+
reject(new Error('TIMEOUT'));
|
|
1068
|
+
});
|
|
1069
|
+
}),
|
|
1070
|
+
]);
|
|
1071
|
+
clearTimeout(timer);
|
|
1072
|
+
return { ...result, timedOut: false };
|
|
1073
|
+
}
|
|
1074
|
+
catch (error) {
|
|
1075
|
+
clearTimeout(timer);
|
|
1076
|
+
if (timedOut) {
|
|
1077
|
+
const exitCode = options.preserveStatus ? 128 + signalNum : 124;
|
|
1078
|
+
let stderr = '';
|
|
1079
|
+
if (options.verbose) {
|
|
1080
|
+
stderr = `timeout: sending signal ${signalNum === 9 ? 'KILL' : 'TERM'} to command '${command}'`;
|
|
1081
|
+
}
|
|
1082
|
+
// SIGKILL exit code is 137 (128 + 9)
|
|
1083
|
+
const finalExitCode = signalNum === 9 ? 137 : exitCode;
|
|
1084
|
+
return {
|
|
1085
|
+
exitCode: finalExitCode,
|
|
1086
|
+
stdout: '',
|
|
1087
|
+
stderr,
|
|
1088
|
+
timedOut: true,
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
// Re-throw non-timeout errors
|
|
1092
|
+
throw error;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Handle command not found error for timeout.
|
|
1097
|
+
*
|
|
1098
|
+
* @param command - Command that was not found
|
|
1099
|
+
* @returns Error result with exit code 126
|
|
1100
|
+
*/
|
|
1101
|
+
export function timeoutCommandNotFound(command) {
|
|
1102
|
+
return {
|
|
1103
|
+
exitCode: 126,
|
|
1104
|
+
stderr: `timeout: failed to run command '${command}': No such file or directory`,
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
// ============================================================================
|
|
1108
|
+
// EXPORTS FOR INTEGRATION
|
|
1109
|
+
// ============================================================================
|
|
1110
|
+
/**
|
|
1111
|
+
* Unified export of all math and control commands.
|
|
1112
|
+
* Useful for command dispatching in the shell executor.
|
|
1113
|
+
*/
|
|
1114
|
+
export const mathControlCommands = {
|
|
1115
|
+
bc: executeBc,
|
|
1116
|
+
expr: executeExpr,
|
|
1117
|
+
seq: executeSeq,
|
|
1118
|
+
shuf: executeShuf,
|
|
1119
|
+
sleep: executeSleep,
|
|
1120
|
+
timeout: executeTimeout,
|
|
1121
|
+
};
|
|
1122
|
+
//# sourceMappingURL=math-control.js.map
|