@evalops/maestro 0.10.18 → 0.10.20
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/README.md +56 -1
- package/dist/agent/action-approval.d.ts +12 -2
- package/dist/agent/action-approval.d.ts.map +1 -1
- package/dist/agent/action-approval.js +19 -32
- package/dist/agent/action-approval.js.map +1 -1
- package/dist/agent/agent.d.ts +1 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +26 -0
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/compaction.d.ts +2 -0
- package/dist/agent/compaction.d.ts.map +1 -1
- package/dist/agent/compaction.js +4 -2
- package/dist/agent/compaction.js.map +1 -1
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/modes.d.ts +56 -4
- package/dist/agent/modes.d.ts.map +1 -1
- package/dist/agent/modes.js +163 -2
- package/dist/agent/modes.js.map +1 -1
- package/dist/agent/prompt-recovery.d.ts.map +1 -1
- package/dist/agent/prompt-recovery.js +1 -3
- package/dist/agent/prompt-recovery.js.map +1 -1
- package/dist/agent/providers/anthropic.d.ts.map +1 -1
- package/dist/agent/providers/anthropic.js +9 -1
- package/dist/agent/providers/anthropic.js.map +1 -1
- package/dist/agent/providers/codex-app-server.d.ts +12 -0
- package/dist/agent/providers/codex-app-server.d.ts.map +1 -0
- package/dist/agent/providers/codex-app-server.js +788 -0
- package/dist/agent/providers/codex-app-server.js.map +1 -0
- package/dist/agent/providers/google-gemini-cli.js +14 -3
- package/dist/agent/providers/google.js +22 -3
- package/dist/agent/providers/scripted.d.ts +11 -0
- package/dist/agent/providers/scripted.d.ts.map +1 -0
- package/dist/agent/providers/scripted.js +399 -0
- package/dist/agent/providers/scripted.js.map +1 -0
- package/dist/agent/providers/vertex.js +14 -3
- package/dist/agent/scenario-source.d.ts +19 -0
- package/dist/agent/scenario-source.d.ts.map +1 -0
- package/dist/agent/scenario-source.js +112 -0
- package/dist/agent/scenario-source.js.map +1 -0
- package/dist/agent/subagent-specs.d.ts +1 -1
- package/dist/agent/subagent-specs.js +1 -1
- package/dist/agent/subagent-specs.js.map +1 -1
- package/dist/agent/swarm/executor.d.ts +25 -0
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +795 -20
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/runtime-events.d.ts +11 -0
- package/dist/agent/swarm/runtime-events.d.ts.map +1 -0
- package/dist/agent/swarm/runtime-events.js +26 -0
- package/dist/agent/swarm/runtime-events.js.map +1 -0
- package/dist/agent/swarm/types.d.ts +78 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/tracing.d.ts +1 -1
- package/dist/agent/tracing.d.ts.map +1 -1
- package/dist/agent/tracing.js +17 -9
- package/dist/agent/tracing.js.map +1 -1
- package/dist/agent/transport/create-provider-stream.d.ts.map +1 -1
- package/dist/agent/transport/create-provider-stream.js +14 -0
- package/dist/agent/transport/create-provider-stream.js.map +1 -1
- package/dist/agent/transport/stable-stringify.d.ts +2 -0
- package/dist/agent/transport/stable-stringify.d.ts.map +1 -0
- package/dist/agent/transport/stable-stringify.js +14 -0
- package/dist/agent/transport/stable-stringify.js.map +1 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
- package/dist/agent/transport/tool-execution-bridge.js +2 -15
- package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
- package/dist/agent/transport/tool-safety-pipeline.d.ts +5 -1
- package/dist/agent/transport/tool-safety-pipeline.d.ts.map +1 -1
- package/dist/agent/transport/tool-safety-pipeline.js +184 -36
- package/dist/agent/transport/tool-safety-pipeline.js.map +1 -1
- package/dist/agent/transport.d.ts +8 -0
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/transport.js +1613 -68
- package/dist/agent/transport.js.map +1 -1
- package/dist/agent/types.d.ts +170 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/enterprise-routes.d.ts.map +1 -1
- package/dist/api/enterprise-routes.js +34 -3
- package/dist/api/enterprise-routes.js.map +1 -1
- package/dist/app-server/in-process-client.d.ts +32 -0
- package/dist/app-server/in-process-client.d.ts.map +1 -0
- package/dist/app-server/in-process-client.js +73 -0
- package/dist/app-server/in-process-client.js.map +1 -0
- package/dist/app-server/session-api.d.ts +36 -0
- package/dist/app-server/session-api.d.ts.map +1 -0
- package/dist/app-server/session-api.js +713 -0
- package/dist/app-server/session-api.js.map +1 -0
- package/dist/approvals/platform-action-approval.d.ts +3 -1
- package/dist/approvals/platform-action-approval.d.ts.map +1 -1
- package/dist/approvals/platform-action-approval.js +16 -9
- package/dist/approvals/platform-action-approval.js.map +1 -1
- package/dist/approvals/service-client.d.ts.map +1 -1
- package/dist/approvals/service-client.js +7 -7
- package/dist/approvals/service-client.js.map +1 -1
- package/dist/audit/logger.d.ts +4 -4
- package/dist/bootstrap/agent-creation-setup.d.ts +4 -0
- package/dist/bootstrap/agent-creation-setup.d.ts.map +1 -1
- package/dist/bootstrap/agent-creation-setup.js +3 -1
- package/dist/bootstrap/agent-creation-setup.js.map +1 -1
- package/dist/bootstrap/auth-setup.js +1 -1
- package/dist/bootstrap/auth-setup.js.map +1 -1
- package/dist/bootstrap/event-subscriptions-setup.d.ts +6 -0
- package/dist/bootstrap/event-subscriptions-setup.d.ts.map +1 -1
- package/dist/bootstrap/event-subscriptions-setup.js +26 -2
- package/dist/bootstrap/event-subscriptions-setup.js.map +1 -1
- package/dist/bootstrap/model-resolution-setup.d.ts.map +1 -1
- package/dist/bootstrap/model-resolution-setup.js +4 -1
- package/dist/bootstrap/model-resolution-setup.js.map +1 -1
- package/dist/bootstrap/tools-setup.d.ts +2 -1
- package/dist/bootstrap/tools-setup.d.ts.map +1 -1
- package/dist/bootstrap/tools-setup.js +5 -1
- package/dist/bootstrap/tools-setup.js.map +1 -1
- package/dist/cli/args.d.ts +9 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +130 -5
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts +9 -0
- package/dist/cli/commands/a2a.d.ts.map +1 -0
- package/dist/cli/commands/a2a.js +1714 -0
- package/dist/cli/commands/a2a.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +16 -2
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +223 -35
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/codex.d.ts +1 -1
- package/dist/cli/commands/codex.d.ts.map +1 -1
- package/dist/cli/commands/codex.js +145 -39
- package/dist/cli/commands/codex.js.map +1 -1
- package/dist/cli/commands/context.d.ts +10 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +176 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/hosted-runner.d.ts +1 -0
- package/dist/cli/commands/hosted-runner.d.ts.map +1 -1
- package/dist/cli/commands/hosted-runner.js +9 -1
- package/dist/cli/commands/hosted-runner.js.map +1 -1
- package/dist/cli/commands/modes.d.ts +8 -0
- package/dist/cli/commands/modes.d.ts.map +1 -0
- package/dist/cli/commands/modes.js +151 -0
- package/dist/cli/commands/modes.js.map +1 -0
- package/dist/cli/commands/operating-plane.d.ts +14 -0
- package/dist/cli/commands/operating-plane.d.ts.map +1 -0
- package/dist/cli/commands/operating-plane.js +160 -0
- package/dist/cli/commands/operating-plane.js.map +1 -0
- package/dist/cli/commands/run.d.ts +87 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +356 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/scenario.d.ts +7 -0
- package/dist/cli/commands/scenario.d.ts.map +1 -0
- package/dist/cli/commands/scenario.js +195 -0
- package/dist/cli/commands/scenario.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +7 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +286 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/headless-protocol.d.ts +55 -1
- package/dist/cli/headless-protocol.d.ts.map +1 -1
- package/dist/cli/headless-protocol.js +446 -7
- package/dist/cli/headless-protocol.js.map +1 -1
- package/dist/cli/headless-runtime-selection.d.ts +38 -0
- package/dist/cli/headless-runtime-selection.d.ts.map +1 -0
- package/dist/cli/headless-runtime-selection.js +48 -0
- package/dist/cli/headless-runtime-selection.js.map +1 -0
- package/dist/cli/headless.d.ts +5 -1
- package/dist/cli/headless.d.ts.map +1 -1
- package/dist/cli/headless.js +11 -1
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/help.d.ts +3 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +135 -30
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/system-prompt.d.ts +22 -4
- package/dist/cli/system-prompt.d.ts.map +1 -1
- package/dist/cli/system-prompt.js +224 -127
- package/dist/cli/system-prompt.js.map +1 -1
- package/dist/cli-tui/commands/a2a-handlers.d.ts +7 -0
- package/dist/cli-tui/commands/a2a-handlers.d.ts.map +1 -0
- package/dist/cli-tui/commands/a2a-handlers.js +160 -0
- package/dist/cli-tui/commands/a2a-handlers.js.map +1 -0
- package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
- package/dist/cli-tui/commands/command-catalog.js +15 -0
- package/dist/cli-tui/commands/command-catalog.js.map +1 -1
- package/dist/cli-tui/commands/command-registry-adapter.js +10 -1
- package/dist/cli-tui/commands/command-registry-adapter.js.map +1 -1
- package/dist/cli-tui/commands/handlers/mode-handler.d.ts.map +1 -1
- package/dist/cli-tui/commands/handlers/mode-handler.js +22 -10
- package/dist/cli-tui/commands/handlers/mode-handler.js.map +1 -1
- package/dist/cli-tui/commands/mcp-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/mcp-handlers.js +6 -5
- package/dist/cli-tui/commands/mcp-handlers.js.map +1 -1
- package/dist/cli-tui/commands/types.d.ts +1 -0
- package/dist/cli-tui/commands/types.d.ts.map +1 -1
- package/dist/cli-tui/commands/types.js.map +1 -1
- package/dist/cli-tui/commands/utility-handlers.d.ts +4 -0
- package/dist/cli-tui/commands/utility-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/utility-handlers.js +45 -6
- package/dist/cli-tui/commands/utility-handlers.js.map +1 -1
- package/dist/cli-tui/run/run-shell-command.d.ts.map +1 -1
- package/dist/cli-tui/run/run-shell-command.js +14 -5
- package/dist/cli-tui/run/run-shell-command.js.map +1 -1
- package/dist/cli-tui/run/streaming-shell-command.d.ts.map +1 -1
- package/dist/cli-tui/run/streaming-shell-command.js +14 -5
- package/dist/cli-tui/run/streaming-shell-command.js.map +1 -1
- package/dist/cli-tui/selectors/model-selector.d.ts +1 -0
- package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/model-selector.js +6 -2
- package/dist/cli-tui/selectors/model-selector.js.map +1 -1
- package/dist/cli-tui/tui-renderer/command-registry-options.d.ts.map +1 -1
- package/dist/cli-tui/tui-renderer/command-registry-options.js +5 -0
- package/dist/cli-tui/tui-renderer/command-registry-options.js.map +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.d.ts +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.d.ts.map +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.js +8 -3
- package/dist/cli-tui/utils/commands/review-prompt.js.map +1 -1
- package/dist/cli-tui/utils/runtime-badges.d.ts +1 -0
- package/dist/cli-tui/utils/runtime-badges.d.ts.map +1 -1
- package/dist/cli-tui/utils/runtime-badges.js +7 -0
- package/dist/cli-tui/utils/runtime-badges.js.map +1 -1
- package/dist/cli-tui/utils/text-formatting.d.ts +1 -0
- package/dist/cli-tui/utils/text-formatting.d.ts.map +1 -1
- package/dist/cli-tui/utils/text-formatting.js +5 -0
- package/dist/cli-tui/utils/text-formatting.js.map +1 -1
- package/dist/cli.js +49158 -26161
- package/dist/cli.js.map +1 -1
- package/dist/codex/app-server-client.d.ts +139 -0
- package/dist/codex/app-server-client.d.ts.map +1 -0
- package/dist/codex/app-server-client.js +352 -0
- package/dist/codex/app-server-client.js.map +1 -0
- package/dist/codex/compatibility.d.ts +48 -0
- package/dist/codex/compatibility.d.ts.map +1 -0
- package/dist/codex/compatibility.js +344 -0
- package/dist/codex/compatibility.js.map +1 -0
- package/dist/codex/subagent-dispatch-table.d.ts +66 -0
- package/dist/codex/subagent-dispatch-table.d.ts.map +1 -0
- package/dist/codex/subagent-dispatch-table.js +127 -0
- package/dist/codex/subagent-dispatch-table.js.map +1 -0
- package/dist/codex/subagent-workgraph.d.ts +56 -0
- package/dist/codex/subagent-workgraph.d.ts.map +1 -0
- package/dist/codex/subagent-workgraph.js +89 -0
- package/dist/codex/subagent-workgraph.js.map +1 -0
- package/dist/config/constants.d.ts +3 -1
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +9 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/config/feature-flags.d.ts +10 -1
- package/dist/config/feature-flags.d.ts.map +1 -1
- package/dist/config/feature-flags.js +17 -6
- package/dist/config/feature-flags.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/toml-config.d.ts +32 -0
- package/dist/config/toml-config.d.ts.map +1 -1
- package/dist/config/toml-config.js +152 -43
- package/dist/config/toml-config.js.map +1 -1
- package/dist/connectors/service-client.d.ts.map +1 -1
- package/dist/connectors/service-client.js +4 -7
- package/dist/connectors/service-client.js.map +1 -1
- package/dist/context/manifest-types.d.ts +59 -0
- package/dist/context/manifest-types.d.ts.map +1 -0
- package/dist/context/manifest-types.js +2 -0
- package/dist/context/manifest-types.js.map +1 -0
- package/dist/context/manifest.d.ts +16 -0
- package/dist/context/manifest.d.ts.map +1 -0
- package/dist/context/manifest.js +503 -0
- package/dist/context/manifest.js.map +1 -0
- package/dist/db/schema.d.ts +10 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/evalops/env-aliases.d.ts +13 -0
- package/dist/evalops/env-aliases.d.ts.map +1 -0
- package/dist/evalops/env-aliases.js +60 -0
- package/dist/evalops/env-aliases.js.map +1 -0
- package/dist/evalops/managed-context.d.ts.map +1 -1
- package/dist/evalops/managed-context.js +28 -62
- package/dist/evalops/managed-context.js.map +1 -1
- package/dist/guardian/config.d.ts.map +1 -1
- package/dist/guardian/config.js +1 -0
- package/dist/guardian/config.js.map +1 -1
- package/dist/guardian/runner.d.ts +2 -0
- package/dist/guardian/runner.d.ts.map +1 -1
- package/dist/guardian/runner.js +105 -2
- package/dist/guardian/runner.js.map +1 -1
- package/dist/guardian/types.d.ts +1 -0
- package/dist/guardian/types.d.ts.map +1 -1
- package/dist/guardian/types.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +267 -55
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +89 -7
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/manager.d.ts +5 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +159 -4
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/platform-plugin.d.ts.map +1 -1
- package/dist/mcp/platform-plugin.js +9 -26
- package/dist/mcp/platform-plugin.js.map +1 -1
- package/dist/mcp/schema.d.ts +15 -0
- package/dist/mcp/schema.d.ts.map +1 -1
- package/dist/mcp/schema.js +24 -0
- package/dist/mcp/schema.js.map +1 -1
- package/dist/mcp/tool-bridge.d.ts +39 -10
- package/dist/mcp/tool-bridge.d.ts.map +1 -1
- package/dist/mcp/tool-bridge.js +101 -24
- package/dist/mcp/tool-bridge.js.map +1 -1
- package/dist/mcp/types.d.ts +27 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/mcp/workspace-trust.d.ts +10 -0
- package/dist/mcp/workspace-trust.d.ts.map +1 -0
- package/dist/mcp/workspace-trust.js +295 -0
- package/dist/mcp/workspace-trust.js.map +1 -0
- package/dist/memory/service-client.d.ts +1 -0
- package/dist/memory/service-client.d.ts.map +1 -1
- package/dist/memory/service-client.js +194 -9
- package/dist/memory/service-client.js.map +1 -1
- package/dist/models/builtin.d.ts.map +1 -1
- package/dist/models/builtin.js +66 -25
- package/dist/models/builtin.js.map +1 -1
- package/dist/models/config-loader.d.ts +10 -10
- package/dist/models/config-loader.d.ts.map +1 -1
- package/dist/models/config-loader.js +2 -0
- package/dist/models/config-loader.js.map +1 -1
- package/dist/models/registry.d.ts +1 -0
- package/dist/models/registry.d.ts.map +1 -1
- package/dist/models/registry.js +1 -0
- package/dist/models/registry.js.map +1 -1
- package/dist/oauth/device-identity.d.ts.map +1 -1
- package/dist/oauth/device-identity.js +1 -3
- package/dist/oauth/device-identity.js.map +1 -1
- package/dist/oauth/evalops.d.ts.map +1 -1
- package/dist/oauth/evalops.js +2 -5
- package/dist/oauth/evalops.js.map +1 -1
- package/dist/opentelemetry.d.ts.map +1 -1
- package/dist/opentelemetry.js +12 -12
- package/dist/opentelemetry.js.map +1 -1
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +11 -0
- package/dist/package-version.js.map +1 -0
- package/dist/packages/constants.d.ts +3 -0
- package/dist/packages/constants.d.ts.map +1 -0
- package/dist/packages/constants.js +3 -0
- package/dist/packages/constants.js.map +1 -0
- package/dist/packages/inspection.d.ts.map +1 -1
- package/dist/packages/inspection.js +2 -1
- package/dist/packages/inspection.js.map +1 -1
- package/dist/packages/search.d.ts.map +1 -1
- package/dist/packages/search.js +1 -1
- package/dist/packages/search.js.map +1 -1
- package/dist/platform/a2a-capability-market.d.ts +21 -0
- package/dist/platform/a2a-capability-market.d.ts.map +1 -0
- package/dist/platform/a2a-capability-market.js +176 -0
- package/dist/platform/a2a-capability-market.js.map +1 -0
- package/dist/platform/a2a-client.d.ts +119 -0
- package/dist/platform/a2a-client.d.ts.map +1 -1
- package/dist/platform/a2a-client.js +413 -24
- package/dist/platform/a2a-client.js.map +1 -1
- package/dist/platform/a2a-fleet.d.ts +41 -0
- package/dist/platform/a2a-fleet.d.ts.map +1 -0
- package/dist/platform/a2a-fleet.js +109 -0
- package/dist/platform/a2a-fleet.js.map +1 -0
- package/dist/platform/a2a-maestro-peer.d.ts +20 -0
- package/dist/platform/a2a-maestro-peer.d.ts.map +1 -0
- package/dist/platform/a2a-maestro-peer.js +176 -0
- package/dist/platform/a2a-maestro-peer.js.map +1 -0
- package/dist/platform/a2a-peer-pairing.d.ts +107 -0
- package/dist/platform/a2a-peer-pairing.d.ts.map +1 -0
- package/dist/platform/a2a-peer-pairing.js +489 -0
- package/dist/platform/a2a-peer-pairing.js.map +1 -0
- package/dist/platform/a2a-peer-registry.d.ts +68 -0
- package/dist/platform/a2a-peer-registry.d.ts.map +1 -0
- package/dist/platform/a2a-peer-registry.js +320 -0
- package/dist/platform/a2a-peer-registry.js.map +1 -0
- package/dist/platform/a2a-task-ledger.d.ts +86 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -0
- package/dist/platform/a2a-task-ledger.js +546 -0
- package/dist/platform/a2a-task-ledger.js.map +1 -0
- package/dist/platform/a2a-work-graph.d.ts +43 -0
- package/dist/platform/a2a-work-graph.d.ts.map +1 -0
- package/dist/platform/a2a-work-graph.js +267 -0
- package/dist/platform/a2a-work-graph.js.map +1 -0
- package/dist/platform/agent-registry-client.d.ts +327 -0
- package/dist/platform/agent-registry-client.d.ts.map +1 -0
- package/dist/platform/agent-registry-client.js +803 -0
- package/dist/platform/agent-registry-client.js.map +1 -0
- package/dist/platform/agent-runtime-client.d.ts +135 -1
- package/dist/platform/agent-runtime-client.d.ts.map +1 -1
- package/dist/platform/agent-runtime-client.js +467 -10
- package/dist/platform/agent-runtime-client.js.map +1 -1
- package/dist/platform/cerebro-facts-client.d.ts.map +1 -1
- package/dist/platform/cerebro-facts-client.js +4 -7
- package/dist/platform/cerebro-facts-client.js.map +1 -1
- package/dist/platform/client.d.ts.map +1 -1
- package/dist/platform/client.js +3 -12
- package/dist/platform/client.js.map +1 -1
- package/dist/platform/core-services.d.ts +68 -0
- package/dist/platform/core-services.d.ts.map +1 -1
- package/dist/platform/core-services.js +68 -0
- package/dist/platform/core-services.js.map +1 -1
- package/dist/platform/fermata-eval-client.d.ts +195 -0
- package/dist/platform/fermata-eval-client.d.ts.map +1 -0
- package/dist/platform/fermata-eval-client.js +146 -0
- package/dist/platform/fermata-eval-client.js.map +1 -0
- package/dist/platform/fermata-scenario-suite.d.ts +99 -0
- package/dist/platform/fermata-scenario-suite.d.ts.map +1 -0
- package/dist/platform/fermata-scenario-suite.js +459 -0
- package/dist/platform/fermata-scenario-suite.js.map +1 -0
- package/dist/platform/maestro-timeline-client.d.ts.map +1 -1
- package/dist/platform/maestro-timeline-client.js +5 -11
- package/dist/platform/maestro-timeline-client.js.map +1 -1
- package/dist/platform/operating-plane-client.d.ts +156 -0
- package/dist/platform/operating-plane-client.d.ts.map +1 -0
- package/dist/platform/operating-plane-client.js +131 -0
- package/dist/platform/operating-plane-client.js.map +1 -0
- package/dist/platform/operating-plane-summary.d.ts +47 -0
- package/dist/platform/operating-plane-summary.d.ts.map +1 -0
- package/dist/platform/operating-plane-summary.js +209 -0
- package/dist/platform/operating-plane-summary.js.map +1 -0
- package/dist/platform/tool-execution-client.d.ts.map +1 -1
- package/dist/platform/tool-execution-client.js +4 -11
- package/dist/platform/tool-execution-client.js.map +1 -1
- package/dist/prompts/service-client.d.ts.map +1 -1
- package/dist/prompts/service-client.js +3 -5
- package/dist/prompts/service-client.js.map +1 -1
- package/dist/prompts/system-prompt.d.ts +3 -0
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +13 -3
- package/dist/prompts/system-prompt.js.map +1 -1
- package/dist/prompts/types.d.ts +2 -0
- package/dist/prompts/types.d.ts.map +1 -1
- package/dist/prompts/types.js.map +1 -1
- package/dist/providers/api-keys.d.ts +1 -1
- package/dist/providers/api-keys.d.ts.map +1 -1
- package/dist/providers/api-keys.js +2 -1
- package/dist/providers/api-keys.js.map +1 -1
- package/dist/providers/auth.d.ts.map +1 -1
- package/dist/providers/auth.js +48 -25
- package/dist/providers/auth.js.map +1 -1
- package/dist/remote-runner/attach-client.d.ts.map +1 -1
- package/dist/remote-runner/attach-client.js +1 -0
- package/dist/remote-runner/attach-client.js.map +1 -1
- package/dist/remote-runner/client.d.ts.map +1 -1
- package/dist/remote-runner/client.js +4 -7
- package/dist/remote-runner/client.js.map +1 -1
- package/dist/rpc/rpc-types.d.ts.map +1 -1
- package/dist/rpc/rpc-types.js +1 -0
- package/dist/rpc/rpc-types.js.map +1 -1
- package/dist/safety/action-firewall.d.ts.map +1 -1
- package/dist/safety/action-firewall.js +69 -6
- package/dist/safety/action-firewall.js.map +1 -1
- package/dist/safety/attack-patterns.d.ts.map +1 -1
- package/dist/safety/attack-patterns.js +31 -14
- package/dist/safety/attack-patterns.js.map +1 -1
- package/dist/safety/bash-parser.d.ts.map +1 -1
- package/dist/safety/bash-parser.js +4 -3
- package/dist/safety/bash-parser.js.map +1 -1
- package/dist/safety/execpolicy.d.ts +15 -3
- package/dist/safety/execpolicy.d.ts.map +1 -1
- package/dist/safety/execpolicy.js +248 -37
- package/dist/safety/execpolicy.js.map +1 -1
- package/dist/safety/governance-service-client.d.ts.map +1 -1
- package/dist/safety/governance-service-client.js +4 -7
- package/dist/safety/governance-service-client.js.map +1 -1
- package/dist/safety/guarded-files.d.ts +34 -0
- package/dist/safety/guarded-files.d.ts.map +1 -0
- package/dist/safety/guarded-files.js +372 -0
- package/dist/safety/guarded-files.js.map +1 -0
- package/dist/safety/loop-detector.d.ts.map +1 -1
- package/dist/safety/loop-detector.js +6 -1
- package/dist/safety/loop-detector.js.map +1 -1
- package/dist/safety/permission-profile.d.ts +47 -0
- package/dist/safety/permission-profile.d.ts.map +1 -0
- package/dist/safety/permission-profile.js +349 -0
- package/dist/safety/permission-profile.js.map +1 -0
- package/dist/safety/safety-middleware.d.ts +5 -1
- package/dist/safety/safety-middleware.d.ts.map +1 -1
- package/dist/safety/safety-middleware.js +3 -2
- package/dist/safety/safety-middleware.js.map +1 -1
- package/dist/safety/suspicious-patterns.d.ts.map +1 -1
- package/dist/safety/suspicious-patterns.js +12 -7
- package/dist/safety/suspicious-patterns.js.map +1 -1
- package/dist/safety/tool-categorization.js +1 -1
- package/dist/safety/tool-categorization.js.map +1 -1
- package/dist/safety/validators/path-policy-validator.d.ts.map +1 -1
- package/dist/safety/validators/path-policy-validator.js +7 -0
- package/dist/safety/validators/path-policy-validator.js.map +1 -1
- package/dist/sandbox/index.d.ts +6 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +30 -4
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/native-sandbox.d.ts +3 -0
- package/dist/sandbox/native-sandbox.d.ts.map +1 -1
- package/dist/sandbox/native-sandbox.js +139 -18
- package/dist/sandbox/native-sandbox.js.map +1 -1
- package/dist/sentry.d.ts +17 -0
- package/dist/sentry.d.ts.map +1 -0
- package/dist/sentry.js +91 -0
- package/dist/sentry.js.map +1 -0
- package/dist/server/agent-runtime-ledger.d.ts +141 -0
- package/dist/server/agent-runtime-ledger.d.ts.map +1 -0
- package/dist/server/agent-runtime-ledger.js +334 -0
- package/dist/server/agent-runtime-ledger.js.map +1 -0
- package/dist/server/agent-trajectory-inspection.d.ts +104 -0
- package/dist/server/agent-trajectory-inspection.d.ts.map +1 -0
- package/dist/server/agent-trajectory-inspection.js +168 -0
- package/dist/server/agent-trajectory-inspection.js.map +1 -0
- package/dist/server/agent-trajectory-replay.d.ts +56 -0
- package/dist/server/agent-trajectory-replay.d.ts.map +1 -0
- package/dist/server/agent-trajectory-replay.js +214 -0
- package/dist/server/agent-trajectory-replay.js.map +1 -0
- package/dist/server/agent-trajectory-scenarios.d.ts +109 -0
- package/dist/server/agent-trajectory-scenarios.d.ts.map +1 -0
- package/dist/server/agent-trajectory-scenarios.js +822 -0
- package/dist/server/agent-trajectory-scenarios.js.map +1 -0
- package/dist/server/agent-trajectory-scorers.d.ts +61 -0
- package/dist/server/agent-trajectory-scorers.d.ts.map +1 -0
- package/dist/server/agent-trajectory-scorers.js +162 -0
- package/dist/server/agent-trajectory-scorers.js.map +1 -0
- package/dist/server/agent-trajectory-validation.d.ts +7 -0
- package/dist/server/agent-trajectory-validation.d.ts.map +1 -0
- package/dist/server/agent-trajectory-validation.js +101 -0
- package/dist/server/agent-trajectory-validation.js.map +1 -0
- package/dist/server/agent-trajectory.d.ts +50 -0
- package/dist/server/agent-trajectory.d.ts.map +1 -0
- package/dist/server/agent-trajectory.js +159 -0
- package/dist/server/agent-trajectory.js.map +1 -0
- package/dist/server/app-context.d.ts +18 -0
- package/dist/server/app-context.d.ts.map +1 -1
- package/dist/server/app-context.js.map +1 -1
- package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
- package/dist/server/handlers/headless-sessions.js +64 -27
- package/dist/server/handlers/headless-sessions.js.map +1 -1
- package/dist/server/handlers/health.d.ts +6 -0
- package/dist/server/handlers/health.d.ts.map +1 -1
- package/dist/server/handlers/health.js +6 -0
- package/dist/server/handlers/health.js.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.d.ts +69 -1
- package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.js +309 -18
- package/dist/server/handlers/hosted-runner-drain.js.map +1 -1
- package/dist/server/handlers/hosted-runner-identity.d.ts +16 -0
- package/dist/server/handlers/hosted-runner-identity.d.ts.map +1 -1
- package/dist/server/handlers/hosted-runner-identity.js +43 -0
- package/dist/server/handlers/hosted-runner-identity.js.map +1 -1
- package/dist/server/handlers/mode.d.ts.map +1 -1
- package/dist/server/handlers/mode.js +3 -1
- package/dist/server/handlers/mode.js.map +1 -1
- package/dist/server/handlers/pending-requests.d.ts.map +1 -1
- package/dist/server/handlers/pending-requests.js +336 -51
- package/dist/server/handlers/pending-requests.js.map +1 -1
- package/dist/server/handlers/platform-a2a-push.d.ts +6 -0
- package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -0
- package/dist/server/handlers/platform-a2a-push.js +136 -0
- package/dist/server/handlers/platform-a2a-push.js.map +1 -0
- package/dist/server/handlers/sessions.d.ts.map +1 -1
- package/dist/server/handlers/sessions.js +21 -1
- package/dist/server/handlers/sessions.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts +9 -2
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +39 -0
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.d.ts +144 -0
- package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -0
- package/dist/server/hosted-agent-runtime-progress.js +1650 -0
- package/dist/server/hosted-agent-runtime-progress.js.map +1 -0
- package/dist/server/hosted-runner-lease.d.ts +41 -0
- package/dist/server/hosted-runner-lease.d.ts.map +1 -0
- package/dist/server/hosted-runner-lease.js +140 -0
- package/dist/server/hosted-runner-lease.js.map +1 -0
- package/dist/server/hosted-session-manager.d.ts +16 -8
- package/dist/server/hosted-session-manager.d.ts.map +1 -1
- package/dist/server/hosted-session-manager.js +98 -76
- package/dist/server/hosted-session-manager.js.map +1 -1
- package/dist/server/junit-xml.d.ts +2 -0
- package/dist/server/junit-xml.d.ts.map +1 -0
- package/dist/server/junit-xml.js +9 -0
- package/dist/server/junit-xml.js.map +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +6 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/server/scenario-recorder.d.ts +56 -0
- package/dist/server/scenario-recorder.d.ts.map +1 -0
- package/dist/server/scenario-recorder.js +109 -0
- package/dist/server/scenario-recorder.js.map +1 -0
- package/dist/server/scripted-scenario-runner.d.ts +46 -0
- package/dist/server/scripted-scenario-runner.d.ts.map +1 -0
- package/dist/server/scripted-scenario-runner.js +190 -0
- package/dist/server/scripted-scenario-runner.js.map +1 -0
- package/dist/server/server-middlewares.d.ts +6 -2
- package/dist/server/server-middlewares.d.ts.map +1 -1
- package/dist/server/server-middlewares.js +8 -2
- package/dist/server/server-middlewares.js.map +1 -1
- package/dist/server/server-request-manager.d.ts +9 -1
- package/dist/server/server-request-manager.d.ts.map +1 -1
- package/dist/server/server-request-manager.js +49 -4
- package/dist/server/server-request-manager.js.map +1 -1
- package/dist/services/intelligent-router/service.d.ts +2 -0
- package/dist/services/intelligent-router/service.d.ts.map +1 -1
- package/dist/services/intelligent-router/service.js +4 -0
- package/dist/services/intelligent-router/service.js.map +1 -1
- package/dist/services/service-authority.d.ts +25 -0
- package/dist/services/service-authority.d.ts.map +1 -0
- package/dist/services/service-authority.js +143 -0
- package/dist/services/service-authority.js.map +1 -0
- package/dist/services/workspace-config/service.d.ts +2 -0
- package/dist/services/workspace-config/service.d.ts.map +1 -1
- package/dist/services/workspace-config/service.js +4 -0
- package/dist/services/workspace-config/service.js.map +1 -1
- package/dist/session/manager.d.ts +8 -2
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +19 -4
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-branch.d.ts.map +1 -1
- package/dist/session/session-branch.js +5 -1
- package/dist/session/session-branch.js.map +1 -1
- package/dist/session/session-catalog.d.ts +7 -2
- package/dist/session/session-catalog.d.ts.map +1 -1
- package/dist/session/session-catalog.js +13 -2
- package/dist/session/session-catalog.js.map +1 -1
- package/dist/session/session-context.d.ts +6 -2
- package/dist/session/session-context.d.ts.map +1 -1
- package/dist/session/session-context.js +44 -4
- package/dist/session/session-context.js.map +1 -1
- package/dist/session/session-graph-projection.d.ts +32 -0
- package/dist/session/session-graph-projection.d.ts.map +1 -0
- package/dist/session/session-graph-projection.js +133 -0
- package/dist/session/session-graph-projection.js.map +1 -0
- package/dist/session/types.d.ts +18 -0
- package/dist/session/types.d.ts.map +1 -1
- package/dist/session/types.js +8 -0
- package/dist/session/types.js.map +1 -1
- package/dist/session/wire-format.generated.d.ts +3 -0
- package/dist/session/wire-format.generated.d.ts.map +1 -1
- package/dist/session/wire-format.generated.js +20 -0
- package/dist/session/wire-format.generated.js.map +1 -1
- package/dist/skills/eval-harness.d.ts +38 -0
- package/dist/skills/eval-harness.d.ts.map +1 -0
- package/dist/skills/eval-harness.js +112 -0
- package/dist/skills/eval-harness.js.map +1 -0
- package/dist/skills/index.d.ts +5 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +5 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/linter.d.ts +36 -0
- package/dist/skills/linter.d.ts.map +1 -0
- package/dist/skills/linter.js +398 -0
- package/dist/skills/linter.js.map +1 -0
- package/dist/skills/loader.d.ts +36 -6
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +169 -86
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/package-contract.d.ts +45 -0
- package/dist/skills/package-contract.d.ts.map +1 -0
- package/dist/skills/package-contract.js +153 -0
- package/dist/skills/package-contract.js.map +1 -0
- package/dist/skills/runtime-activation.d.ts +68 -0
- package/dist/skills/runtime-activation.d.ts.map +1 -0
- package/dist/skills/runtime-activation.js +228 -0
- package/dist/skills/runtime-activation.js.map +1 -0
- package/dist/skills/service-client.d.ts.map +1 -1
- package/dist/skills/service-client.js +3 -4
- package/dist/skills/service-client.js.map +1 -1
- package/dist/skills/tool.d.ts.map +1 -1
- package/dist/skills/tool.js +2 -0
- package/dist/skills/tool.js.map +1 -1
- package/dist/skills/types.d.ts +14 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/types.js.map +1 -1
- package/dist/telemetry/agent-operating-plane-context.d.ts +24 -0
- package/dist/telemetry/agent-operating-plane-context.d.ts.map +1 -0
- package/dist/telemetry/agent-operating-plane-context.js +54 -0
- package/dist/telemetry/agent-operating-plane-context.js.map +1 -0
- package/dist/telemetry/beacon.d.ts +24 -0
- package/dist/telemetry/beacon.d.ts.map +1 -0
- package/dist/telemetry/beacon.js +115 -0
- package/dist/telemetry/beacon.js.map +1 -0
- package/dist/telemetry/cli-command-aggregator.d.ts +36 -0
- package/dist/telemetry/cli-command-aggregator.d.ts.map +1 -0
- package/dist/telemetry/cli-command-aggregator.js +251 -0
- package/dist/telemetry/cli-command-aggregator.js.map +1 -0
- package/dist/telemetry/cli-startup.d.ts +21 -0
- package/dist/telemetry/cli-startup.d.ts.map +1 -0
- package/dist/telemetry/cli-startup.js +83 -0
- package/dist/telemetry/cli-startup.js.map +1 -0
- package/dist/telemetry/disablement.d.ts +13 -0
- package/dist/telemetry/disablement.d.ts.map +1 -0
- package/dist/telemetry/disablement.js +19 -0
- package/dist/telemetry/disablement.js.map +1 -0
- package/dist/telemetry/index.d.ts +6 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +6 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts +52 -0
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +179 -3
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-event-catalog.d.ts +3 -1
- package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-catalog.js +2 -0
- package/dist/telemetry/maestro-event-catalog.js.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.js +74 -9
- package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts.map +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.js +46 -11
- package/dist/telemetry/maestro-publisher-conformance-fixture.js.map +1 -1
- package/dist/telemetry/mcp-beacon.d.ts +20 -0
- package/dist/telemetry/mcp-beacon.d.ts.map +1 -0
- package/dist/telemetry/mcp-beacon.js +54 -0
- package/dist/telemetry/mcp-beacon.js.map +1 -0
- package/dist/telemetry/metadata-normalization.d.ts +7 -0
- package/dist/telemetry/metadata-normalization.d.ts.map +1 -0
- package/dist/telemetry/metadata-normalization.js +189 -0
- package/dist/telemetry/metadata-normalization.js.map +1 -0
- package/dist/telemetry/meter-service-client.d.ts.map +1 -1
- package/dist/telemetry/meter-service-client.js +5 -10
- package/dist/telemetry/meter-service-client.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +123 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +184 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/turn-tracker.d.ts +1 -0
- package/dist/telemetry/turn-tracker.d.ts.map +1 -1
- package/dist/telemetry/turn-tracker.js +22 -1
- package/dist/telemetry/turn-tracker.js.map +1 -1
- package/dist/telemetry/wide-events.d.ts +31 -1
- package/dist/telemetry/wide-events.d.ts.map +1 -1
- package/dist/telemetry/wide-events.js +229 -1
- package/dist/telemetry/wide-events.js.map +1 -1
- package/dist/telemetry.d.ts +39 -3
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +160 -3
- package/dist/telemetry.js.map +1 -1
- package/dist/testing/test-verification-hook.d.ts.map +1 -1
- package/dist/testing/test-verification-hook.js +34 -21
- package/dist/testing/test-verification-hook.js.map +1 -1
- package/dist/tools/apply-patch-parser.d.ts +26 -0
- package/dist/tools/apply-patch-parser.d.ts.map +1 -0
- package/dist/tools/apply-patch-parser.js +146 -0
- package/dist/tools/apply-patch-parser.js.map +1 -0
- package/dist/tools/apply-patch.d.ts +42 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +648 -0
- package/dist/tools/apply-patch.js.map +1 -0
- package/dist/tools/ask-user.d.ts +1 -0
- package/dist/tools/ask-user.d.ts.map +1 -1
- package/dist/tools/background/tool-handler.d.ts +1 -0
- package/dist/tools/background/tool-handler.d.ts.map +1 -1
- package/dist/tools/bash.d.ts +1 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/codesearch.d.ts +1 -0
- package/dist/tools/codesearch.d.ts.map +1 -1
- package/dist/tools/conductor-client.d.ts +1 -0
- package/dist/tools/conductor-client.d.ts.map +1 -1
- package/dist/tools/conductor-client.js +63 -0
- package/dist/tools/conductor-client.js.map +1 -1
- package/dist/tools/diff.d.ts +1 -0
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/edit.d.ts +1 -0
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/extract-document.d.ts +1 -0
- package/dist/tools/extract-document.d.ts.map +1 -1
- package/dist/tools/find.d.ts +10 -0
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +236 -27
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/gh.d.ts +3 -0
- package/dist/tools/gh.d.ts.map +1 -1
- package/dist/tools/index.d.ts +50 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list.d.ts +1 -0
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/notebook.d.ts +1 -0
- package/dist/tools/notebook.d.ts.map +1 -1
- package/dist/tools/oracle.d.ts +1 -0
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +17 -32
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/parallel-execution.d.ts +13 -2
- package/dist/tools/parallel-execution.d.ts.map +1 -1
- package/dist/tools/parallel-execution.js +178 -7
- package/dist/tools/parallel-execution.js.map +1 -1
- package/dist/tools/parallel-ripgrep.d.ts +1 -0
- package/dist/tools/parallel-ripgrep.d.ts.map +1 -1
- package/dist/tools/pipeline.d.ts +4 -0
- package/dist/tools/pipeline.d.ts.map +1 -1
- package/dist/tools/read.d.ts +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/search.d.ts +1 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/status.d.ts +1 -0
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/todo.d.ts +1 -0
- package/dist/tools/todo.d.ts.map +1 -1
- package/dist/tools/tool-dsl.d.ts +5 -1
- package/dist/tools/tool-dsl.d.ts.map +1 -1
- package/dist/tools/tool-dsl.js +1 -0
- package/dist/tools/tool-dsl.js.map +1 -1
- package/dist/tools/tool-result-cache.d.ts.map +1 -1
- package/dist/tools/tool-result-cache.js +1 -0
- package/dist/tools/tool-result-cache.js.map +1 -1
- package/dist/tools/typebox-tool.d.ts.map +1 -1
- package/dist/tools/typebox-tool.js +3 -0
- package/dist/tools/typebox-tool.js.map +1 -1
- package/dist/tools/webfetch.d.ts +1 -0
- package/dist/tools/webfetch.d.ts.map +1 -1
- package/dist/tools/websearch.d.ts +1 -0
- package/dist/tools/websearch.d.ts.map +1 -1
- package/dist/tools/write.d.ts +1 -0
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/utils/abort-error.d.ts +2 -0
- package/dist/utils/abort-error.d.ts.map +1 -0
- package/dist/utils/abort-error.js +7 -0
- package/dist/utils/abort-error.js.map +1 -0
- package/dist/utils/downstream.d.ts.map +1 -1
- package/dist/utils/downstream.js +4 -0
- package/dist/utils/downstream.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +14 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/path-containment.d.ts +2 -0
- package/dist/utils/path-containment.d.ts.map +1 -0
- package/dist/utils/path-containment.js +14 -0
- package/dist/utils/path-containment.js.map +1 -0
- package/dist/utils/prompt-safe-text.d.ts +7 -0
- package/dist/utils/prompt-safe-text.d.ts.map +1 -0
- package/dist/utils/prompt-safe-text.js +44 -0
- package/dist/utils/prompt-safe-text.js.map +1 -0
- package/dist/version.json +2 -2
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +32 -7
- package/dist/web-server.js.map +1 -1
- package/dist/workspace/root-resolver.d.ts +4 -1
- package/dist/workspace/root-resolver.d.ts.map +1 -1
- package/dist/workspace/root-resolver.js +16 -6
- package/dist/workspace/root-resolver.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts +8 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.js +35 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts +10 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.js +48 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts +20 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.js +147 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts +2 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js +1 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +280 -5
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js +36 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/index.d.ts +15 -1
- package/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/index.js +6 -0
- package/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +593 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.js +218 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts +91 -0
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js +92 -61
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +3 -0
- package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts +28 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.js +71 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +7 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-server-request.js +2 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/scenario.d.ts +191 -0
- package/node_modules/@evalops/contracts/dist/scenario.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/scenario.js +4 -0
- package/node_modules/@evalops/contracts/dist/scenario.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/schemas.d.ts +17 -3
- package/node_modules/@evalops/contracts/dist/schemas.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/schemas.js +16 -0
- package/node_modules/@evalops/contracts/dist/schemas.js.map +1 -1
- package/node_modules/@evalops/contracts/package.json +1 -1
- package/node_modules/@evalops/tui/package.json +1 -1
- package/package.json +41 -7
- package/skills/incident-triage/SKILL.md +40 -0
- package/skills/incident-triage/mcp.json +14 -0
- package/skills/incident-triage/reference/triage.md +20 -0
- package/skills/incident-triage/toolbox/incident-timeline +22 -0
- package/skills/incident-triage/toolbox/incident-timeline.cmd +16 -0
- package/skills/pr-review/SKILL.md +40 -0
- package/skills/pr-review/mcp.json +14 -0
- package/skills/pr-review/reference/rubric.md +20 -0
- package/skills/pr-review/toolbox/review-summary +20 -0
- package/skills/pr-review/toolbox/review-summary.cmd +14 -0
- package/skills/release-verification/SKILL.md +40 -0
- package/skills/release-verification/mcp.json +15 -0
- package/skills/release-verification/reference/checklist.md +21 -0
- package/skills/release-verification/toolbox/release-readiness +18 -0
- package/skills/release-verification/toolbox/release-readiness.cmd +12 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { DEFAULT_GUARDED_FILE_PATTERNS, normalizeGuardedFilesSettings, } from "@evalops/contracts";
|
|
3
|
+
import { minimatch } from "minimatch";
|
|
4
|
+
import { parseApplyPatchPaths } from "../tools/apply-patch-parser.js";
|
|
5
|
+
import { expandTildePathWithHomeDir, getOsHomeDir, } from "../utils/path-expansion.js";
|
|
6
|
+
import { tokenizeSimple, unwrapShellCommand } from "./bash-safety-analyzer.js";
|
|
7
|
+
export const DEFAULT_GUARDED_FILE_RULE_ID = "default-guarded-file";
|
|
8
|
+
export const GUARDED_FILES_BLOCK_POLICY_ID = "guardedFiles_block";
|
|
9
|
+
export function classifyGuardedFileAccessAction(toolName) {
|
|
10
|
+
const normalizedToolName = toolName.toLowerCase();
|
|
11
|
+
if ([
|
|
12
|
+
"write",
|
|
13
|
+
"edit",
|
|
14
|
+
"apply_patch",
|
|
15
|
+
"delete_file",
|
|
16
|
+
"move_file",
|
|
17
|
+
"copy_file",
|
|
18
|
+
].includes(normalizedToolName)) {
|
|
19
|
+
return "write";
|
|
20
|
+
}
|
|
21
|
+
if ([
|
|
22
|
+
"read",
|
|
23
|
+
"list",
|
|
24
|
+
"find",
|
|
25
|
+
"search",
|
|
26
|
+
"parallel_ripgrep",
|
|
27
|
+
"diff",
|
|
28
|
+
"status",
|
|
29
|
+
].includes(normalizedToolName)) {
|
|
30
|
+
return "read";
|
|
31
|
+
}
|
|
32
|
+
if (["bash", "background_tasks"].includes(normalizedToolName)) {
|
|
33
|
+
return "execute";
|
|
34
|
+
}
|
|
35
|
+
return "unknown";
|
|
36
|
+
}
|
|
37
|
+
function guardedPatternToRule(pattern) {
|
|
38
|
+
return {
|
|
39
|
+
key: pattern.key,
|
|
40
|
+
category: pattern.description,
|
|
41
|
+
patterns: pattern.patterns,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export const DEFAULT_GUARDED_FILE_RULES = DEFAULT_GUARDED_FILE_PATTERNS.map(guardedPatternToRule);
|
|
45
|
+
function guardedPatternToEffectiveRule(pattern, source) {
|
|
46
|
+
return {
|
|
47
|
+
key: pattern.key,
|
|
48
|
+
category: pattern.description,
|
|
49
|
+
patterns: pattern.patterns,
|
|
50
|
+
defaultBehavior: pattern.defaultBehavior,
|
|
51
|
+
...(pattern.reason ? { reason: pattern.reason } : {}),
|
|
52
|
+
source,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const DEFAULT_EFFECTIVE_GUARDED_FILE_RULES = DEFAULT_GUARDED_FILE_PATTERNS.map((pattern) => guardedPatternToEffectiveRule(pattern, "default"));
|
|
56
|
+
function normalizeGuardedFilesPolicy(policy) {
|
|
57
|
+
const organization = normalizeGuardedFilesSettings(policy?.organization);
|
|
58
|
+
const user = normalizeGuardedFilesSettings(policy?.user);
|
|
59
|
+
return {
|
|
60
|
+
allowlist: [...organization.allowlist, ...user.allowlist],
|
|
61
|
+
mandatoryKeys: new Set([
|
|
62
|
+
...organization.mandatoryKeys,
|
|
63
|
+
...user.mandatoryKeys,
|
|
64
|
+
]),
|
|
65
|
+
rules: [
|
|
66
|
+
...DEFAULT_EFFECTIVE_GUARDED_FILE_RULES,
|
|
67
|
+
...organization.rules.map((rule) => guardedPatternToEffectiveRule(rule, "organization")),
|
|
68
|
+
...user.rules.map((rule) => guardedPatternToEffectiveRule(rule, "user")),
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const ENV_TOKEN_PATTERN = /%([A-Z0-9_()]+)%/gi;
|
|
73
|
+
const SHELL_ENV_TOKEN_PATTERN = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
74
|
+
function normalizeForGlob(value) {
|
|
75
|
+
return value.replace(/\\/g, "/");
|
|
76
|
+
}
|
|
77
|
+
function hasGlob(pattern) {
|
|
78
|
+
return /[*?{\[]/.test(pattern);
|
|
79
|
+
}
|
|
80
|
+
function expandEnvTokens(pattern, env) {
|
|
81
|
+
let missingToken = false;
|
|
82
|
+
const expanded = pattern.replace(ENV_TOKEN_PATTERN, (_token, name) => {
|
|
83
|
+
const value = env[name] ?? env[name.toUpperCase()];
|
|
84
|
+
if (!value?.trim()) {
|
|
85
|
+
missingToken = true;
|
|
86
|
+
return "";
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
89
|
+
});
|
|
90
|
+
return missingToken ? null : expanded;
|
|
91
|
+
}
|
|
92
|
+
function normalizePattern(pattern, options) {
|
|
93
|
+
const envExpanded = expandEnvTokens(pattern, options.env);
|
|
94
|
+
if (envExpanded === null) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const homeExpanded = expandTildePathWithHomeDir(envExpanded, options.homeDir);
|
|
98
|
+
if (hasGlob(homeExpanded)) {
|
|
99
|
+
return normalizeForGlob(homeExpanded);
|
|
100
|
+
}
|
|
101
|
+
return normalizeForGlob(resolve(options.cwd, homeExpanded));
|
|
102
|
+
}
|
|
103
|
+
function normalizePatternVariants(pattern, options) {
|
|
104
|
+
const variants = [pattern];
|
|
105
|
+
if (pattern.endsWith("/**")) {
|
|
106
|
+
variants.push(pattern.slice(0, -3));
|
|
107
|
+
}
|
|
108
|
+
return variants.flatMap((variant) => {
|
|
109
|
+
const normalized = normalizePattern(variant, options);
|
|
110
|
+
return normalized ? [normalized] : [];
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function buildCandidatePaths(path, options) {
|
|
114
|
+
const homeExpanded = expandTildePathWithHomeDir(path, options.homeDir);
|
|
115
|
+
const shellEnvExpanded = expandShellEnvTokens(path, options);
|
|
116
|
+
const profileEnvExpanded = expandEnvTokens(path, options.env);
|
|
117
|
+
const candidates = [path, homeExpanded];
|
|
118
|
+
if (shellEnvExpanded) {
|
|
119
|
+
candidates.push(shellEnvExpanded);
|
|
120
|
+
}
|
|
121
|
+
if (profileEnvExpanded) {
|
|
122
|
+
candidates.push(profileEnvExpanded);
|
|
123
|
+
}
|
|
124
|
+
for (const candidate of [...candidates]) {
|
|
125
|
+
candidates.push(resolve(options.cwd, candidate));
|
|
126
|
+
}
|
|
127
|
+
return Array.from(new Set(candidates.map(normalizeForGlob)));
|
|
128
|
+
}
|
|
129
|
+
function allowlistEntryMatchesPath(entry, candidates, options) {
|
|
130
|
+
const normalizedEntries = normalizePatternVariants(entry, options);
|
|
131
|
+
return candidates.some((candidate) => normalizedEntries.some((normalizedEntry) => minimatch(candidate, normalizedEntry, {
|
|
132
|
+
dot: true,
|
|
133
|
+
nocase: process.platform === "win32",
|
|
134
|
+
})));
|
|
135
|
+
}
|
|
136
|
+
function isGuardedMatchAllowlisted(match, candidates, policy, options) {
|
|
137
|
+
if (match.defaultBehavior === "block") {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (match.mandatory) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return policy.allowlist.some((entry) => {
|
|
144
|
+
const trimmed = entry.trim();
|
|
145
|
+
return (trimmed === match.key ||
|
|
146
|
+
allowlistEntryMatchesPath(trimmed, candidates, options));
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function expandShellEnvTokens(path, options) {
|
|
150
|
+
let expandedAny = false;
|
|
151
|
+
let missingToken = false;
|
|
152
|
+
const expanded = path.replace(SHELL_ENV_TOKEN_PATTERN, (_token, bracedName, bareName) => {
|
|
153
|
+
const name = bracedName ?? bareName;
|
|
154
|
+
if (!name) {
|
|
155
|
+
return "";
|
|
156
|
+
}
|
|
157
|
+
const value = name === "HOME"
|
|
158
|
+
? options.homeDir
|
|
159
|
+
: (options.env[name] ?? options.env[name.toUpperCase()]);
|
|
160
|
+
if (!value?.trim()) {
|
|
161
|
+
missingToken = true;
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
expandedAny = true;
|
|
165
|
+
return value;
|
|
166
|
+
});
|
|
167
|
+
return expandedAny && !missingToken ? expanded : null;
|
|
168
|
+
}
|
|
169
|
+
export function findGuardedFileMatch(path, options = {}) {
|
|
170
|
+
const trimmedPath = path.trim();
|
|
171
|
+
if (!trimmedPath) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const requiredOptions = {
|
|
175
|
+
cwd: options.cwd ?? process.cwd(),
|
|
176
|
+
homeDir: options.homeDir ?? getOsHomeDir(),
|
|
177
|
+
env: options.env ?? process.env,
|
|
178
|
+
};
|
|
179
|
+
const candidates = buildCandidatePaths(trimmedPath, requiredOptions);
|
|
180
|
+
const policy = normalizeGuardedFilesPolicy(options.policy);
|
|
181
|
+
let firstApprovalMatch = null;
|
|
182
|
+
for (const rule of policy.rules) {
|
|
183
|
+
for (const pattern of rule.patterns) {
|
|
184
|
+
const normalizedPatterns = normalizePatternVariants(pattern, requiredOptions);
|
|
185
|
+
const matches = candidates.some((candidate) => normalizedPatterns.some((normalizedPattern) => minimatch(candidate, normalizedPattern, {
|
|
186
|
+
dot: true,
|
|
187
|
+
nocase: process.platform === "win32",
|
|
188
|
+
})));
|
|
189
|
+
if (matches) {
|
|
190
|
+
const match = {
|
|
191
|
+
ruleId: DEFAULT_GUARDED_FILE_RULE_ID,
|
|
192
|
+
key: rule.key,
|
|
193
|
+
category: rule.category,
|
|
194
|
+
pattern,
|
|
195
|
+
path: trimmedPath,
|
|
196
|
+
defaultBehavior: rule.defaultBehavior,
|
|
197
|
+
mandatory: policy.mandatoryKeys.has(rule.key),
|
|
198
|
+
...(rule.reason ? { reason: rule.reason } : {}),
|
|
199
|
+
source: rule.source,
|
|
200
|
+
};
|
|
201
|
+
if (isGuardedMatchAllowlisted(match, candidates, policy, requiredOptions)) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (match.defaultBehavior === "block") {
|
|
205
|
+
return match;
|
|
206
|
+
}
|
|
207
|
+
firstApprovalMatch ??= match;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return firstApprovalMatch;
|
|
212
|
+
}
|
|
213
|
+
export function findDefaultGuardedFileMatch(path, options = {}) {
|
|
214
|
+
return findGuardedFileMatch(path, options);
|
|
215
|
+
}
|
|
216
|
+
function getArgsObject(args) {
|
|
217
|
+
return args && typeof args === "object"
|
|
218
|
+
? args
|
|
219
|
+
: null;
|
|
220
|
+
}
|
|
221
|
+
function getStringArg(args, key) {
|
|
222
|
+
const value = args[key];
|
|
223
|
+
return typeof value === "string" ? value : null;
|
|
224
|
+
}
|
|
225
|
+
function getStringListArg(args, key) {
|
|
226
|
+
const value = args[key];
|
|
227
|
+
if (typeof value === "string") {
|
|
228
|
+
return [value];
|
|
229
|
+
}
|
|
230
|
+
if (Array.isArray(value)) {
|
|
231
|
+
return value.filter((item) => typeof item === "string");
|
|
232
|
+
}
|
|
233
|
+
return [];
|
|
234
|
+
}
|
|
235
|
+
function addStringArgs(paths, args, keys) {
|
|
236
|
+
for (const key of keys) {
|
|
237
|
+
paths.push(...getStringListArg(args, key));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function isAnchoredPath(path) {
|
|
241
|
+
const trimmed = path.trim();
|
|
242
|
+
return (trimmed.startsWith("/") ||
|
|
243
|
+
trimmed.startsWith("~") ||
|
|
244
|
+
trimmed.startsWith("$") ||
|
|
245
|
+
/^[A-Za-z]:[\\/]/.test(trimmed) ||
|
|
246
|
+
/^%[^%]+%[\\/]/.test(trimmed));
|
|
247
|
+
}
|
|
248
|
+
function combineRelativePathWithCwd(cwd, path) {
|
|
249
|
+
if (isAnchoredPath(path) || !cwd.trim()) {
|
|
250
|
+
return path;
|
|
251
|
+
}
|
|
252
|
+
const trimmedCwd = cwd.trim().replace(/[\\/]+$/, "");
|
|
253
|
+
const trimmedPath = path.trim().replace(/^[\\/]+/, "");
|
|
254
|
+
return `${trimmedCwd}/${trimmedPath}`;
|
|
255
|
+
}
|
|
256
|
+
function addStringArgsWithCwd(paths, args, keys, cwd) {
|
|
257
|
+
const values = keys.flatMap((key) => getStringListArg(args, key));
|
|
258
|
+
paths.push(...values);
|
|
259
|
+
if (cwd) {
|
|
260
|
+
paths.push(...values.map((path) => combineRelativePathWithCwd(cwd, path)));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function stripShellTokenQuotes(token) {
|
|
264
|
+
const trimmed = token.trim();
|
|
265
|
+
if (trimmed.length < 2) {
|
|
266
|
+
return trimmed;
|
|
267
|
+
}
|
|
268
|
+
const first = trimmed[0];
|
|
269
|
+
const last = trimmed[trimmed.length - 1];
|
|
270
|
+
if ((first === "'" && last === "'") || (first === '"' && last === '"')) {
|
|
271
|
+
return trimmed.slice(1, -1);
|
|
272
|
+
}
|
|
273
|
+
return trimmed;
|
|
274
|
+
}
|
|
275
|
+
function extractGuardedShellCommandPaths(command) {
|
|
276
|
+
const unwrapped = unwrapShellCommand(command) ?? command;
|
|
277
|
+
return tokenizeSimple(unwrapped)
|
|
278
|
+
.map(stripShellTokenQuotes)
|
|
279
|
+
.filter((token) => token.length > 0 && !token.startsWith("-"));
|
|
280
|
+
}
|
|
281
|
+
function extractGuardedToolCallPaths(toolName, args) {
|
|
282
|
+
const argsObject = getArgsObject(args);
|
|
283
|
+
if (!argsObject) {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
const paths = [];
|
|
287
|
+
const normalizedToolName = toolName.toLowerCase();
|
|
288
|
+
if (["read", "write", "edit"].includes(normalizedToolName)) {
|
|
289
|
+
const path = getStringArg(argsObject, "file_path") || getStringArg(argsObject, "path");
|
|
290
|
+
if (path) {
|
|
291
|
+
paths.push(path);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (normalizedToolName === "apply_patch") {
|
|
295
|
+
const patch = getStringArg(argsObject, "patch");
|
|
296
|
+
if (patch) {
|
|
297
|
+
paths.push(...parseApplyPatchPaths(patch));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (normalizedToolName === "delete_file") {
|
|
301
|
+
const path = getStringArg(argsObject, "file_path") ||
|
|
302
|
+
getStringArg(argsObject, "target_file");
|
|
303
|
+
if (path) {
|
|
304
|
+
paths.push(path);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (normalizedToolName === "move_file" ||
|
|
308
|
+
normalizedToolName === "copy_file") {
|
|
309
|
+
const source = getStringArg(argsObject, "source") ||
|
|
310
|
+
getStringArg(argsObject, "source_path") ||
|
|
311
|
+
getStringArg(argsObject, "from");
|
|
312
|
+
const destination = getStringArg(argsObject, "destination") ||
|
|
313
|
+
getStringArg(argsObject, "destination_path") ||
|
|
314
|
+
getStringArg(argsObject, "dest") ||
|
|
315
|
+
getStringArg(argsObject, "to");
|
|
316
|
+
if (source) {
|
|
317
|
+
paths.push(source);
|
|
318
|
+
}
|
|
319
|
+
if (destination) {
|
|
320
|
+
paths.push(destination);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (["list", "find"].includes(normalizedToolName)) {
|
|
324
|
+
addStringArgs(paths, argsObject, ["path"]);
|
|
325
|
+
}
|
|
326
|
+
if (["search", "parallel_ripgrep", "diff", "status"].includes(normalizedToolName)) {
|
|
327
|
+
addStringArgsWithCwd(paths, argsObject, ["paths"], getStringArg(argsObject, "cwd"));
|
|
328
|
+
}
|
|
329
|
+
if (["search", "parallel_ripgrep", "diff"].includes(normalizedToolName)) {
|
|
330
|
+
addStringArgs(paths, argsObject, ["cwd"]);
|
|
331
|
+
}
|
|
332
|
+
if (normalizedToolName === "bash" ||
|
|
333
|
+
normalizedToolName === "background_tasks") {
|
|
334
|
+
const command = getStringArg(argsObject, "command");
|
|
335
|
+
const cwd = getStringArg(argsObject, "cwd");
|
|
336
|
+
if (cwd) {
|
|
337
|
+
paths.push(cwd);
|
|
338
|
+
}
|
|
339
|
+
if (command) {
|
|
340
|
+
const shellPaths = extractGuardedShellCommandPaths(command);
|
|
341
|
+
paths.push(...shellPaths);
|
|
342
|
+
if (cwd) {
|
|
343
|
+
paths.push(...shellPaths.map((path) => combineRelativePathWithCwd(cwd, path)));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return paths;
|
|
348
|
+
}
|
|
349
|
+
export function findGuardedToolCallMatch(toolName, args, options = {}) {
|
|
350
|
+
let firstMatch = null;
|
|
351
|
+
for (const path of extractGuardedToolCallPaths(toolName, args)) {
|
|
352
|
+
const match = findGuardedFileMatch(path, options);
|
|
353
|
+
if (match) {
|
|
354
|
+
if (match.defaultBehavior === "block") {
|
|
355
|
+
return match;
|
|
356
|
+
}
|
|
357
|
+
firstMatch ??= match;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return firstMatch;
|
|
361
|
+
}
|
|
362
|
+
export function findDefaultGuardedToolCallMatch(toolName, args, options = {}) {
|
|
363
|
+
return findGuardedToolCallMatch(toolName, args, options);
|
|
364
|
+
}
|
|
365
|
+
export function describeDefaultGuardedFileMatch(match) {
|
|
366
|
+
const policyReason = match.reason ? ` ${match.reason}` : "";
|
|
367
|
+
const actionDescription = match.defaultBehavior === "block"
|
|
368
|
+
? "is blocked by policy"
|
|
369
|
+
: "requires explicit approval";
|
|
370
|
+
return `Guarded file access ${actionDescription}: ${match.category} (${match.pattern}) at ${match.path}.${policyReason}`;
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=guarded-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guarded-files.js","sourceRoot":"","sources":["../../src/safety/guarded-files.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport {\n\tDEFAULT_GUARDED_FILE_PATTERNS,\n\ttype GuardedFileDefaultBehavior,\n\ttype GuardedFilePattern,\n\ttype GuardedFilesPolicySettings,\n\tnormalizeGuardedFilesSettings,\n} from \"@evalops/contracts\";\nimport { minimatch } from \"minimatch\";\nimport { parseApplyPatchPaths } from \"../tools/apply-patch-parser.js\";\nimport {\n\texpandTildePathWithHomeDir,\n\tgetOsHomeDir,\n} from \"../utils/path-expansion.js\";\nimport { tokenizeSimple, unwrapShellCommand } from \"./bash-safety-analyzer.js\";\n\nexport const DEFAULT_GUARDED_FILE_RULE_ID = \"default-guarded-file\";\nexport const GUARDED_FILES_BLOCK_POLICY_ID = \"guardedFiles_block\";\n\nexport type GuardedFileAccessAction = \"read\" | \"write\" | \"execute\" | \"unknown\";\n\nexport interface GuardedFileRule {\n\tkey: string;\n\tcategory: string;\n\tpatterns: string[];\n}\n\nexport interface GuardedFileMatch {\n\truleId: typeof DEFAULT_GUARDED_FILE_RULE_ID;\n\tkey: string;\n\tcategory: string;\n\tpattern: string;\n\tpath: string;\n\tdefaultBehavior: GuardedFileDefaultBehavior;\n\tmandatory: boolean;\n\treason?: string;\n\tsource: \"default\" | \"organization\" | \"user\";\n}\n\nexport interface GuardedFileMatchOptions {\n\tcwd?: string;\n\thomeDir?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tpolicy?: GuardedFilesPolicySettings;\n}\n\nexport function classifyGuardedFileAccessAction(\n\ttoolName: string,\n): GuardedFileAccessAction {\n\tconst normalizedToolName = toolName.toLowerCase();\n\tif (\n\t\t[\n\t\t\t\"write\",\n\t\t\t\"edit\",\n\t\t\t\"apply_patch\",\n\t\t\t\"delete_file\",\n\t\t\t\"move_file\",\n\t\t\t\"copy_file\",\n\t\t].includes(normalizedToolName)\n\t) {\n\t\treturn \"write\";\n\t}\n\tif (\n\t\t[\n\t\t\t\"read\",\n\t\t\t\"list\",\n\t\t\t\"find\",\n\t\t\t\"search\",\n\t\t\t\"parallel_ripgrep\",\n\t\t\t\"diff\",\n\t\t\t\"status\",\n\t\t].includes(normalizedToolName)\n\t) {\n\t\treturn \"read\";\n\t}\n\tif ([\"bash\", \"background_tasks\"].includes(normalizedToolName)) {\n\t\treturn \"execute\";\n\t}\n\treturn \"unknown\";\n}\n\nfunction guardedPatternToRule(pattern: GuardedFilePattern): GuardedFileRule {\n\treturn {\n\t\tkey: pattern.key,\n\t\tcategory: pattern.description,\n\t\tpatterns: pattern.patterns,\n\t};\n}\n\nexport const DEFAULT_GUARDED_FILE_RULES: GuardedFileRule[] =\n\tDEFAULT_GUARDED_FILE_PATTERNS.map(guardedPatternToRule);\n\ninterface EffectiveGuardedFileRule extends GuardedFileRule {\n\tdefaultBehavior: GuardedFileDefaultBehavior;\n\treason?: string;\n\tsource: \"default\" | \"organization\" | \"user\";\n}\n\ninterface NormalizedGuardedFilesPolicy {\n\tallowlist: string[];\n\tmandatoryKeys: Set<string>;\n\trules: EffectiveGuardedFileRule[];\n}\n\nfunction guardedPatternToEffectiveRule(\n\tpattern: GuardedFilePattern,\n\tsource: EffectiveGuardedFileRule[\"source\"],\n): EffectiveGuardedFileRule {\n\treturn {\n\t\tkey: pattern.key,\n\t\tcategory: pattern.description,\n\t\tpatterns: pattern.patterns,\n\t\tdefaultBehavior: pattern.defaultBehavior,\n\t\t...(pattern.reason ? { reason: pattern.reason } : {}),\n\t\tsource,\n\t};\n}\n\nconst DEFAULT_EFFECTIVE_GUARDED_FILE_RULES: EffectiveGuardedFileRule[] =\n\tDEFAULT_GUARDED_FILE_PATTERNS.map((pattern) =>\n\t\tguardedPatternToEffectiveRule(pattern, \"default\"),\n\t);\n\nfunction normalizeGuardedFilesPolicy(\n\tpolicy?: GuardedFilesPolicySettings,\n): NormalizedGuardedFilesPolicy {\n\tconst organization = normalizeGuardedFilesSettings(policy?.organization);\n\tconst user = normalizeGuardedFilesSettings(policy?.user);\n\treturn {\n\t\tallowlist: [...organization.allowlist, ...user.allowlist],\n\t\tmandatoryKeys: new Set([\n\t\t\t...organization.mandatoryKeys,\n\t\t\t...user.mandatoryKeys,\n\t\t]),\n\t\trules: [\n\t\t\t...DEFAULT_EFFECTIVE_GUARDED_FILE_RULES,\n\t\t\t...organization.rules.map((rule) =>\n\t\t\t\tguardedPatternToEffectiveRule(rule, \"organization\"),\n\t\t\t),\n\t\t\t...user.rules.map((rule) => guardedPatternToEffectiveRule(rule, \"user\")),\n\t\t],\n\t};\n}\n\nconst ENV_TOKEN_PATTERN = /%([A-Z0-9_()]+)%/gi;\nconst SHELL_ENV_TOKEN_PATTERN =\n\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}|\\$([A-Za-z_][A-Za-z0-9_]*)/g;\n\nfunction normalizeForGlob(value: string): string {\n\treturn value.replace(/\\\\/g, \"/\");\n}\n\nfunction hasGlob(pattern: string): boolean {\n\treturn /[*?{\\[]/.test(pattern);\n}\n\nfunction expandEnvTokens(\n\tpattern: string,\n\tenv: NodeJS.ProcessEnv,\n): string | null {\n\tlet missingToken = false;\n\tconst expanded = pattern.replace(\n\t\tENV_TOKEN_PATTERN,\n\t\t(_token, name: string) => {\n\t\t\tconst value = env[name] ?? env[name.toUpperCase()];\n\t\t\tif (!value?.trim()) {\n\t\t\t\tmissingToken = true;\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n\t);\n\treturn missingToken ? null : expanded;\n}\n\nfunction normalizePattern(\n\tpattern: string,\n\toptions: Required<Pick<GuardedFileMatchOptions, \"cwd\" | \"homeDir\" | \"env\">>,\n): string | null {\n\tconst envExpanded = expandEnvTokens(pattern, options.env);\n\tif (envExpanded === null) {\n\t\treturn null;\n\t}\n\tconst homeExpanded = expandTildePathWithHomeDir(envExpanded, options.homeDir);\n\tif (hasGlob(homeExpanded)) {\n\t\treturn normalizeForGlob(homeExpanded);\n\t}\n\treturn normalizeForGlob(resolve(options.cwd, homeExpanded));\n}\n\nfunction normalizePatternVariants(\n\tpattern: string,\n\toptions: Required<Pick<GuardedFileMatchOptions, \"cwd\" | \"homeDir\" | \"env\">>,\n): string[] {\n\tconst variants = [pattern];\n\tif (pattern.endsWith(\"/**\")) {\n\t\tvariants.push(pattern.slice(0, -3));\n\t}\n\treturn variants.flatMap((variant) => {\n\t\tconst normalized = normalizePattern(variant, options);\n\t\treturn normalized ? [normalized] : [];\n\t});\n}\n\nfunction buildCandidatePaths(\n\tpath: string,\n\toptions: Required<Pick<GuardedFileMatchOptions, \"cwd\" | \"homeDir\" | \"env\">>,\n): string[] {\n\tconst homeExpanded = expandTildePathWithHomeDir(path, options.homeDir);\n\tconst shellEnvExpanded = expandShellEnvTokens(path, options);\n\tconst profileEnvExpanded = expandEnvTokens(path, options.env);\n\tconst candidates = [path, homeExpanded];\n\tif (shellEnvExpanded) {\n\t\tcandidates.push(shellEnvExpanded);\n\t}\n\tif (profileEnvExpanded) {\n\t\tcandidates.push(profileEnvExpanded);\n\t}\n\tfor (const candidate of [...candidates]) {\n\t\tcandidates.push(resolve(options.cwd, candidate));\n\t}\n\treturn Array.from(new Set(candidates.map(normalizeForGlob)));\n}\n\nfunction allowlistEntryMatchesPath(\n\tentry: string,\n\tcandidates: string[],\n\toptions: Required<Pick<GuardedFileMatchOptions, \"cwd\" | \"homeDir\" | \"env\">>,\n): boolean {\n\tconst normalizedEntries = normalizePatternVariants(entry, options);\n\treturn candidates.some((candidate) =>\n\t\tnormalizedEntries.some((normalizedEntry) =>\n\t\t\tminimatch(candidate, normalizedEntry, {\n\t\t\t\tdot: true,\n\t\t\t\tnocase: process.platform === \"win32\",\n\t\t\t}),\n\t\t),\n\t);\n}\n\nfunction isGuardedMatchAllowlisted(\n\tmatch: Pick<GuardedFileMatch, \"key\" | \"mandatory\" | \"defaultBehavior\">,\n\tcandidates: string[],\n\tpolicy: NormalizedGuardedFilesPolicy,\n\toptions: Required<Pick<GuardedFileMatchOptions, \"cwd\" | \"homeDir\" | \"env\">>,\n): boolean {\n\tif (match.defaultBehavior === \"block\") {\n\t\treturn false;\n\t}\n\tif (match.mandatory) {\n\t\treturn false;\n\t}\n\treturn policy.allowlist.some((entry) => {\n\t\tconst trimmed = entry.trim();\n\t\treturn (\n\t\t\ttrimmed === match.key ||\n\t\t\tallowlistEntryMatchesPath(trimmed, candidates, options)\n\t\t);\n\t});\n}\n\nfunction expandShellEnvTokens(\n\tpath: string,\n\toptions: Required<Pick<GuardedFileMatchOptions, \"homeDir\" | \"env\">>,\n): string | null {\n\tlet expandedAny = false;\n\tlet missingToken = false;\n\tconst expanded = path.replace(\n\t\tSHELL_ENV_TOKEN_PATTERN,\n\t\t(_token, bracedName: string | undefined, bareName: string | undefined) => {\n\t\t\tconst name = bracedName ?? bareName;\n\t\t\tif (!name) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tconst value =\n\t\t\t\tname === \"HOME\"\n\t\t\t\t\t? options.homeDir\n\t\t\t\t\t: (options.env[name] ?? options.env[name.toUpperCase()]);\n\t\t\tif (!value?.trim()) {\n\t\t\t\tmissingToken = true;\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\texpandedAny = true;\n\t\t\treturn value;\n\t\t},\n\t);\n\treturn expandedAny && !missingToken ? expanded : null;\n}\n\nexport function findGuardedFileMatch(\n\tpath: string,\n\toptions: GuardedFileMatchOptions = {},\n): GuardedFileMatch | null {\n\tconst trimmedPath = path.trim();\n\tif (!trimmedPath) {\n\t\treturn null;\n\t}\n\tconst requiredOptions = {\n\t\tcwd: options.cwd ?? process.cwd(),\n\t\thomeDir: options.homeDir ?? getOsHomeDir(),\n\t\tenv: options.env ?? process.env,\n\t};\n\tconst candidates = buildCandidatePaths(trimmedPath, requiredOptions);\n\tconst policy = normalizeGuardedFilesPolicy(options.policy);\n\tlet firstApprovalMatch: GuardedFileMatch | null = null;\n\n\tfor (const rule of policy.rules) {\n\t\tfor (const pattern of rule.patterns) {\n\t\t\tconst normalizedPatterns = normalizePatternVariants(\n\t\t\t\tpattern,\n\t\t\t\trequiredOptions,\n\t\t\t);\n\t\t\tconst matches = candidates.some((candidate) =>\n\t\t\t\tnormalizedPatterns.some((normalizedPattern) =>\n\t\t\t\t\tminimatch(candidate, normalizedPattern, {\n\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\tnocase: process.platform === \"win32\",\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (matches) {\n\t\t\t\tconst match: GuardedFileMatch = {\n\t\t\t\t\truleId: DEFAULT_GUARDED_FILE_RULE_ID,\n\t\t\t\t\tkey: rule.key,\n\t\t\t\t\tcategory: rule.category,\n\t\t\t\t\tpattern,\n\t\t\t\t\tpath: trimmedPath,\n\t\t\t\t\tdefaultBehavior: rule.defaultBehavior,\n\t\t\t\t\tmandatory: policy.mandatoryKeys.has(rule.key),\n\t\t\t\t\t...(rule.reason ? { reason: rule.reason } : {}),\n\t\t\t\t\tsource: rule.source,\n\t\t\t\t};\n\t\t\t\tif (\n\t\t\t\t\tisGuardedMatchAllowlisted(match, candidates, policy, requiredOptions)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (match.defaultBehavior === \"block\") {\n\t\t\t\t\treturn match;\n\t\t\t\t}\n\t\t\t\tfirstApprovalMatch ??= match;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn firstApprovalMatch;\n}\n\nexport function findDefaultGuardedFileMatch(\n\tpath: string,\n\toptions: GuardedFileMatchOptions = {},\n): GuardedFileMatch | null {\n\treturn findGuardedFileMatch(path, options);\n}\n\nfunction getArgsObject(args: unknown): Record<string, unknown> | null {\n\treturn args && typeof args === \"object\"\n\t\t? (args as Record<string, unknown>)\n\t\t: null;\n}\n\nfunction getStringArg(\n\targs: Record<string, unknown>,\n\tkey: string,\n): string | null {\n\tconst value = args[key];\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction getStringListArg(\n\targs: Record<string, unknown>,\n\tkey: string,\n): string[] {\n\tconst value = args[key];\n\tif (typeof value === \"string\") {\n\t\treturn [value];\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.filter((item): item is string => typeof item === \"string\");\n\t}\n\treturn [];\n}\n\nfunction addStringArgs(\n\tpaths: string[],\n\targs: Record<string, unknown>,\n\tkeys: string[],\n) {\n\tfor (const key of keys) {\n\t\tpaths.push(...getStringListArg(args, key));\n\t}\n}\n\nfunction isAnchoredPath(path: string): boolean {\n\tconst trimmed = path.trim();\n\treturn (\n\t\ttrimmed.startsWith(\"/\") ||\n\t\ttrimmed.startsWith(\"~\") ||\n\t\ttrimmed.startsWith(\"$\") ||\n\t\t/^[A-Za-z]:[\\\\/]/.test(trimmed) ||\n\t\t/^%[^%]+%[\\\\/]/.test(trimmed)\n\t);\n}\n\nfunction combineRelativePathWithCwd(cwd: string, path: string): string {\n\tif (isAnchoredPath(path) || !cwd.trim()) {\n\t\treturn path;\n\t}\n\tconst trimmedCwd = cwd.trim().replace(/[\\\\/]+$/, \"\");\n\tconst trimmedPath = path.trim().replace(/^[\\\\/]+/, \"\");\n\treturn `${trimmedCwd}/${trimmedPath}`;\n}\n\nfunction addStringArgsWithCwd(\n\tpaths: string[],\n\targs: Record<string, unknown>,\n\tkeys: string[],\n\tcwd: string | null,\n) {\n\tconst values = keys.flatMap((key) => getStringListArg(args, key));\n\tpaths.push(...values);\n\tif (cwd) {\n\t\tpaths.push(...values.map((path) => combineRelativePathWithCwd(cwd, path)));\n\t}\n}\n\nfunction stripShellTokenQuotes(token: string): string {\n\tconst trimmed = token.trim();\n\tif (trimmed.length < 2) {\n\t\treturn trimmed;\n\t}\n\tconst first = trimmed[0];\n\tconst last = trimmed[trimmed.length - 1];\n\tif ((first === \"'\" && last === \"'\") || (first === '\"' && last === '\"')) {\n\t\treturn trimmed.slice(1, -1);\n\t}\n\treturn trimmed;\n}\n\nfunction extractGuardedShellCommandPaths(command: string): string[] {\n\tconst unwrapped = unwrapShellCommand(command) ?? command;\n\treturn tokenizeSimple(unwrapped)\n\t\t.map(stripShellTokenQuotes)\n\t\t.filter((token) => token.length > 0 && !token.startsWith(\"-\"));\n}\n\nfunction extractGuardedToolCallPaths(\n\ttoolName: string,\n\targs: unknown,\n): string[] {\n\tconst argsObject = getArgsObject(args);\n\tif (!argsObject) {\n\t\treturn [];\n\t}\n\tconst paths: string[] = [];\n\tconst normalizedToolName = toolName.toLowerCase();\n\tif ([\"read\", \"write\", \"edit\"].includes(normalizedToolName)) {\n\t\tconst path =\n\t\t\tgetStringArg(argsObject, \"file_path\") || getStringArg(argsObject, \"path\");\n\t\tif (path) {\n\t\t\tpaths.push(path);\n\t\t}\n\t}\n\tif (normalizedToolName === \"apply_patch\") {\n\t\tconst patch = getStringArg(argsObject, \"patch\");\n\t\tif (patch) {\n\t\t\tpaths.push(...parseApplyPatchPaths(patch));\n\t\t}\n\t}\n\tif (normalizedToolName === \"delete_file\") {\n\t\tconst path =\n\t\t\tgetStringArg(argsObject, \"file_path\") ||\n\t\t\tgetStringArg(argsObject, \"target_file\");\n\t\tif (path) {\n\t\t\tpaths.push(path);\n\t\t}\n\t}\n\tif (\n\t\tnormalizedToolName === \"move_file\" ||\n\t\tnormalizedToolName === \"copy_file\"\n\t) {\n\t\tconst source =\n\t\t\tgetStringArg(argsObject, \"source\") ||\n\t\t\tgetStringArg(argsObject, \"source_path\") ||\n\t\t\tgetStringArg(argsObject, \"from\");\n\t\tconst destination =\n\t\t\tgetStringArg(argsObject, \"destination\") ||\n\t\t\tgetStringArg(argsObject, \"destination_path\") ||\n\t\t\tgetStringArg(argsObject, \"dest\") ||\n\t\t\tgetStringArg(argsObject, \"to\");\n\t\tif (source) {\n\t\t\tpaths.push(source);\n\t\t}\n\t\tif (destination) {\n\t\t\tpaths.push(destination);\n\t\t}\n\t}\n\tif ([\"list\", \"find\"].includes(normalizedToolName)) {\n\t\taddStringArgs(paths, argsObject, [\"path\"]);\n\t}\n\tif (\n\t\t[\"search\", \"parallel_ripgrep\", \"diff\", \"status\"].includes(\n\t\t\tnormalizedToolName,\n\t\t)\n\t) {\n\t\taddStringArgsWithCwd(\n\t\t\tpaths,\n\t\t\targsObject,\n\t\t\t[\"paths\"],\n\t\t\tgetStringArg(argsObject, \"cwd\"),\n\t\t);\n\t}\n\tif ([\"search\", \"parallel_ripgrep\", \"diff\"].includes(normalizedToolName)) {\n\t\taddStringArgs(paths, argsObject, [\"cwd\"]);\n\t}\n\tif (\n\t\tnormalizedToolName === \"bash\" ||\n\t\tnormalizedToolName === \"background_tasks\"\n\t) {\n\t\tconst command = getStringArg(argsObject, \"command\");\n\t\tconst cwd = getStringArg(argsObject, \"cwd\");\n\t\tif (cwd) {\n\t\t\tpaths.push(cwd);\n\t\t}\n\t\tif (command) {\n\t\t\tconst shellPaths = extractGuardedShellCommandPaths(command);\n\t\t\tpaths.push(...shellPaths);\n\t\t\tif (cwd) {\n\t\t\t\tpaths.push(\n\t\t\t\t\t...shellPaths.map((path) => combineRelativePathWithCwd(cwd, path)),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\treturn paths;\n}\n\nexport function findGuardedToolCallMatch(\n\ttoolName: string,\n\targs: unknown,\n\toptions: GuardedFileMatchOptions = {},\n): GuardedFileMatch | null {\n\tlet firstMatch: GuardedFileMatch | null = null;\n\tfor (const path of extractGuardedToolCallPaths(toolName, args)) {\n\t\tconst match = findGuardedFileMatch(path, options);\n\t\tif (match) {\n\t\t\tif (match.defaultBehavior === \"block\") {\n\t\t\t\treturn match;\n\t\t\t}\n\t\t\tfirstMatch ??= match;\n\t\t}\n\t}\n\treturn firstMatch;\n}\n\nexport function findDefaultGuardedToolCallMatch(\n\ttoolName: string,\n\targs: unknown,\n\toptions: GuardedFileMatchOptions = {},\n): GuardedFileMatch | null {\n\treturn findGuardedToolCallMatch(toolName, args, options);\n}\n\nexport function describeDefaultGuardedFileMatch(\n\tmatch: GuardedFileMatch,\n): string {\n\tconst policyReason = match.reason ? ` ${match.reason}` : \"\";\n\tconst actionDescription =\n\t\tmatch.defaultBehavior === \"block\"\n\t\t\t? \"is blocked by policy\"\n\t\t\t: \"requires explicit approval\";\n\treturn `Guarded file access ${actionDescription}: ${match.category} (${match.pattern}) at ${match.path}.${policyReason}`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-detector.d.ts","sourceRoot":"","sources":["../../src/safety/loop-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"loop-detector.d.ts","sourceRoot":"","sources":["../../src/safety/loop-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gDAAgD;IAChD,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,kCAAkC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;IACpD,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACnC,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAyGD;;GAEG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,MAAM,CAAC,EAAE,kBAAkB;IAWvC;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB;IA4HvE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAezD;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3B;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,EAAE,OAAO,CAAC;KAClB;IAeD;;OAEG;IACH,OAAO,CAAC,YAAY;CAIpB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,cAAqB,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,GAAE,YAAkC,GAC1C;IACF,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CA+BA"}
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
* @module safety/loop-detector
|
|
22
22
|
*/
|
|
23
23
|
import { createHash } from "node:crypto";
|
|
24
|
+
import { stableStringify } from "../agent/transport/stable-stringify.js";
|
|
24
25
|
import { createLogger } from "../utils/logger.js";
|
|
25
26
|
const logger = createLogger("safety:loop-detector");
|
|
26
27
|
/**
|
|
27
28
|
* Generate a hash for a tool call
|
|
28
29
|
*/
|
|
29
30
|
function hashCall(tool, args) {
|
|
30
|
-
const normalized =
|
|
31
|
+
const normalized = stableStringify({ tool, args });
|
|
31
32
|
return createHash("md5").update(normalized).digest("hex").slice(0, 16);
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
@@ -70,6 +71,10 @@ function detectCycle(sequence, minCycleLength = 2, maxCycleLength = 10) {
|
|
|
70
71
|
break;
|
|
71
72
|
}
|
|
72
73
|
// Check if the last cycleLen items match the previous cycleLen items
|
|
74
|
+
const candidateCycle = sequence.slice(-cycleLen);
|
|
75
|
+
if (new Set(candidateCycle).size < 2) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
73
78
|
let isCycle = true;
|
|
74
79
|
for (let i = 0; i < cycleLen; i++) {
|
|
75
80
|
const idx1 = sequence.length - 1 - i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-detector.js","sourceRoot":"","sources":["../../src/safety/loop-detector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Loop Detector - Automatic detection of repetitive tool patterns\n *\n * This module detects when the agent appears to be stuck in a loop, either\n * from confusion, injection attacks, or other issues. It monitors tool calls\n * and triggers warnings or pauses when repetitive patterns are detected.\n *\n * ## Detection Methods\n *\n * 1. **Exact Repetition**: Same tool+args called multiple times\n * 2. **Similar Operations**: Same tool with varying args (e.g., reading similar paths)\n * 3. **Cyclic Patterns**: Repeating sequences of tools (A→B→C→A→B→C)\n * 4. **High Frequency**: Unusually rapid tool execution\n *\n * ## Actions\n *\n * - **warn**: Log a warning for monitoring\n * - **pause**: Require user confirmation to continue\n * - **halt**: Stop execution entirely\n *\n * @module safety/loop-detector\n */\n\nimport { createHash } from \"node:crypto\";\nimport { createLogger } from \"../utils/logger.js\";\n\nconst logger = createLogger(\"safety:loop-detector\");\n\n/**\n * Configuration for loop detection\n */\nexport interface LoopDetectorConfig {\n\t/** Maximum identical calls before warning (default: 3) */\n\tmaxIdenticalCalls?: number;\n\t/** Maximum similar calls before warning (default: 5) */\n\tmaxSimilarCalls?: number;\n\t/** Time window for detection in ms (default: 60000) */\n\twindowMs?: number;\n\t/** Minimum time between calls in ms (default: 100) */\n\tminCallIntervalMs?: number;\n\t/** Maximum calls per minute before warning (default: 60) */\n\tmaxCallsPerMinute?: number;\n\t/** Enable/disable auto-pause (default: true) */\n\tautoPause?: boolean;\n}\n\n/**\n * Loop detection result\n */\nexport interface LoopDetectionResult {\n\t/** Whether a loop was detected */\n\tdetected: boolean;\n\t/** Type of loop detected */\n\ttype?: \"exact\" | \"similar\" | \"cyclic\" | \"frequency\";\n\t/** Recommended action */\n\taction?: \"warn\" | \"pause\" | \"halt\";\n\t/** Human-readable description */\n\treason?: string;\n\t/** Number of repetitions detected */\n\trepetitions?: number;\n\t/** Suggestion for the user */\n\tsuggestion?: string;\n}\n\n/**\n * Internal record of a tool call\n */\ninterface CallRecord {\n\t/** Hash of tool + args */\n\thash: string;\n\t/** Tool name */\n\ttool: string;\n\t/** Simplified args signature */\n\targsSignature: string;\n\t/** Timestamp */\n\ttimestamp: number;\n}\n\n/**\n * Generate a hash for a tool call\n */\nfunction hashCall(tool: string, args: Record<string, unknown>): string {\n\tconst normalized = JSON.stringify(\n\t\t{ tool, args },\n\t\tObject.keys({ tool, args }).sort(),\n\t);\n\treturn createHash(\"md5\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Generate a simplified signature for args (for similarity detection)\n */\nfunction getArgsSignature(args: Record<string, unknown>): string {\n\tconst parts: string[] = [];\n\n\tfor (const [key, value] of Object.entries(args)) {\n\t\tif (typeof value === \"string\") {\n\t\t\t// For strings, use a normalized version (lowercase, truncated)\n\t\t\tconst normalized = value.toLowerCase().slice(0, 50);\n\t\t\tparts.push(`${key}:str(${normalized.length})`);\n\t\t} else if (typeof value === \"number\") {\n\t\t\tparts.push(`${key}:num`);\n\t\t} else if (typeof value === \"boolean\") {\n\t\t\tparts.push(`${key}:bool`);\n\t\t} else if (Array.isArray(value)) {\n\t\t\tparts.push(`${key}:arr(${value.length})`);\n\t\t} else if (value && typeof value === \"object\") {\n\t\t\tparts.push(`${key}:obj`);\n\t\t}\n\t}\n\n\treturn parts.sort().join(\",\");\n}\n\n/**\n * Detect cyclic patterns in a sequence\n * Returns the cycle length if found, 0 otherwise\n */\nfunction detectCycle(\n\tsequence: string[],\n\tminCycleLength = 2,\n\tmaxCycleLength = 10,\n): number {\n\tif (sequence.length < minCycleLength * 2) {\n\t\treturn 0;\n\t}\n\n\t// Try different cycle lengths\n\tfor (let cycleLen = minCycleLength; cycleLen <= maxCycleLength; cycleLen++) {\n\t\tif (sequence.length < cycleLen * 2) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// Check if the last cycleLen items match the previous cycleLen items\n\t\tlet isCycle = true;\n\t\tfor (let i = 0; i < cycleLen; i++) {\n\t\t\tconst idx1 = sequence.length - 1 - i;\n\t\t\tconst idx2 = sequence.length - 1 - cycleLen - i;\n\t\t\tif (idx2 < 0 || sequence[idx1] !== sequence[idx2]) {\n\t\t\t\tisCycle = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (isCycle) {\n\t\t\t// Verify the cycle repeats at least once more\n\t\t\tconst lastIdx = sequence.length - 1 - cycleLen * 2;\n\t\t\tif (lastIdx >= 0) {\n\t\t\t\tlet hasThirdRepeat = true;\n\t\t\t\tfor (let i = 0; i < cycleLen && lastIdx - i >= 0; i++) {\n\t\t\t\t\tif (sequence[lastIdx - i] !== sequence[sequence.length - 1 - i]) {\n\t\t\t\t\t\thasThirdRepeat = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (hasThirdRepeat) {\n\t\t\t\t\treturn cycleLen;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cycleLen;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * Loop Detector class\n */\nexport class LoopDetector {\n\tprivate config: Required<LoopDetectorConfig>;\n\tprivate records: CallRecord[] = [];\n\tprivate isPaused = false;\n\tprivate pauseReason?: string;\n\n\tconstructor(config?: LoopDetectorConfig) {\n\t\tthis.config = {\n\t\t\tmaxIdenticalCalls: config?.maxIdenticalCalls ?? 3,\n\t\t\tmaxSimilarCalls: config?.maxSimilarCalls ?? 5,\n\t\t\twindowMs: config?.windowMs ?? 60000,\n\t\t\tminCallIntervalMs: config?.minCallIntervalMs ?? 100,\n\t\t\tmaxCallsPerMinute: config?.maxCallsPerMinute ?? 60,\n\t\t\tautoPause: config?.autoPause ?? true,\n\t\t};\n\t}\n\n\t/**\n\t * Check a tool call for loop patterns\n\t */\n\tcheck(tool: string, args: Record<string, unknown>): LoopDetectionResult {\n\t\tconst now = Date.now();\n\t\tconst hash = hashCall(tool, args);\n\t\tconst argsSignature = getArgsSignature(args);\n\n\t\t// Prune old records\n\t\tthis.pruneRecords(now);\n\n\t\t// Check for paused state\n\t\tif (this.isPaused) {\n\t\t\treturn {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"exact\",\n\t\t\t\taction: \"pause\",\n\t\t\t\treason: this.pauseReason ?? \"Loop detector is paused\",\n\t\t\t\tsuggestion: \"Resume execution or investigate the repeated pattern\",\n\t\t\t};\n\t\t}\n\n\t\t// Check 1: Exact repetition\n\t\tconst identicalCount = this.records.filter((r) => r.hash === hash).length;\n\t\tif (identicalCount >= this.config.maxIdenticalCalls) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"exact\",\n\t\t\t\taction: this.config.autoPause ? \"pause\" : \"warn\",\n\t\t\t\treason: `Identical tool call repeated ${identicalCount + 1} times: ${tool}`,\n\t\t\t\trepetitions: identicalCount + 1,\n\t\t\t\tsuggestion: \"Check if the operation is completing successfully\",\n\t\t\t};\n\n\t\t\tif (this.config.autoPause) {\n\t\t\t\tthis.pause(result.reason!);\n\t\t\t}\n\n\t\t\tlogger.warn(\"Exact repetition loop detected\", {\n\t\t\t\ttool,\n\t\t\t\tcount: identicalCount + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 2: Similar operations (same tool, similar args pattern)\n\t\tconst similarCount = this.records.filter(\n\t\t\t(r) => r.tool === tool && r.argsSignature === argsSignature,\n\t\t).length;\n\t\tif (similarCount >= this.config.maxSimilarCalls) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"similar\",\n\t\t\t\taction: this.config.autoPause ? \"pause\" : \"warn\",\n\t\t\t\treason: `Similar ${tool} calls detected ${similarCount + 1} times`,\n\t\t\t\trepetitions: similarCount + 1,\n\t\t\t\tsuggestion: \"Verify that these operations are intentional\",\n\t\t\t};\n\n\t\t\tif (this.config.autoPause) {\n\t\t\t\tthis.pause(result.reason!);\n\t\t\t}\n\n\t\t\tlogger.warn(\"Similar operation loop detected\", {\n\t\t\t\ttool,\n\t\t\t\tcount: similarCount + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 3: Cyclic patterns\n\t\tconst toolSequence = [...this.records.map((r) => r.tool), tool];\n\t\tconst cycleLength = detectCycle(toolSequence);\n\t\tif (cycleLength > 0) {\n\t\t\tconst cyclePattern = toolSequence.slice(-cycleLength).join(\" → \");\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"cyclic\",\n\t\t\t\taction: \"warn\",\n\t\t\t\treason: `Cyclic pattern detected: ${cyclePattern}`,\n\t\t\t\trepetitions: 2,\n\t\t\t\tsuggestion: \"The agent may be stuck in a decision loop\",\n\t\t\t};\n\n\t\t\tlogger.warn(\"Cyclic pattern detected\", {\n\t\t\t\tcycleLength,\n\t\t\t\tpattern: cyclePattern,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 4: High frequency\n\t\tconst recentCalls = this.records.filter(\n\t\t\t(r) => now - r.timestamp < 60000,\n\t\t).length;\n\t\tif (recentCalls >= this.config.maxCallsPerMinute) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"frequency\",\n\t\t\t\taction: \"warn\",\n\t\t\t\treason: `High call frequency detected: ${recentCalls + 1} calls in the last minute`,\n\t\t\t\trepetitions: recentCalls + 1,\n\t\t\t\tsuggestion: \"Consider if this many operations are necessary\",\n\t\t\t};\n\n\t\t\tlogger.warn(\"High frequency loop detected\", {\n\t\t\t\tcallsPerMinute: recentCalls + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 5: Too rapid calls\n\t\tconst lastCall = this.records[this.records.length - 1];\n\t\tif (lastCall && now - lastCall.timestamp < this.config.minCallIntervalMs) {\n\t\t\t// Don't trigger on this alone, just note it\n\t\t\tlogger.debug(\"Very rapid tool calls detected\", {\n\t\t\t\tintervalMs: now - lastCall.timestamp,\n\t\t\t});\n\t\t}\n\n\t\treturn { detected: false };\n\t}\n\n\t/**\n\t * Record a tool call (call after check)\n\t */\n\trecord(tool: string, args: Record<string, unknown>): void {\n\t\tconst now = Date.now();\n\t\tthis.records.push({\n\t\t\thash: hashCall(tool, args),\n\t\t\ttool,\n\t\t\targsSignature: getArgsSignature(args),\n\t\t\ttimestamp: now,\n\t\t});\n\n\t\t// Keep records bounded\n\t\tif (this.records.length > 200) {\n\t\t\tthis.records = this.records.slice(-100);\n\t\t}\n\t}\n\n\t/**\n\t * Pause the detector (requires resume to continue)\n\t */\n\tpause(reason: string): void {\n\t\tthis.isPaused = true;\n\t\tthis.pauseReason = reason;\n\t\tlogger.info(\"Loop detector paused\", { reason });\n\t}\n\n\t/**\n\t * Resume from paused state\n\t */\n\tresume(): void {\n\t\tthis.isPaused = false;\n\t\tthis.pauseReason = undefined;\n\t\tlogger.info(\"Loop detector resumed\");\n\t}\n\n\t/**\n\t * Check if detector is paused\n\t */\n\tisPausedState(): boolean {\n\t\treturn this.isPaused;\n\t}\n\n\t/**\n\t * Get pause reason\n\t */\n\tgetPauseReason(): string | undefined {\n\t\treturn this.pauseReason;\n\t}\n\n\t/**\n\t * Clear all records and reset state\n\t */\n\treset(): void {\n\t\tthis.records = [];\n\t\tthis.isPaused = false;\n\t\tthis.pauseReason = undefined;\n\t}\n\n\t/**\n\t * Get statistics about recent calls\n\t */\n\tgetStats(): {\n\t\ttotalRecords: number;\n\t\tuniqueTools: number;\n\t\tuniqueHashes: number;\n\t\toldestRecordAge: number | null;\n\t\tisPaused: boolean;\n\t} {\n\t\tconst now = Date.now();\n\t\tconst uniqueTools = new Set(this.records.map((r) => r.tool)).size;\n\t\tconst uniqueHashes = new Set(this.records.map((r) => r.hash)).size;\n\t\tconst oldestRecord = this.records[0];\n\n\t\treturn {\n\t\t\ttotalRecords: this.records.length,\n\t\t\tuniqueTools,\n\t\t\tuniqueHashes,\n\t\t\toldestRecordAge: oldestRecord ? now - oldestRecord.timestamp : null,\n\t\t\tisPaused: this.isPaused,\n\t\t};\n\t}\n\n\t/**\n\t * Prune records older than the window\n\t */\n\tprivate pruneRecords(now: number): void {\n\t\tconst cutoff = now - this.config.windowMs;\n\t\tthis.records = this.records.filter((r) => r.timestamp > cutoff);\n\t}\n}\n\n/**\n * Default loop detector instance\n */\nexport const defaultLoopDetector = new LoopDetector();\n\n/**\n * Integration helper for tool execution\n *\n * Call this before executing each tool. Returns an action to take.\n */\nexport function checkForLoop(\n\ttool: string,\n\targs: Record<string, unknown>,\n\tdetector: LoopDetector = defaultLoopDetector,\n): {\n\tshouldProceed: boolean;\n\trequiresConfirmation: boolean;\n\tmessage?: string;\n} {\n\tconst result = detector.check(tool, args);\n\n\tif (!result.detected) {\n\t\tdetector.record(tool, args);\n\t\treturn { shouldProceed: true, requiresConfirmation: false };\n\t}\n\n\tswitch (result.action) {\n\t\tcase \"halt\":\n\t\t\treturn {\n\t\t\t\tshouldProceed: false,\n\t\t\t\trequiresConfirmation: false,\n\t\t\t\tmessage: result.reason,\n\t\t\t};\n\n\t\tcase \"pause\":\n\t\t\treturn {\n\t\t\t\tshouldProceed: false,\n\t\t\t\trequiresConfirmation: true,\n\t\t\t\tmessage: `${result.reason}. ${result.suggestion ?? \"\"}`,\n\t\t\t};\n\t\tdefault:\n\t\t\t// Record and continue with warning\n\t\t\tdetector.record(tool, args);\n\t\t\treturn {\n\t\t\t\tshouldProceed: true,\n\t\t\t\trequiresConfirmation: false,\n\t\t\t\tmessage: result.reason,\n\t\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loop-detector.js","sourceRoot":"","sources":["../../src/safety/loop-detector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Loop Detector - Automatic detection of repetitive tool patterns\n *\n * This module detects when the agent appears to be stuck in a loop, either\n * from confusion, injection attacks, or other issues. It monitors tool calls\n * and triggers warnings or pauses when repetitive patterns are detected.\n *\n * ## Detection Methods\n *\n * 1. **Exact Repetition**: Same tool+args called multiple times\n * 2. **Similar Operations**: Same tool with varying args (e.g., reading similar paths)\n * 3. **Cyclic Patterns**: Repeating sequences of tools (A→B→C→A→B→C)\n * 4. **High Frequency**: Unusually rapid tool execution\n *\n * ## Actions\n *\n * - **warn**: Log a warning for monitoring\n * - **pause**: Require user confirmation to continue\n * - **halt**: Stop execution entirely\n *\n * @module safety/loop-detector\n */\n\nimport { createHash } from \"node:crypto\";\nimport { stableStringify } from \"../agent/transport/stable-stringify.js\";\nimport { createLogger } from \"../utils/logger.js\";\n\nconst logger = createLogger(\"safety:loop-detector\");\n\n/**\n * Configuration for loop detection\n */\nexport interface LoopDetectorConfig {\n\t/** Maximum identical calls before warning (default: 3) */\n\tmaxIdenticalCalls?: number;\n\t/** Maximum similar calls before warning (default: 5) */\n\tmaxSimilarCalls?: number;\n\t/** Time window for detection in ms (default: 60000) */\n\twindowMs?: number;\n\t/** Minimum time between calls in ms (default: 100) */\n\tminCallIntervalMs?: number;\n\t/** Maximum calls per minute before warning (default: 60) */\n\tmaxCallsPerMinute?: number;\n\t/** Enable/disable auto-pause (default: true) */\n\tautoPause?: boolean;\n}\n\n/**\n * Loop detection result\n */\nexport interface LoopDetectionResult {\n\t/** Whether a loop was detected */\n\tdetected: boolean;\n\t/** Type of loop detected */\n\ttype?: \"exact\" | \"similar\" | \"cyclic\" | \"frequency\";\n\t/** Recommended action */\n\taction?: \"warn\" | \"pause\" | \"halt\";\n\t/** Human-readable description */\n\treason?: string;\n\t/** Number of repetitions detected */\n\trepetitions?: number;\n\t/** Suggestion for the user */\n\tsuggestion?: string;\n}\n\n/**\n * Internal record of a tool call\n */\ninterface CallRecord {\n\t/** Hash of tool + args */\n\thash: string;\n\t/** Tool name */\n\ttool: string;\n\t/** Simplified args signature */\n\targsSignature: string;\n\t/** Timestamp */\n\ttimestamp: number;\n}\n\n/**\n * Generate a hash for a tool call\n */\nfunction hashCall(tool: string, args: Record<string, unknown>): string {\n\tconst normalized = stableStringify({ tool, args });\n\treturn createHash(\"md5\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Generate a simplified signature for args (for similarity detection)\n */\nfunction getArgsSignature(args: Record<string, unknown>): string {\n\tconst parts: string[] = [];\n\n\tfor (const [key, value] of Object.entries(args)) {\n\t\tif (typeof value === \"string\") {\n\t\t\t// For strings, use a normalized version (lowercase, truncated)\n\t\t\tconst normalized = value.toLowerCase().slice(0, 50);\n\t\t\tparts.push(`${key}:str(${normalized.length})`);\n\t\t} else if (typeof value === \"number\") {\n\t\t\tparts.push(`${key}:num`);\n\t\t} else if (typeof value === \"boolean\") {\n\t\t\tparts.push(`${key}:bool`);\n\t\t} else if (Array.isArray(value)) {\n\t\t\tparts.push(`${key}:arr(${value.length})`);\n\t\t} else if (value && typeof value === \"object\") {\n\t\t\tparts.push(`${key}:obj`);\n\t\t}\n\t}\n\n\treturn parts.sort().join(\",\");\n}\n\n/**\n * Detect cyclic patterns in a sequence\n * Returns the cycle length if found, 0 otherwise\n */\nfunction detectCycle(\n\tsequence: string[],\n\tminCycleLength = 2,\n\tmaxCycleLength = 10,\n): number {\n\tif (sequence.length < minCycleLength * 2) {\n\t\treturn 0;\n\t}\n\n\t// Try different cycle lengths\n\tfor (let cycleLen = minCycleLength; cycleLen <= maxCycleLength; cycleLen++) {\n\t\tif (sequence.length < cycleLen * 2) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// Check if the last cycleLen items match the previous cycleLen items\n\t\tconst candidateCycle = sequence.slice(-cycleLen);\n\t\tif (new Set(candidateCycle).size < 2) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet isCycle = true;\n\t\tfor (let i = 0; i < cycleLen; i++) {\n\t\t\tconst idx1 = sequence.length - 1 - i;\n\t\t\tconst idx2 = sequence.length - 1 - cycleLen - i;\n\t\t\tif (idx2 < 0 || sequence[idx1] !== sequence[idx2]) {\n\t\t\t\tisCycle = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (isCycle) {\n\t\t\t// Verify the cycle repeats at least once more\n\t\t\tconst lastIdx = sequence.length - 1 - cycleLen * 2;\n\t\t\tif (lastIdx >= 0) {\n\t\t\t\tlet hasThirdRepeat = true;\n\t\t\t\tfor (let i = 0; i < cycleLen && lastIdx - i >= 0; i++) {\n\t\t\t\t\tif (sequence[lastIdx - i] !== sequence[sequence.length - 1 - i]) {\n\t\t\t\t\t\thasThirdRepeat = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (hasThirdRepeat) {\n\t\t\t\t\treturn cycleLen;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cycleLen;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * Loop Detector class\n */\nexport class LoopDetector {\n\tprivate config: Required<LoopDetectorConfig>;\n\tprivate records: CallRecord[] = [];\n\tprivate isPaused = false;\n\tprivate pauseReason?: string;\n\n\tconstructor(config?: LoopDetectorConfig) {\n\t\tthis.config = {\n\t\t\tmaxIdenticalCalls: config?.maxIdenticalCalls ?? 3,\n\t\t\tmaxSimilarCalls: config?.maxSimilarCalls ?? 5,\n\t\t\twindowMs: config?.windowMs ?? 60000,\n\t\t\tminCallIntervalMs: config?.minCallIntervalMs ?? 100,\n\t\t\tmaxCallsPerMinute: config?.maxCallsPerMinute ?? 60,\n\t\t\tautoPause: config?.autoPause ?? true,\n\t\t};\n\t}\n\n\t/**\n\t * Check a tool call for loop patterns\n\t */\n\tcheck(tool: string, args: Record<string, unknown>): LoopDetectionResult {\n\t\tconst now = Date.now();\n\t\tconst hash = hashCall(tool, args);\n\t\tconst argsSignature = getArgsSignature(args);\n\n\t\t// Prune old records\n\t\tthis.pruneRecords(now);\n\n\t\t// Check for paused state\n\t\tif (this.isPaused) {\n\t\t\treturn {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"exact\",\n\t\t\t\taction: \"pause\",\n\t\t\t\treason: this.pauseReason ?? \"Loop detector is paused\",\n\t\t\t\tsuggestion: \"Resume execution or investigate the repeated pattern\",\n\t\t\t};\n\t\t}\n\n\t\t// Check 1: Exact repetition\n\t\tconst identicalCount = this.records.filter((r) => r.hash === hash).length;\n\t\tif (identicalCount >= this.config.maxIdenticalCalls) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"exact\",\n\t\t\t\taction: this.config.autoPause ? \"pause\" : \"warn\",\n\t\t\t\treason: `Identical tool call repeated ${identicalCount + 1} times: ${tool}`,\n\t\t\t\trepetitions: identicalCount + 1,\n\t\t\t\tsuggestion: \"Check if the operation is completing successfully\",\n\t\t\t};\n\n\t\t\tif (this.config.autoPause) {\n\t\t\t\tthis.pause(result.reason!);\n\t\t\t}\n\n\t\t\tlogger.warn(\"Exact repetition loop detected\", {\n\t\t\t\ttool,\n\t\t\t\tcount: identicalCount + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 2: Similar operations (same tool, similar args pattern)\n\t\tconst similarCount = this.records.filter(\n\t\t\t(r) => r.tool === tool && r.argsSignature === argsSignature,\n\t\t).length;\n\t\tif (similarCount >= this.config.maxSimilarCalls) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"similar\",\n\t\t\t\taction: this.config.autoPause ? \"pause\" : \"warn\",\n\t\t\t\treason: `Similar ${tool} calls detected ${similarCount + 1} times`,\n\t\t\t\trepetitions: similarCount + 1,\n\t\t\t\tsuggestion: \"Verify that these operations are intentional\",\n\t\t\t};\n\n\t\t\tif (this.config.autoPause) {\n\t\t\t\tthis.pause(result.reason!);\n\t\t\t}\n\n\t\t\tlogger.warn(\"Similar operation loop detected\", {\n\t\t\t\ttool,\n\t\t\t\tcount: similarCount + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 3: Cyclic patterns\n\t\tconst toolSequence = [...this.records.map((r) => r.tool), tool];\n\t\tconst cycleLength = detectCycle(toolSequence);\n\t\tif (cycleLength > 0) {\n\t\t\tconst cyclePattern = toolSequence.slice(-cycleLength).join(\" → \");\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"cyclic\",\n\t\t\t\taction: \"warn\",\n\t\t\t\treason: `Cyclic pattern detected: ${cyclePattern}`,\n\t\t\t\trepetitions: 2,\n\t\t\t\tsuggestion: \"The agent may be stuck in a decision loop\",\n\t\t\t};\n\n\t\t\tlogger.warn(\"Cyclic pattern detected\", {\n\t\t\t\tcycleLength,\n\t\t\t\tpattern: cyclePattern,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 4: High frequency\n\t\tconst recentCalls = this.records.filter(\n\t\t\t(r) => now - r.timestamp < 60000,\n\t\t).length;\n\t\tif (recentCalls >= this.config.maxCallsPerMinute) {\n\t\t\tconst result: LoopDetectionResult = {\n\t\t\t\tdetected: true,\n\t\t\t\ttype: \"frequency\",\n\t\t\t\taction: \"warn\",\n\t\t\t\treason: `High call frequency detected: ${recentCalls + 1} calls in the last minute`,\n\t\t\t\trepetitions: recentCalls + 1,\n\t\t\t\tsuggestion: \"Consider if this many operations are necessary\",\n\t\t\t};\n\n\t\t\tlogger.warn(\"High frequency loop detected\", {\n\t\t\t\tcallsPerMinute: recentCalls + 1,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check 5: Too rapid calls\n\t\tconst lastCall = this.records[this.records.length - 1];\n\t\tif (lastCall && now - lastCall.timestamp < this.config.minCallIntervalMs) {\n\t\t\t// Don't trigger on this alone, just note it\n\t\t\tlogger.debug(\"Very rapid tool calls detected\", {\n\t\t\t\tintervalMs: now - lastCall.timestamp,\n\t\t\t});\n\t\t}\n\n\t\treturn { detected: false };\n\t}\n\n\t/**\n\t * Record a tool call (call after check)\n\t */\n\trecord(tool: string, args: Record<string, unknown>): void {\n\t\tconst now = Date.now();\n\t\tthis.records.push({\n\t\t\thash: hashCall(tool, args),\n\t\t\ttool,\n\t\t\targsSignature: getArgsSignature(args),\n\t\t\ttimestamp: now,\n\t\t});\n\n\t\t// Keep records bounded\n\t\tif (this.records.length > 200) {\n\t\t\tthis.records = this.records.slice(-100);\n\t\t}\n\t}\n\n\t/**\n\t * Pause the detector (requires resume to continue)\n\t */\n\tpause(reason: string): void {\n\t\tthis.isPaused = true;\n\t\tthis.pauseReason = reason;\n\t\tlogger.info(\"Loop detector paused\", { reason });\n\t}\n\n\t/**\n\t * Resume from paused state\n\t */\n\tresume(): void {\n\t\tthis.isPaused = false;\n\t\tthis.pauseReason = undefined;\n\t\tlogger.info(\"Loop detector resumed\");\n\t}\n\n\t/**\n\t * Check if detector is paused\n\t */\n\tisPausedState(): boolean {\n\t\treturn this.isPaused;\n\t}\n\n\t/**\n\t * Get pause reason\n\t */\n\tgetPauseReason(): string | undefined {\n\t\treturn this.pauseReason;\n\t}\n\n\t/**\n\t * Clear all records and reset state\n\t */\n\treset(): void {\n\t\tthis.records = [];\n\t\tthis.isPaused = false;\n\t\tthis.pauseReason = undefined;\n\t}\n\n\t/**\n\t * Get statistics about recent calls\n\t */\n\tgetStats(): {\n\t\ttotalRecords: number;\n\t\tuniqueTools: number;\n\t\tuniqueHashes: number;\n\t\toldestRecordAge: number | null;\n\t\tisPaused: boolean;\n\t} {\n\t\tconst now = Date.now();\n\t\tconst uniqueTools = new Set(this.records.map((r) => r.tool)).size;\n\t\tconst uniqueHashes = new Set(this.records.map((r) => r.hash)).size;\n\t\tconst oldestRecord = this.records[0];\n\n\t\treturn {\n\t\t\ttotalRecords: this.records.length,\n\t\t\tuniqueTools,\n\t\t\tuniqueHashes,\n\t\t\toldestRecordAge: oldestRecord ? now - oldestRecord.timestamp : null,\n\t\t\tisPaused: this.isPaused,\n\t\t};\n\t}\n\n\t/**\n\t * Prune records older than the window\n\t */\n\tprivate pruneRecords(now: number): void {\n\t\tconst cutoff = now - this.config.windowMs;\n\t\tthis.records = this.records.filter((r) => r.timestamp > cutoff);\n\t}\n}\n\n/**\n * Default loop detector instance\n */\nexport const defaultLoopDetector = new LoopDetector();\n\n/**\n * Integration helper for tool execution\n *\n * Call this before executing each tool. Returns an action to take.\n */\nexport function checkForLoop(\n\ttool: string,\n\targs: Record<string, unknown>,\n\tdetector: LoopDetector = defaultLoopDetector,\n): {\n\tshouldProceed: boolean;\n\trequiresConfirmation: boolean;\n\tmessage?: string;\n} {\n\tconst result = detector.check(tool, args);\n\n\tif (!result.detected) {\n\t\tdetector.record(tool, args);\n\t\treturn { shouldProceed: true, requiresConfirmation: false };\n\t}\n\n\tswitch (result.action) {\n\t\tcase \"halt\":\n\t\t\treturn {\n\t\t\t\tshouldProceed: false,\n\t\t\t\trequiresConfirmation: false,\n\t\t\t\tmessage: result.reason,\n\t\t\t};\n\n\t\tcase \"pause\":\n\t\t\treturn {\n\t\t\t\tshouldProceed: false,\n\t\t\t\trequiresConfirmation: true,\n\t\t\t\tmessage: `${result.reason}. ${result.suggestion ?? \"\"}`,\n\t\t\t};\n\t\tdefault:\n\t\t\t// Record and continue with warning\n\t\t\tdetector.record(tool, args);\n\t\t\treturn {\n\t\t\t\tshouldProceed: true,\n\t\t\t\trequiresConfirmation: false,\n\t\t\t\tmessage: result.reason,\n\t\t\t};\n\t}\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NativeSandboxMode, NativeSandboxPolicy } from "../sandbox/native-sandbox.js";
|
|
2
|
+
export type FileSystemAccessMode = "none" | "read-only" | "read-write";
|
|
3
|
+
export type FileSystemPermissionPath = {
|
|
4
|
+
kind: "path";
|
|
5
|
+
path: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "special";
|
|
8
|
+
value: "workspace" | "tmp" | "tmpdir" | "full-disk";
|
|
9
|
+
} | {
|
|
10
|
+
kind: "glob";
|
|
11
|
+
pattern: string;
|
|
12
|
+
};
|
|
13
|
+
export interface FileSystemPermissionEntry {
|
|
14
|
+
path: FileSystemPermissionPath;
|
|
15
|
+
access: FileSystemAccessMode;
|
|
16
|
+
}
|
|
17
|
+
export interface FileSystemPermissions {
|
|
18
|
+
entries: FileSystemPermissionEntry[];
|
|
19
|
+
globScanMaxDepth?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NetworkPermissions {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface PermissionProfile {
|
|
25
|
+
fileSystem?: FileSystemPermissions;
|
|
26
|
+
network?: NetworkPermissions;
|
|
27
|
+
}
|
|
28
|
+
export interface NormalizePermissionProfileOptions {
|
|
29
|
+
cwd?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface IntersectPermissionProfileOptions {
|
|
32
|
+
cwd?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function normalizePermissionProfile(profile: PermissionProfile, options?: NormalizePermissionProfileOptions): PermissionProfile;
|
|
35
|
+
export declare function mergePermissionProfiles(base: PermissionProfile, additional: PermissionProfile, options?: NormalizePermissionProfileOptions): PermissionProfile;
|
|
36
|
+
export declare function intersectPermissionProfiles(requested: PermissionProfile, granted: PermissionProfile, options?: IntersectPermissionProfileOptions): PermissionProfile;
|
|
37
|
+
export declare function permissionProfileFromNativeSandboxPolicy(policy: NativeSandboxPolicy, cwd?: string): PermissionProfile;
|
|
38
|
+
export declare function nativeSandboxPolicyFromPermissionProfile(profile: PermissionProfile, cwd?: string): NativeSandboxPolicy;
|
|
39
|
+
export interface NativeSandboxPolicyInput {
|
|
40
|
+
mode: NativeSandboxMode;
|
|
41
|
+
writableRoots?: string[];
|
|
42
|
+
networkAccess?: boolean;
|
|
43
|
+
excludeTmpdir?: boolean;
|
|
44
|
+
excludeSlashTmp?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare function buildNativeSandboxPolicy(input: NativeSandboxPolicyInput, cwd?: string): NativeSandboxPolicy;
|
|
47
|
+
//# sourceMappingURL=permission-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-profile.d.ts","sourceRoot":"","sources":["../../src/safety/permission-profile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,iBAAiB,EACjB,mBAAmB,EACnB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;AAEvE,MAAM,MAAM,wBAAwB,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,WAAW,yBAAyB;IACzC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,MAAM,EAAE,oBAAoB,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,iCAAiC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iCAAiC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAkMD,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,iCAAsC,GAC7C,iBAAiB,CA8BnB;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE,iCAAsC,GAC7C,iBAAiB,CA4BnB;AAED,wBAAgB,2BAA2B,CAC1C,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,iCAAsC,GAC7C,iBAAiB,CAmEnB;AAED,wBAAgB,wCAAwC,CACvD,MAAM,EAAE,mBAAmB,EAC3B,GAAG,GAAE,MAA4B,GAC/B,iBAAiB,CA2DnB;AAED,wBAAgB,wCAAwC,CACvD,OAAO,EAAE,iBAAiB,EAC1B,GAAG,GAAE,MAA4B,GAC/B,mBAAmB,CAuFrB;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,iBAAiB,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,wBAAwB,EAC/B,GAAG,GAAE,MAA4B,GAC/B,mBAAmB,CAcrB"}
|