siclaw 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 +190 -0
- package/README.md +268 -0
- package/dist/agentbox/gateway-client.d.ts +41 -0
- package/dist/agentbox/gateway-client.js +108 -0
- package/dist/agentbox/gateway-client.js.map +1 -0
- package/dist/agentbox/http-server.d.ts +12 -0
- package/dist/agentbox/http-server.js +700 -0
- package/dist/agentbox/http-server.js.map +1 -0
- package/dist/agentbox/mcp-sync.d.ts +6 -0
- package/dist/agentbox/mcp-sync.js +26 -0
- package/dist/agentbox/mcp-sync.js.map +1 -0
- package/dist/agentbox/resource-handlers.d.ts +40 -0
- package/dist/agentbox/resource-handlers.js +116 -0
- package/dist/agentbox/resource-handlers.js.map +1 -0
- package/dist/agentbox/resource-sync.d.ts +28 -0
- package/dist/agentbox/resource-sync.js +74 -0
- package/dist/agentbox/resource-sync.js.map +1 -0
- package/dist/agentbox/session.d.ts +145 -0
- package/dist/agentbox/session.js +444 -0
- package/dist/agentbox/session.js.map +1 -0
- package/dist/agentbox-main.d.ts +7 -0
- package/dist/agentbox-main.js +90 -0
- package/dist/agentbox-main.js.map +1 -0
- package/dist/cli-main.d.ts +1 -0
- package/dist/cli-main.js +187 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/cli-setup.d.ts +17 -0
- package/dist/cli-setup.js +247 -0
- package/dist/cli-setup.js.map +1 -0
- package/dist/core/agent-factory.d.ts +52 -0
- package/dist/core/agent-factory.js +547 -0
- package/dist/core/agent-factory.js.map +1 -0
- package/dist/core/brain-session.d.ts +67 -0
- package/dist/core/brain-session.js +15 -0
- package/dist/core/brain-session.js.map +1 -0
- package/dist/core/brains/claude-sdk-brain.d.ts +76 -0
- package/dist/core/brains/claude-sdk-brain.js +403 -0
- package/dist/core/brains/claude-sdk-brain.js.map +1 -0
- package/dist/core/brains/pi-agent-brain.d.ts +28 -0
- package/dist/core/brains/pi-agent-brain.js +84 -0
- package/dist/core/brains/pi-agent-brain.js.map +1 -0
- package/dist/core/config.d.ts +109 -0
- package/dist/core/config.js +294 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/extensions/context-pruning.d.ts +38 -0
- package/dist/core/extensions/context-pruning.js +162 -0
- package/dist/core/extensions/context-pruning.js.map +1 -0
- package/dist/core/extensions/deep-investigation.d.ts +2 -0
- package/dist/core/extensions/deep-investigation.js +541 -0
- package/dist/core/extensions/deep-investigation.js.map +1 -0
- package/dist/core/extensions/memory-flush.d.ts +20 -0
- package/dist/core/extensions/memory-flush.js +120 -0
- package/dist/core/extensions/memory-flush.js.map +1 -0
- package/dist/core/llm-proxy.d.ts +37 -0
- package/dist/core/llm-proxy.js +578 -0
- package/dist/core/llm-proxy.js.map +1 -0
- package/dist/core/mcp-client.d.ts +80 -0
- package/dist/core/mcp-client.js +285 -0
- package/dist/core/mcp-client.js.map +1 -0
- package/dist/core/prompt.d.ts +1 -0
- package/dist/core/prompt.js +64 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/tool-adapter.d.ts +45 -0
- package/dist/core/tool-adapter.js +154 -0
- package/dist/core/tool-adapter.js.map +1 -0
- package/dist/cron/cron-api.d.ts +9 -0
- package/dist/cron/cron-api.js +94 -0
- package/dist/cron/cron-api.js.map +1 -0
- package/dist/cron/cron-coordinator.d.ts +29 -0
- package/dist/cron/cron-coordinator.js +150 -0
- package/dist/cron/cron-coordinator.js.map +1 -0
- package/dist/cron/cron-executor.d.ts +15 -0
- package/dist/cron/cron-executor.js +90 -0
- package/dist/cron/cron-executor.js.map +1 -0
- package/dist/cron/cron-matcher.d.ts +19 -0
- package/dist/cron/cron-matcher.js +114 -0
- package/dist/cron/cron-matcher.js.map +1 -0
- package/dist/cron/cron-scheduler.d.ts +42 -0
- package/dist/cron/cron-scheduler.js +91 -0
- package/dist/cron/cron-scheduler.js.map +1 -0
- package/dist/cron/gateway-client.d.ts +32 -0
- package/dist/cron/gateway-client.js +91 -0
- package/dist/cron/gateway-client.js.map +1 -0
- package/dist/cron-main.d.ts +10 -0
- package/dist/cron-main.js +75 -0
- package/dist/cron-main.js.map +1 -0
- package/dist/gateway/agentbox/client.d.ts +187 -0
- package/dist/gateway/agentbox/client.js +314 -0
- package/dist/gateway/agentbox/client.js.map +1 -0
- package/dist/gateway/agentbox/index.d.ts +10 -0
- package/dist/gateway/agentbox/index.js +11 -0
- package/dist/gateway/agentbox/index.js.map +1 -0
- package/dist/gateway/agentbox/k8s-spawner.d.ts +70 -0
- package/dist/gateway/agentbox/k8s-spawner.js +466 -0
- package/dist/gateway/agentbox/k8s-spawner.js.map +1 -0
- package/dist/gateway/agentbox/local-spawner.d.ts +63 -0
- package/dist/gateway/agentbox/local-spawner.js +234 -0
- package/dist/gateway/agentbox/local-spawner.js.map +1 -0
- package/dist/gateway/agentbox/manager.d.ts +121 -0
- package/dist/gateway/agentbox/manager.js +325 -0
- package/dist/gateway/agentbox/manager.js.map +1 -0
- package/dist/gateway/agentbox/process-spawner.d.ts +21 -0
- package/dist/gateway/agentbox/process-spawner.js +168 -0
- package/dist/gateway/agentbox/process-spawner.js.map +1 -0
- package/dist/gateway/agentbox/spawner.d.ts +33 -0
- package/dist/gateway/agentbox/spawner.js +10 -0
- package/dist/gateway/agentbox/spawner.js.map +1 -0
- package/dist/gateway/agentbox/types.d.ts +39 -0
- package/dist/gateway/agentbox/types.js +5 -0
- package/dist/gateway/agentbox/types.js.map +1 -0
- package/dist/gateway/auth/bind-code-store.d.ts +31 -0
- package/dist/gateway/auth/bind-code-store.js +73 -0
- package/dist/gateway/auth/bind-code-store.js.map +1 -0
- package/dist/gateway/auth/index.d.ts +9 -0
- package/dist/gateway/auth/index.js +10 -0
- package/dist/gateway/auth/index.js.map +1 -0
- package/dist/gateway/auth/jwt.d.ts +23 -0
- package/dist/gateway/auth/jwt.js +82 -0
- package/dist/gateway/auth/jwt.js.map +1 -0
- package/dist/gateway/auth/login.d.ts +26 -0
- package/dist/gateway/auth/login.js +74 -0
- package/dist/gateway/auth/login.js.map +1 -0
- package/dist/gateway/auth/middleware.d.ts +23 -0
- package/dist/gateway/auth/middleware.js +67 -0
- package/dist/gateway/auth/middleware.js.map +1 -0
- package/dist/gateway/auth/oauth2.d.ts +57 -0
- package/dist/gateway/auth/oauth2.js +113 -0
- package/dist/gateway/auth/oauth2.js.map +1 -0
- package/dist/gateway/auth/user-store.d.ts +95 -0
- package/dist/gateway/auth/user-store.js +291 -0
- package/dist/gateway/auth/user-store.js.map +1 -0
- package/dist/gateway/channels/channel-manager.d.ts +42 -0
- package/dist/gateway/channels/channel-manager.js +156 -0
- package/dist/gateway/channels/channel-manager.js.map +1 -0
- package/dist/gateway/channels/channel-rpc.d.ts +9 -0
- package/dist/gateway/channels/channel-rpc.js +104 -0
- package/dist/gateway/channels/channel-rpc.js.map +1 -0
- package/dist/gateway/channels/channel-store.d.ts +32 -0
- package/dist/gateway/channels/channel-store.js +114 -0
- package/dist/gateway/channels/channel-store.js.map +1 -0
- package/dist/gateway/channels/discord.d.ts +5 -0
- package/dist/gateway/channels/discord.js +177 -0
- package/dist/gateway/channels/discord.js.map +1 -0
- package/dist/gateway/channels/lark-format.d.ts +41 -0
- package/dist/gateway/channels/lark-format.js +620 -0
- package/dist/gateway/channels/lark-format.js.map +1 -0
- package/dist/gateway/channels/lark.d.ts +5 -0
- package/dist/gateway/channels/lark.js +1000 -0
- package/dist/gateway/channels/lark.js.map +1 -0
- package/dist/gateway/channels/slack.d.ts +5 -0
- package/dist/gateway/channels/slack.js +170 -0
- package/dist/gateway/channels/slack.js.map +1 -0
- package/dist/gateway/channels/telegram.d.ts +5 -0
- package/dist/gateway/channels/telegram.js +173 -0
- package/dist/gateway/channels/telegram.js.map +1 -0
- package/dist/gateway/channels/utils.d.ts +34 -0
- package/dist/gateway/channels/utils.js +115 -0
- package/dist/gateway/channels/utils.js.map +1 -0
- package/dist/gateway/config.d.ts +14 -0
- package/dist/gateway/config.js +12 -0
- package/dist/gateway/config.js.map +1 -0
- package/dist/gateway/cron/notify.d.ts +14 -0
- package/dist/gateway/cron/notify.js +40 -0
- package/dist/gateway/cron/notify.js.map +1 -0
- package/dist/gateway/db/dialect-helpers.d.ts +8 -0
- package/dist/gateway/db/dialect-helpers.js +26 -0
- package/dist/gateway/db/dialect-helpers.js.map +1 -0
- package/dist/gateway/db/index.d.ts +20 -0
- package/dist/gateway/db/index.js +140 -0
- package/dist/gateway/db/index.js.map +1 -0
- package/dist/gateway/db/init-schema.d.ts +8 -0
- package/dist/gateway/db/init-schema.js +385 -0
- package/dist/gateway/db/init-schema.js.map +1 -0
- package/dist/gateway/db/migrate-sqlite.d.ts +8 -0
- package/dist/gateway/db/migrate-sqlite.js +335 -0
- package/dist/gateway/db/migrate-sqlite.js.map +1 -0
- package/dist/gateway/db/repositories/chat-repo.d.ts +64 -0
- package/dist/gateway/db/repositories/chat-repo.js +115 -0
- package/dist/gateway/db/repositories/chat-repo.js.map +1 -0
- package/dist/gateway/db/repositories/config-repo.d.ts +164 -0
- package/dist/gateway/db/repositories/config-repo.js +267 -0
- package/dist/gateway/db/repositories/config-repo.js.map +1 -0
- package/dist/gateway/db/repositories/credential-repo.d.ts +51 -0
- package/dist/gateway/db/repositories/credential-repo.js +70 -0
- package/dist/gateway/db/repositories/credential-repo.js.map +1 -0
- package/dist/gateway/db/repositories/env-repo.d.ts +37 -0
- package/dist/gateway/db/repositories/env-repo.js +74 -0
- package/dist/gateway/db/repositories/env-repo.js.map +1 -0
- package/dist/gateway/db/repositories/mcp-server-repo.d.ts +97 -0
- package/dist/gateway/db/repositories/mcp-server-repo.js +83 -0
- package/dist/gateway/db/repositories/mcp-server-repo.js.map +1 -0
- package/dist/gateway/db/repositories/model-config-repo.d.ts +141 -0
- package/dist/gateway/db/repositories/model-config-repo.js +439 -0
- package/dist/gateway/db/repositories/model-config-repo.js.map +1 -0
- package/dist/gateway/db/repositories/notification-repo.d.ts +50 -0
- package/dist/gateway/db/repositories/notification-repo.js +105 -0
- package/dist/gateway/db/repositories/notification-repo.js.map +1 -0
- package/dist/gateway/db/repositories/permission-repo.d.ts +28 -0
- package/dist/gateway/db/repositories/permission-repo.js +74 -0
- package/dist/gateway/db/repositories/permission-repo.js.map +1 -0
- package/dist/gateway/db/repositories/skill-content-repo.d.ts +29 -0
- package/dist/gateway/db/repositories/skill-content-repo.js +90 -0
- package/dist/gateway/db/repositories/skill-content-repo.js.map +1 -0
- package/dist/gateway/db/repositories/skill-repo.d.ts +170 -0
- package/dist/gateway/db/repositories/skill-repo.js +185 -0
- package/dist/gateway/db/repositories/skill-repo.js.map +1 -0
- package/dist/gateway/db/repositories/skill-review-repo.d.ts +44 -0
- package/dist/gateway/db/repositories/skill-review-repo.js +44 -0
- package/dist/gateway/db/repositories/skill-review-repo.js.map +1 -0
- package/dist/gateway/db/repositories/skill-version-repo.d.ts +30 -0
- package/dist/gateway/db/repositories/skill-version-repo.js +56 -0
- package/dist/gateway/db/repositories/skill-version-repo.js.map +1 -0
- package/dist/gateway/db/repositories/system-config-repo.d.ts +21 -0
- package/dist/gateway/db/repositories/system-config-repo.js +86 -0
- package/dist/gateway/db/repositories/system-config-repo.js.map +1 -0
- package/dist/gateway/db/repositories/user-env-config-repo.d.ts +32 -0
- package/dist/gateway/db/repositories/user-env-config-repo.js +79 -0
- package/dist/gateway/db/repositories/user-env-config-repo.js.map +1 -0
- package/dist/gateway/db/repositories/user-repo.d.ts +59 -0
- package/dist/gateway/db/repositories/user-repo.js +83 -0
- package/dist/gateway/db/repositories/user-repo.js.map +1 -0
- package/dist/gateway/db/repositories/vote-repo.d.ts +26 -0
- package/dist/gateway/db/repositories/vote-repo.js +97 -0
- package/dist/gateway/db/repositories/vote-repo.js.map +1 -0
- package/dist/gateway/db/repositories/workspace-repo.d.ts +27 -0
- package/dist/gateway/db/repositories/workspace-repo.js +145 -0
- package/dist/gateway/db/repositories/workspace-repo.js.map +1 -0
- package/dist/gateway/db/schema-mysql.d.ts +3897 -0
- package/dist/gateway/db/schema-mysql.js +354 -0
- package/dist/gateway/db/schema-mysql.js.map +1 -0
- package/dist/gateway/db/schema-sqlite.d.ts +4147 -0
- package/dist/gateway/db/schema-sqlite.js +345 -0
- package/dist/gateway/db/schema-sqlite.js.map +1 -0
- package/dist/gateway/db/schema.d.ts +3869 -0
- package/dist/gateway/db/schema.js +16 -0
- package/dist/gateway/db/schema.js.map +1 -0
- package/dist/gateway/mcp-config-builder.d.ts +8 -0
- package/dist/gateway/mcp-config-builder.js +39 -0
- package/dist/gateway/mcp-config-builder.js.map +1 -0
- package/dist/gateway/output-redactor.d.ts +27 -0
- package/dist/gateway/output-redactor.js +101 -0
- package/dist/gateway/output-redactor.js.map +1 -0
- package/dist/gateway/plugins/api.d.ts +181 -0
- package/dist/gateway/plugins/api.js +28 -0
- package/dist/gateway/plugins/api.js.map +1 -0
- package/dist/gateway/plugins/channel-bridge.d.ts +72 -0
- package/dist/gateway/plugins/channel-bridge.js +586 -0
- package/dist/gateway/plugins/channel-bridge.js.map +1 -0
- package/dist/gateway/plugins/loader.d.ts +2 -0
- package/dist/gateway/plugins/loader.js +83 -0
- package/dist/gateway/plugins/loader.js.map +1 -0
- package/dist/gateway/plugins/runtime.d.ts +25 -0
- package/dist/gateway/plugins/runtime.js +64 -0
- package/dist/gateway/plugins/runtime.js.map +1 -0
- package/dist/gateway/resource-notifier.d.ts +36 -0
- package/dist/gateway/resource-notifier.js +123 -0
- package/dist/gateway/resource-notifier.js.map +1 -0
- package/dist/gateway/rpc-methods.d.ts +34 -0
- package/dist/gateway/rpc-methods.js +3198 -0
- package/dist/gateway/rpc-methods.js.map +1 -0
- package/dist/gateway/security/cert-manager.d.ts +77 -0
- package/dist/gateway/security/cert-manager.js +280 -0
- package/dist/gateway/security/cert-manager.js.map +1 -0
- package/dist/gateway/security/mtls-middleware.d.ts +33 -0
- package/dist/gateway/security/mtls-middleware.js +89 -0
- package/dist/gateway/security/mtls-middleware.js.map +1 -0
- package/dist/gateway/server.d.ts +54 -0
- package/dist/gateway/server.js +1146 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/gateway/skill-labels.d.ts +16 -0
- package/dist/gateway/skill-labels.js +79 -0
- package/dist/gateway/skill-labels.js.map +1 -0
- package/dist/gateway/skills/file-writer.d.ts +75 -0
- package/dist/gateway/skills/file-writer.js +320 -0
- package/dist/gateway/skills/file-writer.js.map +1 -0
- package/dist/gateway/skills/script-evaluator.d.ts +42 -0
- package/dist/gateway/skills/script-evaluator.js +204 -0
- package/dist/gateway/skills/script-evaluator.js.map +1 -0
- package/dist/gateway/skills/skill-bundle.d.ts +34 -0
- package/dist/gateway/skills/skill-bundle.js +83 -0
- package/dist/gateway/skills/skill-bundle.js.map +1 -0
- package/dist/gateway/web/dist/assets/index-BF6CtvnV.css +1 -0
- package/dist/gateway/web/dist/assets/index-Dumzqsr-.js +680 -0
- package/dist/gateway/web/dist/assets/index-n4IMHP1Q.js +675 -0
- package/dist/gateway/web/dist/index.html +14 -0
- package/dist/gateway/web/dist/noise.png +1 -0
- package/dist/gateway/web/dist/robots.txt +2 -0
- package/dist/gateway/web/dist/vite.svg +1 -0
- package/dist/gateway/ws-protocol.d.ts +68 -0
- package/dist/gateway/ws-protocol.js +106 -0
- package/dist/gateway/ws-protocol.js.map +1 -0
- package/dist/gateway-main.d.ts +1 -0
- package/dist/gateway-main.js +129 -0
- package/dist/gateway-main.js.map +1 -0
- package/dist/lib/s3-backup.d.ts +28 -0
- package/dist/lib/s3-backup.js +85 -0
- package/dist/lib/s3-backup.js.map +1 -0
- package/dist/lib/s3-storage.d.ts +45 -0
- package/dist/lib/s3-storage.js +210 -0
- package/dist/lib/s3-storage.js.map +1 -0
- package/dist/memory/chunker.d.ts +15 -0
- package/dist/memory/chunker.js +94 -0
- package/dist/memory/chunker.js.map +1 -0
- package/dist/memory/embeddings.d.ts +14 -0
- package/dist/memory/embeddings.js +143 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/index.d.ts +18 -0
- package/dist/memory/index.js +15 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/indexer.d.ts +70 -0
- package/dist/memory/indexer.js +567 -0
- package/dist/memory/indexer.js.map +1 -0
- package/dist/memory/mmr.d.ts +22 -0
- package/dist/memory/mmr.js +82 -0
- package/dist/memory/mmr.js.map +1 -0
- package/dist/memory/schema.d.ts +2 -0
- package/dist/memory/schema.js +85 -0
- package/dist/memory/schema.js.map +1 -0
- package/dist/memory/session-summarizer.d.ts +19 -0
- package/dist/memory/session-summarizer.js +139 -0
- package/dist/memory/session-summarizer.js.map +1 -0
- package/dist/memory/stop-words.d.ts +13 -0
- package/dist/memory/stop-words.js +132 -0
- package/dist/memory/stop-words.js.map +1 -0
- package/dist/memory/temporal-decay.d.ts +20 -0
- package/dist/memory/temporal-decay.js +63 -0
- package/dist/memory/temporal-decay.js.map +1 -0
- package/dist/memory/types.d.ts +40 -0
- package/dist/memory/types.js +2 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/shared/resource-sync.d.ts +80 -0
- package/dist/shared/resource-sync.js +24 -0
- package/dist/shared/resource-sync.js.map +1 -0
- package/dist/tools/command-sets.d.ts +61 -0
- package/dist/tools/command-sets.js +845 -0
- package/dist/tools/command-sets.js.map +1 -0
- package/dist/tools/create-skill.d.ts +2 -0
- package/dist/tools/create-skill.js +169 -0
- package/dist/tools/create-skill.js.map +1 -0
- package/dist/tools/credential-list.d.ts +8 -0
- package/dist/tools/credential-list.js +139 -0
- package/dist/tools/credential-list.js.map +1 -0
- package/dist/tools/deep-search/engine.d.ts +40 -0
- package/dist/tools/deep-search/engine.js +594 -0
- package/dist/tools/deep-search/engine.js.map +1 -0
- package/dist/tools/deep-search/events.d.ts +11 -0
- package/dist/tools/deep-search/events.js +10 -0
- package/dist/tools/deep-search/events.js.map +1 -0
- package/dist/tools/deep-search/format.d.ts +11 -0
- package/dist/tools/deep-search/format.js +143 -0
- package/dist/tools/deep-search/format.js.map +1 -0
- package/dist/tools/deep-search/prompts.d.ts +30 -0
- package/dist/tools/deep-search/prompts.js +237 -0
- package/dist/tools/deep-search/prompts.js.map +1 -0
- package/dist/tools/deep-search/sre-knowledge.d.ts +21 -0
- package/dist/tools/deep-search/sre-knowledge.js +112 -0
- package/dist/tools/deep-search/sre-knowledge.js.map +1 -0
- package/dist/tools/deep-search/sub-agent.d.ts +71 -0
- package/dist/tools/deep-search/sub-agent.js +401 -0
- package/dist/tools/deep-search/sub-agent.js.map +1 -0
- package/dist/tools/deep-search/tool.d.ts +9 -0
- package/dist/tools/deep-search/tool.js +201 -0
- package/dist/tools/deep-search/tool.js.map +1 -0
- package/dist/tools/deep-search/types.d.ts +67 -0
- package/dist/tools/deep-search/types.js +41 -0
- package/dist/tools/deep-search/types.js.map +1 -0
- package/dist/tools/dp-tools.d.ts +47 -0
- package/dist/tools/dp-tools.js +170 -0
- package/dist/tools/dp-tools.js.map +1 -0
- package/dist/tools/fork-skill.d.ts +2 -0
- package/dist/tools/fork-skill.js +93 -0
- package/dist/tools/fork-skill.js.map +1 -0
- package/dist/tools/k8s-checks.d.ts +18 -0
- package/dist/tools/k8s-checks.js +105 -0
- package/dist/tools/k8s-checks.js.map +1 -0
- package/dist/tools/kubeconfig-resolver.d.ts +11 -0
- package/dist/tools/kubeconfig-resolver.js +53 -0
- package/dist/tools/kubeconfig-resolver.js.map +1 -0
- package/dist/tools/kubectl.d.ts +12 -0
- package/dist/tools/kubectl.js +169 -0
- package/dist/tools/kubectl.js.map +1 -0
- package/dist/tools/manage-schedule.d.ts +3 -0
- package/dist/tools/manage-schedule.js +189 -0
- package/dist/tools/manage-schedule.js.map +1 -0
- package/dist/tools/memory-get.d.ts +2 -0
- package/dist/tools/memory-get.js +99 -0
- package/dist/tools/memory-get.js.map +1 -0
- package/dist/tools/memory-search.d.ts +3 -0
- package/dist/tools/memory-search.js +93 -0
- package/dist/tools/memory-search.js.map +1 -0
- package/dist/tools/netns-script.d.ts +3 -0
- package/dist/tools/netns-script.js +394 -0
- package/dist/tools/netns-script.js.map +1 -0
- package/dist/tools/node-exec.d.ts +18 -0
- package/dist/tools/node-exec.js +342 -0
- package/dist/tools/node-exec.js.map +1 -0
- package/dist/tools/node-script.d.ts +3 -0
- package/dist/tools/node-script.js +266 -0
- package/dist/tools/node-script.js.map +1 -0
- package/dist/tools/pod-exec.d.ts +4 -0
- package/dist/tools/pod-exec.js +146 -0
- package/dist/tools/pod-exec.js.map +1 -0
- package/dist/tools/pod-nsenter-exec.d.ts +3 -0
- package/dist/tools/pod-nsenter-exec.js +333 -0
- package/dist/tools/pod-nsenter-exec.js.map +1 -0
- package/dist/tools/pod-script.d.ts +3 -0
- package/dist/tools/pod-script.js +176 -0
- package/dist/tools/pod-script.js.map +1 -0
- package/dist/tools/restricted-bash.d.ts +41 -0
- package/dist/tools/restricted-bash.js +503 -0
- package/dist/tools/restricted-bash.js.map +1 -0
- package/dist/tools/run-skill.d.ts +3 -0
- package/dist/tools/run-skill.js +169 -0
- package/dist/tools/run-skill.js.map +1 -0
- package/dist/tools/sanitize-env.d.ts +14 -0
- package/dist/tools/sanitize-env.js +95 -0
- package/dist/tools/sanitize-env.js.map +1 -0
- package/dist/tools/script-resolver.d.ts +35 -0
- package/dist/tools/script-resolver.js +213 -0
- package/dist/tools/script-resolver.js.map +1 -0
- package/dist/tools/tool-render.d.ts +20 -0
- package/dist/tools/tool-render.js +77 -0
- package/dist/tools/tool-render.js.map +1 -0
- package/dist/tools/update-skill.d.ts +2 -0
- package/dist/tools/update-skill.js +169 -0
- package/dist/tools/update-skill.js.map +1 -0
- package/package.json +106 -0
- package/settings.example.json +74 -0
- package/siclaw.mjs +48 -0
- package/skills/core/cluster-events/SKILL.md +150 -0
- package/skills/core/deep-investigation/SKILL.md +87 -0
- package/skills/core/deep-investigation/default-memory.md +8 -0
- package/skills/core/deployment-rollout-debug/SKILL.md +144 -0
- package/skills/core/dns-debug/SKILL.md +144 -0
- package/skills/core/find-node/SKILL.md +23 -0
- package/skills/core/find-node/scripts/find-node.sh +9 -0
- package/skills/core/hpa-debug/SKILL.md +159 -0
- package/skills/core/image-pull-debug/SKILL.md +151 -0
- package/skills/core/ingress-debug/SKILL.md +189 -0
- package/skills/core/job-debug/SKILL.md +180 -0
- package/skills/core/meta.json +23 -0
- package/skills/core/node-health-check/SKILL.md +150 -0
- package/skills/core/node-logs/SKILL.md +68 -0
- package/skills/core/node-logs/scripts/get-node-logs.sh +78 -0
- package/skills/core/node-ping-gateway/SKILL.md +54 -0
- package/skills/core/node-ping-gateway/scripts/ping-node-gateway.sh +71 -0
- package/skills/core/node-show-gateway/SKILL.md +55 -0
- package/skills/core/node-show-gateway/scripts/show-node-gateway.sh +90 -0
- package/skills/core/pod-crash-debug/SKILL.md +135 -0
- package/skills/core/pod-pending-debug/SKILL.md +146 -0
- package/skills/core/pod-ping-gateway/SKILL.md +44 -0
- package/skills/core/pod-ping-gateway/scripts/ping-gateway.sh +76 -0
- package/skills/core/pod-show-gateway/SKILL.md +54 -0
- package/skills/core/pod-show-gateway/scripts/show-gateway.sh +115 -0
- package/skills/core/pvc-debug/SKILL.md +169 -0
- package/skills/core/service-debug/SKILL.md +164 -0
- package/skills/extension/.gitkeep +0 -0
- package/skills/platform/create-skill/SKILL.md +288 -0
- package/skills/platform/manage-skill/SKILL.md +23 -0
- package/skills/platform/update-skill/SKILL.md +52 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared command whitelist and command-level validators used by
|
|
3
|
+
* restricted-bash, node-exec, and kubectl-exec tools.
|
|
4
|
+
*/
|
|
5
|
+
// ── Utility functions ────────────────────────────────────────────
|
|
6
|
+
/**
|
|
7
|
+
* Shell-escape a single argument by wrapping in single quotes.
|
|
8
|
+
* Handles embedded single quotes via the standard '\'' idiom.
|
|
9
|
+
* Safe for embedding in sh -c "..." strings passed to remote execution.
|
|
10
|
+
*/
|
|
11
|
+
export function shellEscape(arg) {
|
|
12
|
+
return "'" + arg.replace(/'/g, "'\\''") + "'";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse a command string into an array of arguments, respecting quotes.
|
|
16
|
+
* Moved from kubectl.ts to be shared.
|
|
17
|
+
*/
|
|
18
|
+
export function parseArgs(command) {
|
|
19
|
+
const args = [];
|
|
20
|
+
let current = "";
|
|
21
|
+
let inQuote = null;
|
|
22
|
+
for (const ch of command) {
|
|
23
|
+
if (inQuote) {
|
|
24
|
+
if (ch === inQuote) {
|
|
25
|
+
inQuote = null;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
current += ch;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (ch === '"' || ch === "'") {
|
|
32
|
+
inQuote = ch;
|
|
33
|
+
}
|
|
34
|
+
else if (ch === " " || ch === "\t") {
|
|
35
|
+
if (current) {
|
|
36
|
+
args.push(current);
|
|
37
|
+
current = "";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
current += ch;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (current)
|
|
45
|
+
args.push(current);
|
|
46
|
+
return args;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the base binary name from a command string.
|
|
50
|
+
* Strips env vars, leading whitespace, and path prefixes.
|
|
51
|
+
* Moved from restricted-bash.ts to be shared.
|
|
52
|
+
*/
|
|
53
|
+
export function getCommandBinary(cmd) {
|
|
54
|
+
// Strip inline env assignments (FOO=bar cmd ...)
|
|
55
|
+
let stripped = cmd;
|
|
56
|
+
while (/^\s*\w+=\S*\s+/.test(stripped)) {
|
|
57
|
+
stripped = stripped.replace(/^\s*\w+=\S*\s+/, "");
|
|
58
|
+
}
|
|
59
|
+
const first = stripped.trim().split(/\s+/)[0] ?? "";
|
|
60
|
+
// Extract basename from absolute path
|
|
61
|
+
return first.split("/").pop() ?? first;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if arg starts with any of the given prefixes.
|
|
65
|
+
*/
|
|
66
|
+
function startsWithAny(arg, prefixes) {
|
|
67
|
+
return prefixes.some((p) => arg.startsWith(p));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Extract the flag name from a --flag=value or -f form.
|
|
71
|
+
*/
|
|
72
|
+
function extractFlag(arg) {
|
|
73
|
+
const eqIdx = arg.indexOf("=");
|
|
74
|
+
return eqIdx >= 0 ? arg.slice(0, eqIdx) : arg;
|
|
75
|
+
}
|
|
76
|
+
// ── Unified command whitelist ────────────────────────────────────
|
|
77
|
+
/**
|
|
78
|
+
* Commands allowed across all three tools (restricted-bash, node-exec, kubectl-exec).
|
|
79
|
+
* restricted-bash additionally allows `kubectl` and skill scripts.
|
|
80
|
+
*
|
|
81
|
+
* NOTE: sed and awk/gawk are intentionally excluded — they are Turing-complete
|
|
82
|
+
* scripting languages with built-in capabilities for command execution (system(),
|
|
83
|
+
* pipe-to-command), file writes, and shell escapes that cannot be reliably
|
|
84
|
+
* whitelisted. Use grep + cut/tr/head/tail/jq for text processing instead.
|
|
85
|
+
*/
|
|
86
|
+
export const ALLOWED_COMMANDS = new Set([
|
|
87
|
+
// text processing (sed, awk intentionally excluded — Turing-complete, unsafe)
|
|
88
|
+
"grep", "egrep", "fgrep",
|
|
89
|
+
"sort", "uniq", "wc", "head", "tail", "cut", "tr",
|
|
90
|
+
"jq", "yq", "column",
|
|
91
|
+
// network diagnostics
|
|
92
|
+
"ip", "ifconfig", "ping", "traceroute", "tracepath", "ss", "netstat",
|
|
93
|
+
"route", "arp", "ethtool", "mtr", "nslookup", "dig", "host",
|
|
94
|
+
"bridge", "tc", "conntrack", "curl",
|
|
95
|
+
// RDMA / RoCE
|
|
96
|
+
"ibstat", "ibstatus", "ibv_devinfo", "ibv_devices", "rdma",
|
|
97
|
+
"ibaddr", "iblinkinfo", "ibportstate", "ibswitches", "ibroute",
|
|
98
|
+
"show_gids", "ibdev2netdev",
|
|
99
|
+
// perftest
|
|
100
|
+
"ib_write_bw", "ib_write_lat", "ib_read_bw", "ib_read_lat",
|
|
101
|
+
"ib_send_bw", "ib_send_lat", "ib_atomic_bw", "ib_atomic_lat",
|
|
102
|
+
"raw_ethernet_bw", "raw_ethernet_lat", "raw_ethernet_burst_lat",
|
|
103
|
+
// GPU
|
|
104
|
+
"nvidia-smi", "gpustat", "nvtopo",
|
|
105
|
+
// hardware info
|
|
106
|
+
"lspci", "lsusb", "lsblk", "lscpu", "lsmem", "lshw", "dmidecode",
|
|
107
|
+
// kernel / system
|
|
108
|
+
"uname", "hostname", "uptime", "dmesg", "sysctl", "lsmod", "modinfo",
|
|
109
|
+
// process / resource
|
|
110
|
+
"ps", "pgrep", "top", "free", "vmstat", "iostat", "mpstat",
|
|
111
|
+
"df", "du", "mount", "findmnt", "nproc",
|
|
112
|
+
// file inspection (read-only)
|
|
113
|
+
"cat", "ls", "pwd", "stat", "file", "find",
|
|
114
|
+
"readlink", "realpath", "basename", "dirname",
|
|
115
|
+
"diff", "md5sum", "sha256sum",
|
|
116
|
+
// SiChek diagnostics
|
|
117
|
+
"sichek",
|
|
118
|
+
// system logs & services
|
|
119
|
+
"journalctl", "systemctl", "timedatectl", "hostnamectl",
|
|
120
|
+
// container runtime
|
|
121
|
+
"crictl", "ctr",
|
|
122
|
+
// firewall (read-only via validator)
|
|
123
|
+
"iptables", "ip6tables",
|
|
124
|
+
// file / process inspection
|
|
125
|
+
"lsof", "lsns", "strings",
|
|
126
|
+
// compressed file reading
|
|
127
|
+
"zcat", "zgrep", "bzcat", "xzcat",
|
|
128
|
+
// system activity
|
|
129
|
+
"sar", "blkid",
|
|
130
|
+
// stream utility (restricted via validator)
|
|
131
|
+
"tee",
|
|
132
|
+
// general
|
|
133
|
+
"date", "whoami", "id", "env", "printenv", "which",
|
|
134
|
+
// flow control
|
|
135
|
+
"echo", "printf", "true", "false", "sleep", "wait", "test",
|
|
136
|
+
// math (bc removed — !command escapes to shell)
|
|
137
|
+
"expr", "seq",
|
|
138
|
+
]);
|
|
139
|
+
export const COMMAND_RULES = {
|
|
140
|
+
// ── Flag whitelist ──
|
|
141
|
+
sort: {
|
|
142
|
+
command: "sort", category: "text",
|
|
143
|
+
allowedFlags: [
|
|
144
|
+
"-r", "-n", "-k", "-t", "-u", "-f", "-h", "-V", "-s", "-b", "-g", "-M", "-d", "-i",
|
|
145
|
+
"--reverse", "--numeric-sort", "--key", "--field-separator", "--unique",
|
|
146
|
+
"--human-numeric-sort", "--version-sort", "--stable", "--ignore-leading-blanks",
|
|
147
|
+
"--general-numeric-sort", "--month-sort", "--dictionary-order", "--ignore-case",
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
yq: {
|
|
151
|
+
command: "yq", category: "text",
|
|
152
|
+
allowedFlags: [
|
|
153
|
+
"-r", "--raw-output", "-e", "--exit-status", "-o", "--output-format",
|
|
154
|
+
"-P", "--prettyprint", "-C", "--colors", "-M", "--no-colors",
|
|
155
|
+
"-N", "--no-doc", "-j", "--tojson", "-p", "--input-format",
|
|
156
|
+
"--xml-attribute-prefix", "--xml-content-name",
|
|
157
|
+
"-s", "--split-exp", "--unwrapScalar", "--nul-output", "--header-preprocess",
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
ethtool: {
|
|
161
|
+
command: "ethtool", category: "network",
|
|
162
|
+
allowedFlags: [
|
|
163
|
+
"-i", "-S", "-T", "-a", "-c", "-g", "-k", "-l", "-P", "-m", "-d", "--phy-statistics",
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
arp: {
|
|
167
|
+
command: "arp", category: "network",
|
|
168
|
+
allowedFlags: ["-a", "-n", "-e", "-v", "--all", "--numeric", "--verbose"],
|
|
169
|
+
},
|
|
170
|
+
dmesg: {
|
|
171
|
+
command: "dmesg", category: "system",
|
|
172
|
+
allowedFlags: [
|
|
173
|
+
"-T", "--ctime", "-H", "--human", "-l", "--level", "-f", "--facility",
|
|
174
|
+
"-k", "--kernel", "-x", "--decode", "-L", "--color", "--time-format",
|
|
175
|
+
"--nopager",
|
|
176
|
+
"--since", "--until", "-S", "--syslog", "-t", "--notime", "-P",
|
|
177
|
+
// NOTE: -w/--follow/-W/--follow-new intentionally excluded — they hang indefinitely
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
journalctl: {
|
|
181
|
+
command: "journalctl", category: "system",
|
|
182
|
+
allowedFlags: [
|
|
183
|
+
"-u", "--unit", "-n", "--lines", "--since", "--until",
|
|
184
|
+
"-p", "--priority", "-b", "--boot", "-k", "--dmesg",
|
|
185
|
+
"--no-pager", "-o", "--output", "-r", "--reverse",
|
|
186
|
+
"-x", "--catalog", "--system", "--user",
|
|
187
|
+
"-t", "--identifier", "-g", "--grep", "--case-sensitive",
|
|
188
|
+
"-S", "-U", "-e", "--pager-end", "-a", "--all",
|
|
189
|
+
"-q", "--quiet", "--no-hostname", "--no-full",
|
|
190
|
+
"-m", "--merge", "-D", "--directory", "--file", "--list-boots",
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
iptables: {
|
|
194
|
+
command: "iptables", category: "network",
|
|
195
|
+
allowedFlags: [
|
|
196
|
+
"-L", "--list", "-S", "--list-rules",
|
|
197
|
+
"-n", "--numeric", "-v", "--verbose",
|
|
198
|
+
"-x", "--exact", "--line-numbers", "-t", "--table",
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
// ── Flag whitelist + requiredFlags ──
|
|
202
|
+
top: {
|
|
203
|
+
command: "top", category: "process",
|
|
204
|
+
allowedFlags: [
|
|
205
|
+
"-b", "--batch", "-n", "-d", "-p", "-H", "-c", "-o", "-O",
|
|
206
|
+
"-w", "-1", "-e", "-E", "-i", "-S", "-s", "-u", "-U",
|
|
207
|
+
],
|
|
208
|
+
requiredFlags: ["-b", "--batch"],
|
|
209
|
+
},
|
|
210
|
+
// ── Flag whitelist + positional restrictions ──
|
|
211
|
+
hostname: {
|
|
212
|
+
command: "hostname", category: "system",
|
|
213
|
+
allowedFlags: [
|
|
214
|
+
"-f", "-d", "-s", "-i", "-I", "-A",
|
|
215
|
+
"--fqdn", "--domain", "--short", "--ip-address", "--all-ip-addresses",
|
|
216
|
+
],
|
|
217
|
+
positionals: "block",
|
|
218
|
+
},
|
|
219
|
+
route: {
|
|
220
|
+
command: "route", category: "network",
|
|
221
|
+
allowedFlags: ["-n", "-e", "-v", "-F", "-C", "--numeric", "--extend", "--verbose"],
|
|
222
|
+
positionals: "block",
|
|
223
|
+
},
|
|
224
|
+
ifconfig: {
|
|
225
|
+
command: "ifconfig", category: "network",
|
|
226
|
+
allowedFlags: ["-a", "-s", "--all", "--short"],
|
|
227
|
+
positionals: 1,
|
|
228
|
+
},
|
|
229
|
+
uniq: {
|
|
230
|
+
command: "uniq", category: "text",
|
|
231
|
+
positionals: 1,
|
|
232
|
+
},
|
|
233
|
+
// ── Subcommand whitelist (position: 0) ──
|
|
234
|
+
systemctl: {
|
|
235
|
+
command: "systemctl", category: "service",
|
|
236
|
+
allowedSubcommands: {
|
|
237
|
+
position: 0,
|
|
238
|
+
allowed: [
|
|
239
|
+
"status", "show", "list-units", "list-unit-files",
|
|
240
|
+
"is-active", "is-enabled", "is-failed", "cat",
|
|
241
|
+
"list-dependencies", "list-sockets", "list-timers",
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
crictl: {
|
|
246
|
+
command: "crictl", category: "container",
|
|
247
|
+
allowedSubcommands: {
|
|
248
|
+
position: 0,
|
|
249
|
+
allowed: [
|
|
250
|
+
"ps", "images", "inspect", "inspecti", "inspectp",
|
|
251
|
+
"logs", "stats", "info", "version", "pods",
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
timedatectl: {
|
|
256
|
+
command: "timedatectl", category: "system",
|
|
257
|
+
allowedSubcommands: {
|
|
258
|
+
position: 0,
|
|
259
|
+
allowed: ["status", "show", "list-timezones", "timesync-status"],
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
hostnamectl: {
|
|
263
|
+
command: "hostnamectl", category: "system",
|
|
264
|
+
allowedSubcommands: {
|
|
265
|
+
position: 0,
|
|
266
|
+
allowed: ["status", "show"],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
// ── Action whitelist (position: 1) ──
|
|
270
|
+
tc: {
|
|
271
|
+
command: "tc", category: "network",
|
|
272
|
+
allowedSubcommands: { position: 1, allowed: ["show", "list", "ls"] },
|
|
273
|
+
},
|
|
274
|
+
bridge: {
|
|
275
|
+
command: "bridge", category: "network",
|
|
276
|
+
allowedSubcommands: { position: 1, allowed: ["show", "list", "ls"] },
|
|
277
|
+
},
|
|
278
|
+
rdma: {
|
|
279
|
+
command: "rdma", category: "network",
|
|
280
|
+
allowedSubcommands: { position: 1, allowed: ["show", "list", "ls"] },
|
|
281
|
+
},
|
|
282
|
+
// ── Custom validators ──
|
|
283
|
+
curl: { command: "curl", category: "network", customValidator: "curl" },
|
|
284
|
+
conntrack: { command: "conntrack", category: "network", customValidator: "conntrack" },
|
|
285
|
+
find: { command: "find", category: "file", customValidator: "find" },
|
|
286
|
+
ip: { command: "ip", category: "network", customValidator: "ip" },
|
|
287
|
+
"nvidia-smi": { command: "nvidia-smi", category: "gpu", customValidator: "nvidia-smi" },
|
|
288
|
+
date: { command: "date", category: "system", customValidator: "date" },
|
|
289
|
+
ctr: { command: "ctr", category: "container", customValidator: "ctr" },
|
|
290
|
+
ibportstate: { command: "ibportstate", category: "rdma", customValidator: "ibportstate" },
|
|
291
|
+
env: { command: "env", category: "system", customValidator: "env" },
|
|
292
|
+
tee: { command: "tee", category: "system", customValidator: "tee" },
|
|
293
|
+
mount: { command: "mount", category: "system", customValidator: "mount" },
|
|
294
|
+
sysctl: { command: "sysctl", category: "system", customValidator: "sysctl" },
|
|
295
|
+
};
|
|
296
|
+
// ip6tables shares iptables rules
|
|
297
|
+
COMMAND_RULES["ip6tables"] = { ...COMMAND_RULES["iptables"], command: "ip6tables" };
|
|
298
|
+
// Perftest: 11 binaries share one flag set
|
|
299
|
+
const PERFTEST_FLAGS = [
|
|
300
|
+
"-s", "--size", "-D", "--duration", "-n", "--iters",
|
|
301
|
+
"-p", "--port", "-d", "--ib-dev", "-i", "--ib-port",
|
|
302
|
+
"-m", "--mtu", "-x", "--gid-index", "--sl",
|
|
303
|
+
"-a", "--all", "-b", "--bidirectional",
|
|
304
|
+
"-F", "--CPU-freq", "-c", "--connection",
|
|
305
|
+
"-R", "--rdma_cm", "-q", "--qp",
|
|
306
|
+
"--run_infinitely", "--report_gbits", "--report_per_port",
|
|
307
|
+
"-l", "--post_list", "--use_cuda", "--use_rocm", "--output_format",
|
|
308
|
+
"-h", "--help", "-V", "--version",
|
|
309
|
+
];
|
|
310
|
+
for (const bin of [
|
|
311
|
+
"ib_write_bw", "ib_write_lat", "ib_read_bw", "ib_read_lat",
|
|
312
|
+
"ib_send_bw", "ib_send_lat", "ib_atomic_bw", "ib_atomic_lat",
|
|
313
|
+
"raw_ethernet_bw", "raw_ethernet_lat", "raw_ethernet_burst_lat",
|
|
314
|
+
]) {
|
|
315
|
+
COMMAND_RULES[bin] = { command: bin, category: "perftest", allowedFlags: PERFTEST_FLAGS };
|
|
316
|
+
}
|
|
317
|
+
// ── Generic rule engine ──────────────────────────────────────────
|
|
318
|
+
function validateByRule(args, rule) {
|
|
319
|
+
const cmd = rule.command;
|
|
320
|
+
// 1. requiredFlags: at least one must be present
|
|
321
|
+
if (rule.requiredFlags?.length) {
|
|
322
|
+
if (!rule.requiredFlags.some((f) => args.includes(f))) {
|
|
323
|
+
return JSON.stringify({
|
|
324
|
+
error: `${cmd} requires one of: ${rule.requiredFlags.join(", ")}`,
|
|
325
|
+
}, null, 2);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// 2. allowedSubcommands: check the Nth positional
|
|
329
|
+
if (rule.allowedSubcommands) {
|
|
330
|
+
const { position, allowed } = rule.allowedSubcommands;
|
|
331
|
+
let posCount = 0;
|
|
332
|
+
for (const arg of args.slice(1)) {
|
|
333
|
+
if (arg.startsWith("-"))
|
|
334
|
+
continue;
|
|
335
|
+
if (posCount === position) {
|
|
336
|
+
if (!allowed.includes(arg)) {
|
|
337
|
+
return JSON.stringify({
|
|
338
|
+
error: `${cmd} ${position === 0 ? "subcommand" : "action"} "${arg}" is not allowed.`,
|
|
339
|
+
}, null, 2);
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
posCount++;
|
|
344
|
+
}
|
|
345
|
+
return null; // not enough positionals → safe default
|
|
346
|
+
}
|
|
347
|
+
// 3. check flags + positionals
|
|
348
|
+
const positionalPolicy = rule.positionals ?? "allow";
|
|
349
|
+
let positionalCount = 0;
|
|
350
|
+
for (let i = 1; i < args.length; i++) {
|
|
351
|
+
const arg = args[i];
|
|
352
|
+
if (!arg.startsWith("-")) {
|
|
353
|
+
positionalCount++;
|
|
354
|
+
if (positionalPolicy === "block") {
|
|
355
|
+
return JSON.stringify({
|
|
356
|
+
error: `${cmd} "${arg}" is not allowed.`,
|
|
357
|
+
}, null, 2);
|
|
358
|
+
}
|
|
359
|
+
if (typeof positionalPolicy === "number" && positionalCount > positionalPolicy) {
|
|
360
|
+
return JSON.stringify({
|
|
361
|
+
error: `${cmd} does not allow more than ${positionalPolicy} positional argument(s).`,
|
|
362
|
+
}, null, 2);
|
|
363
|
+
}
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
// flag check — skip if no allowedFlags defined
|
|
367
|
+
if (!rule.allowedFlags)
|
|
368
|
+
continue;
|
|
369
|
+
const flag = extractFlag(arg);
|
|
370
|
+
if (rule.allowedFlags.includes(flag))
|
|
371
|
+
continue;
|
|
372
|
+
// short flag with attached value: -k2,3 → check "-k"
|
|
373
|
+
// Only when 3rd char is NOT a letter — prevents combined flags like -ro
|
|
374
|
+
// from bypassing the check (where -r is safe but -o is not)
|
|
375
|
+
if (!arg.startsWith("--") && arg.length > 2) {
|
|
376
|
+
const thirdChar = arg[2];
|
|
377
|
+
if (thirdChar && !/[a-zA-Z]/.test(thirdChar)) {
|
|
378
|
+
const shortFlag = arg.slice(0, 2);
|
|
379
|
+
if (rule.allowedFlags.includes(shortFlag))
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return JSON.stringify({
|
|
384
|
+
error: `${cmd} "${arg}" is not allowed.`,
|
|
385
|
+
}, null, 2);
|
|
386
|
+
}
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
// ── Custom validator functions ───────────────────────────────────
|
|
390
|
+
// ─── find ────────────────────────────────────────────────────────
|
|
391
|
+
const FIND_SAFE_ACTIONS = new Set(["-print", "-print0", "-ls", "-prune", "-quit"]);
|
|
392
|
+
const FIND_SAFE_TESTS = new Set([
|
|
393
|
+
"-name", "-iname", "-path", "-ipath", "-regex", "-iregex",
|
|
394
|
+
"-type", "-size", "-mtime", "-atime", "-ctime", "-mmin", "-amin", "-cmin",
|
|
395
|
+
"-newer", "-newermt", "-newerat", "-newerct",
|
|
396
|
+
"-perm", "-user", "-group", "-uid", "-gid", "-nouser", "-nogroup",
|
|
397
|
+
"-empty", "-readable", "-writable", "-executable",
|
|
398
|
+
"-maxdepth", "-mindepth", "-mount", "-xdev",
|
|
399
|
+
"-not", "-and", "-or", "-a", "-o",
|
|
400
|
+
"-true", "-false", "-depth", "-daystart",
|
|
401
|
+
"-samefile", "-inum", "-links", "-lname", "-ilname",
|
|
402
|
+
"-wholename", "-iwholename",
|
|
403
|
+
"-fstype", "-xtype",
|
|
404
|
+
]);
|
|
405
|
+
function validateFind(args) {
|
|
406
|
+
for (const arg of args.slice(1)) {
|
|
407
|
+
if (!arg.startsWith("-"))
|
|
408
|
+
continue; // path arguments are ok
|
|
409
|
+
if (arg === "-")
|
|
410
|
+
continue; // stdin marker
|
|
411
|
+
if (!FIND_SAFE_ACTIONS.has(arg) && !FIND_SAFE_TESTS.has(arg)) {
|
|
412
|
+
return JSON.stringify({
|
|
413
|
+
error: `find "${arg}" is not allowed. Only read-only find operations are permitted.`,
|
|
414
|
+
allowed_actions: [...FIND_SAFE_ACTIONS],
|
|
415
|
+
}, null, 2);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
// ─── conntrack ───────────────────────────────────────────────────
|
|
421
|
+
const CONNTRACK_SAFE_OPS = new Set([
|
|
422
|
+
"-L", "--dump", "-G", "--get", "-C", "--count", "-S", "--stats", "-E", "--event",
|
|
423
|
+
]);
|
|
424
|
+
const CONNTRACK_SAFE_FLAGS = new Set([
|
|
425
|
+
"-p", "--proto", "-s", "--src", "-d", "--dst", "--sport", "--dport",
|
|
426
|
+
"-m", "--mark", "-f", "--family", "-z", "--zero",
|
|
427
|
+
"-o", "--output", "-e", "--event-mask", "-b", "--buffer-size",
|
|
428
|
+
"-n", "--src-nat", "-g", "--dst-nat",
|
|
429
|
+
"--orig-src", "--orig-dst", "--reply-src", "--reply-dst",
|
|
430
|
+
"--orig-port-src", "--orig-port-dst", "--reply-port-src", "--reply-port-dst",
|
|
431
|
+
"--state", "--status", "--timeout",
|
|
432
|
+
]);
|
|
433
|
+
const CONNTRACK_SAFE_PREFIXES = [
|
|
434
|
+
"-p=", "--proto=", "-s=", "--src=", "-d=", "--dst=", "--sport=", "--dport=",
|
|
435
|
+
"-m=", "--mark=", "-f=", "--family=", "-o=", "--output=", "-e=", "--event-mask=",
|
|
436
|
+
"-b=", "--buffer-size=", "--state=", "--status=", "--timeout=",
|
|
437
|
+
];
|
|
438
|
+
function validateConntrack(args) {
|
|
439
|
+
for (let i = 1; i < args.length; i++) {
|
|
440
|
+
const arg = args[i];
|
|
441
|
+
if (!arg.startsWith("-"))
|
|
442
|
+
continue;
|
|
443
|
+
if (CONNTRACK_SAFE_OPS.has(arg)) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const flag = extractFlag(arg);
|
|
447
|
+
if (!CONNTRACK_SAFE_FLAGS.has(flag) && !startsWithAny(arg, CONNTRACK_SAFE_PREFIXES)) {
|
|
448
|
+
return JSON.stringify({
|
|
449
|
+
error: `conntrack "${arg}" is not allowed. Only read-only operations are permitted.`,
|
|
450
|
+
allowed_ops: [...CONNTRACK_SAFE_OPS],
|
|
451
|
+
}, null, 2);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
// ─── curl ────────────────────────────────────────────────────────
|
|
457
|
+
const CURL_SAFE_FLAGS = new Set([
|
|
458
|
+
"-s", "--silent", "-S", "--show-error", "-k", "--insecure", "-v", "--verbose",
|
|
459
|
+
"-H", "--header", "-m", "--max-time", "--connect-timeout",
|
|
460
|
+
"-L", "--location", "-I", "--head", "-w", "--write-out",
|
|
461
|
+
"-d", "--data", "--data-raw", "--data-urlencode", "--compressed",
|
|
462
|
+
"-A", "--user-agent", "-b", "--cookie", "-e", "--referer",
|
|
463
|
+
"-u", "--user", "--cacert", "--cert", "-x", "--proxy",
|
|
464
|
+
"--retry", "--retry-delay", "--retry-max-time",
|
|
465
|
+
"-f", "--fail", "-4", "-6", "-N", "--no-buffer",
|
|
466
|
+
]);
|
|
467
|
+
const CURL_SAFE_PREFIXES = [
|
|
468
|
+
"-H=", "--header=", "-m=", "--max-time=", "--connect-timeout=",
|
|
469
|
+
"-w=", "--write-out=", "-d=", "--data=", "--data-raw=", "--data-urlencode=",
|
|
470
|
+
"-A=", "--user-agent=", "-b=", "--cookie=", "-e=", "--referer=",
|
|
471
|
+
"-u=", "--user=", "--cacert=", "--cert=", "-x=", "--proxy=",
|
|
472
|
+
"--retry=", "--retry-delay=", "--retry-max-time=",
|
|
473
|
+
];
|
|
474
|
+
const CURL_DATA_FLAGS = new Set(["-d", "--data", "--data-raw", "--data-urlencode"]);
|
|
475
|
+
const CURL_REQUEST_FLAGS = new Set(["-X", "--request"]);
|
|
476
|
+
const CURL_SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS", "POST"]);
|
|
477
|
+
const CURL_SAFE_SHORT_CHARS = new Set([
|
|
478
|
+
"s", "S", "k", "v", "H", "X", "m", "L", "I", "w", "d", "A", "b", "e", "u", "x", "f", "N",
|
|
479
|
+
"4", "6",
|
|
480
|
+
]);
|
|
481
|
+
function checkCurlMethod(method) {
|
|
482
|
+
if (method && !CURL_SAFE_METHODS.has(method.toUpperCase())) {
|
|
483
|
+
return JSON.stringify({
|
|
484
|
+
error: `curl -X ${method.toUpperCase()} is not allowed. Only safe HTTP methods (${[...CURL_SAFE_METHODS].join(", ")}) are permitted.`,
|
|
485
|
+
}, null, 2);
|
|
486
|
+
}
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
489
|
+
function checkCurlDataValue(flag, value) {
|
|
490
|
+
if (value && value.startsWith("@")) {
|
|
491
|
+
return `curl ${flag} with @file is not allowed. File uploads are blocked.`;
|
|
492
|
+
}
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
function validateCurl(args) {
|
|
496
|
+
for (let i = 1; i < args.length; i++) {
|
|
497
|
+
const arg = args[i];
|
|
498
|
+
if (!arg.startsWith("-"))
|
|
499
|
+
continue;
|
|
500
|
+
// ── Long flags (--xxx) ──────────────────────────────────
|
|
501
|
+
if (arg.startsWith("--")) {
|
|
502
|
+
const flag = extractFlag(arg);
|
|
503
|
+
const hasValue = arg.includes("=");
|
|
504
|
+
const inlineValue = hasValue ? arg.slice(flag.length + 1) : undefined;
|
|
505
|
+
if (CURL_REQUEST_FLAGS.has(flag)) {
|
|
506
|
+
const method = hasValue ? inlineValue : args[i + 1];
|
|
507
|
+
const err = checkCurlMethod(method);
|
|
508
|
+
if (err)
|
|
509
|
+
return err;
|
|
510
|
+
if (!hasValue)
|
|
511
|
+
i++;
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
if (CURL_DATA_FLAGS.has(flag)) {
|
|
515
|
+
const value = hasValue ? inlineValue : args[i + 1];
|
|
516
|
+
const err = checkCurlDataValue(flag, value);
|
|
517
|
+
if (err)
|
|
518
|
+
return err;
|
|
519
|
+
if (!hasValue)
|
|
520
|
+
i++;
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
if (!CURL_SAFE_FLAGS.has(flag) && !startsWithAny(arg, CURL_SAFE_PREFIXES)) {
|
|
524
|
+
return JSON.stringify({
|
|
525
|
+
error: `curl "${arg}" is not allowed. Only read-only curl flags are permitted.`,
|
|
526
|
+
}, null, 2);
|
|
527
|
+
}
|
|
528
|
+
if (!hasValue && CURL_SAFE_FLAGS.has(flag) && (["-H", "--header", "-m", "--max-time", "--connect-timeout",
|
|
529
|
+
"-w", "--write-out", "-A", "--user-agent", "-b", "--cookie",
|
|
530
|
+
"-e", "--referer", "-u", "--user", "--cacert", "--cert",
|
|
531
|
+
"-x", "--proxy", "--retry", "--retry-delay", "--retry-max-time",
|
|
532
|
+
].includes(flag))) {
|
|
533
|
+
i++;
|
|
534
|
+
}
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
// ── Short flags with = (e.g. -m=10, -X=GET) ────────────
|
|
538
|
+
if (arg.includes("=")) {
|
|
539
|
+
const flag = extractFlag(arg);
|
|
540
|
+
const inlineValue = arg.slice(flag.length + 1);
|
|
541
|
+
if (flag === "-X") {
|
|
542
|
+
const err = checkCurlMethod(inlineValue);
|
|
543
|
+
if (err)
|
|
544
|
+
return err;
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (flag === "-d") {
|
|
548
|
+
const err = checkCurlDataValue("-d", inlineValue);
|
|
549
|
+
if (err)
|
|
550
|
+
return err;
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
if (!CURL_SAFE_FLAGS.has(flag) && !startsWithAny(arg, CURL_SAFE_PREFIXES)) {
|
|
554
|
+
return JSON.stringify({
|
|
555
|
+
error: `curl "${arg}" is not allowed. Only read-only curl flags are permitted.`,
|
|
556
|
+
}, null, 2);
|
|
557
|
+
}
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
// ── Combined short flags (e.g. -sS, -sSX, -vk) ─────────
|
|
561
|
+
const chars = arg.slice(1);
|
|
562
|
+
for (const ch of chars) {
|
|
563
|
+
if (!CURL_SAFE_SHORT_CHARS.has(ch)) {
|
|
564
|
+
return JSON.stringify({
|
|
565
|
+
error: `curl "-${ch}" (in "${arg}") is not allowed. Only read-only curl flags are permitted.`,
|
|
566
|
+
}, null, 2);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
const lastChar = chars[chars.length - 1];
|
|
570
|
+
if (lastChar && "HXmwdAbeuxr".includes(lastChar)) {
|
|
571
|
+
if (lastChar === "X") {
|
|
572
|
+
const err = checkCurlMethod(args[i + 1]);
|
|
573
|
+
if (err)
|
|
574
|
+
return err;
|
|
575
|
+
}
|
|
576
|
+
if (lastChar === "d") {
|
|
577
|
+
const err = checkCurlDataValue("-d", args[i + 1]);
|
|
578
|
+
if (err)
|
|
579
|
+
return err;
|
|
580
|
+
}
|
|
581
|
+
i++;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
// ─── ibportstate ─────────────────────────────────────────────────
|
|
587
|
+
const IBPORTSTATE_SAFE_ACTIONS = new Set(["query"]);
|
|
588
|
+
function validateIbportstate(args) {
|
|
589
|
+
for (let i = 1; i < args.length; i++) {
|
|
590
|
+
const arg = args[i];
|
|
591
|
+
if (arg.startsWith("-"))
|
|
592
|
+
continue;
|
|
593
|
+
if (/^\d+$/.test(arg))
|
|
594
|
+
continue;
|
|
595
|
+
if (!IBPORTSTATE_SAFE_ACTIONS.has(arg)) {
|
|
596
|
+
return JSON.stringify({
|
|
597
|
+
error: `ibportstate "${arg}" is not allowed. Only query operations are permitted.`,
|
|
598
|
+
allowed: [...IBPORTSTATE_SAFE_ACTIONS],
|
|
599
|
+
}, null, 2);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
// ─── nvidia-smi ──────────────────────────────────────────────────
|
|
605
|
+
const NVIDIA_SMI_SAFE_FLAGS = new Set([
|
|
606
|
+
"-q", "--query", "-L", "--list-gpus", "-i",
|
|
607
|
+
]);
|
|
608
|
+
const NVIDIA_SMI_SAFE_PREFIXES = [
|
|
609
|
+
"--query-gpu=", "--query-compute-apps=", "--id=", "--format=",
|
|
610
|
+
"-i=",
|
|
611
|
+
];
|
|
612
|
+
const NVIDIA_SMI_SUBCMDS = new Set(["topo", "nvlink"]);
|
|
613
|
+
function validateNvidiaSmi(args) {
|
|
614
|
+
if (args.length <= 1)
|
|
615
|
+
return null;
|
|
616
|
+
for (let i = 1; i < args.length; i++) {
|
|
617
|
+
const arg = args[i];
|
|
618
|
+
if (!arg.startsWith("-")) {
|
|
619
|
+
if (NVIDIA_SMI_SUBCMDS.has(arg))
|
|
620
|
+
return null;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
const flag = extractFlag(arg);
|
|
624
|
+
if (!NVIDIA_SMI_SAFE_FLAGS.has(flag) && !startsWithAny(arg, NVIDIA_SMI_SAFE_PREFIXES)) {
|
|
625
|
+
return JSON.stringify({
|
|
626
|
+
error: `nvidia-smi "${arg}" is not allowed. Only read-only nvidia-smi queries are permitted.`,
|
|
627
|
+
}, null, 2);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
// ─── date ────────────────────────────────────────────────────────
|
|
633
|
+
const DATE_SAFE_FLAGS = new Set([
|
|
634
|
+
"-d", "--date", "-u", "--utc", "--universal",
|
|
635
|
+
"-I", "--iso-8601", "-R", "--rfc-email", "--rfc-3339",
|
|
636
|
+
"-r", "--reference",
|
|
637
|
+
]);
|
|
638
|
+
const DATE_SAFE_PREFIXES = [
|
|
639
|
+
"-d=", "--date=", "-I=", "--iso-8601=", "--rfc-3339=", "-r=", "--reference=",
|
|
640
|
+
];
|
|
641
|
+
function validateDate(args) {
|
|
642
|
+
for (let i = 1; i < args.length; i++) {
|
|
643
|
+
const arg = args[i];
|
|
644
|
+
if (arg.startsWith("+"))
|
|
645
|
+
continue; // format string
|
|
646
|
+
if (arg.startsWith("-")) {
|
|
647
|
+
const flag = extractFlag(arg);
|
|
648
|
+
if (!DATE_SAFE_FLAGS.has(flag) && !startsWithAny(arg, DATE_SAFE_PREFIXES)) {
|
|
649
|
+
return JSON.stringify({
|
|
650
|
+
error: `date "${arg}" is not allowed. Only read-only date queries are permitted.`,
|
|
651
|
+
}, null, 2);
|
|
652
|
+
}
|
|
653
|
+
if (DATE_SAFE_FLAGS.has(arg) && (arg === "-d" || arg === "--date" || arg === "-r" || arg === "--reference")) {
|
|
654
|
+
i++;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
return JSON.stringify({
|
|
659
|
+
error: `date "${arg}" is not allowed. Only format strings (+...) and read-only flags are permitted.`,
|
|
660
|
+
}, null, 2);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
// ─── sysctl ──────────────────────────────────────────────────────
|
|
666
|
+
const SYSCTL_SAFE_FLAGS = new Set([
|
|
667
|
+
"-a", "--all", "-n", "--values", "-e", "--ignore",
|
|
668
|
+
"-N", "--names", "-q", "--quiet", "-b", "--binary",
|
|
669
|
+
"--pattern", "-d", "--deprecated", "-r",
|
|
670
|
+
]);
|
|
671
|
+
const SYSCTL_SAFE_PREFIXES = ["--pattern=", "-r="];
|
|
672
|
+
function validateSysctl(args) {
|
|
673
|
+
for (let i = 1; i < args.length; i++) {
|
|
674
|
+
const arg = args[i];
|
|
675
|
+
if (arg.startsWith("-")) {
|
|
676
|
+
const flag = extractFlag(arg);
|
|
677
|
+
if (!SYSCTL_SAFE_FLAGS.has(flag) && !startsWithAny(arg, SYSCTL_SAFE_PREFIXES)) {
|
|
678
|
+
return JSON.stringify({
|
|
679
|
+
error: `sysctl "${arg}" is not allowed. Only read-only sysctl queries are permitted.`,
|
|
680
|
+
}, null, 2);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
if (arg.includes("=")) {
|
|
685
|
+
return JSON.stringify({
|
|
686
|
+
error: `sysctl write ("${arg}") is not allowed. Only read-only sysctl queries are permitted.`,
|
|
687
|
+
}, null, 2);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
// ─── ip ──────────────────────────────────────────────────────────
|
|
694
|
+
const IP_SAFE_ACTIONS = new Set(["show", "list", "ls", "get"]);
|
|
695
|
+
function validateIp(cmd) {
|
|
696
|
+
const parts = cmd.trim().split(/\s+/);
|
|
697
|
+
let objectIdx = 1;
|
|
698
|
+
while (objectIdx < parts.length && parts[objectIdx].startsWith("-")) {
|
|
699
|
+
objectIdx++;
|
|
700
|
+
}
|
|
701
|
+
const action = parts[objectIdx + 1];
|
|
702
|
+
if (!action)
|
|
703
|
+
return null;
|
|
704
|
+
let actionStr = action;
|
|
705
|
+
if (action.startsWith("-")) {
|
|
706
|
+
let i = objectIdx + 2;
|
|
707
|
+
while (i < parts.length && parts[i].startsWith("-"))
|
|
708
|
+
i++;
|
|
709
|
+
actionStr = parts[i] ?? "";
|
|
710
|
+
if (!actionStr)
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
if (!IP_SAFE_ACTIONS.has(actionStr)) {
|
|
714
|
+
return JSON.stringify({
|
|
715
|
+
error: `ip action "${actionStr}" is not allowed. Only read-only actions are permitted.`,
|
|
716
|
+
allowed: [...IP_SAFE_ACTIONS],
|
|
717
|
+
}, null, 2);
|
|
718
|
+
}
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
721
|
+
// ─── mount ───────────────────────────────────────────────────────
|
|
722
|
+
const MOUNT_SAFE_FLAGS = new Set([
|
|
723
|
+
"-l", "--list", "-t", "--types", "-v", "--verbose", "-n", "--no-mtab",
|
|
724
|
+
"-r", "--read-only",
|
|
725
|
+
]);
|
|
726
|
+
const MOUNT_SAFE_PREFIXES = ["-t=", "--types="];
|
|
727
|
+
function validateMount(args) {
|
|
728
|
+
let nonFlagCount = 0;
|
|
729
|
+
for (let i = 1; i < args.length; i++) {
|
|
730
|
+
const arg = args[i];
|
|
731
|
+
if (!arg.startsWith("-")) {
|
|
732
|
+
nonFlagCount++;
|
|
733
|
+
if (nonFlagCount >= 2) {
|
|
734
|
+
return "mount with device and mountpoint arguments is not allowed. Only listing mounts (mount without arguments or with -l) is permitted.";
|
|
735
|
+
}
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
const flag = extractFlag(arg);
|
|
739
|
+
if (MOUNT_SAFE_FLAGS.has(flag) || startsWithAny(arg, MOUNT_SAFE_PREFIXES)) {
|
|
740
|
+
// -t/--types consumes next arg as value
|
|
741
|
+
if (!arg.includes("=") && (flag === "-t" || flag === "--types")) {
|
|
742
|
+
i++;
|
|
743
|
+
}
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
return JSON.stringify({
|
|
747
|
+
error: `mount "${arg}" is not allowed. Only listing mounts is permitted.`,
|
|
748
|
+
}, null, 2);
|
|
749
|
+
}
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
752
|
+
// ─── env ─────────────────────────────────────────────────────────
|
|
753
|
+
function validateEnv(args) {
|
|
754
|
+
const restArgs = args.slice(1);
|
|
755
|
+
for (let i = 0; i < restArgs.length; i++) {
|
|
756
|
+
const arg = restArgs[i];
|
|
757
|
+
if (arg === "-u" || arg === "--unset") {
|
|
758
|
+
i++;
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
if (arg.startsWith("-"))
|
|
762
|
+
continue;
|
|
763
|
+
if (arg.includes("="))
|
|
764
|
+
continue;
|
|
765
|
+
return 'env cannot be used to execute commands. Use "printenv" to view environment variables.';
|
|
766
|
+
}
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
// ─── ctr ─────────────────────────────────────────────────────────
|
|
770
|
+
const CTR_SAFE_ACTIONS = new Set(["ls", "list", "info", "check"]);
|
|
771
|
+
function validateCtr(args) {
|
|
772
|
+
const positional = [];
|
|
773
|
+
const skipNext = new Set(["-n", "--namespace", "-a", "--address"]);
|
|
774
|
+
for (let i = 1; i < args.length; i++) {
|
|
775
|
+
if (skipNext.has(args[i])) {
|
|
776
|
+
i++;
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
if (args[i].startsWith("-"))
|
|
780
|
+
continue;
|
|
781
|
+
positional.push(args[i]);
|
|
782
|
+
}
|
|
783
|
+
if (positional.length === 0)
|
|
784
|
+
return null;
|
|
785
|
+
if (positional[0] === "version" || positional[0] === "info")
|
|
786
|
+
return null;
|
|
787
|
+
const action = positional[1];
|
|
788
|
+
if (!action)
|
|
789
|
+
return null;
|
|
790
|
+
if (!CTR_SAFE_ACTIONS.has(action)) {
|
|
791
|
+
return JSON.stringify({
|
|
792
|
+
error: `ctr action "${action}" on "${positional[0]}" is not allowed. Only read-only actions are permitted.`,
|
|
793
|
+
allowed: [...CTR_SAFE_ACTIONS].sort(),
|
|
794
|
+
}, null, 2);
|
|
795
|
+
}
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
// ─── tee ─────────────────────────────────────────────────────────
|
|
799
|
+
function validateTee(args) {
|
|
800
|
+
for (const arg of args.slice(1)) {
|
|
801
|
+
if (arg.startsWith("-"))
|
|
802
|
+
continue;
|
|
803
|
+
if (arg !== "/dev/null") {
|
|
804
|
+
return JSON.stringify({
|
|
805
|
+
error: `tee to "${arg}" is not allowed. Only "tee" or "tee /dev/null" is permitted.`,
|
|
806
|
+
}, null, 2);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
// ── Custom validator registry ────────────────────────────────────
|
|
812
|
+
const CUSTOM_VALIDATORS = {
|
|
813
|
+
curl: (args) => validateCurl(args),
|
|
814
|
+
conntrack: (args) => validateConntrack(args),
|
|
815
|
+
find: (args) => validateFind(args),
|
|
816
|
+
ip: (args) => validateIp(args.join(" ")),
|
|
817
|
+
"nvidia-smi": (args) => validateNvidiaSmi(args),
|
|
818
|
+
date: (args) => validateDate(args),
|
|
819
|
+
ctr: (args) => validateCtr(args),
|
|
820
|
+
ibportstate: (args) => validateIbportstate(args),
|
|
821
|
+
env: (args) => validateEnv(args),
|
|
822
|
+
tee: (args) => validateTee(args),
|
|
823
|
+
mount: (args) => validateMount(args),
|
|
824
|
+
sysctl: (args) => validateSysctl(args),
|
|
825
|
+
};
|
|
826
|
+
// ── Entry point ──────────────────────────────────────────────────
|
|
827
|
+
/**
|
|
828
|
+
* Apply extra security restrictions to whitelisted commands.
|
|
829
|
+
* Takes a raw command string, parses it internally.
|
|
830
|
+
* Returns an error message string if blocked, or null if allowed.
|
|
831
|
+
*/
|
|
832
|
+
export function validateCommandRestrictions(cmd) {
|
|
833
|
+
const args = parseArgs(cmd);
|
|
834
|
+
if (args.length === 0)
|
|
835
|
+
return null;
|
|
836
|
+
const baseName = args[0].split("/").pop()?.toLowerCase() ?? "";
|
|
837
|
+
const rule = COMMAND_RULES[baseName];
|
|
838
|
+
if (!rule)
|
|
839
|
+
return null;
|
|
840
|
+
if (rule.customValidator) {
|
|
841
|
+
return CUSTOM_VALIDATORS[rule.customValidator]?.(args, baseName) ?? null;
|
|
842
|
+
}
|
|
843
|
+
return validateByRule(args, rule);
|
|
844
|
+
}
|
|
845
|
+
//# sourceMappingURL=command-sets.js.map
|