lattice-orchestrator 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +58 -0
- package/config/logrotate.conf +15 -0
- package/dist/cli-parser.d.ts +11 -0
- package/dist/cli-parser.d.ts.map +1 -0
- package/dist/cli-parser.js +48 -0
- package/dist/cli-parser.js.map +1 -0
- package/dist/lattice-server.d.ts +70 -0
- package/dist/lattice-server.d.ts.map +1 -0
- package/dist/lattice-server.js +969 -0
- package/dist/lattice-server.js.map +1 -0
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +190 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/mcp-server/lattice-tools.d.ts +15 -0
- package/dist/mcp-server/lattice-tools.d.ts.map +1 -0
- package/dist/mcp-server/lattice-tools.js +366 -0
- package/dist/mcp-server/lattice-tools.js.map +1 -0
- package/dist/middleware/cors-setup.d.ts +7 -0
- package/dist/middleware/cors-setup.d.ts.map +1 -0
- package/dist/middleware/cors-setup.js +8 -0
- package/dist/middleware/cors-setup.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +4 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +27 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/query-parser.d.ts +11 -0
- package/dist/middleware/query-parser.d.ts.map +1 -0
- package/dist/middleware/query-parser.js +68 -0
- package/dist/middleware/query-parser.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +4 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +6 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/process-daemon/index.d.ts +14 -0
- package/dist/process-daemon/index.d.ts.map +1 -0
- package/dist/process-daemon/index.js +51 -0
- package/dist/process-daemon/index.js.map +1 -0
- package/dist/process-daemon/process-daemon.d.ts +101 -0
- package/dist/process-daemon/process-daemon.d.ts.map +1 -0
- package/dist/process-daemon/process-daemon.js +846 -0
- package/dist/process-daemon/process-daemon.js.map +1 -0
- package/dist/process-daemon/process-manager-client.d.ts +123 -0
- package/dist/process-daemon/process-manager-client.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-client.js +329 -0
- package/dist/process-daemon/process-manager-client.js.map +1 -0
- package/dist/process-daemon/process-manager-interface.d.ts +61 -0
- package/dist/process-daemon/process-manager-interface.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-interface.js +8 -0
- package/dist/process-daemon/process-manager-interface.js.map +1 -0
- package/dist/process-daemon/test-daemon.d.ts +12 -0
- package/dist/process-daemon/test-daemon.d.ts.map +1 -0
- package/dist/process-daemon/test-daemon.js +81 -0
- package/dist/process-daemon/test-daemon.js.map +1 -0
- package/dist/process-daemon/types.d.ts +97 -0
- package/dist/process-daemon/types.d.ts.map +1 -0
- package/dist/process-daemon/types.js +8 -0
- package/dist/process-daemon/types.js.map +1 -0
- package/dist/routes/analysis.routes.d.ts +13 -0
- package/dist/routes/analysis.routes.d.ts.map +1 -0
- package/dist/routes/analysis.routes.js +520 -0
- package/dist/routes/analysis.routes.js.map +1 -0
- package/dist/routes/config.routes.d.ts +4 -0
- package/dist/routes/config.routes.d.ts.map +1 -0
- package/dist/routes/config.routes.js +27 -0
- package/dist/routes/config.routes.js.map +1 -0
- package/dist/routes/conversation.routes.d.ts +43 -0
- package/dist/routes/conversation.routes.d.ts.map +1 -0
- package/dist/routes/conversation.routes.js +79 -0
- package/dist/routes/conversation.routes.js.map +1 -0
- package/dist/routes/filesystem.routes.d.ts +4 -0
- package/dist/routes/filesystem.routes.d.ts.map +1 -0
- package/dist/routes/filesystem.routes.js +86 -0
- package/dist/routes/filesystem.routes.js.map +1 -0
- package/dist/routes/insights.routes.d.ts +17 -0
- package/dist/routes/insights.routes.d.ts.map +1 -0
- package/dist/routes/insights.routes.js +633 -0
- package/dist/routes/insights.routes.js.map +1 -0
- package/dist/routes/lattice.routes.d.ts +10 -0
- package/dist/routes/lattice.routes.d.ts.map +1 -0
- package/dist/routes/lattice.routes.js +123 -0
- package/dist/routes/lattice.routes.js.map +1 -0
- package/dist/routes/license.routes.d.ts +3 -0
- package/dist/routes/license.routes.d.ts.map +1 -0
- package/dist/routes/license.routes.js +95 -0
- package/dist/routes/license.routes.js.map +1 -0
- package/dist/routes/log.routes.d.ts +3 -0
- package/dist/routes/log.routes.d.ts.map +1 -0
- package/dist/routes/log.routes.js +184 -0
- package/dist/routes/log.routes.js.map +1 -0
- package/dist/routes/pending-question.routes.d.ts +9 -0
- package/dist/routes/pending-question.routes.d.ts.map +1 -0
- package/dist/routes/pending-question.routes.js +162 -0
- package/dist/routes/pending-question.routes.js.map +1 -0
- package/dist/routes/permission.routes.d.ts +18 -0
- package/dist/routes/permission.routes.d.ts.map +1 -0
- package/dist/routes/permission.routes.js +370 -0
- package/dist/routes/permission.routes.js.map +1 -0
- package/dist/routes/process-events.routes.d.ts +9 -0
- package/dist/routes/process-events.routes.d.ts.map +1 -0
- package/dist/routes/process-events.routes.js +141 -0
- package/dist/routes/process-events.routes.js.map +1 -0
- package/dist/routes/prototype.routes.d.ts +9 -0
- package/dist/routes/prototype.routes.d.ts.map +1 -0
- package/dist/routes/prototype.routes.js +757 -0
- package/dist/routes/prototype.routes.js.map +1 -0
- package/dist/routes/question.routes.d.ts +8 -0
- package/dist/routes/question.routes.d.ts.map +1 -0
- package/dist/routes/question.routes.js +83 -0
- package/dist/routes/question.routes.js.map +1 -0
- package/dist/routes/session-control.routes.d.ts +29 -0
- package/dist/routes/session-control.routes.d.ts.map +1 -0
- package/dist/routes/session-control.routes.js +455 -0
- package/dist/routes/session-control.routes.js.map +1 -0
- package/dist/routes/session-lifecycle.routes.d.ts +21 -0
- package/dist/routes/session-lifecycle.routes.d.ts.map +1 -0
- package/dist/routes/session-lifecycle.routes.js +256 -0
- package/dist/routes/session-lifecycle.routes.js.map +1 -0
- package/dist/routes/session-query.routes.d.ts +25 -0
- package/dist/routes/session-query.routes.d.ts.map +1 -0
- package/dist/routes/session-query.routes.js +363 -0
- package/dist/routes/session-query.routes.js.map +1 -0
- package/dist/routes/session-stream.routes.d.ts +21 -0
- package/dist/routes/session-stream.routes.d.ts.map +1 -0
- package/dist/routes/session-stream.routes.js +235 -0
- package/dist/routes/session-stream.routes.js.map +1 -0
- package/dist/routes/streaming.routes.d.ts +4 -0
- package/dist/routes/streaming.routes.d.ts.map +1 -0
- package/dist/routes/streaming.routes.js +33 -0
- package/dist/routes/streaming.routes.js.map +1 -0
- package/dist/routes/system.routes.d.ts +7 -0
- package/dist/routes/system.routes.d.ts.map +1 -0
- package/dist/routes/system.routes.js +214 -0
- package/dist/routes/system.routes.js.map +1 -0
- package/dist/routes/walkthrough.routes.d.ts +19 -0
- package/dist/routes/walkthrough.routes.d.ts.map +1 -0
- package/dist/routes/walkthrough.routes.js +688 -0
- package/dist/routes/walkthrough.routes.js.map +1 -0
- package/dist/routes/working-directories.routes.d.ts +4 -0
- package/dist/routes/working-directories.routes.d.ts.map +1 -0
- package/dist/routes/working-directories.routes.js +25 -0
- package/dist/routes/working-directories.routes.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +34 -0
- package/dist/server.js.map +1 -0
- package/dist/services/ToolMetricsService.d.ts +53 -0
- package/dist/services/ToolMetricsService.d.ts.map +1 -0
- package/dist/services/ToolMetricsService.js +230 -0
- package/dist/services/ToolMetricsService.js.map +1 -0
- package/dist/services/claude-router-service.d.ts +19 -0
- package/dist/services/claude-router-service.d.ts.map +1 -0
- package/dist/services/claude-router-service.js +160 -0
- package/dist/services/claude-router-service.js.map +1 -0
- package/dist/services/commands-service.d.ts +20 -0
- package/dist/services/commands-service.d.ts.map +1 -0
- package/dist/services/commands-service.js +115 -0
- package/dist/services/commands-service.js.map +1 -0
- package/dist/services/connection-debug-logger.d.ts +85 -0
- package/dist/services/connection-debug-logger.d.ts.map +1 -0
- package/dist/services/connection-debug-logger.js +221 -0
- package/dist/services/connection-debug-logger.js.map +1 -0
- package/dist/services/debug-log.d.ts +6 -0
- package/dist/services/debug-log.d.ts.map +1 -0
- package/dist/services/debug-log.js +27 -0
- package/dist/services/debug-log.js.map +1 -0
- package/dist/services/gemini-service.d.ts +35 -0
- package/dist/services/gemini-service.d.ts.map +1 -0
- package/dist/services/gemini-service.js +256 -0
- package/dist/services/gemini-service.js.map +1 -0
- package/dist/services/infrastructure/config-service.d.ts +79 -0
- package/dist/services/infrastructure/config-service.d.ts.map +1 -0
- package/dist/services/infrastructure/config-service.js +431 -0
- package/dist/services/infrastructure/config-service.js.map +1 -0
- package/dist/services/infrastructure/cost-tracker.d.ts +112 -0
- package/dist/services/infrastructure/cost-tracker.d.ts.map +1 -0
- package/dist/services/infrastructure/cost-tracker.js +423 -0
- package/dist/services/infrastructure/cost-tracker.js.map +1 -0
- package/dist/services/infrastructure/file-system-service.d.ts +61 -0
- package/dist/services/infrastructure/file-system-service.d.ts.map +1 -0
- package/dist/services/infrastructure/file-system-service.js +348 -0
- package/dist/services/infrastructure/file-system-service.js.map +1 -0
- package/dist/services/infrastructure/log-formatter.d.ts +5 -0
- package/dist/services/infrastructure/log-formatter.d.ts.map +1 -0
- package/dist/services/infrastructure/log-formatter.js +77 -0
- package/dist/services/infrastructure/log-formatter.js.map +1 -0
- package/dist/services/infrastructure/log-stream-buffer.d.ts +11 -0
- package/dist/services/infrastructure/log-stream-buffer.d.ts.map +1 -0
- package/dist/services/infrastructure/log-stream-buffer.js +36 -0
- package/dist/services/infrastructure/log-stream-buffer.js.map +1 -0
- package/dist/services/infrastructure/logger.d.ts +71 -0
- package/dist/services/infrastructure/logger.d.ts.map +1 -0
- package/dist/services/infrastructure/logger.js +215 -0
- package/dist/services/infrastructure/logger.js.map +1 -0
- package/dist/services/infrastructure/service-registry.d.ts +86 -0
- package/dist/services/infrastructure/service-registry.d.ts.map +1 -0
- package/dist/services/infrastructure/service-registry.js +162 -0
- package/dist/services/infrastructure/service-registry.js.map +1 -0
- package/dist/services/infrastructure/stream-manager.d.ts +87 -0
- package/dist/services/infrastructure/stream-manager.d.ts.map +1 -0
- package/dist/services/infrastructure/stream-manager.js +436 -0
- package/dist/services/infrastructure/stream-manager.js.map +1 -0
- package/dist/services/infrastructure/timing.d.ts +72 -0
- package/dist/services/infrastructure/timing.d.ts.map +1 -0
- package/dist/services/infrastructure/timing.js +115 -0
- package/dist/services/infrastructure/timing.js.map +1 -0
- package/dist/services/insights/anthropic-service.d.ts +224 -0
- package/dist/services/insights/anthropic-service.d.ts.map +1 -0
- package/dist/services/insights/anthropic-service.js +1062 -0
- package/dist/services/insights/anthropic-service.js.map +1 -0
- package/dist/services/insights/insight-audit-repository.d.ts +119 -0
- package/dist/services/insights/insight-audit-repository.d.ts.map +1 -0
- package/dist/services/insights/insight-audit-repository.js +242 -0
- package/dist/services/insights/insight-audit-repository.js.map +1 -0
- package/dist/services/insights/insight-queue.d.ts +99 -0
- package/dist/services/insights/insight-queue.d.ts.map +1 -0
- package/dist/services/insights/insight-queue.js +277 -0
- package/dist/services/insights/insight-queue.js.map +1 -0
- package/dist/services/insights/insights-computer.d.ts +132 -0
- package/dist/services/insights/insights-computer.d.ts.map +1 -0
- package/dist/services/insights/insights-computer.js +936 -0
- package/dist/services/insights/insights-computer.js.map +1 -0
- package/dist/services/insights/insights-coordinator.d.ts +165 -0
- package/dist/services/insights/insights-coordinator.d.ts.map +1 -0
- package/dist/services/insights/insights-coordinator.js +1678 -0
- package/dist/services/insights/insights-coordinator.js.map +1 -0
- package/dist/services/insights/insights-event-log.d.ts +196 -0
- package/dist/services/insights/insights-event-log.d.ts.map +1 -0
- package/dist/services/insights/insights-event-log.js +319 -0
- package/dist/services/insights/insights-event-log.js.map +1 -0
- package/dist/services/lattice-service.d.ts +77 -0
- package/dist/services/lattice-service.d.ts.map +1 -0
- package/dist/services/lattice-service.js +195 -0
- package/dist/services/lattice-service.js.map +1 -0
- package/dist/services/license-service.d.ts +69 -0
- package/dist/services/license-service.d.ts.map +1 -0
- package/dist/services/license-service.js +330 -0
- package/dist/services/license-service.js.map +1 -0
- package/dist/services/mcp-config-generator.d.ts +32 -0
- package/dist/services/mcp-config-generator.d.ts.map +1 -0
- package/dist/services/mcp-config-generator.js +126 -0
- package/dist/services/mcp-config-generator.js.map +1 -0
- package/dist/services/message-filter.d.ts +22 -0
- package/dist/services/message-filter.d.ts.map +1 -0
- package/dist/services/message-filter.js +57 -0
- package/dist/services/message-filter.js.map +1 -0
- package/dist/services/notification-service.d.ts +45 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/pending-question-service.d.ts +97 -0
- package/dist/services/pending-question-service.d.ts.map +1 -0
- package/dist/services/pending-question-service.js +223 -0
- package/dist/services/pending-question-service.js.map +1 -0
- package/dist/services/permission-event-log.d.ts +136 -0
- package/dist/services/permission-event-log.d.ts.map +1 -0
- package/dist/services/permission-event-log.js +252 -0
- package/dist/services/permission-event-log.js.map +1 -0
- package/dist/services/permission-pattern-matcher.d.ts +82 -0
- package/dist/services/permission-pattern-matcher.d.ts.map +1 -0
- package/dist/services/permission-pattern-matcher.js +294 -0
- package/dist/services/permission-pattern-matcher.js.map +1 -0
- package/dist/services/permission-tracker.d.ts +67 -0
- package/dist/services/permission-tracker.d.ts.map +1 -0
- package/dist/services/permission-tracker.js +162 -0
- package/dist/services/permission-tracker.js.map +1 -0
- package/dist/services/process/claude-process-manager.d.ts +142 -0
- package/dist/services/process/claude-process-manager.d.ts.map +1 -0
- package/dist/services/process/claude-process-manager.js +1218 -0
- package/dist/services/process/claude-process-manager.js.map +1 -0
- package/dist/services/process/conversation-status-manager.d.ts +110 -0
- package/dist/services/process/conversation-status-manager.d.ts.map +1 -0
- package/dist/services/process/conversation-status-manager.js +349 -0
- package/dist/services/process/conversation-status-manager.js.map +1 -0
- package/dist/services/process/json-lines-parser.d.ts +19 -0
- package/dist/services/process/json-lines-parser.d.ts.map +1 -0
- package/dist/services/process/json-lines-parser.js +59 -0
- package/dist/services/process/json-lines-parser.js.map +1 -0
- package/dist/services/process/process-event-log.d.ts +263 -0
- package/dist/services/process/process-event-log.d.ts.map +1 -0
- package/dist/services/process/process-event-log.js +509 -0
- package/dist/services/process/process-event-log.js.map +1 -0
- package/dist/services/process/process-manager-factory.d.ts +109 -0
- package/dist/services/process/process-manager-factory.d.ts.map +1 -0
- package/dist/services/process/process-manager-factory.js +338 -0
- package/dist/services/process/process-manager-factory.js.map +1 -0
- package/dist/services/question-tracker.d.ts +51 -0
- package/dist/services/question-tracker.d.ts.map +1 -0
- package/dist/services/question-tracker.js +111 -0
- package/dist/services/question-tracker.js.map +1 -0
- package/dist/services/sessions/claude-history-reader.d.ts +139 -0
- package/dist/services/sessions/claude-history-reader.d.ts.map +1 -0
- package/dist/services/sessions/claude-history-reader.js +864 -0
- package/dist/services/sessions/claude-history-reader.js.map +1 -0
- package/dist/services/sessions/conversation-cache.d.ts +98 -0
- package/dist/services/sessions/conversation-cache.d.ts.map +1 -0
- package/dist/services/sessions/conversation-cache.js +329 -0
- package/dist/services/sessions/conversation-cache.js.map +1 -0
- package/dist/services/sessions/session-activity-watcher.d.ts +67 -0
- package/dist/services/sessions/session-activity-watcher.d.ts.map +1 -0
- package/dist/services/sessions/session-activity-watcher.js +236 -0
- package/dist/services/sessions/session-activity-watcher.js.map +1 -0
- package/dist/services/sessions/session-analysis-service.d.ts +72 -0
- package/dist/services/sessions/session-analysis-service.d.ts.map +1 -0
- package/dist/services/sessions/session-analysis-service.js +373 -0
- package/dist/services/sessions/session-analysis-service.js.map +1 -0
- package/dist/services/sessions/session-branch-service.d.ts +76 -0
- package/dist/services/sessions/session-branch-service.d.ts.map +1 -0
- package/dist/services/sessions/session-branch-service.js +355 -0
- package/dist/services/sessions/session-branch-service.js.map +1 -0
- package/dist/services/sessions/session-info-service.d.ts +455 -0
- package/dist/services/sessions/session-info-service.d.ts.map +1 -0
- package/dist/services/sessions/session-info-service.js +1640 -0
- package/dist/services/sessions/session-info-service.js.map +1 -0
- package/dist/services/sessions/session-marks-repository.d.ts +78 -0
- package/dist/services/sessions/session-marks-repository.d.ts.map +1 -0
- package/dist/services/sessions/session-marks-repository.js +263 -0
- package/dist/services/sessions/session-marks-repository.js.map +1 -0
- package/dist/services/sessions/session-marks-service.d.ts +137 -0
- package/dist/services/sessions/session-marks-service.d.ts.map +1 -0
- package/dist/services/sessions/session-marks-service.js +562 -0
- package/dist/services/sessions/session-marks-service.js.map +1 -0
- package/dist/services/sessions/session-review-service.d.ts +98 -0
- package/dist/services/sessions/session-review-service.d.ts.map +1 -0
- package/dist/services/sessions/session-review-service.js +629 -0
- package/dist/services/sessions/session-review-service.js.map +1 -0
- package/dist/services/sessions/turn-capture-service.d.ts +83 -0
- package/dist/services/sessions/turn-capture-service.d.ts.map +1 -0
- package/dist/services/sessions/turn-capture-service.js +477 -0
- package/dist/services/sessions/turn-capture-service.js.map +1 -0
- package/dist/services/sessions/turn-repository.d.ts +48 -0
- package/dist/services/sessions/turn-repository.d.ts.map +1 -0
- package/dist/services/sessions/turn-repository.js +103 -0
- package/dist/services/sessions/turn-repository.js.map +1 -0
- package/dist/services/walkthrough-service.d.ts +226 -0
- package/dist/services/walkthrough-service.d.ts.map +1 -0
- package/dist/services/walkthrough-service.js +1112 -0
- package/dist/services/walkthrough-service.js.map +1 -0
- package/dist/services/walkthrough-skill-prompt.d.ts +34 -0
- package/dist/services/walkthrough-skill-prompt.d.ts.map +1 -0
- package/dist/services/walkthrough-skill-prompt.js +313 -0
- package/dist/services/walkthrough-skill-prompt.js.map +1 -0
- package/dist/services/web-push-service.d.ts +48 -0
- package/dist/services/web-push-service.d.ts.map +1 -0
- package/dist/services/web-push-service.js +186 -0
- package/dist/services/web-push-service.js.map +1 -0
- package/dist/services/working-directories-service.d.ts +19 -0
- package/dist/services/working-directories-service.d.ts.map +1 -0
- package/dist/services/working-directories-service.js +103 -0
- package/dist/services/working-directories-service.js.map +1 -0
- package/dist/types/config.d.ts +122 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +21 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/express.d.ts +5 -0
- package/dist/types/express.d.ts.map +1 -0
- package/dist/types/express.js +2 -0
- package/dist/types/express.js.map +1 -0
- package/dist/types/index.d.ts +400 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/insights.d.ts +176 -0
- package/dist/types/insights.d.ts.map +1 -0
- package/dist/types/insights.js +23 -0
- package/dist/types/insights.js.map +1 -0
- package/dist/types/license.d.ts +70 -0
- package/dist/types/license.d.ts.map +1 -0
- package/dist/types/license.js +5 -0
- package/dist/types/license.js.map +1 -0
- package/dist/types/router-config.d.ts +13 -0
- package/dist/types/router-config.d.ts.map +1 -0
- package/dist/types/router-config.js +2 -0
- package/dist/types/router-config.js.map +1 -0
- package/dist/utils/constants.d.ts +26 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +28 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/machine-id.d.ts +7 -0
- package/dist/utils/machine-id.d.ts.map +1 -0
- package/dist/utils/machine-id.js +76 -0
- package/dist/utils/machine-id.js.map +1 -0
- package/dist/utils/server-startup.d.ts +11 -0
- package/dist/utils/server-startup.d.ts.map +1 -0
- package/dist/utils/server-startup.js +9 -0
- package/dist/utils/server-startup.js.map +1 -0
- package/dist/utils/update-check.d.ts +13 -0
- package/dist/utils/update-check.d.ts.map +1 -0
- package/dist/utils/update-check.js +90 -0
- package/dist/utils/update-check.js.map +1 -0
- package/dist/web/assets/ArchivedCardPrototype-S9ifiasa.js +5 -0
- package/dist/web/assets/BannerGallery-B__rJV6F.js +1 -0
- package/dist/web/assets/BannerPrototype-DBKP9Uiu.js +52 -0
- package/dist/web/assets/CodeHikeExperiment-B8jjWAFy.js +15 -0
- package/dist/web/assets/ContextTooltipVariations-DzklAFam.js +1 -0
- package/dist/web/assets/FontShowcasePrototype-KIMEWeP2.js +13 -0
- package/dist/web/assets/GeometricGallery-DddlWhHK.js +1 -0
- package/dist/web/assets/HistoryWalkthroughPrototype-DeniRRdw.js +18 -0
- package/dist/web/assets/InlineWalkthroughPrototype-Csd5r_Hk.js +1 -0
- package/dist/web/assets/MarkButtonPrototype-CxhxE0RP.js +1 -0
- package/dist/web/assets/MenuStylesPrototype-D7neA6YM.js +1 -0
- package/dist/web/assets/MomentCardVariations-2GT7GyFn.js +1 -0
- package/dist/web/assets/MomentHeaderVariations-DhGEw4XC.js +1 -0
- package/dist/web/assets/NarrativeWalkthroughDemo-B5C566fu.js +389 -0
- package/dist/web/assets/OutcomeVariations-BrZfsVcs.js +1 -0
- package/dist/web/assets/PermissionPatternPickerPrototype-CBOhe2Me.js +1 -0
- package/dist/web/assets/PermissionPrototype-BcF-a5an.js +1 -0
- package/dist/web/assets/PipelineGallery-BJhyM0rx.js +1 -0
- package/dist/web/assets/ScopeHeaderPrototype-GD1HNfaO.js +1 -0
- package/dist/web/assets/ScopeHeaderStylesPrototype-aa4uNJJ1.js +1 -0
- package/dist/web/assets/ScrollycodingPrototype-CKW1bf72.js +70 -0
- package/dist/web/assets/SectionHeaderVariations-DM8vUwfj.js +1 -0
- package/dist/web/assets/SemanticGallery-CtQEo7St.js +1 -0
- package/dist/web/assets/SessionCardPrototype-CgHCIMHe.js +1 -0
- package/dist/web/assets/SessionSidebarVariations-DMQL3Azj.js +3 -0
- package/dist/web/assets/SessionStartPrototype-Cwsv01Rr.js +1 -0
- package/dist/web/assets/SmartMenuPrototype-Br37Qbs_.js +1 -0
- package/dist/web/assets/StyleGallery-rZgrploB.js +1 -0
- package/dist/web/assets/TimelineCardPrototype-lzPc5mhe.js +19 -0
- package/dist/web/assets/ToolbarPrototype-Dm4BNZra.js +1 -0
- package/dist/web/assets/TooltipExperiment-Dy8QzTIP.js +13 -0
- package/dist/web/assets/WalkthroughCTAPrototype-uHoovujd.js +1 -0
- package/dist/web/assets/WalkthroughHeaderVariations-Do7Di1g1.js +1 -0
- package/dist/web/assets/WalkthroughShowcase-sGmRoPoM.js +112 -0
- package/dist/web/assets/arrow-right-D46Nx1mC.js +1 -0
- package/dist/web/assets/brain-BXIZKtOZ.js +1 -0
- package/dist/web/assets/grid-3x3-Cb81B62m.js +1 -0
- package/dist/web/assets/main-B1fyog77.js +321 -0
- package/dist/web/assets/main-C2PK2Klg.css +1 -0
- package/dist/web/assets/semantic-variations-Bd-W7ea2.js +1 -0
- package/dist/web/assets/target-Cf92wDTW.js +1 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/favicon.svg +22 -0
- package/dist/web/icon-192x192.png +0 -0
- package/dist/web/icon-512x512.png +0 -0
- package/dist/web/index.html +45 -0
- package/dist/web/manifest.json +61 -0
- package/package.json +192 -0
- package/scripts/postinstall.js +60 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PermissionEventLog - Structured event logging for permission flow observability.
|
|
3
|
+
*
|
|
4
|
+
* This provides a clear, queryable log of all permission system decisions:
|
|
5
|
+
* - Permission requests from MCP server
|
|
6
|
+
* - Pattern matching decisions (allowed/denied)
|
|
7
|
+
* - Pattern suggestions (LLM vs heuristic)
|
|
8
|
+
* - Allowlist modifications
|
|
9
|
+
*
|
|
10
|
+
* The log is designed for:
|
|
11
|
+
* 1. Debugging: "Why was this tool auto-approved?" / "What pattern matched?"
|
|
12
|
+
* 2. Monitoring: "How many permissions are being requested?"
|
|
13
|
+
* 3. Pattern analysis: "What patterns would reduce permission prompts?"
|
|
14
|
+
*/
|
|
15
|
+
import { createLogger } from './infrastructure/logger.js';
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Event Log Service
|
|
18
|
+
// ============================================================================
|
|
19
|
+
export class PermissionEventLog {
|
|
20
|
+
logger;
|
|
21
|
+
events = [];
|
|
22
|
+
eventId = 0;
|
|
23
|
+
maxEvents = 500; // Ring buffer size
|
|
24
|
+
constructor() {
|
|
25
|
+
this.logger = createLogger('PermissionEventLog');
|
|
26
|
+
}
|
|
27
|
+
// ========== Logging Methods ==========
|
|
28
|
+
/**
|
|
29
|
+
* Log a permission request from MCP server
|
|
30
|
+
*/
|
|
31
|
+
request(params) {
|
|
32
|
+
this.addEvent({
|
|
33
|
+
eventType: 'request',
|
|
34
|
+
toolName: params.toolName,
|
|
35
|
+
toolInput: params.toolInput,
|
|
36
|
+
streamingId: params.streamingId,
|
|
37
|
+
permissionRequestId: params.permissionRequestId,
|
|
38
|
+
});
|
|
39
|
+
this.logger.info('Permission request', {
|
|
40
|
+
tool: params.toolName,
|
|
41
|
+
streamingId: params.streamingId?.slice(0, 8),
|
|
42
|
+
requestId: params.permissionRequestId.slice(0, 8),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Log auto-approval by pattern match
|
|
47
|
+
*/
|
|
48
|
+
autoApproved(params) {
|
|
49
|
+
this.addEvent({
|
|
50
|
+
eventType: 'auto_approved',
|
|
51
|
+
toolName: params.toolName,
|
|
52
|
+
toolInput: params.toolInput,
|
|
53
|
+
streamingId: params.streamingId,
|
|
54
|
+
matchedPattern: params.matchedPattern,
|
|
55
|
+
patternSource: params.patternSource,
|
|
56
|
+
});
|
|
57
|
+
this.logger.info('Permission auto-approved', {
|
|
58
|
+
tool: params.toolName,
|
|
59
|
+
pattern: params.matchedPattern,
|
|
60
|
+
source: params.patternSource,
|
|
61
|
+
streamingId: params.streamingId?.slice(0, 8),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Log pattern suggestions
|
|
66
|
+
*/
|
|
67
|
+
patternSuggest(params) {
|
|
68
|
+
this.addEvent({
|
|
69
|
+
eventType: 'pattern_suggest',
|
|
70
|
+
toolName: params.toolName,
|
|
71
|
+
toolInput: params.toolInput,
|
|
72
|
+
suggestedPatterns: params.suggestedPatterns,
|
|
73
|
+
suggestionSource: params.suggestionSource,
|
|
74
|
+
durationMs: params.durationMs,
|
|
75
|
+
});
|
|
76
|
+
this.logger.debug('Pattern suggestions generated', {
|
|
77
|
+
tool: params.toolName,
|
|
78
|
+
patterns: params.suggestedPatterns,
|
|
79
|
+
source: params.suggestionSource,
|
|
80
|
+
durationMs: params.durationMs,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Log user decision
|
|
85
|
+
*/
|
|
86
|
+
decision(params) {
|
|
87
|
+
this.addEvent({
|
|
88
|
+
eventType: params.decision === 'approve' ? 'approved' : 'denied',
|
|
89
|
+
toolName: params.toolName,
|
|
90
|
+
permissionRequestId: params.permissionRequestId,
|
|
91
|
+
decision: params.decision,
|
|
92
|
+
denyReason: params.denyReason,
|
|
93
|
+
streamingId: params.streamingId,
|
|
94
|
+
});
|
|
95
|
+
this.logger.info('Permission decision', {
|
|
96
|
+
tool: params.toolName,
|
|
97
|
+
decision: params.decision,
|
|
98
|
+
requestId: params.permissionRequestId.slice(0, 8),
|
|
99
|
+
streamingId: params.streamingId?.slice(0, 8),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Log pattern added to allowlist
|
|
104
|
+
*/
|
|
105
|
+
allowlistAdd(params) {
|
|
106
|
+
this.addEvent({
|
|
107
|
+
eventType: 'allowlist_add',
|
|
108
|
+
toolName: '', // Not applicable for allowlist add
|
|
109
|
+
addedPattern: params.pattern,
|
|
110
|
+
allowlistScope: params.scope,
|
|
111
|
+
streamingId: params.streamingId,
|
|
112
|
+
});
|
|
113
|
+
this.logger.info('Pattern added to allowlist', {
|
|
114
|
+
pattern: params.pattern,
|
|
115
|
+
scope: params.scope,
|
|
116
|
+
streamingId: params.streamingId?.slice(0, 8),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// ========== Internal ==========
|
|
120
|
+
addEvent(params) {
|
|
121
|
+
const event = {
|
|
122
|
+
id: ++this.eventId,
|
|
123
|
+
timestamp: Date.now(),
|
|
124
|
+
...params,
|
|
125
|
+
};
|
|
126
|
+
// Ring buffer
|
|
127
|
+
if (this.events.length >= this.maxEvents) {
|
|
128
|
+
this.events.shift();
|
|
129
|
+
}
|
|
130
|
+
this.events.push(event);
|
|
131
|
+
}
|
|
132
|
+
// ========== Query Methods ==========
|
|
133
|
+
/**
|
|
134
|
+
* Get all events (most recent first)
|
|
135
|
+
*/
|
|
136
|
+
getAll(limit = 100) {
|
|
137
|
+
return this.events.slice(-limit).reverse();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get events for a specific streaming session
|
|
141
|
+
*/
|
|
142
|
+
getForSession(streamingId, limit = 50) {
|
|
143
|
+
return this.events
|
|
144
|
+
.filter(e => e.streamingId === streamingId)
|
|
145
|
+
.slice(-limit)
|
|
146
|
+
.reverse();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get events for a specific tool
|
|
150
|
+
*/
|
|
151
|
+
getForTool(toolName, limit = 50) {
|
|
152
|
+
return this.events
|
|
153
|
+
.filter(e => e.toolName === toolName)
|
|
154
|
+
.slice(-limit)
|
|
155
|
+
.reverse();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get auto-approved events (useful for understanding pattern coverage)
|
|
159
|
+
*/
|
|
160
|
+
getAutoApproved(limit = 50) {
|
|
161
|
+
return this.events
|
|
162
|
+
.filter(e => e.eventType === 'auto_approved')
|
|
163
|
+
.slice(-limit)
|
|
164
|
+
.reverse();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get pending/denied events (useful for identifying missing patterns)
|
|
168
|
+
*/
|
|
169
|
+
getManualDecisions(limit = 50) {
|
|
170
|
+
return this.events
|
|
171
|
+
.filter(e => e.eventType === 'approved' || e.eventType === 'denied')
|
|
172
|
+
.slice(-limit)
|
|
173
|
+
.reverse();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get pattern match statistics
|
|
177
|
+
*/
|
|
178
|
+
getPatternStats() {
|
|
179
|
+
const requests = this.events.filter(e => e.eventType === 'request').length;
|
|
180
|
+
const autoApproved = this.events.filter(e => e.eventType === 'auto_approved').length;
|
|
181
|
+
const approved = this.events.filter(e => e.eventType === 'approved').length;
|
|
182
|
+
const denied = this.events.filter(e => e.eventType === 'denied').length;
|
|
183
|
+
// Count pattern matches
|
|
184
|
+
const patternCounts = new Map();
|
|
185
|
+
for (const event of this.events) {
|
|
186
|
+
if (event.eventType === 'auto_approved' && event.matchedPattern) {
|
|
187
|
+
patternCounts.set(event.matchedPattern, (patternCounts.get(event.matchedPattern) || 0) + 1);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const topPatterns = Array.from(patternCounts.entries())
|
|
191
|
+
.sort((a, b) => b[1] - a[1])
|
|
192
|
+
.slice(0, 10)
|
|
193
|
+
.map(([pattern, count]) => ({ pattern, count }));
|
|
194
|
+
const total = autoApproved + approved + denied;
|
|
195
|
+
return {
|
|
196
|
+
totalRequests: requests,
|
|
197
|
+
autoApproved,
|
|
198
|
+
manualApproved: approved,
|
|
199
|
+
denied,
|
|
200
|
+
patternHitRate: total > 0 ? autoApproved / total : 0,
|
|
201
|
+
topMatchedPatterns: topPatterns,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get a human-readable timeline
|
|
206
|
+
*/
|
|
207
|
+
getTimeline(limit = 30) {
|
|
208
|
+
const events = this.getAll(limit);
|
|
209
|
+
return events.map(e => {
|
|
210
|
+
const time = new Date(e.timestamp).toISOString().slice(11, 19);
|
|
211
|
+
const duration = e.durationMs ? ` (${e.durationMs}ms)` : '';
|
|
212
|
+
switch (e.eventType) {
|
|
213
|
+
case 'request':
|
|
214
|
+
return `${time} 📋 Request: ${e.toolName}`;
|
|
215
|
+
case 'auto_approved':
|
|
216
|
+
return `${time} ✅ AutoApproved: ${e.toolName} [${e.matchedPattern}] (${e.patternSource})`;
|
|
217
|
+
case 'approved':
|
|
218
|
+
return `${time} 👍 Approved: ${e.toolName}`;
|
|
219
|
+
case 'denied':
|
|
220
|
+
return `${time} 👎 Denied: ${e.toolName}${e.denyReason ? ` - ${e.denyReason}` : ''}`;
|
|
221
|
+
case 'pattern_suggest':
|
|
222
|
+
return `${time} 💡 Suggest: ${e.toolName} → [${e.suggestedPatterns?.join(', ')}]${duration}`;
|
|
223
|
+
case 'allowlist_add':
|
|
224
|
+
return `${time} ➕ Allowlist: ${e.addedPattern} (${e.allowlistScope})`;
|
|
225
|
+
default:
|
|
226
|
+
return `${time} ❓ ${e.eventType}: ${e.toolName}`;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Clear all events (for testing)
|
|
232
|
+
*/
|
|
233
|
+
clear() {
|
|
234
|
+
this.events = [];
|
|
235
|
+
this.eventId = 0;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// ============================================================================
|
|
239
|
+
// Singleton
|
|
240
|
+
// ============================================================================
|
|
241
|
+
let instance = null;
|
|
242
|
+
export function getPermissionEventLog() {
|
|
243
|
+
if (!instance) {
|
|
244
|
+
instance = new PermissionEventLog();
|
|
245
|
+
}
|
|
246
|
+
return instance;
|
|
247
|
+
}
|
|
248
|
+
// For testing
|
|
249
|
+
export function resetPermissionEventLog() {
|
|
250
|
+
instance = null;
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=permission-event-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-event-log.js","sourceRoot":"","sources":["../../src/services/permission-event-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern-based permission matching for granular tool control.
|
|
3
|
+
*
|
|
4
|
+
* Supports Claude Code-style patterns:
|
|
5
|
+
* - Bash - all bash commands
|
|
6
|
+
* - Bash(npm *) - bash commands starting with "npm "
|
|
7
|
+
* - Bash(git commit *) - bash commands starting with "git commit "
|
|
8
|
+
* - Write(src/**) - write to any file under src/
|
|
9
|
+
* - Write(*.ts) - write to any .ts file
|
|
10
|
+
* - Edit(src/**.tsx) - edit .tsx files under src/
|
|
11
|
+
* - Read - all read operations
|
|
12
|
+
*
|
|
13
|
+
* Pattern syntax:
|
|
14
|
+
* - * matches any characters except path separators
|
|
15
|
+
* - ** matches any characters including path separators
|
|
16
|
+
* - Patterns without parentheses match the entire tool (e.g., Bash matches all bash)
|
|
17
|
+
*/
|
|
18
|
+
export interface PermissionPattern {
|
|
19
|
+
tool: string;
|
|
20
|
+
pattern: string | null;
|
|
21
|
+
raw: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parse a permission pattern string into its components.
|
|
25
|
+
*
|
|
26
|
+
* Examples:
|
|
27
|
+
* - "Bash" -> { tool: "Bash", pattern: null, raw: "Bash" }
|
|
28
|
+
* - "Bash(npm *)" -> { tool: "Bash", pattern: "npm *", raw: "Bash(npm *)" }
|
|
29
|
+
* - "Write(src/**)" -> { tool: "Write", pattern: "src/**", raw: "Write(src/**)" }
|
|
30
|
+
*/
|
|
31
|
+
export declare function parsePattern(patternStr: string): PermissionPattern;
|
|
32
|
+
/**
|
|
33
|
+
* Extract the matchable value from a tool input based on tool type.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getMatchableValue(toolName: string, input: Record<string, unknown>): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a tool invocation matches a permission pattern.
|
|
38
|
+
*
|
|
39
|
+
* @param pattern - The parsed permission pattern
|
|
40
|
+
* @param toolName - The tool being invoked (e.g., "Bash")
|
|
41
|
+
* @param input - The tool input parameters
|
|
42
|
+
* @returns true if the pattern allows this invocation
|
|
43
|
+
*/
|
|
44
|
+
export declare function matchesPermission(pattern: PermissionPattern, toolName: string, input: Record<string, unknown>): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a tool invocation is allowed by any pattern in a list.
|
|
47
|
+
*
|
|
48
|
+
* @param patterns - List of permission pattern strings
|
|
49
|
+
* @param toolName - The tool being invoked
|
|
50
|
+
* @param input - The tool input parameters
|
|
51
|
+
* @returns The matching pattern if allowed, null otherwise
|
|
52
|
+
*/
|
|
53
|
+
export declare function isAllowedByPatterns(patterns: string[], toolName: string, input: Record<string, unknown>): string | null;
|
|
54
|
+
/**
|
|
55
|
+
* Generate suggested patterns for a given tool invocation.
|
|
56
|
+
* Returns patterns from most specific to least specific.
|
|
57
|
+
*
|
|
58
|
+
* For bash commands, handles complex multi-part commands:
|
|
59
|
+
* - Extracts primary command before pipes (|) and chains (&&, ;)
|
|
60
|
+
* - Recognizes common CLI tools and their subcommands
|
|
61
|
+
* - Generates meaningful intermediate patterns
|
|
62
|
+
*
|
|
63
|
+
* Examples for Bash(fd -e tsx . ~/cui-custom | head -30):
|
|
64
|
+
* - "Bash(fd -e tsx . ~/cui-custom | head -30)" - exact command
|
|
65
|
+
* - "Bash(fd *)" - any fd command
|
|
66
|
+
* - "Bash" - all bash
|
|
67
|
+
*
|
|
68
|
+
* Examples for Bash(git commit -m "message"):
|
|
69
|
+
* - "Bash(git commit -m "message")" - exact command
|
|
70
|
+
* - "Bash(git commit *)" - any git commit
|
|
71
|
+
* - "Bash(git *)" - any git command
|
|
72
|
+
* - "Bash" - all bash
|
|
73
|
+
*
|
|
74
|
+
* Examples for Write(src/components/Button.tsx):
|
|
75
|
+
* - "Write(src/components/Button.tsx)" - exact file
|
|
76
|
+
* - "Write(src/components/[star].tsx)" - any tsx in components
|
|
77
|
+
* - "Write(src/[starstar]/[star].tsx)" - any tsx under src
|
|
78
|
+
* - "Write([star].tsx)" - any tsx file
|
|
79
|
+
* - "Write" - all writes
|
|
80
|
+
*/
|
|
81
|
+
export declare function suggestPatterns(toolName: string, input: Record<string, unknown>): string[];
|
|
82
|
+
//# sourceMappingURL=permission-pattern-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-pattern-matcher.d.ts","sourceRoot":"","sources":["../../src/services/permission-pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAclE;AAkCD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAUjG;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAsBT;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,GAAG,IAAI,CAQf;AA4FD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,EAAE,CAuEV"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern-based permission matching for granular tool control.
|
|
3
|
+
*
|
|
4
|
+
* Supports Claude Code-style patterns:
|
|
5
|
+
* - Bash - all bash commands
|
|
6
|
+
* - Bash(npm *) - bash commands starting with "npm "
|
|
7
|
+
* - Bash(git commit *) - bash commands starting with "git commit "
|
|
8
|
+
* - Write(src/**) - write to any file under src/
|
|
9
|
+
* - Write(*.ts) - write to any .ts file
|
|
10
|
+
* - Edit(src/**.tsx) - edit .tsx files under src/
|
|
11
|
+
* - Read - all read operations
|
|
12
|
+
*
|
|
13
|
+
* Pattern syntax:
|
|
14
|
+
* - * matches any characters except path separators
|
|
15
|
+
* - ** matches any characters including path separators
|
|
16
|
+
* - Patterns without parentheses match the entire tool (e.g., Bash matches all bash)
|
|
17
|
+
*/
|
|
18
|
+
import { minimatch } from 'minimatch';
|
|
19
|
+
// Tool input field mappings - which field to match against for each tool
|
|
20
|
+
const TOOL_MATCH_FIELDS = {
|
|
21
|
+
Bash: 'command',
|
|
22
|
+
Write: 'file_path',
|
|
23
|
+
Read: 'file_path',
|
|
24
|
+
Edit: 'file_path',
|
|
25
|
+
Glob: 'pattern',
|
|
26
|
+
Grep: 'pattern',
|
|
27
|
+
// MCP tools use the full tool name as the pattern
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Parse a permission pattern string into its components.
|
|
31
|
+
*
|
|
32
|
+
* Examples:
|
|
33
|
+
* - "Bash" -> { tool: "Bash", pattern: null, raw: "Bash" }
|
|
34
|
+
* - "Bash(npm *)" -> { tool: "Bash", pattern: "npm *", raw: "Bash(npm *)" }
|
|
35
|
+
* - "Write(src/**)" -> { tool: "Write", pattern: "src/**", raw: "Write(src/**)" }
|
|
36
|
+
*/
|
|
37
|
+
export function parsePattern(patternStr) {
|
|
38
|
+
const match = patternStr.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:\((.+)\))?$/);
|
|
39
|
+
if (!match) {
|
|
40
|
+
// Invalid pattern, treat as literal tool name
|
|
41
|
+
return { tool: patternStr, pattern: null, raw: patternStr };
|
|
42
|
+
}
|
|
43
|
+
const [, tool, pattern] = match;
|
|
44
|
+
return {
|
|
45
|
+
tool,
|
|
46
|
+
pattern: pattern || null,
|
|
47
|
+
raw: patternStr,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Convert a Claude Code-style pattern to a regex or minimatch pattern.
|
|
52
|
+
*
|
|
53
|
+
* For Bash commands:
|
|
54
|
+
* - "npm *" matches "npm install", "npm run test", etc.
|
|
55
|
+
* - "*" is converted to match any non-newline characters
|
|
56
|
+
*
|
|
57
|
+
* For file paths:
|
|
58
|
+
* - "src/**" matches any file under src/
|
|
59
|
+
* - "*.ts" matches any .ts file
|
|
60
|
+
* - Uses minimatch for glob-style matching
|
|
61
|
+
*/
|
|
62
|
+
function matchesPattern(value, pattern, isPath) {
|
|
63
|
+
if (isPath) {
|
|
64
|
+
// Use minimatch for file path patterns (supports ** and *)
|
|
65
|
+
return minimatch(value, pattern, {
|
|
66
|
+
matchBase: true, // Match basename if pattern has no slashes
|
|
67
|
+
dot: true, // Match dotfiles
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// For command matching, convert simple wildcards to regex
|
|
72
|
+
// "npm *" should match "npm install" but not "npm"
|
|
73
|
+
// "*" matches any characters
|
|
74
|
+
const regexPattern = pattern
|
|
75
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except *
|
|
76
|
+
.replace(/\*/g, '.*'); // Convert * to .*
|
|
77
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
78
|
+
return regex.test(value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Extract the matchable value from a tool input based on tool type.
|
|
83
|
+
*/
|
|
84
|
+
export function getMatchableValue(toolName, input) {
|
|
85
|
+
const field = TOOL_MATCH_FIELDS[toolName];
|
|
86
|
+
if (!field) {
|
|
87
|
+
// Unknown tool or MCP tool - no pattern matching support
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const value = input[field];
|
|
91
|
+
return typeof value === 'string' ? value : null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if a tool invocation matches a permission pattern.
|
|
95
|
+
*
|
|
96
|
+
* @param pattern - The parsed permission pattern
|
|
97
|
+
* @param toolName - The tool being invoked (e.g., "Bash")
|
|
98
|
+
* @param input - The tool input parameters
|
|
99
|
+
* @returns true if the pattern allows this invocation
|
|
100
|
+
*/
|
|
101
|
+
export function matchesPermission(pattern, toolName, input) {
|
|
102
|
+
// Tool name must match
|
|
103
|
+
if (pattern.tool !== toolName) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// If no pattern specified, match all invocations of this tool
|
|
107
|
+
if (!pattern.pattern) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
// Get the value to match against
|
|
111
|
+
const value = getMatchableValue(toolName, input);
|
|
112
|
+
if (value === null) {
|
|
113
|
+
// Can't extract matchable value - no match
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
// Determine if this is a path-based tool
|
|
117
|
+
const isPath = ['Write', 'Read', 'Edit', 'Glob'].includes(toolName);
|
|
118
|
+
return matchesPattern(value, pattern.pattern, isPath);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if a tool invocation is allowed by any pattern in a list.
|
|
122
|
+
*
|
|
123
|
+
* @param patterns - List of permission pattern strings
|
|
124
|
+
* @param toolName - The tool being invoked
|
|
125
|
+
* @param input - The tool input parameters
|
|
126
|
+
* @returns The matching pattern if allowed, null otherwise
|
|
127
|
+
*/
|
|
128
|
+
export function isAllowedByPatterns(patterns, toolName, input) {
|
|
129
|
+
for (const patternStr of patterns) {
|
|
130
|
+
const pattern = parsePattern(patternStr);
|
|
131
|
+
if (matchesPermission(pattern, toolName, input)) {
|
|
132
|
+
return patternStr;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Extract the primary command from a complex bash command.
|
|
139
|
+
* Handles pipes, chains (&&, ;), and redirections.
|
|
140
|
+
*
|
|
141
|
+
* Examples:
|
|
142
|
+
* - "fd -e tsx . ~/cui-custom | head -30" -> "fd -e tsx . ~/cui-custom"
|
|
143
|
+
* - "git add . && git commit -m 'msg'" -> "git add ."
|
|
144
|
+
* - "echo 'test' > file.txt && cat file.txt" -> "echo 'test'"
|
|
145
|
+
*/
|
|
146
|
+
function extractPrimaryCommand(command) {
|
|
147
|
+
// Remove leading/trailing whitespace
|
|
148
|
+
let cmd = command.trim();
|
|
149
|
+
// Find the first pipe or chain operator (not inside quotes)
|
|
150
|
+
let inSingleQuote = false;
|
|
151
|
+
let inDoubleQuote = false;
|
|
152
|
+
let cutIndex = -1;
|
|
153
|
+
for (let i = 0; i < cmd.length; i++) {
|
|
154
|
+
const char = cmd[i];
|
|
155
|
+
const prevChar = i > 0 ? cmd[i - 1] : '';
|
|
156
|
+
if (char === "'" && prevChar !== '\\' && !inDoubleQuote) {
|
|
157
|
+
inSingleQuote = !inSingleQuote;
|
|
158
|
+
}
|
|
159
|
+
else if (char === '"' && prevChar !== '\\' && !inSingleQuote) {
|
|
160
|
+
inDoubleQuote = !inDoubleQuote;
|
|
161
|
+
}
|
|
162
|
+
else if (!inSingleQuote && !inDoubleQuote) {
|
|
163
|
+
// Check for pipe or chain operators
|
|
164
|
+
if (char === '|' || char === ';') {
|
|
165
|
+
cutIndex = i;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
if (char === '&' && cmd[i + 1] === '&') {
|
|
169
|
+
cutIndex = i;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (cutIndex > 0) {
|
|
175
|
+
cmd = cmd.substring(0, cutIndex).trim();
|
|
176
|
+
}
|
|
177
|
+
// Remove output redirections from end (> file, >> file, 2>&1, etc.)
|
|
178
|
+
// Be careful to preserve redirections that are part of the command meaning
|
|
179
|
+
cmd = cmd.replace(/\s*(?:2>&1|>&2|>\s*\S+|>>\s*\S+)\s*$/, '').trim();
|
|
180
|
+
return cmd;
|
|
181
|
+
}
|
|
182
|
+
function analyzeCommand(command) {
|
|
183
|
+
const primary = extractPrimaryCommand(command);
|
|
184
|
+
const parts = primary.split(/\s+/).filter(p => p.length > 0);
|
|
185
|
+
if (parts.length === 0) {
|
|
186
|
+
return { baseCommand: '', subCommand: null, fullCommand: primary };
|
|
187
|
+
}
|
|
188
|
+
const baseCommand = parts[0];
|
|
189
|
+
// Commands that have meaningful subcommands
|
|
190
|
+
const commandsWithSubcommands = new Set([
|
|
191
|
+
'git', 'npm', 'pnpm', 'yarn', 'docker', 'kubectl', 'systemctl',
|
|
192
|
+
'cargo', 'go', 'pip', 'python', 'node', 'deno', 'bun',
|
|
193
|
+
'gh', 'aws', 'gcloud', 'az', 'terraform', 'make',
|
|
194
|
+
]);
|
|
195
|
+
// Check if second part is a subcommand (not a flag)
|
|
196
|
+
let subCommand = null;
|
|
197
|
+
if (parts.length > 1 && commandsWithSubcommands.has(baseCommand)) {
|
|
198
|
+
const second = parts[1];
|
|
199
|
+
// Subcommands don't start with - and aren't paths
|
|
200
|
+
if (!second.startsWith('-') && !second.includes('/')) {
|
|
201
|
+
subCommand = second;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return { baseCommand, subCommand, fullCommand: primary };
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Generate suggested patterns for a given tool invocation.
|
|
208
|
+
* Returns patterns from most specific to least specific.
|
|
209
|
+
*
|
|
210
|
+
* For bash commands, handles complex multi-part commands:
|
|
211
|
+
* - Extracts primary command before pipes (|) and chains (&&, ;)
|
|
212
|
+
* - Recognizes common CLI tools and their subcommands
|
|
213
|
+
* - Generates meaningful intermediate patterns
|
|
214
|
+
*
|
|
215
|
+
* Examples for Bash(fd -e tsx . ~/cui-custom | head -30):
|
|
216
|
+
* - "Bash(fd -e tsx . ~/cui-custom | head -30)" - exact command
|
|
217
|
+
* - "Bash(fd *)" - any fd command
|
|
218
|
+
* - "Bash" - all bash
|
|
219
|
+
*
|
|
220
|
+
* Examples for Bash(git commit -m "message"):
|
|
221
|
+
* - "Bash(git commit -m "message")" - exact command
|
|
222
|
+
* - "Bash(git commit *)" - any git commit
|
|
223
|
+
* - "Bash(git *)" - any git command
|
|
224
|
+
* - "Bash" - all bash
|
|
225
|
+
*
|
|
226
|
+
* Examples for Write(src/components/Button.tsx):
|
|
227
|
+
* - "Write(src/components/Button.tsx)" - exact file
|
|
228
|
+
* - "Write(src/components/[star].tsx)" - any tsx in components
|
|
229
|
+
* - "Write(src/[starstar]/[star].tsx)" - any tsx under src
|
|
230
|
+
* - "Write([star].tsx)" - any tsx file
|
|
231
|
+
* - "Write" - all writes
|
|
232
|
+
*/
|
|
233
|
+
export function suggestPatterns(toolName, input) {
|
|
234
|
+
const suggestions = [];
|
|
235
|
+
const value = getMatchableValue(toolName, input);
|
|
236
|
+
if (!value) {
|
|
237
|
+
// No matchable value - just return tool-level permission
|
|
238
|
+
return [toolName];
|
|
239
|
+
}
|
|
240
|
+
if (toolName === 'Bash') {
|
|
241
|
+
const { baseCommand, subCommand, fullCommand } = analyzeCommand(value);
|
|
242
|
+
// 1. Exact command (safest) - always include full original
|
|
243
|
+
suggestions.push(`Bash(${value})`);
|
|
244
|
+
// 2. If command was extracted from pipes/chains, offer the primary command
|
|
245
|
+
if (fullCommand !== value && fullCommand.length > 0) {
|
|
246
|
+
suggestions.push(`Bash(${fullCommand})`);
|
|
247
|
+
}
|
|
248
|
+
// 3. If there's a subcommand, offer "base subcommand *" pattern
|
|
249
|
+
if (subCommand) {
|
|
250
|
+
suggestions.push(`Bash(${baseCommand} ${subCommand} *)`);
|
|
251
|
+
}
|
|
252
|
+
// 4. Offer "base *" pattern for the base command
|
|
253
|
+
if (baseCommand) {
|
|
254
|
+
suggestions.push(`Bash(${baseCommand} *)`);
|
|
255
|
+
}
|
|
256
|
+
// 5. All bash commands (broadest)
|
|
257
|
+
suggestions.push(toolName);
|
|
258
|
+
}
|
|
259
|
+
else if (['Write', 'Read', 'Edit'].includes(toolName)) {
|
|
260
|
+
// For file operations, suggest path patterns from specific to broad
|
|
261
|
+
const filePath = value;
|
|
262
|
+
const fileName = filePath.split('/').pop() || filePath;
|
|
263
|
+
const ext = fileName.includes('.') ? fileName.split('.').pop() : null;
|
|
264
|
+
const dirPath = filePath.includes('/') ? filePath.substring(0, filePath.lastIndexOf('/')) : null;
|
|
265
|
+
// 1. Exact file (safest)
|
|
266
|
+
suggestions.push(`${toolName}(${filePath})`);
|
|
267
|
+
// 2. Same directory, same extension (e.g., src/components/*.tsx)
|
|
268
|
+
if (dirPath && ext) {
|
|
269
|
+
suggestions.push(`${toolName}(${dirPath}/*.${ext})`);
|
|
270
|
+
}
|
|
271
|
+
// 3. Recursive from directory with same extension (e.g., src/**/*.tsx)
|
|
272
|
+
if (dirPath && ext) {
|
|
273
|
+
// Find the top-level directory for recursive pattern
|
|
274
|
+
const topDir = dirPath.split('/')[0];
|
|
275
|
+
if (topDir && topDir !== dirPath) {
|
|
276
|
+
suggestions.push(`${toolName}(${topDir}/**/*.${ext})`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// 4. Any file with this extension anywhere (e.g., *.tsx)
|
|
280
|
+
if (ext) {
|
|
281
|
+
suggestions.push(`${toolName}(*.${ext})`);
|
|
282
|
+
}
|
|
283
|
+
// 5. All operations of this tool (broadest)
|
|
284
|
+
suggestions.push(toolName);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// Unknown tool type - just exact and all
|
|
288
|
+
suggestions.push(`${toolName}(${value})`);
|
|
289
|
+
suggestions.push(toolName);
|
|
290
|
+
}
|
|
291
|
+
// Remove duplicates while preserving order
|
|
292
|
+
return [...new Set(suggestions)];
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=permission-pattern-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-pattern-matcher.js","sourceRoot":"","sources":["../../src/services/permission-pattern-matcher.ts"],"names":[],"mappings":"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"}
|