@trenchwork/coder 1.3.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 +16 -0
- package/README.md +173 -0
- package/agents/trenchwork-code.rules.json +199 -0
- package/dist/bin/deepseek.d.ts +3 -0
- package/dist/bin/deepseek.d.ts.map +1 -0
- package/dist/bin/deepseek.js +23 -0
- package/dist/bin/deepseek.js.map +1 -0
- package/dist/capabilities/baseCapability.d.ts +72 -0
- package/dist/capabilities/baseCapability.d.ts.map +1 -0
- package/dist/capabilities/baseCapability.js +183 -0
- package/dist/capabilities/baseCapability.js.map +1 -0
- package/dist/capabilities/bashCapability.d.ts +13 -0
- package/dist/capabilities/bashCapability.d.ts.map +1 -0
- package/dist/capabilities/bashCapability.js +24 -0
- package/dist/capabilities/bashCapability.js.map +1 -0
- package/dist/capabilities/editCapability.d.ts +17 -0
- package/dist/capabilities/editCapability.d.ts.map +1 -0
- package/dist/capabilities/editCapability.js +27 -0
- package/dist/capabilities/editCapability.js.map +1 -0
- package/dist/capabilities/enhancedGitCapability.d.ts +7 -0
- package/dist/capabilities/enhancedGitCapability.d.ts.map +1 -0
- package/dist/capabilities/enhancedGitCapability.js +220 -0
- package/dist/capabilities/enhancedGitCapability.js.map +1 -0
- package/dist/capabilities/filesystemCapability.d.ts +13 -0
- package/dist/capabilities/filesystemCapability.d.ts.map +1 -0
- package/dist/capabilities/filesystemCapability.js +24 -0
- package/dist/capabilities/filesystemCapability.js.map +1 -0
- package/dist/capabilities/gitHistoryCapability.d.ts +6 -0
- package/dist/capabilities/gitHistoryCapability.d.ts.map +1 -0
- package/dist/capabilities/gitHistoryCapability.js +184 -0
- package/dist/capabilities/gitHistoryCapability.js.map +1 -0
- package/dist/capabilities/hitlCapability.d.ts +18 -0
- package/dist/capabilities/hitlCapability.d.ts.map +1 -0
- package/dist/capabilities/hitlCapability.js +29 -0
- package/dist/capabilities/hitlCapability.js.map +1 -0
- package/dist/capabilities/index.d.ts +11 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +16 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/memoryCapability.d.ts +10 -0
- package/dist/capabilities/memoryCapability.d.ts.map +1 -0
- package/dist/capabilities/memoryCapability.js +22 -0
- package/dist/capabilities/memoryCapability.js.map +1 -0
- package/dist/capabilities/notebookCapability.d.ts +6 -0
- package/dist/capabilities/notebookCapability.d.ts.map +1 -0
- package/dist/capabilities/notebookCapability.js +17 -0
- package/dist/capabilities/notebookCapability.js.map +1 -0
- package/dist/capabilities/searchCapability.d.ts +19 -0
- package/dist/capabilities/searchCapability.d.ts.map +1 -0
- package/dist/capabilities/searchCapability.js +29 -0
- package/dist/capabilities/searchCapability.js.map +1 -0
- package/dist/capabilities/skillCapability.d.ts +6 -0
- package/dist/capabilities/skillCapability.d.ts.map +1 -0
- package/dist/capabilities/skillCapability.js +17 -0
- package/dist/capabilities/skillCapability.js.map +1 -0
- package/dist/capabilities/todoCapability.d.ts +11 -0
- package/dist/capabilities/todoCapability.d.ts.map +1 -0
- package/dist/capabilities/todoCapability.js +22 -0
- package/dist/capabilities/todoCapability.js.map +1 -0
- package/dist/capabilities/toolManifest.d.ts +3 -0
- package/dist/capabilities/toolManifest.d.ts.map +1 -0
- package/dist/capabilities/toolManifest.js +163 -0
- package/dist/capabilities/toolManifest.js.map +1 -0
- package/dist/capabilities/toolRegistry.d.ts +25 -0
- package/dist/capabilities/toolRegistry.d.ts.map +1 -0
- package/dist/capabilities/toolRegistry.js +150 -0
- package/dist/capabilities/toolRegistry.js.map +1 -0
- package/dist/capabilities/unifiedCodingCapability.d.ts +62 -0
- package/dist/capabilities/unifiedCodingCapability.d.ts.map +1 -0
- package/dist/capabilities/unifiedCodingCapability.js +790 -0
- package/dist/capabilities/unifiedCodingCapability.js.map +1 -0
- package/dist/capabilities/webCapability.d.ts +23 -0
- package/dist/capabilities/webCapability.d.ts.map +1 -0
- package/dist/capabilities/webCapability.js +33 -0
- package/dist/capabilities/webCapability.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +181 -0
- package/dist/config.js.map +1 -0
- package/dist/contracts/agent-profiles.schema.json +25 -0
- package/dist/contracts/agent-schemas.json +158 -0
- package/dist/contracts/models.schema.json +9 -0
- package/dist/contracts/module-schema.json +367 -0
- package/dist/contracts/schemas/agent-profile.schema.json +157 -0
- package/dist/contracts/schemas/agent-rules.schema.json +238 -0
- package/dist/contracts/schemas/agent-schemas.schema.json +528 -0
- package/dist/contracts/schemas/agent.schema.json +90 -0
- package/dist/contracts/schemas/tool-selection.schema.json +174 -0
- package/dist/contracts/tools.schema.json +42 -0
- package/dist/contracts/unified-schema.json +40 -0
- package/dist/contracts/v1/agent.d.ts +225 -0
- package/dist/contracts/v1/agent.d.ts.map +1 -0
- package/dist/contracts/v1/agent.js +8 -0
- package/dist/contracts/v1/agent.js.map +1 -0
- package/dist/contracts/v1/agentProfileManifest.d.ts +60 -0
- package/dist/contracts/v1/agentProfileManifest.d.ts.map +1 -0
- package/dist/contracts/v1/agentProfileManifest.js +9 -0
- package/dist/contracts/v1/agentProfileManifest.js.map +1 -0
- package/dist/contracts/v1/agentRules.d.ts +60 -0
- package/dist/contracts/v1/agentRules.d.ts.map +1 -0
- package/dist/contracts/v1/agentRules.js +10 -0
- package/dist/contracts/v1/agentRules.js.map +1 -0
- package/dist/contracts/v1/provider.d.ts +149 -0
- package/dist/contracts/v1/provider.d.ts.map +1 -0
- package/dist/contracts/v1/provider.js +7 -0
- package/dist/contracts/v1/provider.js.map +1 -0
- package/dist/contracts/v1/tool.d.ts +136 -0
- package/dist/contracts/v1/tool.d.ts.map +1 -0
- package/dist/contracts/v1/tool.js +7 -0
- package/dist/contracts/v1/tool.js.map +1 -0
- package/dist/contracts/v1/toolAccess.d.ts +43 -0
- package/dist/contracts/v1/toolAccess.d.ts.map +1 -0
- package/dist/contracts/v1/toolAccess.js +9 -0
- package/dist/contracts/v1/toolAccess.js.map +1 -0
- package/dist/core/adversarial.d.ts +38 -0
- package/dist/core/adversarial.d.ts.map +1 -0
- package/dist/core/adversarial.js +106 -0
- package/dist/core/adversarial.js.map +1 -0
- package/dist/core/adversarialCorrection.d.ts +22 -0
- package/dist/core/adversarialCorrection.d.ts.map +1 -0
- package/dist/core/adversarialCorrection.js +25 -0
- package/dist/core/adversarialCorrection.js.map +1 -0
- package/dist/core/agent.d.ts +331 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +1637 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/agentProfileManifest.d.ts +3 -0
- package/dist/core/agentProfileManifest.d.ts.map +1 -0
- package/dist/core/agentProfileManifest.js +188 -0
- package/dist/core/agentProfileManifest.js.map +1 -0
- package/dist/core/agentProfiles.d.ts +22 -0
- package/dist/core/agentProfiles.d.ts.map +1 -0
- package/dist/core/agentProfiles.js +35 -0
- package/dist/core/agentProfiles.js.map +1 -0
- package/dist/core/agentRegistry.d.ts +111 -0
- package/dist/core/agentRegistry.d.ts.map +1 -0
- package/dist/core/agentRegistry.js +229 -0
- package/dist/core/agentRegistry.js.map +1 -0
- package/dist/core/agentRulebook.d.ts +11 -0
- package/dist/core/agentRulebook.d.ts.map +1 -0
- package/dist/core/agentRulebook.js +136 -0
- package/dist/core/agentRulebook.js.map +1 -0
- package/dist/core/agentSchemaLoader.d.ts +131 -0
- package/dist/core/agentSchemaLoader.d.ts.map +1 -0
- package/dist/core/agentSchemaLoader.js +235 -0
- package/dist/core/agentSchemaLoader.js.map +1 -0
- package/dist/core/aiErrorFixer.d.ts +57 -0
- package/dist/core/aiErrorFixer.d.ts.map +1 -0
- package/dist/core/aiErrorFixer.js +214 -0
- package/dist/core/aiErrorFixer.js.map +1 -0
- package/dist/core/bashCommandGuidance.d.ts +16 -0
- package/dist/core/bashCommandGuidance.d.ts.map +1 -0
- package/dist/core/bashCommandGuidance.js +40 -0
- package/dist/core/bashCommandGuidance.js.map +1 -0
- package/dist/core/compactionNote.d.ts +13 -0
- package/dist/core/compactionNote.d.ts.map +1 -0
- package/dist/core/compactionNote.js +13 -0
- package/dist/core/compactionNote.js.map +1 -0
- package/dist/core/constants.d.ts +31 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +62 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/contextManager.d.ts +271 -0
- package/dist/core/contextManager.d.ts.map +1 -0
- package/dist/core/contextManager.js +1076 -0
- package/dist/core/contextManager.js.map +1 -0
- package/dist/core/contextUsage.d.ts +28 -0
- package/dist/core/contextUsage.d.ts.map +1 -0
- package/dist/core/contextUsage.js +62 -0
- package/dist/core/contextUsage.js.map +1 -0
- package/dist/core/contextWindow.d.ts +42 -0
- package/dist/core/contextWindow.d.ts.map +1 -0
- package/dist/core/contextWindow.js +127 -0
- package/dist/core/contextWindow.js.map +1 -0
- package/dist/core/customCommands.d.ts +19 -0
- package/dist/core/customCommands.d.ts.map +1 -0
- package/dist/core/customCommands.js +85 -0
- package/dist/core/customCommands.js.map +1 -0
- package/dist/core/diffPanel.d.ts +30 -0
- package/dist/core/diffPanel.d.ts.map +1 -0
- package/dist/core/diffPanel.js +48 -0
- package/dist/core/diffPanel.js.map +1 -0
- package/dist/core/errorClassification.d.ts +44 -0
- package/dist/core/errorClassification.d.ts.map +1 -0
- package/dist/core/errorClassification.js +333 -0
- package/dist/core/errorClassification.js.map +1 -0
- package/dist/core/errors/apiKeyErrors.d.ts +11 -0
- package/dist/core/errors/apiKeyErrors.d.ts.map +1 -0
- package/dist/core/errors/apiKeyErrors.js +159 -0
- package/dist/core/errors/apiKeyErrors.js.map +1 -0
- package/dist/core/errors/errorTypes.d.ts +111 -0
- package/dist/core/errors/errorTypes.d.ts.map +1 -0
- package/dist/core/errors/errorTypes.js +345 -0
- package/dist/core/errors/errorTypes.js.map +1 -0
- package/dist/core/errors/index.d.ts +50 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/core/errors/index.js +156 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/errors/networkErrors.d.ts +14 -0
- package/dist/core/errors/networkErrors.d.ts.map +1 -0
- package/dist/core/errors/networkErrors.js +53 -0
- package/dist/core/errors/networkErrors.js.map +1 -0
- package/dist/core/errors/safetyValidator.d.ts +109 -0
- package/dist/core/errors/safetyValidator.d.ts.map +1 -0
- package/dist/core/errors/safetyValidator.js +272 -0
- package/dist/core/errors/safetyValidator.js.map +1 -0
- package/dist/core/errors.d.ts +4 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +33 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/failureRegistry.d.ts +30 -0
- package/dist/core/failureRegistry.d.ts.map +1 -0
- package/dist/core/failureRegistry.js +74 -0
- package/dist/core/failureRegistry.js.map +1 -0
- package/dist/core/fileMentions.d.ts +40 -0
- package/dist/core/fileMentions.d.ts.map +1 -0
- package/dist/core/fileMentions.js +136 -0
- package/dist/core/fileMentions.js.map +1 -0
- package/dist/core/finalResponseFormatter.d.ts +10 -0
- package/dist/core/finalResponseFormatter.d.ts.map +1 -0
- package/dist/core/finalResponseFormatter.js +14 -0
- package/dist/core/finalResponseFormatter.js.map +1 -0
- package/dist/core/guardrails.d.ts +146 -0
- package/dist/core/guardrails.d.ts.map +1 -0
- package/dist/core/guardrails.js +361 -0
- package/dist/core/guardrails.js.map +1 -0
- package/dist/core/hitl.d.ts +119 -0
- package/dist/core/hitl.d.ts.map +1 -0
- package/dist/core/hitl.js +396 -0
- package/dist/core/hitl.js.map +1 -0
- package/dist/core/hooks.d.ts +95 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +236 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/hostedAuth.d.ts +88 -0
- package/dist/core/hostedAuth.d.ts.map +1 -0
- package/dist/core/hostedAuth.js +219 -0
- package/dist/core/hostedAuth.js.map +1 -0
- package/dist/core/inputProtection.d.ts +122 -0
- package/dist/core/inputProtection.d.ts.map +1 -0
- package/dist/core/inputProtection.js +422 -0
- package/dist/core/inputProtection.js.map +1 -0
- package/dist/core/modelDiscovery.d.ts +102 -0
- package/dist/core/modelDiscovery.d.ts.map +1 -0
- package/dist/core/modelDiscovery.js +416 -0
- package/dist/core/modelDiscovery.js.map +1 -0
- package/dist/core/multilinePasteHandler.d.ts +35 -0
- package/dist/core/multilinePasteHandler.d.ts.map +1 -0
- package/dist/core/multilinePasteHandler.js +81 -0
- package/dist/core/multilinePasteHandler.js.map +1 -0
- package/dist/core/permissionMode.d.ts +40 -0
- package/dist/core/permissionMode.d.ts.map +1 -0
- package/dist/core/permissionMode.js +86 -0
- package/dist/core/permissionMode.js.map +1 -0
- package/dist/core/postWriteDiagnostics.d.ts +32 -0
- package/dist/core/postWriteDiagnostics.d.ts.map +1 -0
- package/dist/core/postWriteDiagnostics.js +127 -0
- package/dist/core/postWriteDiagnostics.js.map +1 -0
- package/dist/core/preferences.d.ts +66 -0
- package/dist/core/preferences.d.ts.map +1 -0
- package/dist/core/preferences.js +310 -0
- package/dist/core/preferences.js.map +1 -0
- package/dist/core/quota.d.ts +61 -0
- package/dist/core/quota.d.ts.map +1 -0
- package/dist/core/quota.js +104 -0
- package/dist/core/quota.js.map +1 -0
- package/dist/core/quotaErrors.d.ts +42 -0
- package/dist/core/quotaErrors.d.ts.map +1 -0
- package/dist/core/quotaErrors.js +86 -0
- package/dist/core/quotaErrors.js.map +1 -0
- package/dist/core/refusalDetection.d.ts +2 -0
- package/dist/core/refusalDetection.d.ts.map +1 -0
- package/dist/core/refusalDetection.js +51 -0
- package/dist/core/refusalDetection.js.map +1 -0
- package/dist/core/relativeTime.d.ts +8 -0
- package/dist/core/relativeTime.d.ts.map +1 -0
- package/dist/core/relativeTime.js +29 -0
- package/dist/core/relativeTime.js.map +1 -0
- package/dist/core/resultVerification.d.ts +48 -0
- package/dist/core/resultVerification.d.ts.map +1 -0
- package/dist/core/resultVerification.js +127 -0
- package/dist/core/resultVerification.js.map +1 -0
- package/dist/core/rewind.d.ts +14 -0
- package/dist/core/rewind.d.ts.map +1 -0
- package/dist/core/rewind.js +25 -0
- package/dist/core/rewind.js.map +1 -0
- package/dist/core/schemaValidator.d.ts +49 -0
- package/dist/core/schemaValidator.d.ts.map +1 -0
- package/dist/core/schemaValidator.js +234 -0
- package/dist/core/schemaValidator.js.map +1 -0
- package/dist/core/secretStore.d.ts +59 -0
- package/dist/core/secretStore.d.ts.map +1 -0
- package/dist/core/secretStore.js +278 -0
- package/dist/core/secretStore.js.map +1 -0
- package/dist/core/sessionStorage.d.ts +10 -0
- package/dist/core/sessionStorage.d.ts.map +1 -0
- package/dist/core/sessionStorage.js +46 -0
- package/dist/core/sessionStorage.js.map +1 -0
- package/dist/core/sessionStore.d.ts +35 -0
- package/dist/core/sessionStore.d.ts.map +1 -0
- package/dist/core/sessionStore.js +190 -0
- package/dist/core/sessionStore.js.map +1 -0
- package/dist/core/shutdown.d.ts +34 -0
- package/dist/core/shutdown.d.ts.map +1 -0
- package/dist/core/shutdown.js +186 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/slashCommands.d.ts +38 -0
- package/dist/core/slashCommands.d.ts.map +1 -0
- package/dist/core/slashCommands.js +72 -0
- package/dist/core/slashCommands.js.map +1 -0
- package/dist/core/subAgentNote.d.ts +15 -0
- package/dist/core/subAgentNote.d.ts.map +1 -0
- package/dist/core/subAgentNote.js +16 -0
- package/dist/core/subAgentNote.js.map +1 -0
- package/dist/core/sudoPasswordManager.d.ts +52 -0
- package/dist/core/sudoPasswordManager.d.ts.map +1 -0
- package/dist/core/sudoPasswordManager.js +115 -0
- package/dist/core/sudoPasswordManager.js.map +1 -0
- package/dist/core/taskCompletionDetector.d.ts +117 -0
- package/dist/core/taskCompletionDetector.d.ts.map +1 -0
- package/dist/core/taskCompletionDetector.js +532 -0
- package/dist/core/taskCompletionDetector.js.map +1 -0
- package/dist/core/testFailureMonitor.d.ts +67 -0
- package/dist/core/testFailureMonitor.d.ts.map +1 -0
- package/dist/core/testFailureMonitor.js +262 -0
- package/dist/core/testFailureMonitor.js.map +1 -0
- package/dist/core/thinkingVerbs.d.ts +31 -0
- package/dist/core/thinkingVerbs.d.ts.map +1 -0
- package/dist/core/thinkingVerbs.js +58 -0
- package/dist/core/thinkingVerbs.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts +34 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -0
- package/dist/core/toolPreconditions.js +242 -0
- package/dist/core/toolPreconditions.js.map +1 -0
- package/dist/core/toolRuntime.d.ts +193 -0
- package/dist/core/toolRuntime.d.ts.map +1 -0
- package/dist/core/toolRuntime.js +526 -0
- package/dist/core/toolRuntime.js.map +1 -0
- package/dist/core/turnGovernor.d.ts +63 -0
- package/dist/core/turnGovernor.d.ts.map +1 -0
- package/dist/core/turnGovernor.js +94 -0
- package/dist/core/turnGovernor.js.map +1 -0
- package/dist/core/types/utilityTypes.d.ts +183 -0
- package/dist/core/types/utilityTypes.d.ts.map +1 -0
- package/dist/core/types/utilityTypes.js +273 -0
- package/dist/core/types/utilityTypes.js.map +1 -0
- package/dist/core/types.d.ts +334 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +76 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/updateChecker.d.ts +148 -0
- package/dist/core/updateChecker.d.ts.map +1 -0
- package/dist/core/updateChecker.js +605 -0
- package/dist/core/updateChecker.js.map +1 -0
- package/dist/core/usage.d.ts +28 -0
- package/dist/core/usage.d.ts.map +1 -0
- package/dist/core/usage.js +77 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/headless/interactiveShell.d.ts +47 -0
- package/dist/headless/interactiveShell.d.ts.map +1 -0
- package/dist/headless/interactiveShell.js +2495 -0
- package/dist/headless/interactiveShell.js.map +1 -0
- package/dist/leanAgent.d.ts +73 -0
- package/dist/leanAgent.d.ts.map +1 -0
- package/dist/leanAgent.js +177 -0
- package/dist/leanAgent.js.map +1 -0
- package/dist/plugins/providers/deepseek/index.d.ts +12 -0
- package/dist/plugins/providers/deepseek/index.d.ts.map +1 -0
- package/dist/plugins/providers/deepseek/index.js +123 -0
- package/dist/plugins/providers/deepseek/index.js.map +1 -0
- package/dist/plugins/providers/index.d.ts +2 -0
- package/dist/plugins/providers/index.d.ts.map +1 -0
- package/dist/plugins/providers/index.js +10 -0
- package/dist/plugins/providers/index.js.map +1 -0
- package/dist/providers/baseProvider.d.ts +140 -0
- package/dist/providers/baseProvider.d.ts.map +1 -0
- package/dist/providers/baseProvider.js +230 -0
- package/dist/providers/baseProvider.js.map +1 -0
- package/dist/providers/openaiChatCompletionsProvider.d.ts +70 -0
- package/dist/providers/openaiChatCompletionsProvider.d.ts.map +1 -0
- package/dist/providers/openaiChatCompletionsProvider.js +971 -0
- package/dist/providers/openaiChatCompletionsProvider.js.map +1 -0
- package/dist/providers/providerFactory.d.ts +22 -0
- package/dist/providers/providerFactory.d.ts.map +1 -0
- package/dist/providers/providerFactory.js +25 -0
- package/dist/providers/providerFactory.js.map +1 -0
- package/dist/providers/resilientProvider.d.ts +96 -0
- package/dist/providers/resilientProvider.d.ts.map +1 -0
- package/dist/providers/resilientProvider.js +251 -0
- package/dist/providers/resilientProvider.js.map +1 -0
- package/dist/runtime/agentController.d.ts +137 -0
- package/dist/runtime/agentController.d.ts.map +1 -0
- package/dist/runtime/agentController.js +784 -0
- package/dist/runtime/agentController.js.map +1 -0
- package/dist/runtime/agentHost.d.ts +61 -0
- package/dist/runtime/agentHost.d.ts.map +1 -0
- package/dist/runtime/agentHost.js +158 -0
- package/dist/runtime/agentHost.js.map +1 -0
- package/dist/runtime/agentSession.d.ts +49 -0
- package/dist/runtime/agentSession.d.ts.map +1 -0
- package/dist/runtime/agentSession.js +218 -0
- package/dist/runtime/agentSession.js.map +1 -0
- package/dist/runtime/agentSpawningWiring.d.ts +32 -0
- package/dist/runtime/agentSpawningWiring.d.ts.map +1 -0
- package/dist/runtime/agentSpawningWiring.js +114 -0
- package/dist/runtime/agentSpawningWiring.js.map +1 -0
- package/dist/runtime/node.d.ts +7 -0
- package/dist/runtime/node.d.ts.map +1 -0
- package/dist/runtime/node.js +50 -0
- package/dist/runtime/node.js.map +1 -0
- package/dist/runtime/universal.d.ts +18 -0
- package/dist/runtime/universal.d.ts.map +1 -0
- package/dist/runtime/universal.js +21 -0
- package/dist/runtime/universal.js.map +1 -0
- package/dist/shell/liveStatus.d.ts +27 -0
- package/dist/shell/liveStatus.d.ts.map +1 -0
- package/dist/shell/liveStatus.js +53 -0
- package/dist/shell/liveStatus.js.map +1 -0
- package/dist/shell/systemPrompt.d.ts +12 -0
- package/dist/shell/systemPrompt.d.ts.map +1 -0
- package/dist/shell/systemPrompt.js +16 -0
- package/dist/shell/systemPrompt.js.map +1 -0
- package/dist/shell/toolPresentation.d.ts +54 -0
- package/dist/shell/toolPresentation.d.ts.map +1 -0
- package/dist/shell/toolPresentation.js +334 -0
- package/dist/shell/toolPresentation.js.map +1 -0
- package/dist/tools/bashTools.d.ts +11 -0
- package/dist/tools/bashTools.d.ts.map +1 -0
- package/dist/tools/bashTools.js +785 -0
- package/dist/tools/bashTools.js.map +1 -0
- package/dist/tools/diffUtils.d.ts +43 -0
- package/dist/tools/diffUtils.d.ts.map +1 -0
- package/dist/tools/diffUtils.js +607 -0
- package/dist/tools/diffUtils.js.map +1 -0
- package/dist/tools/editTools.d.ts +29 -0
- package/dist/tools/editTools.d.ts.map +1 -0
- package/dist/tools/editTools.js +792 -0
- package/dist/tools/editTools.js.map +1 -0
- package/dist/tools/fileChangeTracker.d.ts +47 -0
- package/dist/tools/fileChangeTracker.d.ts.map +1 -0
- package/dist/tools/fileChangeTracker.js +154 -0
- package/dist/tools/fileChangeTracker.js.map +1 -0
- package/dist/tools/fileReadTracker.d.ts +69 -0
- package/dist/tools/fileReadTracker.d.ts.map +1 -0
- package/dist/tools/fileReadTracker.js +213 -0
- package/dist/tools/fileReadTracker.js.map +1 -0
- package/dist/tools/fileTools.d.ts +3 -0
- package/dist/tools/fileTools.d.ts.map +1 -0
- package/dist/tools/fileTools.js +389 -0
- package/dist/tools/fileTools.js.map +1 -0
- package/dist/tools/grepTools.d.ts +3 -0
- package/dist/tools/grepTools.d.ts.map +1 -0
- package/dist/tools/grepTools.js +137 -0
- package/dist/tools/grepTools.js.map +1 -0
- package/dist/tools/hitlTools.d.ts +7 -0
- package/dist/tools/hitlTools.d.ts.map +1 -0
- package/dist/tools/hitlTools.js +185 -0
- package/dist/tools/hitlTools.js.map +1 -0
- package/dist/tools/memoryTools.d.ts +27 -0
- package/dist/tools/memoryTools.d.ts.map +1 -0
- package/dist/tools/memoryTools.js +197 -0
- package/dist/tools/memoryTools.js.map +1 -0
- package/dist/tools/notebookTools.d.ts +20 -0
- package/dist/tools/notebookTools.d.ts.map +1 -0
- package/dist/tools/notebookTools.js +140 -0
- package/dist/tools/notebookTools.js.map +1 -0
- package/dist/tools/searchTools.d.ts +12 -0
- package/dist/tools/searchTools.d.ts.map +1 -0
- package/dist/tools/searchTools.js +414 -0
- package/dist/tools/searchTools.js.map +1 -0
- package/dist/tools/skillTools.d.ts +24 -0
- package/dist/tools/skillTools.d.ts.map +1 -0
- package/dist/tools/skillTools.js +140 -0
- package/dist/tools/skillTools.js.map +1 -0
- package/dist/tools/todoTools.d.ts +23 -0
- package/dist/tools/todoTools.d.ts.map +1 -0
- package/dist/tools/todoTools.js +120 -0
- package/dist/tools/todoTools.js.map +1 -0
- package/dist/tools/webTools.d.ts +26 -0
- package/dist/tools/webTools.d.ts.map +1 -0
- package/dist/tools/webTools.js +467 -0
- package/dist/tools/webTools.js.map +1 -0
- package/dist/ui/ink/App.d.ts +53 -0
- package/dist/ui/ink/App.d.ts.map +1 -0
- package/dist/ui/ink/App.js +13 -0
- package/dist/ui/ink/App.js.map +1 -0
- package/dist/ui/ink/ChatStatic.d.ts +30 -0
- package/dist/ui/ink/ChatStatic.d.ts.map +1 -0
- package/dist/ui/ink/ChatStatic.js +83 -0
- package/dist/ui/ink/ChatStatic.js.map +1 -0
- package/dist/ui/ink/InkPromptController.d.ts +321 -0
- package/dist/ui/ink/InkPromptController.d.ts.map +1 -0
- package/dist/ui/ink/InkPromptController.js +667 -0
- package/dist/ui/ink/InkPromptController.js.map +1 -0
- package/dist/ui/ink/Menu.d.ts +21 -0
- package/dist/ui/ink/Menu.d.ts.map +1 -0
- package/dist/ui/ink/Menu.js +61 -0
- package/dist/ui/ink/Menu.js.map +1 -0
- package/dist/ui/ink/Prompt.d.ts +47 -0
- package/dist/ui/ink/Prompt.d.ts.map +1 -0
- package/dist/ui/ink/Prompt.js +571 -0
- package/dist/ui/ink/Prompt.js.map +1 -0
- package/dist/ui/ink/StatusLine.d.ts +35 -0
- package/dist/ui/ink/StatusLine.d.ts.map +1 -0
- package/dist/ui/ink/StatusLine.js +66 -0
- package/dist/ui/ink/StatusLine.js.map +1 -0
- package/dist/ui/ink/pasteBuffer.d.ts +44 -0
- package/dist/ui/ink/pasteBuffer.d.ts.map +1 -0
- package/dist/ui/ink/pasteBuffer.js +73 -0
- package/dist/ui/ink/pasteBuffer.js.map +1 -0
- package/dist/ui/theme.d.ts +351 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +435 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/analytics.d.ts +2 -0
- package/dist/utils/analytics.d.ts.map +1 -0
- package/dist/utils/analytics.js +51 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/asyncUtils.d.ts +95 -0
- package/dist/utils/asyncUtils.d.ts.map +1 -0
- package/dist/utils/asyncUtils.js +286 -0
- package/dist/utils/asyncUtils.js.map +1 -0
- package/dist/utils/debugLogger.d.ts +6 -0
- package/dist/utils/debugLogger.d.ts.map +1 -0
- package/dist/utils/debugLogger.js +39 -0
- package/dist/utils/debugLogger.js.map +1 -0
- package/dist/utils/errorUtils.d.ts +12 -0
- package/dist/utils/errorUtils.d.ts.map +1 -0
- package/dist/utils/errorUtils.js +83 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +78 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/packageInfo.d.ts +14 -0
- package/dist/utils/packageInfo.d.ts.map +1 -0
- package/dist/utils/packageInfo.js +45 -0
- package/dist/utils/packageInfo.js.map +1 -0
- package/dist/utils/planFormatter.d.ts +34 -0
- package/dist/utils/planFormatter.d.ts.map +1 -0
- package/dist/utils/planFormatter.js +141 -0
- package/dist/utils/planFormatter.js.map +1 -0
- package/dist/utils/securityUtils.d.ts +132 -0
- package/dist/utils/securityUtils.d.ts.map +1 -0
- package/dist/utils/securityUtils.js +324 -0
- package/dist/utils/securityUtils.js.map +1 -0
- package/dist/utils/statusReporter.d.ts +6 -0
- package/dist/utils/statusReporter.d.ts.map +1 -0
- package/dist/utils/statusReporter.js +26 -0
- package/dist/utils/statusReporter.js.map +1 -0
- package/dist/workspace.d.ts +8 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +135 -0
- package/dist/workspace.js.map +1 -0
- package/dist/workspace.validator.d.ts +49 -0
- package/dist/workspace.validator.d.ts.map +1 -0
- package/dist/workspace.validator.js +215 -0
- package/dist/workspace.validator.js.map +1 -0
- package/package.json +116 -0
- package/scripts/postinstall.cjs +56 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks — Claude-Code-style shell-command hooks that fire around
|
|
3
|
+
* tool execution. Lets users customize agent behavior without
|
|
4
|
+
* editing source: run a linter after every Edit, log Bash commands,
|
|
5
|
+
* block dangerous tools, etc.
|
|
6
|
+
*
|
|
7
|
+
* Settings file (per Claude Code convention):
|
|
8
|
+
* {
|
|
9
|
+
* "hooks": {
|
|
10
|
+
* "PreToolUse": [
|
|
11
|
+
* { "matcher": "Bash", "hooks": [{ "type": "command", "command": "/path/to/script.sh" }] }
|
|
12
|
+
* ],
|
|
13
|
+
* "PostToolUse": [ ... ]
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* Loaded from (in priority order):
|
|
18
|
+
* 1. <workingDir>/.trenchwork/settings.json (project-local)
|
|
19
|
+
* 2. ~/.trenchwork/settings.json (user-global)
|
|
20
|
+
*
|
|
21
|
+
* Both load — project-local extends user-global; matchers from both
|
|
22
|
+
* files fire if applicable.
|
|
23
|
+
*
|
|
24
|
+
* Hook contract: the command receives a JSON envelope on stdin,
|
|
25
|
+
* shape:
|
|
26
|
+
* { event: 'PreToolUse'|'PostToolUse', toolName, toolArgs, toolResult? }
|
|
27
|
+
* The command exits 0 + writes a JSON response on stdout to either
|
|
28
|
+
* pass through or shape the result:
|
|
29
|
+
* {} — pass through
|
|
30
|
+
* { "decision": "block",
|
|
31
|
+
* "reason": "string" } — PreToolUse: block the tool call
|
|
32
|
+
* { "appendToResult": "..." } — PostToolUse: append text to the
|
|
33
|
+
* model-visible tool result
|
|
34
|
+
*
|
|
35
|
+
* Hooks are best-effort: a hook that times out, errors, or returns
|
|
36
|
+
* malformed JSON is logged and skipped — never crashes the agent.
|
|
37
|
+
*/
|
|
38
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
39
|
+
import { homedir } from 'node:os';
|
|
40
|
+
import { join } from 'node:path';
|
|
41
|
+
import { exec, execFile } from 'node:child_process';
|
|
42
|
+
/**
|
|
43
|
+
* Read + merge settings from project-local + user-global locations.
|
|
44
|
+
* Returns an empty config if neither file exists. Malformed JSON is
|
|
45
|
+
* silently skipped (with a console.warn).
|
|
46
|
+
*/
|
|
47
|
+
export function loadHooksConfig(workingDir) {
|
|
48
|
+
const candidates = [
|
|
49
|
+
join(workingDir, '.trenchwork', 'settings.json'),
|
|
50
|
+
join(homedir(), '.trenchwork', 'settings.json'),
|
|
51
|
+
];
|
|
52
|
+
const merged = { hooks: {} };
|
|
53
|
+
for (const path of candidates) {
|
|
54
|
+
if (!existsSync(path))
|
|
55
|
+
continue;
|
|
56
|
+
let parsed = null;
|
|
57
|
+
try {
|
|
58
|
+
const raw = readFileSync(path, 'utf-8');
|
|
59
|
+
parsed = JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.warn(`[hooks] Skipping malformed settings: ${path}: ${err.message}`);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!parsed?.hooks)
|
|
66
|
+
continue;
|
|
67
|
+
for (const ev of Object.keys(parsed.hooks)) {
|
|
68
|
+
const list = parsed.hooks[ev];
|
|
69
|
+
if (!Array.isArray(list))
|
|
70
|
+
continue;
|
|
71
|
+
const existing = merged.hooks[ev] ?? [];
|
|
72
|
+
// Shallow-validate each entry before merging so the executor
|
|
73
|
+
// never has to re-check shape.
|
|
74
|
+
const safe = list.filter((m) => m && typeof m === 'object' && Array.isArray(m.hooks));
|
|
75
|
+
merged.hooks[ev] = [...existing, ...safe];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return merged;
|
|
79
|
+
}
|
|
80
|
+
function matchesMatcher(matcher, toolName) {
|
|
81
|
+
if (!matcher || matcher === '*' || matcher === '.*')
|
|
82
|
+
return true;
|
|
83
|
+
try {
|
|
84
|
+
return new RegExp(`^${matcher}$`).test(toolName);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return matcher === toolName;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Run a single hook command with structured input. Returns the
|
|
92
|
+
* parsed JSON response, or null if the hook errored / timed out /
|
|
93
|
+
* returned malformed output. Never throws — non-fatal on purpose.
|
|
94
|
+
*/
|
|
95
|
+
async function runHookCommand(cmd, input) {
|
|
96
|
+
const timeoutMs = Math.min(30_000, Math.max(500, cmd.timeoutMs ?? 5000));
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
let settled = false;
|
|
99
|
+
const finish = (val) => {
|
|
100
|
+
if (settled)
|
|
101
|
+
return;
|
|
102
|
+
settled = true;
|
|
103
|
+
resolve(val);
|
|
104
|
+
};
|
|
105
|
+
// Use exec (not spawn) so the command string is interpreted by
|
|
106
|
+
// the platform's default shell with its native quoting rules.
|
|
107
|
+
// spawn('cmd.exe', ['/c', '<cmd with quotes>']) on Windows
|
|
108
|
+
// mishandles inner double-quotes; exec handles that internally.
|
|
109
|
+
// We do NOT pass exec's `timeout` option — on Windows it sends
|
|
110
|
+
// SIGTERM which doesn't always reliably kill child processes
|
|
111
|
+
// that aren't blocked on I/O (e.g. a node child sitting on a
|
|
112
|
+
// setTimeout). Instead we own the timeout: fire our own timer,
|
|
113
|
+
// resolve the promise immediately, and force-kill the process
|
|
114
|
+
// tree. The exec callback may still fire later but `settled`
|
|
115
|
+
// makes it a no-op.
|
|
116
|
+
const child = exec(cmd.command, { maxBuffer: 1024 * 1024, encoding: 'utf-8' }, (err, stdout, stderr) => {
|
|
117
|
+
if (settled)
|
|
118
|
+
return;
|
|
119
|
+
if (err && err.code) {
|
|
120
|
+
if (typeof stderr === 'string' && stderr.trim()) {
|
|
121
|
+
console.warn(`[hooks] ${cmd.command} exit ${err.code}: ${stderr.slice(0, 400)}`);
|
|
122
|
+
}
|
|
123
|
+
return finish(null);
|
|
124
|
+
}
|
|
125
|
+
const out = (typeof stdout === 'string' ? stdout : '').trim();
|
|
126
|
+
if (!out)
|
|
127
|
+
return finish({});
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(out);
|
|
130
|
+
if (parsed && typeof parsed === 'object')
|
|
131
|
+
return finish(parsed);
|
|
132
|
+
return finish({});
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// A hook that prints non-JSON is treated as pass-through.
|
|
136
|
+
return finish({});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// Owned timeout — kill the process tree on expiry. On Windows
|
|
140
|
+
// we use taskkill /T /F to clean up children of the shell wrapper;
|
|
141
|
+
// on POSIX, killing the negative pid of the process group does it.
|
|
142
|
+
const timeout = setTimeout(() => {
|
|
143
|
+
if (settled)
|
|
144
|
+
return;
|
|
145
|
+
console.warn(`[hooks] ${cmd.command}: timed out after ${timeoutMs}ms`);
|
|
146
|
+
try {
|
|
147
|
+
if (process.platform === 'win32' && child.pid) {
|
|
148
|
+
// /T = terminate child tree, /F = force. Use execFile with an
|
|
149
|
+
// arg array so the PID can never be interpreted as taskkill
|
|
150
|
+
// flags (defense-in-depth — child.pid is a number from Node so
|
|
151
|
+
// injection isn't reachable today, but the safer pattern is
|
|
152
|
+
// free here).
|
|
153
|
+
execFile('taskkill', ['/pid', String(child.pid), '/T', '/F'], () => { });
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
child.kill('SIGKILL');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (_) { /* best effort */ }
|
|
160
|
+
finish(null);
|
|
161
|
+
}, timeoutMs);
|
|
162
|
+
timeout.unref?.();
|
|
163
|
+
child.on('exit', () => clearTimeout(timeout));
|
|
164
|
+
// A hook that errors/exits fast closes its stdin before we finish
|
|
165
|
+
// writing, which surfaces as an ASYNC 'error' (EPIPE) on the stream —
|
|
166
|
+
// not catchable by the try/catch below. Swallow it so a dead hook is
|
|
167
|
+
// silently skipped instead of crashing the runner with an unhandled
|
|
168
|
+
// stream error.
|
|
169
|
+
child.stdin?.on('error', () => { });
|
|
170
|
+
try {
|
|
171
|
+
child.stdin?.write(JSON.stringify(input));
|
|
172
|
+
child.stdin?.end();
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
console.warn(`[hooks] stdin write failed: ${err.message}`);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Run all PreToolUse hooks matching `toolName`. Returns the FIRST
|
|
181
|
+
* blocking decision encountered, or null if no hook blocks.
|
|
182
|
+
*/
|
|
183
|
+
export async function runPreToolUseHooks(config, toolName, toolArgs) {
|
|
184
|
+
const matchers = config.hooks?.PreToolUse ?? [];
|
|
185
|
+
for (const m of matchers) {
|
|
186
|
+
if (!matchesMatcher(m.matcher, toolName))
|
|
187
|
+
continue;
|
|
188
|
+
for (const cmd of m.hooks) {
|
|
189
|
+
const result = await runHookCommand(cmd, {
|
|
190
|
+
event: 'PreToolUse',
|
|
191
|
+
toolName,
|
|
192
|
+
toolArgs,
|
|
193
|
+
});
|
|
194
|
+
if (!result)
|
|
195
|
+
continue;
|
|
196
|
+
if (result['decision'] === 'block') {
|
|
197
|
+
return {
|
|
198
|
+
decision: 'block',
|
|
199
|
+
reason: typeof result['reason'] === 'string' ? result['reason'] : 'Blocked by hook',
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Run all PostToolUse hooks matching `toolName`. Concatenates any
|
|
208
|
+
* appendToResult strings (in matcher order) so multiple hooks can
|
|
209
|
+
* each contribute a note.
|
|
210
|
+
*/
|
|
211
|
+
export async function runPostToolUseHooks(config, toolName, toolArgs, toolResult) {
|
|
212
|
+
const matchers = config.hooks?.PostToolUse ?? [];
|
|
213
|
+
const appended = [];
|
|
214
|
+
for (const m of matchers) {
|
|
215
|
+
if (!matchesMatcher(m.matcher, toolName))
|
|
216
|
+
continue;
|
|
217
|
+
for (const cmd of m.hooks) {
|
|
218
|
+
const result = await runHookCommand(cmd, {
|
|
219
|
+
event: 'PostToolUse',
|
|
220
|
+
toolName,
|
|
221
|
+
toolArgs,
|
|
222
|
+
toolResult,
|
|
223
|
+
});
|
|
224
|
+
if (!result)
|
|
225
|
+
continue;
|
|
226
|
+
const append = result['appendToResult'];
|
|
227
|
+
if (typeof append === 'string' && append.trim()) {
|
|
228
|
+
appended.push(append.trim());
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (appended.length === 0)
|
|
233
|
+
return null;
|
|
234
|
+
return { appendToResult: appended.join('\n\n') };
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hosted-key access — the CLIENT side of "optional sign-in unlocks hosted keys,
|
|
3
|
+
* or bring your own." Keys NEVER ship in this client (Project Glasswing); they
|
|
4
|
+
* live only in the ero.solar AWS backend, exactly like the Tavily search proxy
|
|
5
|
+
* already does (see src/tools/webTools.ts). Sign-in mints a short-lived token;
|
|
6
|
+
* the proxies validate it and use the operator keys.
|
|
7
|
+
*
|
|
8
|
+
* ── CONTRACT (the ero.solar backend implements this; this file codes against it) ──
|
|
9
|
+
* Sign-in (loopback OAuth, increment 2):
|
|
10
|
+
* open https://ero.solar/cli/login?port=<loopbackPort>&state=<csrf>
|
|
11
|
+
* → Google SSO → 302 http://127.0.0.1:<port>/cb?token=<jwt>&email=<e>&state=<csrf>
|
|
12
|
+
* DeepSeek (hosted): POST {HOSTED_DEEPSEEK_PROXY} header `Authorization: Bearer <token>`
|
|
13
|
+
* Tavily (hosted): the existing tavilySearch proxy, same Bearer token
|
|
14
|
+
* The token is short-lived and server-validated; if it 401s the CLI drops to
|
|
15
|
+
* "signed out" and asks the user to /login again or use their own key.
|
|
16
|
+
*
|
|
17
|
+
* THIS MODULE is state + resolution only (increment 1, fully testable). The live
|
|
18
|
+
* sign-in flow and the provider→proxy wiring are increment 2 (backend-gated).
|
|
19
|
+
*/
|
|
20
|
+
export declare const HOSTED_LOGIN_URL = "https://ero.solar/cli/login";
|
|
21
|
+
export declare const HOSTED_DEEPSEEK_PROXY = "https://ero.solar/api/deepseek";
|
|
22
|
+
export interface HostedSession {
|
|
23
|
+
token: string;
|
|
24
|
+
email: string;
|
|
25
|
+
}
|
|
26
|
+
export type KeyMode = 'hosted' | 'own' | 'none';
|
|
27
|
+
export interface KeyModeStatus {
|
|
28
|
+
mode: KeyMode;
|
|
29
|
+
email: string | null;
|
|
30
|
+
signedIn: boolean;
|
|
31
|
+
ownDeepSeek: boolean;
|
|
32
|
+
ownTavily: boolean;
|
|
33
|
+
preferOwnKeys: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** The active hosted session (token + email), or null when signed out. */
|
|
36
|
+
export declare function getHostedSession(): HostedSession | null;
|
|
37
|
+
/** Persist a hosted session (called by /login once the backend returns a token). */
|
|
38
|
+
export declare function setHostedSession(session: HostedSession): void;
|
|
39
|
+
/** Sign out: drop the token but keep the own/hosted preference. */
|
|
40
|
+
export declare function clearHostedSession(): void;
|
|
41
|
+
export declare function prefersOwnKeys(): boolean;
|
|
42
|
+
export declare function setPreferOwnKeys(value: boolean): void;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve which keys are in effect. Preference order: an explicit "use my own
|
|
45
|
+
* keys" wins when the user actually has a DeepSeek key; otherwise a hosted
|
|
46
|
+
* session is used; otherwise the user's own key; otherwise nothing is set up.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveKeyMode(): KeyModeStatus;
|
|
49
|
+
/**
|
|
50
|
+
* The dim welcome/banner line that makes the active key source unmistakable —
|
|
51
|
+
* the user must be able to see at a glance whether they're on hosted keys or
|
|
52
|
+
* their own. Returns null in 'none' mode (the welcome already shows key setup).
|
|
53
|
+
*/
|
|
54
|
+
export declare function keyModeLine(status?: KeyModeStatus): string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the DeepSeek endpoint the provider should use. Hosted mode routes
|
|
57
|
+
* through the ero.solar proxy authenticated by the short-lived sign-in token
|
|
58
|
+
* (the real key lives only server-side, Glasswing); otherwise the user's own
|
|
59
|
+
* key hits the API directly. `apiKey` is '' in 'none' mode (caller errors).
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveDeepSeekEndpoint(): {
|
|
62
|
+
apiKey: string;
|
|
63
|
+
baseURL: string;
|
|
64
|
+
mode: KeyMode;
|
|
65
|
+
};
|
|
66
|
+
export interface LoginResult {
|
|
67
|
+
ok: boolean;
|
|
68
|
+
session?: HostedSession;
|
|
69
|
+
error?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Loopback-OAuth sign-in (the contract's increment 2). Starts a one-shot
|
|
73
|
+
* 127.0.0.1 server on an ephemeral port, opens the browser to the ero.solar
|
|
74
|
+
* Google-SSO login URL with that port + a CSRF state, and waits for the
|
|
75
|
+
* redirect back to /cb?token=&email=&state=. On match it persists the hosted
|
|
76
|
+
* session. The browser launch is injected (`open`) so the flow is testable
|
|
77
|
+
* against the REAL loopback server without a real browser.
|
|
78
|
+
*
|
|
79
|
+
* Requires the ero.solar backend (SSO + token mint + redirect) to be live; with
|
|
80
|
+
* no backend the browser opens to a not-yet-served endpoint and the wait times
|
|
81
|
+
* out — the caller surfaces that honestly.
|
|
82
|
+
*/
|
|
83
|
+
export declare function loginViaLoopback(opts: {
|
|
84
|
+
open: (url: string) => void | Promise<void>;
|
|
85
|
+
timeoutMs?: number;
|
|
86
|
+
loginUrl?: string;
|
|
87
|
+
}): Promise<LoginResult>;
|
|
88
|
+
//# sourceMappingURL=hostedAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostedAuth.d.ts","sourceRoot":"","sources":["../../src/core/hostedAuth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAUH,eAAO,MAAM,gBAAgB,gCAAgC,CAAC;AAC9D,eAAO,MAAM,qBAAqB,mCAAmC,CAAC;AAWtE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AASD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB;AA+BD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAGvD;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAG7D;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAErD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,aAAa,CAa9C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,aAAgC,GAAG,MAAM,GAAG,IAAI,CAanF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAW5F;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuCvB"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hosted-key access — the CLIENT side of "optional sign-in unlocks hosted keys,
|
|
3
|
+
* or bring your own." Keys NEVER ship in this client (Project Glasswing); they
|
|
4
|
+
* live only in the ero.solar AWS backend, exactly like the Tavily search proxy
|
|
5
|
+
* already does (see src/tools/webTools.ts). Sign-in mints a short-lived token;
|
|
6
|
+
* the proxies validate it and use the operator keys.
|
|
7
|
+
*
|
|
8
|
+
* ── CONTRACT (the ero.solar backend implements this; this file codes against it) ──
|
|
9
|
+
* Sign-in (loopback OAuth, increment 2):
|
|
10
|
+
* open https://ero.solar/cli/login?port=<loopbackPort>&state=<csrf>
|
|
11
|
+
* → Google SSO → 302 http://127.0.0.1:<port>/cb?token=<jwt>&email=<e>&state=<csrf>
|
|
12
|
+
* DeepSeek (hosted): POST {HOSTED_DEEPSEEK_PROXY} header `Authorization: Bearer <token>`
|
|
13
|
+
* Tavily (hosted): the existing tavilySearch proxy, same Bearer token
|
|
14
|
+
* The token is short-lived and server-validated; if it 401s the CLI drops to
|
|
15
|
+
* "signed out" and asks the user to /login again or use their own key.
|
|
16
|
+
*
|
|
17
|
+
* THIS MODULE is state + resolution only (increment 1, fully testable). The live
|
|
18
|
+
* sign-in flow and the provider→proxy wiring are increment 2 (backend-gated).
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, rmSync } from 'node:fs';
|
|
21
|
+
import { createServer } from 'node:http';
|
|
22
|
+
import { randomBytes } from 'node:crypto';
|
|
23
|
+
import { homedir } from 'node:os';
|
|
24
|
+
import { join, resolve } from 'node:path';
|
|
25
|
+
import { getSecretValue } from './secretStore.js';
|
|
26
|
+
// Contract endpoints (the backend the user is building must match these).
|
|
27
|
+
export const HOSTED_LOGIN_URL = 'https://ero.solar/cli/login';
|
|
28
|
+
export const HOSTED_DEEPSEEK_PROXY = 'https://ero.solar/api/deepseek';
|
|
29
|
+
// Resolved per call (not captured at module load) so TRENCHWORK_HOME changes —
|
|
30
|
+
// and tests pointing at a temp dir — take effect.
|
|
31
|
+
function homeDir() {
|
|
32
|
+
return process.env['TRENCHWORK_HOME'] ? resolve(process.env['TRENCHWORK_HOME']) : join(homedir(), '.trenchwork');
|
|
33
|
+
}
|
|
34
|
+
function sessionFile() {
|
|
35
|
+
return join(homeDir(), 'session.json');
|
|
36
|
+
}
|
|
37
|
+
function readFile() {
|
|
38
|
+
// Read the on-disk session first (the future /login writes it; it also holds
|
|
39
|
+
// the own/hosted preference), then let env override the token+email — env
|
|
40
|
+
// lets tests/CI inject a session without touching disk, while still honouring
|
|
41
|
+
// a stored preference.
|
|
42
|
+
let data = {};
|
|
43
|
+
const file = sessionFile();
|
|
44
|
+
if (existsSync(file)) {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
47
|
+
if (parsed && typeof parsed === 'object')
|
|
48
|
+
data = parsed;
|
|
49
|
+
}
|
|
50
|
+
catch { /* corrupt → treat as empty */ }
|
|
51
|
+
}
|
|
52
|
+
const envToken = process.env['TRENCHWORK_HOSTED_TOKEN']?.trim();
|
|
53
|
+
if (envToken) {
|
|
54
|
+
data.token = envToken;
|
|
55
|
+
data.email = process.env['TRENCHWORK_HOSTED_EMAIL']?.trim() || 'you@hosted';
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
58
|
+
}
|
|
59
|
+
function writeFile(data) {
|
|
60
|
+
const file = sessionFile();
|
|
61
|
+
mkdirSync(homeDir(), { recursive: true, mode: 0o700 });
|
|
62
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
63
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', { mode: 0o600 });
|
|
64
|
+
renameSync(tmp, file);
|
|
65
|
+
}
|
|
66
|
+
/** The active hosted session (token + email), or null when signed out. */
|
|
67
|
+
export function getHostedSession() {
|
|
68
|
+
const f = readFile();
|
|
69
|
+
return f.token ? { token: f.token, email: f.email || 'you@hosted' } : null;
|
|
70
|
+
}
|
|
71
|
+
/** Persist a hosted session (called by /login once the backend returns a token). */
|
|
72
|
+
export function setHostedSession(session) {
|
|
73
|
+
const f = readFile();
|
|
74
|
+
writeFile({ ...f, token: session.token, email: session.email });
|
|
75
|
+
}
|
|
76
|
+
/** Sign out: drop the token but keep the own/hosted preference. */
|
|
77
|
+
export function clearHostedSession() {
|
|
78
|
+
const f = readFile();
|
|
79
|
+
delete f.token;
|
|
80
|
+
delete f.email;
|
|
81
|
+
if (Object.keys(f).length === 0) {
|
|
82
|
+
try {
|
|
83
|
+
rmSync(sessionFile(), { force: true });
|
|
84
|
+
}
|
|
85
|
+
catch { /* ignore */ }
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
writeFile(f);
|
|
89
|
+
}
|
|
90
|
+
export function prefersOwnKeys() {
|
|
91
|
+
return readFile().preferOwnKeys === true;
|
|
92
|
+
}
|
|
93
|
+
export function setPreferOwnKeys(value) {
|
|
94
|
+
writeFile({ ...readFile(), preferOwnKeys: value });
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve which keys are in effect. Preference order: an explicit "use my own
|
|
98
|
+
* keys" wins when the user actually has a DeepSeek key; otherwise a hosted
|
|
99
|
+
* session is used; otherwise the user's own key; otherwise nothing is set up.
|
|
100
|
+
*/
|
|
101
|
+
export function resolveKeyMode() {
|
|
102
|
+
const session = getHostedSession();
|
|
103
|
+
const ownDeepSeek = Boolean(getSecretValue('DEEPSEEK_API_KEY'));
|
|
104
|
+
const ownTavily = Boolean(getSecretValue('TAVILY_API_KEY'));
|
|
105
|
+
const preferOwnKeys = prefersOwnKeys();
|
|
106
|
+
let mode;
|
|
107
|
+
if (preferOwnKeys && ownDeepSeek)
|
|
108
|
+
mode = 'own';
|
|
109
|
+
else if (session)
|
|
110
|
+
mode = 'hosted';
|
|
111
|
+
else if (ownDeepSeek)
|
|
112
|
+
mode = 'own';
|
|
113
|
+
else
|
|
114
|
+
mode = 'none';
|
|
115
|
+
return { mode, email: session?.email ?? null, signedIn: Boolean(session), ownDeepSeek, ownTavily, preferOwnKeys };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The dim welcome/banner line that makes the active key source unmistakable —
|
|
119
|
+
* the user must be able to see at a glance whether they're on hosted keys or
|
|
120
|
+
* their own. Returns null in 'none' mode (the welcome already shows key setup).
|
|
121
|
+
*/
|
|
122
|
+
export function keyModeLine(status = resolveKeyMode()) {
|
|
123
|
+
switch (status.mode) {
|
|
124
|
+
case 'hosted':
|
|
125
|
+
return `Signed in as ${status.email} · using hosted keys` +
|
|
126
|
+
(status.ownDeepSeek ? ' · /account to use your own' : '');
|
|
127
|
+
case 'own': {
|
|
128
|
+
const tav = status.ownTavily ? 'Tavily ✓' : 'Tavily (shared proxy)';
|
|
129
|
+
const base = `Using your own keys · DeepSeek ✓ · ${tav}`;
|
|
130
|
+
return status.signedIn ? `${base} · /account to use hosted` : base;
|
|
131
|
+
}
|
|
132
|
+
default:
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Resolve the DeepSeek endpoint the provider should use. Hosted mode routes
|
|
138
|
+
* through the ero.solar proxy authenticated by the short-lived sign-in token
|
|
139
|
+
* (the real key lives only server-side, Glasswing); otherwise the user's own
|
|
140
|
+
* key hits the API directly. `apiKey` is '' in 'none' mode (caller errors).
|
|
141
|
+
*/
|
|
142
|
+
export function resolveDeepSeekEndpoint() {
|
|
143
|
+
const status = resolveKeyMode();
|
|
144
|
+
if (status.mode === 'hosted') {
|
|
145
|
+
const session = getHostedSession();
|
|
146
|
+
if (session)
|
|
147
|
+
return { apiKey: session.token, baseURL: HOSTED_DEEPSEEK_PROXY, mode: 'hosted' };
|
|
148
|
+
}
|
|
149
|
+
const userKey = (process.env['DEEPSEEK_API_KEY'] || '').trim();
|
|
150
|
+
if (userKey) {
|
|
151
|
+
return { apiKey: userKey, baseURL: process.env['DEEPSEEK_BASE_URL'] || 'https://api.deepseek.com', mode: 'own' };
|
|
152
|
+
}
|
|
153
|
+
return { apiKey: '', baseURL: '', mode: 'none' };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Loopback-OAuth sign-in (the contract's increment 2). Starts a one-shot
|
|
157
|
+
* 127.0.0.1 server on an ephemeral port, opens the browser to the ero.solar
|
|
158
|
+
* Google-SSO login URL with that port + a CSRF state, and waits for the
|
|
159
|
+
* redirect back to /cb?token=&email=&state=. On match it persists the hosted
|
|
160
|
+
* session. The browser launch is injected (`open`) so the flow is testable
|
|
161
|
+
* against the REAL loopback server without a real browser.
|
|
162
|
+
*
|
|
163
|
+
* Requires the ero.solar backend (SSO + token mint + redirect) to be live; with
|
|
164
|
+
* no backend the browser opens to a not-yet-served endpoint and the wait times
|
|
165
|
+
* out — the caller surfaces that honestly.
|
|
166
|
+
*/
|
|
167
|
+
export function loginViaLoopback(opts) {
|
|
168
|
+
const state = randomBytes(16).toString('hex');
|
|
169
|
+
const loginUrl = opts.loginUrl ?? HOSTED_LOGIN_URL;
|
|
170
|
+
return new Promise((resolveP) => {
|
|
171
|
+
let settled = false;
|
|
172
|
+
const finish = (result) => {
|
|
173
|
+
if (settled)
|
|
174
|
+
return;
|
|
175
|
+
settled = true;
|
|
176
|
+
clearTimeout(timer);
|
|
177
|
+
try {
|
|
178
|
+
server.close();
|
|
179
|
+
}
|
|
180
|
+
catch { /* ignore */ }
|
|
181
|
+
resolveP(result);
|
|
182
|
+
};
|
|
183
|
+
const server = createServer((req, res) => {
|
|
184
|
+
const url = new URL(req.url ?? '/', 'http://127.0.0.1');
|
|
185
|
+
if (url.pathname !== '/cb') {
|
|
186
|
+
res.writeHead(404);
|
|
187
|
+
res.end('not found');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const token = url.searchParams.get('token') ?? '';
|
|
191
|
+
const email = url.searchParams.get('email') ?? '';
|
|
192
|
+
const gotState = url.searchParams.get('state') ?? '';
|
|
193
|
+
const okPage = '<!doctype html><meta charset="utf-8"><body style="font:16px system-ui;padding:3rem">'
|
|
194
|
+
+ 'Signed in to Trenchwork Coder. You can close this tab and return to the terminal.</body>';
|
|
195
|
+
res.writeHead(200, { 'content-type': 'text/html' });
|
|
196
|
+
res.end(okPage);
|
|
197
|
+
if (gotState !== state) {
|
|
198
|
+
finish({ ok: false, error: 'state mismatch — sign-in rejected (possible CSRF)' });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (!token) {
|
|
202
|
+
finish({ ok: false, error: 'sign-in returned no token' });
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const session = { token, email: email || 'you@hosted' };
|
|
206
|
+
setHostedSession(session);
|
|
207
|
+
finish({ ok: true, session });
|
|
208
|
+
});
|
|
209
|
+
const timer = setTimeout(() => finish({ ok: false, error: 'timed out waiting for sign-in' }), opts.timeoutMs ?? 120_000);
|
|
210
|
+
server.on('error', (e) => finish({ ok: false, error: `loopback server failed: ${e.message}` }));
|
|
211
|
+
server.listen(0, '127.0.0.1', () => {
|
|
212
|
+
const addr = server.address();
|
|
213
|
+
const port = addr && typeof addr === 'object' ? addr.port : 0;
|
|
214
|
+
const url = `${loginUrl}?port=${port}&state=${state}`;
|
|
215
|
+
Promise.resolve(opts.open(url)).catch(() => { });
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=hostedAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostedAuth.js","sourceRoot":"","sources":["../../src/core/hostedAuth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,gCAAgC,CAAC;AAEtE,+EAA+E;AAC/E,kDAAkD;AAClD,SAAS,OAAO;IACd,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACnH,CAAC;AACD,SAAS,WAAW;IAClB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACzC,CAAC;AAyBD,SAAS,QAAQ;IACf,6EAA6E;IAC7E,0EAA0E;IAC1E,8EAA8E;IAC9E,uBAAuB;IACvB,IAAI,IAAI,GAAgB,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YACtD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;gBAAE,IAAI,GAAG,MAAqB,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC;IAChE,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,IAAI,YAAY,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAiB;IAClC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IACzC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB;IAC9B,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7E,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,OAAO,CAAC,CAAC,KAAK,CAAC;IACf,OAAO,CAAC,CAAC,KAAK,CAAC;IACf,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACnH,SAAS,CAAC,CAAC,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,EAAE,CAAC,aAAa,KAAK,IAAI,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;IAEvC,IAAI,IAAa,CAAC;IAClB,IAAI,aAAa,IAAI,WAAW;QAAE,IAAI,GAAG,KAAK,CAAC;SAC1C,IAAI,OAAO;QAAE,IAAI,GAAG,QAAQ,CAAC;SAC7B,IAAI,WAAW;QAAE,IAAI,GAAG,KAAK,CAAC;;QAC9B,IAAI,GAAG,MAAM,CAAC;IAEnB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACpH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,SAAwB,cAAc,EAAE;IAClE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,gBAAgB,MAAM,CAAC,KAAK,sBAAsB;gBACvD,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9D,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,uBAAuB,CAAC;YACpE,MAAM,IAAI,GAAG,sCAAsC,GAAG,EAAE,CAAC;YACzD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,IAAI,OAAO;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAChG,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,0BAA0B,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACnH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC;AAQD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAIhC;IACC,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,gBAAgB,CAAC;IACnD,OAAO,IAAI,OAAO,CAAc,CAAC,QAAQ,EAAE,EAAE;QAC3C,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,MAAmB,EAAQ,EAAE;YAC3C,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC;gBAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YAC9C,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;YACxD,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YACjF,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,sFAAsF;kBACjG,0FAA0F,CAAC;YAC/F,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChB,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YACtH,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YAClF,MAAM,OAAO,GAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;YACvE,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC1B,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC;QACzH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA4B,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3G,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,GAAG,GAAG,GAAG,QAAQ,SAAS,IAAI,UAAU,KAAK,EAAE,CAAC;YACtD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAuC,CAAC,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|