patchwork-os 0.2.0-beta.9.canary.92 → 1.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.bridge.md +15 -16
- package/README.md +46 -458
- package/dist/activationMetrics.js +2 -3
- package/dist/activationMetrics.js.map +1 -1
- package/dist/activityLog.d.ts +1 -0
- package/dist/activityLog.js +8 -3
- package/dist/activityLog.js.map +1 -1
- package/dist/adapters/gemini.js +2 -2
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.js +6 -1
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.js +4 -0
- package/dist/adapters/openai.js.map +1 -1
- package/dist/approvalHttp.d.ts +9 -0
- package/dist/approvalHttp.js +210 -171
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalKpi.d.ts +102 -0
- package/dist/approvalKpi.js +282 -0
- package/dist/approvalKpi.js.map +1 -0
- package/dist/approvalQueue.d.ts +1 -1
- package/dist/approvalQueue.js.map +1 -1
- package/dist/automation.d.ts +45 -4
- package/dist/automation.js +123 -15
- package/dist/automation.js.map +1 -1
- package/dist/bridge.d.ts +10 -0
- package/dist/bridge.js +225 -46
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeLockDiscovery.d.ts +16 -1
- package/dist/bridgeLockDiscovery.js +38 -4
- package/dist/bridgeLockDiscovery.js.map +1 -1
- package/dist/bridgeToolsRules.js +3 -18
- package/dist/bridgeToolsRules.js.map +1 -1
- package/dist/claudeAuthHttp.d.ts +25 -0
- package/dist/claudeAuthHttp.js +219 -0
- package/dist/claudeAuthHttp.js.map +1 -0
- package/dist/claudeDriver.js +4 -1
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +15 -0
- package/dist/claudeOrchestrator.js +44 -0
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/connect.d.ts +47 -0
- package/dist/commands/connect.js +419 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/install.js +3 -10
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/launchd.d.ts +7 -0
- package/dist/commands/launchd.js +20 -2
- package/dist/commands/launchd.js.map +1 -1
- package/dist/commands/patchworkInit.d.ts +7 -0
- package/dist/commands/patchworkInit.js +26 -0
- package/dist/commands/patchworkInit.js.map +1 -1
- package/dist/commands/recipe.d.ts +59 -4
- package/dist/commands/recipe.js +206 -5
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +9 -0
- package/dist/commands/recipeInstall.js +56 -3
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/commands/task.d.ts +25 -0
- package/dist/commands/task.js +61 -41
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tokenEfficiency.d.ts +4 -0
- package/dist/commands/tokenEfficiency.js +23 -26
- package/dist/commands/tokenEfficiency.js.map +1 -1
- package/dist/commands/tracesExport.d.ts +15 -1
- package/dist/commands/tracesExport.js +39 -5
- package/dist/commands/tracesExport.js.map +1 -1
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +613 -62
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/asana.js +9 -3
- package/dist/connectors/asana.js.map +1 -1
- package/dist/connectors/baseConnector.d.ts +16 -0
- package/dist/connectors/baseConnector.js +2 -0
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/caldiy.js +34 -0
- package/dist/connectors/caldiy.js.map +1 -1
- package/dist/connectors/confluence.js +9 -2
- package/dist/connectors/confluence.js.map +1 -1
- package/dist/connectors/connectorActivity.d.ts +24 -0
- package/dist/connectors/connectorActivity.js +32 -0
- package/dist/connectors/connectorActivity.js.map +1 -0
- package/dist/connectors/connectorRedirectUri.js +22 -2
- package/dist/connectors/connectorRedirectUri.js.map +1 -1
- package/dist/connectors/connectorRegistry.d.ts +0 -3
- package/dist/connectors/connectorRegistry.js +8 -8
- package/dist/connectors/connectorRegistry.js.map +1 -1
- package/dist/connectors/datadog.js +8 -1
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/discord.js +4 -3
- package/dist/connectors/discord.js.map +1 -1
- package/dist/connectors/elasticsearch.js +22 -0
- package/dist/connectors/elasticsearch.js.map +1 -1
- package/dist/connectors/github.d.ts +38 -0
- package/dist/connectors/github.js +91 -5
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.js +19 -16
- package/dist/connectors/gitlab.js.map +1 -1
- package/dist/connectors/gmail.d.ts +5 -0
- package/dist/connectors/gmail.js +53 -11
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.js +5 -4
- package/dist/connectors/googleCalendar.js.map +1 -1
- package/dist/connectors/googleDocs.js +7 -6
- package/dist/connectors/googleDocs.js.map +1 -1
- package/dist/connectors/googleDrive.js +15 -8
- package/dist/connectors/googleDrive.js.map +1 -1
- package/dist/connectors/grafana.js +39 -3
- package/dist/connectors/grafana.js.map +1 -1
- package/dist/connectors/jira.d.ts +1 -1
- package/dist/connectors/jira.js +19 -4
- package/dist/connectors/jira.js.map +1 -1
- package/dist/connectors/linear.js +2 -2
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/mcpClient.d.ts +29 -1
- package/dist/connectors/mcpClient.js +114 -44
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/connectors/mcpOAuth.d.ts +1 -0
- package/dist/connectors/mcpOAuth.js +49 -4
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/monday.js +5 -4
- package/dist/connectors/monday.js.map +1 -1
- package/dist/connectors/mongodb.js +32 -5
- package/dist/connectors/mongodb.js.map +1 -1
- package/dist/connectors/notion.d.ts +1 -1
- package/dist/connectors/notion.js +22 -6
- package/dist/connectors/notion.js.map +1 -1
- package/dist/connectors/oauthError.d.ts +17 -0
- package/dist/connectors/oauthError.js +50 -0
- package/dist/connectors/oauthError.js.map +1 -0
- package/dist/connectors/postgres.d.ts +7 -0
- package/dist/connectors/postgres.js +32 -2
- package/dist/connectors/postgres.js.map +1 -1
- package/dist/connectors/posthog.js +26 -0
- package/dist/connectors/posthog.js.map +1 -1
- package/dist/connectors/redis.d.ts +1 -0
- package/dist/connectors/redis.js +47 -20
- package/dist/connectors/redis.js.map +1 -1
- package/dist/connectors/salesforce.js +66 -5
- package/dist/connectors/salesforce.js.map +1 -1
- package/dist/connectors/sentry.js +2 -2
- package/dist/connectors/sentry.js.map +1 -1
- package/dist/connectors/slack.js +37 -14
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/snowflake.js +24 -0
- package/dist/connectors/snowflake.js.map +1 -1
- package/dist/connectors/stripe.js +9 -2
- package/dist/connectors/stripe.js.map +1 -1
- package/dist/connectors/supabase.js +34 -0
- package/dist/connectors/supabase.js.map +1 -1
- package/dist/connectors/tokenStorage.d.ts +20 -0
- package/dist/connectors/tokenStorage.js +196 -64
- package/dist/connectors/tokenStorage.js.map +1 -1
- package/dist/connectors/woocommerce.js +34 -0
- package/dist/connectors/woocommerce.js.map +1 -1
- package/dist/copilot/parseIntent.d.ts +58 -0
- package/dist/copilot/parseIntent.js +149 -0
- package/dist/copilot/parseIntent.js.map +1 -0
- package/dist/decisionReplay.d.ts +8 -6
- package/dist/decisionReplay.js +35 -11
- package/dist/decisionReplay.js.map +1 -1
- package/dist/decisionTraceLog.d.ts +9 -0
- package/dist/decisionTraceLog.js +6 -0
- package/dist/decisionTraceLog.js.map +1 -1
- package/dist/drivers/claude/api.js +49 -7
- package/dist/drivers/claude/api.js.map +1 -1
- package/dist/drivers/claude/envSanitizer.d.ts +9 -1
- package/dist/drivers/claude/envSanitizer.js +41 -3
- package/dist/drivers/claude/envSanitizer.js.map +1 -1
- package/dist/drivers/claude/streamParser.d.ts +13 -0
- package/dist/drivers/claude/streamParser.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +131 -16
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/claude/subprocessSettings.d.ts +1 -1
- package/dist/drivers/claude/subprocessSettings.js +18 -4
- package/dist/drivers/claude/subprocessSettings.js.map +1 -1
- package/dist/drivers/gemini/index.d.ts +13 -0
- package/dist/drivers/gemini/index.js +211 -67
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +2 -17
- package/dist/drivers/local/index.js +5 -92
- package/dist/drivers/local/index.js.map +1 -1
- package/dist/drivers/openai/index.js +69 -9
- package/dist/drivers/openai/index.js.map +1 -1
- package/dist/drivers/outputCap.d.ts +27 -0
- package/dist/drivers/outputCap.js +50 -0
- package/dist/drivers/outputCap.js.map +1 -0
- package/dist/embeddings/cosine.d.ts +23 -0
- package/dist/embeddings/cosine.js +59 -0
- package/dist/embeddings/cosine.js.map +1 -0
- package/dist/embeddings/index.d.ts +19 -0
- package/dist/embeddings/index.js +35 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/localEmbeddings.d.ts +29 -0
- package/dist/embeddings/localEmbeddings.js +103 -0
- package/dist/embeddings/localEmbeddings.js.map +1 -0
- package/dist/embeddings/localEndpoints.d.ts +24 -0
- package/dist/embeddings/localEndpoints.js +37 -0
- package/dist/embeddings/localEndpoints.js.map +1 -0
- package/dist/embeddings/types.d.ts +32 -0
- package/dist/embeddings/types.js +12 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/featureFlags.d.ts +18 -0
- package/dist/featureFlags.js +32 -0
- package/dist/featureFlags.js.map +1 -1
- package/dist/fp/automationInterpreter.js +118 -39
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +10 -0
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/automationState.d.ts +6 -0
- package/dist/fp/automationState.js +38 -0
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/commandDescription.d.ts +6 -0
- package/dist/fp/commandDescription.js +18 -5
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/fp/interpreterContext.d.ts +16 -5
- package/dist/fp/interpreterContext.js +59 -3
- package/dist/fp/interpreterContext.js.map +1 -1
- package/dist/fp/policyParser.js +18 -8
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/haltPushDispatch.d.ts +4 -0
- package/dist/haltPushDispatch.js +7 -22
- package/dist/haltPushDispatch.js.map +1 -1
- package/dist/inboxRoutes.js +2 -2
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.js +672 -135
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -0
- package/dist/installGuard.js.map +1 -1
- package/dist/localEndpointGuard.d.ts +25 -0
- package/dist/localEndpointGuard.js +101 -0
- package/dist/localEndpointGuard.js.map +1 -0
- package/dist/mcpRoutes.js +1 -1
- package/dist/mcpRoutes.js.map +1 -1
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.js +53 -9
- package/dist/oauth.js.map +1 -1
- package/dist/orchestrator/childBridgeClient.d.ts +7 -0
- package/dist/orchestrator/childBridgeClient.js +42 -1
- package/dist/orchestrator/childBridgeClient.js.map +1 -1
- package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
- package/dist/orchestrator/orchestratorBridge.js +75 -9
- package/dist/orchestrator/orchestratorBridge.js.map +1 -1
- package/dist/patchworkConfig.d.ts +4 -0
- package/dist/patchworkConfig.js +33 -4
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/probe.js +39 -5
- package/dist/probe.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +59 -0
- package/dist/recipeOrchestration.js +314 -60
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +93 -0
- package/dist/recipeRoutes.js +664 -27
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/RecipeOrchestrator.d.ts +14 -0
- package/dist/recipes/RecipeOrchestrator.js +42 -2
- package/dist/recipes/RecipeOrchestrator.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +51 -2
- package/dist/recipes/agentExecutor.js +86 -13
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +111 -3
- package/dist/recipes/chainedRunner.js +440 -45
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/compiler.js +42 -29
- package/dist/recipes/compiler.js.map +1 -1
- package/dist/recipes/connectorPreflight.js +31 -0
- package/dist/recipes/connectorPreflight.js.map +1 -1
- package/dist/recipes/dependencyGraph.d.ts +16 -0
- package/dist/recipes/dependencyGraph.js +37 -2
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/eventTriggerPrograms.d.ts +36 -0
- package/dist/recipes/eventTriggerPrograms.js +158 -0
- package/dist/recipes/eventTriggerPrograms.js.map +1 -0
- package/dist/recipes/githubInstallSource.d.ts +9 -2
- package/dist/recipes/githubInstallSource.js +36 -6
- package/dist/recipes/githubInstallSource.js.map +1 -1
- package/dist/recipes/haltCategory.d.ts +10 -0
- package/dist/recipes/haltCategory.js +11 -1
- package/dist/recipes/haltCategory.js.map +1 -1
- package/dist/recipes/idempotencyKey.d.ts +30 -3
- package/dist/recipes/idempotencyKey.js +89 -5
- package/dist/recipes/idempotencyKey.js.map +1 -1
- package/dist/recipes/installer.js +12 -35
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/judgeVerdict.d.ts +11 -1
- package/dist/recipes/judgeVerdict.js +47 -7
- package/dist/recipes/judgeVerdict.js.map +1 -1
- package/dist/recipes/names.d.ts +5 -0
- package/dist/recipes/names.js +10 -5
- package/dist/recipes/names.js.map +1 -1
- package/dist/recipes/parser.js +74 -10
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/pricing/costRouter.d.ts +43 -0
- package/dist/recipes/pricing/costRouter.js +44 -0
- package/dist/recipes/pricing/costRouter.js.map +1 -0
- package/dist/recipes/pricing/priceTable.d.ts +76 -0
- package/dist/recipes/pricing/priceTable.js +144 -0
- package/dist/recipes/pricing/priceTable.js.map +1 -0
- package/dist/recipes/replayRun.js +5 -2
- package/dist/recipes/replayRun.js.map +1 -1
- package/dist/recipes/resolveRecipePath.js +15 -1
- package/dist/recipes/resolveRecipePath.js.map +1 -1
- package/dist/recipes/runBudget.d.ts +93 -32
- package/dist/recipes/runBudget.js +213 -49
- package/dist/recipes/runBudget.js.map +1 -1
- package/dist/recipes/runRegistry.d.ts +32 -0
- package/dist/recipes/runRegistry.js +54 -0
- package/dist/recipes/runRegistry.js.map +1 -0
- package/dist/recipes/scheduler.js +6 -2
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schema.d.ts +59 -6
- package/dist/recipes/schemaGenerator.d.ts +9 -0
- package/dist/recipes/schemaGenerator.js +446 -77
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/simulation/aggregateRunRisk.d.ts +46 -0
- package/dist/recipes/simulation/aggregateRunRisk.js +120 -0
- package/dist/recipes/simulation/aggregateRunRisk.js.map +1 -0
- package/dist/recipes/simulation/costProjector.d.ts +32 -0
- package/dist/recipes/simulation/costProjector.js +194 -0
- package/dist/recipes/simulation/costProjector.js.map +1 -0
- package/dist/recipes/simulation/sideEffects.d.ts +32 -0
- package/dist/recipes/simulation/sideEffects.js +62 -0
- package/dist/recipes/simulation/sideEffects.js.map +1 -0
- package/dist/recipes/simulation/simulate.d.ts +36 -0
- package/dist/recipes/simulation/simulate.js +264 -0
- package/dist/recipes/simulation/simulate.js.map +1 -0
- package/dist/recipes/simulation/simulateMockedRun.d.ts +52 -0
- package/dist/recipes/simulation/simulateMockedRun.js +84 -0
- package/dist/recipes/simulation/simulateMockedRun.js.map +1 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.d.ts +31 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js +50 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js.map +1 -0
- package/dist/recipes/simulation/types.d.ts +198 -0
- package/dist/recipes/simulation/types.js +30 -0
- package/dist/recipes/simulation/types.js.map +1 -0
- package/dist/recipes/stepObservation.d.ts +12 -0
- package/dist/recipes/stepObservation.js +21 -1
- package/dist/recipes/stepObservation.js.map +1 -1
- package/dist/recipes/toolRegistry.js +61 -24
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/airtable.d.ts +15 -0
- package/dist/recipes/tools/airtable.js +240 -0
- package/dist/recipes/tools/airtable.js.map +1 -0
- package/dist/recipes/tools/caldiy.d.ts +13 -0
- package/dist/recipes/tools/caldiy.js +215 -0
- package/dist/recipes/tools/caldiy.js.map +1 -0
- package/dist/recipes/tools/circleci.d.ts +10 -0
- package/dist/recipes/tools/circleci.js +204 -0
- package/dist/recipes/tools/circleci.js.map +1 -0
- package/dist/recipes/tools/cloudflare.d.ts +13 -0
- package/dist/recipes/tools/cloudflare.js +211 -0
- package/dist/recipes/tools/cloudflare.js.map +1 -0
- package/dist/recipes/tools/confluence.js +11 -10
- package/dist/recipes/tools/confluence.js.map +1 -1
- package/dist/recipes/tools/datadog.js +13 -12
- package/dist/recipes/tools/datadog.js.map +1 -1
- package/dist/recipes/tools/docs.d.ts +18 -0
- package/dist/recipes/tools/docs.js +95 -0
- package/dist/recipes/tools/docs.js.map +1 -0
- package/dist/recipes/tools/elasticsearch.d.ts +11 -0
- package/dist/recipes/tools/elasticsearch.js +157 -0
- package/dist/recipes/tools/elasticsearch.js.map +1 -0
- package/dist/recipes/tools/fanOut.js +4 -4
- package/dist/recipes/tools/fanOut.js.map +1 -1
- package/dist/recipes/tools/figma.d.ts +12 -0
- package/dist/recipes/tools/figma.js +195 -0
- package/dist/recipes/tools/figma.js.map +1 -0
- package/dist/recipes/tools/file.js +43 -22
- package/dist/recipes/tools/file.js.map +1 -1
- package/dist/recipes/tools/github.js +162 -5
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gmail.js +45 -33
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/grafana.d.ts +11 -0
- package/dist/recipes/tools/grafana.js +216 -0
- package/dist/recipes/tools/grafana.js.map +1 -0
- package/dist/recipes/tools/http.d.ts +1 -1
- package/dist/recipes/tools/http.js +10 -28
- package/dist/recipes/tools/http.js.map +1 -1
- package/dist/recipes/tools/hubspot.js +13 -12
- package/dist/recipes/tools/hubspot.js.map +1 -1
- package/dist/recipes/tools/index.d.ts +28 -0
- package/dist/recipes/tools/index.js +28 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/intercom.js +11 -10
- package/dist/recipes/tools/intercom.js.map +1 -1
- package/dist/recipes/tools/jira.js +13 -0
- package/dist/recipes/tools/jira.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.js +2 -2
- package/dist/recipes/tools/monday.d.ts +22 -0
- package/dist/recipes/tools/monday.js +242 -0
- package/dist/recipes/tools/monday.js.map +1 -0
- package/dist/recipes/tools/mongodb.d.ts +19 -0
- package/dist/recipes/tools/mongodb.js +194 -0
- package/dist/recipes/tools/mongodb.js.map +1 -0
- package/dist/recipes/tools/notion.js +11 -10
- package/dist/recipes/tools/notion.js.map +1 -1
- package/dist/recipes/tools/obsidian.d.ts +15 -0
- package/dist/recipes/tools/obsidian.js +173 -0
- package/dist/recipes/tools/obsidian.js.map +1 -0
- package/dist/recipes/tools/outcomes.d.ts +15 -0
- package/dist/recipes/tools/outcomes.js +111 -0
- package/dist/recipes/tools/outcomes.js.map +1 -0
- package/dist/recipes/tools/paystack.d.ts +11 -0
- package/dist/recipes/tools/paystack.js +212 -0
- package/dist/recipes/tools/paystack.js.map +1 -0
- package/dist/recipes/tools/pipedrive.d.ts +16 -0
- package/dist/recipes/tools/pipedrive.js +234 -0
- package/dist/recipes/tools/pipedrive.js.map +1 -0
- package/dist/recipes/tools/postgres.d.ts +15 -0
- package/dist/recipes/tools/postgres.js +186 -0
- package/dist/recipes/tools/postgres.js.map +1 -0
- package/dist/recipes/tools/posthog.d.ts +16 -0
- package/dist/recipes/tools/posthog.js +219 -0
- package/dist/recipes/tools/posthog.js.map +1 -0
- package/dist/recipes/tools/redis.d.ts +9 -0
- package/dist/recipes/tools/redis.js +141 -0
- package/dist/recipes/tools/redis.js.map +1 -0
- package/dist/recipes/tools/resend.d.ts +8 -0
- package/dist/recipes/tools/resend.js +153 -0
- package/dist/recipes/tools/resend.js.map +1 -0
- package/dist/recipes/tools/salesforce.d.ts +16 -0
- package/dist/recipes/tools/salesforce.js +184 -0
- package/dist/recipes/tools/salesforce.js.map +1 -0
- package/dist/recipes/tools/sendgrid.d.ts +9 -0
- package/dist/recipes/tools/sendgrid.js +175 -0
- package/dist/recipes/tools/sendgrid.js.map +1 -0
- package/dist/recipes/tools/shopify.d.ts +16 -0
- package/dist/recipes/tools/shopify.js +266 -0
- package/dist/recipes/tools/shopify.js.map +1 -0
- package/dist/recipes/tools/snowflake.d.ts +16 -0
- package/dist/recipes/tools/snowflake.js +173 -0
- package/dist/recipes/tools/snowflake.js.map +1 -0
- package/dist/recipes/tools/stripe.js +13 -12
- package/dist/recipes/tools/stripe.js.map +1 -1
- package/dist/recipes/tools/supabase.d.ts +9 -0
- package/dist/recipes/tools/supabase.js +133 -0
- package/dist/recipes/tools/supabase.js.map +1 -0
- package/dist/recipes/tools/todoist.d.ts +15 -0
- package/dist/recipes/tools/todoist.js +228 -0
- package/dist/recipes/tools/todoist.js.map +1 -0
- package/dist/recipes/tools/twilio.d.ts +11 -0
- package/dist/recipes/tools/twilio.js +180 -0
- package/dist/recipes/tools/twilio.js.map +1 -0
- package/dist/recipes/tools/vercel.d.ts +9 -0
- package/dist/recipes/tools/vercel.js +146 -0
- package/dist/recipes/tools/vercel.js.map +1 -0
- package/dist/recipes/tools/webflow.d.ts +11 -0
- package/dist/recipes/tools/webflow.js +244 -0
- package/dist/recipes/tools/webflow.js.map +1 -0
- package/dist/recipes/tools/woocommerce.d.ts +18 -0
- package/dist/recipes/tools/woocommerce.js +260 -0
- package/dist/recipes/tools/woocommerce.js.map +1 -0
- package/dist/recipes/tools/wrapConnectorExecute.d.ts +25 -0
- package/dist/recipes/tools/wrapConnectorExecute.js +37 -0
- package/dist/recipes/tools/wrapConnectorExecute.js.map +1 -0
- package/dist/recipes/tools/zendesk.js +11 -10
- package/dist/recipes/tools/zendesk.js.map +1 -1
- package/dist/recipes/triggerVars.d.ts +15 -0
- package/dist/recipes/triggerVars.js +57 -0
- package/dist/recipes/triggerVars.js.map +1 -0
- package/dist/recipes/validation.d.ts +1 -1
- package/dist/recipes/validation.js +536 -12
- package/dist/recipes/validation.js.map +1 -1
- package/dist/recipes/yamlPositions.d.ts +1 -1
- package/dist/recipes/yamlPositions.js +7 -2
- package/dist/recipes/yamlPositions.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +216 -4
- package/dist/recipes/yamlRunner.js +1030 -96
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +5 -0
- package/dist/recipesHttp.js +68 -6
- package/dist/recipesHttp.js.map +1 -1
- package/dist/resources.js +14 -1
- package/dist/resources.js.map +1 -1
- package/dist/riskSignals.d.ts +42 -0
- package/dist/riskSignals.js +197 -0
- package/dist/riskSignals.js.map +1 -0
- package/dist/riskTier.d.ts +9 -0
- package/dist/riskTier.js +48 -0
- package/dist/riskTier.js.map +1 -1
- package/dist/runLog.d.ts +53 -0
- package/dist/runLog.js +75 -16
- package/dist/runLog.js.map +1 -1
- package/dist/schemas/recipe.v1.json +360 -16
- package/dist/server.d.ts +60 -0
- package/dist/server.js +192 -31
- package/dist/server.js.map +1 -1
- package/dist/sessionCheckpoint.js +4 -1
- package/dist/sessionCheckpoint.js.map +1 -1
- package/dist/sessionDetail.d.ts +43 -0
- package/dist/sessionDetail.js +59 -0
- package/dist/sessionDetail.js.map +1 -0
- package/dist/settingsEnv.d.ts +47 -0
- package/dist/settingsEnv.js +88 -0
- package/dist/settingsEnv.js.map +1 -0
- package/dist/streamableHttp.js +44 -10
- package/dist/streamableHttp.js.map +1 -1
- package/dist/ta/backtest/abnday.d.ts +53 -0
- package/dist/ta/backtest/abnday.js +123 -0
- package/dist/ta/backtest/abnday.js.map +1 -0
- package/dist/ta/backtest/directional.d.ts +48 -0
- package/dist/ta/backtest/directional.js +103 -0
- package/dist/ta/backtest/directional.js.map +1 -0
- package/dist/ta/backtest/fundx.d.ts +67 -0
- package/dist/ta/backtest/fundx.js +264 -0
- package/dist/ta/backtest/fundx.js.map +1 -0
- package/dist/ta/backtest/fvg.d.ts +62 -0
- package/dist/ta/backtest/fvg.js +236 -0
- package/dist/ta/backtest/fvg.js.map +1 -0
- package/dist/ta/backtest/ichimoku.d.ts +41 -0
- package/dist/ta/backtest/ichimoku.js +146 -0
- package/dist/ta/backtest/ichimoku.js.map +1 -0
- package/dist/ta/backtest/ingest.d.ts +20 -0
- package/dist/ta/backtest/ingest.js +104 -0
- package/dist/ta/backtest/ingest.js.map +1 -0
- package/dist/ta/backtest/msb.d.ts +49 -0
- package/dist/ta/backtest/msb.js +162 -0
- package/dist/ta/backtest/msb.js.map +1 -0
- package/dist/ta/backtest/scoring.d.ts +33 -0
- package/dist/ta/backtest/scoring.js +82 -0
- package/dist/ta/backtest/scoring.js.map +1 -0
- package/dist/ta/backtest/summary.d.ts +20 -0
- package/dist/ta/backtest/summary.js +42 -0
- package/dist/ta/backtest/summary.js.map +1 -0
- package/dist/ta/backtest/tsmom.d.ts +72 -0
- package/dist/ta/backtest/tsmom.js +202 -0
- package/dist/ta/backtest/tsmom.js.map +1 -0
- package/dist/ta/backtest/volsq.d.ts +34 -0
- package/dist/ta/backtest/volsq.js +154 -0
- package/dist/ta/backtest/volsq.js.map +1 -0
- package/dist/ta/backtest/walkForward.d.ts +45 -0
- package/dist/ta/backtest/walkForward.js +136 -0
- package/dist/ta/backtest/walkForward.js.map +1 -0
- package/dist/ta/cycles.d.ts +15 -0
- package/dist/ta/cycles.js +31 -0
- package/dist/ta/cycles.js.map +1 -0
- package/dist/ta/desk/accrualEmitter.d.ts +59 -0
- package/dist/ta/desk/accrualEmitter.js +136 -0
- package/dist/ta/desk/accrualEmitter.js.map +1 -0
- package/dist/ta/desk/cellBacktest.d.ts +179 -0
- package/dist/ta/desk/cellBacktest.js +514 -0
- package/dist/ta/desk/cellBacktest.js.map +1 -0
- package/dist/ta/desk/cells/wpMaRejection.d.ts +49 -0
- package/dist/ta/desk/cells/wpMaRejection.js +141 -0
- package/dist/ta/desk/cells/wpMaRejection.js.map +1 -0
- package/dist/ta/desk/cells/wpVolumeClimax.d.ts +57 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js +193 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js.map +1 -0
- package/dist/ta/desk/collectors.d.ts +18 -0
- package/dist/ta/desk/collectors.js +450 -0
- package/dist/ta/desk/collectors.js.map +1 -0
- package/dist/ta/desk/contract.d.ts +51 -0
- package/dist/ta/desk/contract.js +261 -0
- package/dist/ta/desk/contract.js.map +1 -0
- package/dist/ta/desk/deskLedger.d.ts +36 -0
- package/dist/ta/desk/deskLedger.js +239 -0
- package/dist/ta/desk/deskLedger.js.map +1 -0
- package/dist/ta/desk/liqTape.d.ts +37 -0
- package/dist/ta/desk/liqTape.js +99 -0
- package/dist/ta/desk/liqTape.js.map +1 -0
- package/dist/ta/desk/post.d.ts +20 -0
- package/dist/ta/desk/post.js +65 -0
- package/dist/ta/desk/post.js.map +1 -0
- package/dist/ta/desk/render.d.ts +25 -0
- package/dist/ta/desk/render.js +398 -0
- package/dist/ta/desk/render.js.map +1 -0
- package/dist/ta/desk/surfaces.d.ts +216 -0
- package/dist/ta/desk/surfaces.js +472 -0
- package/dist/ta/desk/surfaces.js.map +1 -0
- package/dist/ta/desk/types.d.ts +174 -0
- package/dist/ta/desk/types.js +104 -0
- package/dist/ta/desk/types.js.map +1 -0
- package/dist/ta/index.d.ts +23 -0
- package/dist/ta/index.js +54 -0
- package/dist/ta/index.js.map +1 -0
- package/dist/ta/ledger.d.ts +44 -0
- package/dist/ta/ledger.js +95 -0
- package/dist/ta/ledger.js.map +1 -0
- package/dist/ta/levels.d.ts +21 -0
- package/dist/ta/levels.js +41 -0
- package/dist/ta/levels.js.map +1 -0
- package/dist/ta/swings.d.ts +30 -0
- package/dist/ta/swings.js +83 -0
- package/dist/ta/swings.js.map +1 -0
- package/dist/ta/types.d.ts +81 -0
- package/dist/ta/types.js +20 -0
- package/dist/ta/types.js.map +1 -0
- package/dist/telemetry.js +20 -9
- package/dist/telemetry.js.map +1 -1
- package/dist/tokenUsageTracker.d.ts +2 -1
- package/dist/tokenUsageTracker.js +38 -20
- package/dist/tokenUsageTracker.js.map +1 -1
- package/dist/tools/contextBundle.js +13 -9
- package/dist/tools/contextBundle.js.map +1 -1
- package/dist/tools/ctxGetTaskContext.js +8 -3
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/ctxQueryTraces.d.ts +18 -1
- package/dist/tools/ctxQueryTraces.js +176 -27
- package/dist/tools/ctxQueryTraces.js.map +1 -1
- package/dist/tools/enrichCommit.js +5 -2
- package/dist/tools/enrichCommit.js.map +1 -1
- package/dist/tools/getDependencyTree.js +2 -2
- package/dist/tools/getDependencyTree.js.map +1 -1
- package/dist/tools/getDiagnostics.js +3 -0
- package/dist/tools/getDiagnostics.js.map +1 -1
- package/dist/tools/getDocumentSymbols.js +5 -1
- package/dist/tools/getDocumentSymbols.js.map +1 -1
- package/dist/tools/getGitHotspots.js +12 -1
- package/dist/tools/getGitHotspots.js.map +1 -1
- package/dist/tools/getGitLog.js +5 -2
- package/dist/tools/getGitLog.js.map +1 -1
- package/dist/tools/getGitStatus.js +6 -1
- package/dist/tools/getGitStatus.js.map +1 -1
- package/dist/tools/getProjectContext.js +3 -1
- package/dist/tools/getProjectContext.js.map +1 -1
- package/dist/tools/getToolCapabilities.js +39 -4
- package/dist/tools/getToolCapabilities.js.map +1 -1
- package/dist/tools/gitWrite.js +12 -3
- package/dist/tools/gitWrite.js.map +1 -1
- package/dist/tools/github/composite.d.ts +1 -1
- package/dist/tools/github/composite.js +7 -7
- package/dist/tools/github/composite.js.map +1 -1
- package/dist/tools/github/pr.d.ts +6 -6
- package/dist/tools/github/pr.js +18 -11
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/httpClient.js +55 -3
- package/dist/tools/httpClient.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +19 -12
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lsp.d.ts +6 -0
- package/dist/tools/lsp.js +81 -12
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/previewEdit.js +16 -1
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/resumeClaudeTask.js +17 -0
- package/dist/tools/resumeClaudeTask.js.map +1 -1
- package/dist/tools/searchAndReplace.js +9 -5
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.d.ts +26 -0
- package/dist/tools/searchTools.js +42 -2
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/terminal.js +23 -51
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/transaction.d.ts +9 -1
- package/dist/tools/transaction.js +59 -4
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/utils.d.ts +16 -0
- package/dist/tools/utils.js +77 -7
- package/dist/tools/utils.js.map +1 -1
- package/dist/transport.d.ts +31 -0
- package/dist/transport.js +117 -14
- package/dist/transport.js.map +1 -1
- package/dist/wireHaltPushDispatch.js +12 -0
- package/dist/wireHaltPushDispatch.js.map +1 -1
- package/dist/workerGateDecisionLog.d.ts +141 -0
- package/dist/workerGateDecisionLog.js +361 -0
- package/dist/workerGateDecisionLog.js.map +1 -0
- package/dist/workers/actionClass.d.ts +38 -0
- package/dist/workers/actionClass.js +155 -0
- package/dist/workers/actionClass.js.map +1 -0
- package/dist/workers/backtest.d.ts +68 -0
- package/dist/workers/backtest.js +113 -0
- package/dist/workers/backtest.js.map +1 -0
- package/dist/workers/contextRisk.d.ts +35 -0
- package/dist/workers/contextRisk.js +20 -0
- package/dist/workers/contextRisk.js.map +1 -0
- package/dist/workers/contextRiskScorer.d.ts +48 -0
- package/dist/workers/contextRiskScorer.js +94 -0
- package/dist/workers/contextRiskScorer.js.map +1 -0
- package/dist/workers/graduation.d.ts +61 -0
- package/dist/workers/graduation.js +112 -0
- package/dist/workers/graduation.js.map +1 -0
- package/dist/workers/outcomeStore.d.ts +98 -0
- package/dist/workers/outcomeStore.js +146 -0
- package/dist/workers/outcomeStore.js.map +1 -0
- package/dist/workers/outcomesCli.d.ts +34 -0
- package/dist/workers/outcomesCli.js +91 -0
- package/dist/workers/outcomesCli.js.map +1 -0
- package/dist/workers/runWorkerShadow.d.ts +90 -0
- package/dist/workers/runWorkerShadow.js +323 -0
- package/dist/workers/runWorkerShadow.js.map +1 -0
- package/dist/workers/shadowGate.d.ts +30 -0
- package/dist/workers/shadowGate.js +58 -0
- package/dist/workers/shadowGate.js.map +1 -0
- package/dist/workers/shadowObserver.d.ts +165 -0
- package/dist/workers/shadowObserver.js +203 -0
- package/dist/workers/shadowObserver.js.map +1 -0
- package/dist/workers/shadowReport.d.ts +16 -0
- package/dist/workers/shadowReport.js +61 -0
- package/dist/workers/shadowReport.js.map +1 -0
- package/dist/workers/shadowRun.d.ts +38 -0
- package/dist/workers/shadowRun.js +44 -0
- package/dist/workers/shadowRun.js.map +1 -0
- package/dist/workers/trustLevel.d.ts +82 -0
- package/dist/workers/trustLevel.js +100 -0
- package/dist/workers/trustLevel.js.map +1 -0
- package/dist/workers/worker.d.ts +49 -0
- package/dist/workers/worker.js +88 -0
- package/dist/workers/worker.js.map +1 -0
- package/dist/workers/workerGate.d.ts +101 -0
- package/dist/workers/workerGate.js +210 -0
- package/dist/workers/workerGate.js.map +1 -0
- package/dist/workers/workerLevelStore.d.ts +33 -0
- package/dist/workers/workerLevelStore.js +87 -0
- package/dist/workers/workerLevelStore.js.map +1 -0
- package/dist/workers/workerLoader.d.ts +7 -0
- package/dist/workers/workerLoader.js +31 -0
- package/dist/workers/workerLoader.js.map +1 -0
- package/dist/writeFileAtomic.js +40 -13
- package/dist/writeFileAtomic.js.map +1 -1
- package/package.json +14 -6
- package/scripts/mcp-stdio-shim.cjs +247 -87
- package/templates/CLAUDE.bridge.md +1 -1
- package/templates/recipes/dependency-bump.yaml +33 -0
- package/templates/recipes/incident-to-pr.yaml +187 -0
- package/templates/recipes/outcome-ingester.yaml +53 -0
- package/templates/recipes/release-notes.yaml +30 -0
- package/templates/recipes/triage-failing-tests-autofile.yaml +152 -0
- package/templates/recipes/triage-failing-tests.yaml +38 -0
- package/templates/workers/dependency-upkeep.worker.yaml +26 -0
- package/templates/workers/release-notes.worker.yaml +17 -0
- package/templates/workers/test-guardian.worker.yaml +24 -0
- package/deploy/README.md +0 -172
- package/deploy/bootstrap-new-vps.sh +0 -364
- package/deploy/bootstrap-vps.sh +0 -192
- package/deploy/claude-ide-bridge.service.template +0 -67
- package/deploy/claude-ide-bridge@.service +0 -31
- package/deploy/deploy-dashboard.sh +0 -198
- package/deploy/deploy-landing.sh +0 -136
- package/deploy/ecosystem.config.js.example +0 -36
- package/deploy/install-vps-service.sh +0 -240
- package/deploy/macos/README.md +0 -153
- package/deploy/macos/com.patchwork.bridge.plist.template +0 -54
- package/deploy/macos/com.patchwork.tunnel.plist.template +0 -76
- package/deploy/macos/install-mac-bridge.sh +0 -244
- package/deploy/macos/uninstall-mac-bridge.sh +0 -22
- package/deploy/nginx-claude-bridge.conf.template +0 -129
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* surfaces.ts — PURE fact-producing functions for each desk surface.
|
|
3
|
+
*
|
|
4
|
+
* Every function returns plain facts (numbers/labels/booleans). NEVER computes a
|
|
5
|
+
* probability, midpoint, composite, or target. Risk math is deterministic
|
|
6
|
+
* arithmetic on a user-supplied trade. Positioning data (taker-buy%, crowd%) is
|
|
7
|
+
* returned as RAW ARCHIVED FACT with NO directional lean (deterministic ≠
|
|
8
|
+
* validated). Ichimoku is computed ONLY as a no-edge LOCATION line.
|
|
9
|
+
*
|
|
10
|
+
* See /tmp/qumo-design/signals-spec.md + DESIGN.md §5/§6.
|
|
11
|
+
*/
|
|
12
|
+
import type { Candle } from "../types.js";
|
|
13
|
+
import type { Collected, DepthBook, OptionRow, Posture, QumoTrade, SectorRow } from "./types.js";
|
|
14
|
+
/** Liq-distance posture bands (rendered inline, never a forward call). */
|
|
15
|
+
export declare const LIQ_WIDE_PCT = 8;
|
|
16
|
+
export declare const LIQ_CONTESTED_PCT = 2;
|
|
17
|
+
/** Linear-perp maintenance-margin proxy for the liq-price estimate. */
|
|
18
|
+
export declare const MAINTENANCE_MARGIN = 0.005;
|
|
19
|
+
/** Trend CONSISTENT band: |24h%| <= this → neutral. */
|
|
20
|
+
export declare const TREND_NEUTRAL_BAND = 1;
|
|
21
|
+
/** Rekt Shield outcome window (bookkeeping grade-at). */
|
|
22
|
+
export declare const REKT_WINDOW_DAYS = 7;
|
|
23
|
+
export interface TodaysReadFacts {
|
|
24
|
+
posture: Posture;
|
|
25
|
+
reason: string;
|
|
26
|
+
nRisk: number;
|
|
27
|
+
nWatch: number;
|
|
28
|
+
nConfirm: number;
|
|
29
|
+
nGreen: number | null;
|
|
30
|
+
nRed: number | null;
|
|
31
|
+
universeN: number | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Deterministic posture rule (pre-registered):
|
|
35
|
+
* - load-bearing feed offline WHILE an open risk tally stands → "Alarm fired"
|
|
36
|
+
* (cannot manage live risk blind)
|
|
37
|
+
* - any other load-bearing feed offline OR zero confirms → "Standing aside"
|
|
38
|
+
* - any risk tally → "Holding-defensive"
|
|
39
|
+
* - any watch tally (no risk) → "Watching X"
|
|
40
|
+
* - confirms present, no risk/watch, feeds healthy → "Holding"
|
|
41
|
+
* Engine-decided, never LLM vibe. Every one of the five ALLOWED_POSTURES is
|
|
42
|
+
* reachable by this rule.
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeTodaysRead(feeds: Collected, tri: {
|
|
45
|
+
nRisk: number;
|
|
46
|
+
nWatch: number;
|
|
47
|
+
nConfirm: number;
|
|
48
|
+
}): TodaysReadFacts;
|
|
49
|
+
export interface RektFacts {
|
|
50
|
+
idle: boolean;
|
|
51
|
+
/** the supplied stop price (for the structural stop-vs-band line). */
|
|
52
|
+
stop?: number;
|
|
53
|
+
liqPrice?: number;
|
|
54
|
+
liqDistancePct?: number;
|
|
55
|
+
rrRatio?: number;
|
|
56
|
+
riskLegPct?: number;
|
|
57
|
+
rewardLegPct?: number;
|
|
58
|
+
capitalAtRiskPct?: number;
|
|
59
|
+
liqPosture?: "WIDE" | "NEAR" | "CONTESTED";
|
|
60
|
+
gradeAt?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Pure risk arithmetic. No prediction. liqPrice from leverage + maintenance;
|
|
64
|
+
* R:R from entry/stop/target legs; capital-at-risk = riskLeg/leverage proxy.
|
|
65
|
+
*/
|
|
66
|
+
export declare function computeRektShield(trade: QumoTrade | null, nowMs: number): RektFacts;
|
|
67
|
+
export interface DnaFacts {
|
|
68
|
+
/** trend lean is allowed (price-only validated). */
|
|
69
|
+
trend: {
|
|
70
|
+
live: boolean;
|
|
71
|
+
pct: number | null;
|
|
72
|
+
lean: string;
|
|
73
|
+
};
|
|
74
|
+
/** funding raw (lean only if a funding claim matured — never in v1). */
|
|
75
|
+
funding: {
|
|
76
|
+
live: boolean;
|
|
77
|
+
pct: number | null;
|
|
78
|
+
};
|
|
79
|
+
spotConfirm: {
|
|
80
|
+
live: boolean;
|
|
81
|
+
pct: number | null;
|
|
82
|
+
};
|
|
83
|
+
leverage: {
|
|
84
|
+
live: boolean;
|
|
85
|
+
crowdPct: number | null;
|
|
86
|
+
oiPct: number | null;
|
|
87
|
+
};
|
|
88
|
+
liveCount: number;
|
|
89
|
+
}
|
|
90
|
+
export declare function computeBtcDna(feeds: Collected): DnaFacts;
|
|
91
|
+
export interface IchimokuLocation {
|
|
92
|
+
available: boolean;
|
|
93
|
+
/** "above" | "below" | "in" the cloud, location only. */
|
|
94
|
+
cloud?: "above" | "below" | "in";
|
|
95
|
+
/** bars since the last TK cross, location only. */
|
|
96
|
+
tkCrossBarsAgo?: number | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Compute cloud position + TK cross as a LOCATION line. NEVER a directional
|
|
100
|
+
* lean, NEVER graded, NEVER in numbersIndex as a tradeable claim. The render
|
|
101
|
+
* layer attaches the explicit no-edge label. Standard 9/26/52 Hosoda params.
|
|
102
|
+
*/
|
|
103
|
+
export declare function computeIchimokuLocation(candles: Candle[] | null): IchimokuLocation;
|
|
104
|
+
export interface AtlasFacts {
|
|
105
|
+
available: boolean;
|
|
106
|
+
sectors: SectorRow[];
|
|
107
|
+
leaders: string[];
|
|
108
|
+
laggards: string[];
|
|
109
|
+
}
|
|
110
|
+
export declare function computeAtlas(rows: SectorRow[] | null): AtlasFacts;
|
|
111
|
+
export interface DepthFacts {
|
|
112
|
+
available: boolean;
|
|
113
|
+
mid?: number;
|
|
114
|
+
/** bid notional $ within ±1% / ±2% of mid. */
|
|
115
|
+
bid1Pct?: number;
|
|
116
|
+
bid2Pct?: number;
|
|
117
|
+
/** ask notional $ within ±1% / ±2% of mid. */
|
|
118
|
+
ask1Pct?: number;
|
|
119
|
+
ask2Pct?: number;
|
|
120
|
+
/** descriptive ratio word (NOT a forecast). */
|
|
121
|
+
skew?: "bid-heavy" | "ask-heavy" | "balanced";
|
|
122
|
+
/** single largest bid wall within ±2% (price + $ notional). */
|
|
123
|
+
bidWallPrice?: number;
|
|
124
|
+
bidWallUsd?: number;
|
|
125
|
+
/** single largest ask wall within ±2% (price + $ notional). */
|
|
126
|
+
askWallPrice?: number;
|
|
127
|
+
askWallUsd?: number;
|
|
128
|
+
/** widest adjacent-level price gap (thin zone) within ±2% [lo, hi]. */
|
|
129
|
+
thinLo?: number;
|
|
130
|
+
thinHi?: number;
|
|
131
|
+
/** false when the book is too dense for a meaningful vacuum (sub-tick gap). */
|
|
132
|
+
thinZone?: boolean;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Pure book-structure facts. mid = (bestBid+bestAsk)/2. Notional = price*qty
|
|
136
|
+
* summed within ±1%/±2% bands; largest single-level wall per side; widest
|
|
137
|
+
* adjacent-level gap as a "thin zone". NEVER a direction/target/signal — "skew"
|
|
138
|
+
* is a descriptive ratio word only.
|
|
139
|
+
*/
|
|
140
|
+
export declare function depthSurface(book: DepthBook | null): DepthFacts;
|
|
141
|
+
export interface MaxPainFacts {
|
|
142
|
+
available: boolean;
|
|
143
|
+
/** parsed expiry token of the front (nearest) expiry (e.g. "27JUN26"). */
|
|
144
|
+
expiry?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Front expiry as a canonical ISO date (YYYY-MM-DD). The render layer narrates
|
|
147
|
+
* THIS, never the raw Deribit DDMMMYY token — the DDMMMYY form embeds bare
|
|
148
|
+
* digits (27, 26) that would otherwise leak as un-indexed narrated numbers
|
|
149
|
+
* (only ISO YYYY-MM-DD dates are machine-exempt from the numbersIndex spine).
|
|
150
|
+
*/
|
|
151
|
+
expiryIso?: string;
|
|
152
|
+
/** max-pain strike = argmin total intrinsic value (OI-weighted). */
|
|
153
|
+
maxPainStrike?: number;
|
|
154
|
+
/** put/call OI ratio for that expiry. */
|
|
155
|
+
putCallRatio?: number;
|
|
156
|
+
/** total option OI (BTC) for that expiry. */
|
|
157
|
+
totalOi?: number;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Front-expiry max-pain. Selects the NEAREST not-yet-expired expiry, then for
|
|
161
|
+
* each listed strike S computes pain(S) = Σ_calls OI*max(0,S-K) +
|
|
162
|
+
* Σ_puts OI*max(0,K-S); max-pain = argmin. Also the put/call OI ratio + total
|
|
163
|
+
* OI for that expiry. This is an OI SNAPSHOT — NOT a price magnet/target. The
|
|
164
|
+
* render layer attaches the explicit no-magnet label.
|
|
165
|
+
*/
|
|
166
|
+
export declare function maxPainSurface(rows: OptionRow[] | null, nowMs: number): MaxPainFacts;
|
|
167
|
+
/** Standard leverage buckets the geometry is modeled at (frozen). */
|
|
168
|
+
export declare const LIQ_LEVERAGE_BUCKETS: readonly [10, 25, 50, 100];
|
|
169
|
+
/** One leverage bucket's modeled long/short liq price bands (whole dollars). */
|
|
170
|
+
export interface LiqBand {
|
|
171
|
+
n: number;
|
|
172
|
+
/** long-liq price ≈ mid·(1 − 1/N), rounded to whole dollars. */
|
|
173
|
+
longLiq: number;
|
|
174
|
+
/** short-liq price ≈ mid·(1 + 1/N), rounded to whole dollars. */
|
|
175
|
+
shortLiq: number;
|
|
176
|
+
}
|
|
177
|
+
export interface LiqGeoFacts {
|
|
178
|
+
available: boolean;
|
|
179
|
+
/** order-book mid (or fallback close) the geometry is modeled from. */
|
|
180
|
+
mid?: number;
|
|
181
|
+
/** total perp OI notional ($) — pool that COULD be exposed (not distributed). */
|
|
182
|
+
oiNotional?: number | null;
|
|
183
|
+
bands?: LiqBand[];
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Pure leverage-bucket geometry — NO network fetch, NO forecast. For each
|
|
187
|
+
* standard leverage N ∈ {10,25,50,100}: long-liq ≈ mid·(1−1/N), short-liq ≈
|
|
188
|
+
* mid·(1+1/N), rounded to whole dollars. The total perp OI $ is reported as the
|
|
189
|
+
* pool that COULD be exposed, NOT distributed (we do not know per-position entry
|
|
190
|
+
* or leverage). This is GEOMETRY/LOCATION, exactly like order-book walls — never
|
|
191
|
+
* a magnet, never a forecast, never directional. The render layer attaches the
|
|
192
|
+
* explicit no-forecast/no-magnet label.
|
|
193
|
+
*/
|
|
194
|
+
export declare function liqGeometrySurface(mid: number | null, oiNotional: number | null): LiqGeoFacts;
|
|
195
|
+
/**
|
|
196
|
+
* Structural stop-vs-band read for Rekt Shield — PURE location, NO recommendation
|
|
197
|
+
* and NO forecast. Given the trade's stop + side, find the modeled liq band on
|
|
198
|
+
* the SAME side (long trade → long-liq bands; short → short-liq) NEAREST the stop,
|
|
199
|
+
* and report whether the stop sits within NEAR_PCT of it or clear of it. Returns
|
|
200
|
+
* null when geometry is unavailable. Wording is assembled in the render layer.
|
|
201
|
+
*/
|
|
202
|
+
export interface StopBandFact {
|
|
203
|
+
/** leverage bucket of the nearest same-side band. */
|
|
204
|
+
n: number;
|
|
205
|
+
/** the band price (whole dollars). */
|
|
206
|
+
bandPrice: number;
|
|
207
|
+
/** absolute % distance stop→band. */
|
|
208
|
+
pct: number;
|
|
209
|
+
/** within NEAR_PCT → "within", else "clear of". */
|
|
210
|
+
within: boolean;
|
|
211
|
+
side: "long" | "short";
|
|
212
|
+
}
|
|
213
|
+
/** Stop-vs-band proximity threshold (%). Pure structure, not a recommendation. */
|
|
214
|
+
export declare const STOP_BAND_NEAR_PCT = 5;
|
|
215
|
+
export declare function stopVsBand(trade: QumoTrade | null, geo: LiqGeoFacts): StopBandFact | null;
|
|
216
|
+
export declare function fmtSigned(n: number): string;
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* surfaces.ts — PURE fact-producing functions for each desk surface.
|
|
3
|
+
*
|
|
4
|
+
* Every function returns plain facts (numbers/labels/booleans). NEVER computes a
|
|
5
|
+
* probability, midpoint, composite, or target. Risk math is deterministic
|
|
6
|
+
* arithmetic on a user-supplied trade. Positioning data (taker-buy%, crowd%) is
|
|
7
|
+
* returned as RAW ARCHIVED FACT with NO directional lean (deterministic ≠
|
|
8
|
+
* validated). Ichimoku is computed ONLY as a no-edge LOCATION line.
|
|
9
|
+
*
|
|
10
|
+
* See /tmp/qumo-design/signals-spec.md + DESIGN.md §5/§6.
|
|
11
|
+
*/
|
|
12
|
+
// ── Pre-registered thresholds (frozen; docs/qumo-desk-precommit.md) ──────────
|
|
13
|
+
/** Liq-distance posture bands (rendered inline, never a forward call). */
|
|
14
|
+
export const LIQ_WIDE_PCT = 8; // > 8% → WIDE
|
|
15
|
+
export const LIQ_CONTESTED_PCT = 2; // < 2% → CONTESTED; else NEAR
|
|
16
|
+
/** Linear-perp maintenance-margin proxy for the liq-price estimate. */
|
|
17
|
+
export const MAINTENANCE_MARGIN = 0.005;
|
|
18
|
+
/** Trend CONSISTENT band: |24h%| <= this → neutral. */
|
|
19
|
+
export const TREND_NEUTRAL_BAND = 1.0;
|
|
20
|
+
/** Rekt Shield outcome window (bookkeeping grade-at). */
|
|
21
|
+
export const REKT_WINDOW_DAYS = 7;
|
|
22
|
+
/**
|
|
23
|
+
* Deterministic posture rule (pre-registered):
|
|
24
|
+
* - load-bearing feed offline WHILE an open risk tally stands → "Alarm fired"
|
|
25
|
+
* (cannot manage live risk blind)
|
|
26
|
+
* - any other load-bearing feed offline OR zero confirms → "Standing aside"
|
|
27
|
+
* - any risk tally → "Holding-defensive"
|
|
28
|
+
* - any watch tally (no risk) → "Watching X"
|
|
29
|
+
* - confirms present, no risk/watch, feeds healthy → "Holding"
|
|
30
|
+
* Engine-decided, never LLM vibe. Every one of the five ALLOWED_POSTURES is
|
|
31
|
+
* reachable by this rule.
|
|
32
|
+
*/
|
|
33
|
+
export function computeTodaysRead(feeds, tri) {
|
|
34
|
+
const breadth = feeds.breadth.value;
|
|
35
|
+
const loadBearingOffline = feeds.btc1d.state !== "live" || feeds.btc24hPct.state !== "live";
|
|
36
|
+
let posture;
|
|
37
|
+
let reason;
|
|
38
|
+
if (loadBearingOffline && tri.nRisk > 0) {
|
|
39
|
+
posture = "Alarm fired";
|
|
40
|
+
reason =
|
|
41
|
+
"load-bearing price feed offline while open risk stands — cannot manage risk blind";
|
|
42
|
+
}
|
|
43
|
+
else if (loadBearingOffline) {
|
|
44
|
+
posture = "Standing aside";
|
|
45
|
+
reason = "load-bearing price feed offline — no read";
|
|
46
|
+
}
|
|
47
|
+
else if (tri.nRisk > 0) {
|
|
48
|
+
posture = "Holding-defensive";
|
|
49
|
+
reason = "open risk tally on the live ledger";
|
|
50
|
+
}
|
|
51
|
+
else if (tri.nWatch > 0) {
|
|
52
|
+
posture = "Watching X";
|
|
53
|
+
reason = "watch tally accruing, no confirmed risk";
|
|
54
|
+
}
|
|
55
|
+
else if (tri.nConfirm === 0) {
|
|
56
|
+
posture = "Standing aside";
|
|
57
|
+
reason = "no confirmed signals and no open tallies";
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const pct = feeds.btc24hPct.value;
|
|
61
|
+
posture = "Holding";
|
|
62
|
+
reason =
|
|
63
|
+
pct !== null && Math.abs(pct) <= TREND_NEUTRAL_BAND
|
|
64
|
+
? `trend flat (24h ${fmtSigned(pct)}%), confirms present`
|
|
65
|
+
: "confirms present, no open risk";
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
posture,
|
|
69
|
+
reason,
|
|
70
|
+
nRisk: tri.nRisk,
|
|
71
|
+
nWatch: tri.nWatch,
|
|
72
|
+
nConfirm: tri.nConfirm,
|
|
73
|
+
nGreen: breadth ? breadth.green : null,
|
|
74
|
+
nRed: breadth ? breadth.red : null,
|
|
75
|
+
universeN: breadth ? breadth.universe : null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Pure risk arithmetic. No prediction. liqPrice from leverage + maintenance;
|
|
80
|
+
* R:R from entry/stop/target legs; capital-at-risk = riskLeg/leverage proxy.
|
|
81
|
+
*/
|
|
82
|
+
export function computeRektShield(trade, nowMs) {
|
|
83
|
+
if (!trade)
|
|
84
|
+
return { idle: true };
|
|
85
|
+
const { side, entry, stop, target, leverage } = trade;
|
|
86
|
+
if (!(entry > 0) ||
|
|
87
|
+
!(leverage > 0) ||
|
|
88
|
+
!Number.isFinite(stop) ||
|
|
89
|
+
!Number.isFinite(target)) {
|
|
90
|
+
return { idle: true };
|
|
91
|
+
}
|
|
92
|
+
const long = side === "long";
|
|
93
|
+
// Liquidation price for an isolated linear perp (maintenance-margin proxy).
|
|
94
|
+
// M27: clamp to a minimum fraction — at leverage >= 200x the naive formula
|
|
95
|
+
// yields a non-positive liqFrac (e.g. 250x: 1/250 - 0.005 = -0.001), which
|
|
96
|
+
// would place liqPrice above entry on a long trade (impossible).
|
|
97
|
+
const liqFrac = Math.max(1 / leverage - MAINTENANCE_MARGIN, 0.0001);
|
|
98
|
+
const liqPrice = long ? entry * (1 - liqFrac) : entry * (1 + liqFrac);
|
|
99
|
+
const liqDistancePct = Number((liqFrac * 100).toFixed(1));
|
|
100
|
+
const riskLeg = Math.abs(entry - stop);
|
|
101
|
+
const rewardLeg = Math.abs(target - entry);
|
|
102
|
+
const riskLegPct = Number(((riskLeg / entry) * 100).toFixed(1));
|
|
103
|
+
const rewardLegPct = Number(((rewardLeg / entry) * 100).toFixed(1));
|
|
104
|
+
const rrRatio = riskLeg > 0 ? Number((rewardLeg / riskLeg).toFixed(2)) : 0;
|
|
105
|
+
// Capital at risk: price-delta risk leg multiplied by leverage (H9).
|
|
106
|
+
// Without the leverage factor, a 1% stop at 10x reports only 1% at risk
|
|
107
|
+
// instead of the correct 10% of margin capital.
|
|
108
|
+
const capitalAtRiskPct = Number((riskLegPct * leverage).toFixed(1));
|
|
109
|
+
const liqPosture = liqDistancePct > LIQ_WIDE_PCT
|
|
110
|
+
? "WIDE"
|
|
111
|
+
: liqDistancePct < LIQ_CONTESTED_PCT
|
|
112
|
+
? "CONTESTED"
|
|
113
|
+
: "NEAR";
|
|
114
|
+
const gradeAt = new Date(nowMs + REKT_WINDOW_DAYS * 86_400_000).toISOString();
|
|
115
|
+
return {
|
|
116
|
+
idle: false,
|
|
117
|
+
stop: Number(stop.toFixed(roundDigits(stop))),
|
|
118
|
+
liqPrice: Number(liqPrice.toFixed(roundDigits(liqPrice))),
|
|
119
|
+
liqDistancePct,
|
|
120
|
+
rrRatio,
|
|
121
|
+
riskLegPct,
|
|
122
|
+
rewardLegPct,
|
|
123
|
+
capitalAtRiskPct,
|
|
124
|
+
liqPosture,
|
|
125
|
+
gradeAt,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export function computeBtcDna(feeds) {
|
|
129
|
+
const pct = feeds.btc24hPct.value;
|
|
130
|
+
const trendLive = feeds.btc24hPct.state === "live" && pct !== null;
|
|
131
|
+
let lean = "feed offline";
|
|
132
|
+
if (trendLive && pct !== null) {
|
|
133
|
+
lean =
|
|
134
|
+
Math.abs(pct) <= TREND_NEUTRAL_BAND
|
|
135
|
+
? "neutral (consistent)"
|
|
136
|
+
: pct > 0
|
|
137
|
+
? "up — consistent"
|
|
138
|
+
: "down — consistent";
|
|
139
|
+
}
|
|
140
|
+
const fundingLive = feeds.funding.state === "live" && feeds.funding.value !== null;
|
|
141
|
+
const spotLive = feeds.takerBuyPct.state === "live" && feeds.takerBuyPct.value !== null;
|
|
142
|
+
const levLive = feeds.crowdLongPct.state === "live" && feeds.crowdLongPct.value !== null;
|
|
143
|
+
// Only price-trend counts as a LIVE lean-bearing strand. Funding/positioning
|
|
144
|
+
// are archived/raw, not "read", per the moat — so the live-strand count is
|
|
145
|
+
// trend-only when present.
|
|
146
|
+
const liveCount = trendLive ? 1 : 0;
|
|
147
|
+
return {
|
|
148
|
+
trend: { live: trendLive, pct, lean },
|
|
149
|
+
funding: { live: fundingLive, pct: feeds.funding.value },
|
|
150
|
+
spotConfirm: { live: spotLive, pct: feeds.takerBuyPct.value },
|
|
151
|
+
leverage: {
|
|
152
|
+
live: levLive,
|
|
153
|
+
crowdPct: feeds.crowdLongPct.value,
|
|
154
|
+
oiPct: feeds.oiChangePct.value,
|
|
155
|
+
},
|
|
156
|
+
liveCount,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Compute cloud position + TK cross as a LOCATION line. NEVER a directional
|
|
161
|
+
* lean, NEVER graded, NEVER in numbersIndex as a tradeable claim. The render
|
|
162
|
+
* layer attaches the explicit no-edge label. Standard 9/26/52 Hosoda params.
|
|
163
|
+
*/
|
|
164
|
+
export function computeIchimokuLocation(candles) {
|
|
165
|
+
if (!candles || candles.length < 53)
|
|
166
|
+
return { available: false };
|
|
167
|
+
const n = candles.length;
|
|
168
|
+
const last = candles[n - 1];
|
|
169
|
+
const periodHL = (lookback, end) => {
|
|
170
|
+
let hi = -Infinity;
|
|
171
|
+
let lo = Infinity;
|
|
172
|
+
for (let i = end - lookback + 1; i <= end; i++) {
|
|
173
|
+
if (i < 0)
|
|
174
|
+
continue;
|
|
175
|
+
hi = Math.max(hi, candles[i].high);
|
|
176
|
+
lo = Math.min(lo, candles[i].low);
|
|
177
|
+
}
|
|
178
|
+
return (hi + lo) / 2;
|
|
179
|
+
};
|
|
180
|
+
// Senkou A/B projected 26 forward; for "current cloud" use the spans plotted
|
|
181
|
+
// at the current bar (computed from 26 bars ago).
|
|
182
|
+
const tenkanAt = (end) => periodHL(9, end);
|
|
183
|
+
const kijunAt = (end) => periodHL(26, end);
|
|
184
|
+
const senkouAAt = (end) => (tenkanAt(end) + kijunAt(end)) / 2;
|
|
185
|
+
const senkouBAt = (end) => periodHL(52, end);
|
|
186
|
+
const spanEnd = n - 1 - 26;
|
|
187
|
+
if (spanEnd < 52) {
|
|
188
|
+
// not enough history for a plotted cloud at the current bar
|
|
189
|
+
return { available: false };
|
|
190
|
+
}
|
|
191
|
+
const a = senkouAAt(spanEnd);
|
|
192
|
+
const b = senkouBAt(spanEnd);
|
|
193
|
+
const cloudTop = Math.max(a, b);
|
|
194
|
+
const cloudBot = Math.min(a, b);
|
|
195
|
+
const cloud = last.close > cloudTop ? "above" : last.close < cloudBot ? "below" : "in";
|
|
196
|
+
// TK cross: walk back to find the most recent tenkan/kijun sign change.
|
|
197
|
+
let tkCrossBarsAgo = null;
|
|
198
|
+
let prevSign = 0;
|
|
199
|
+
for (let i = 26; i < n; i++) {
|
|
200
|
+
const t = tenkanAt(i);
|
|
201
|
+
const k = kijunAt(i);
|
|
202
|
+
const sign = Math.sign(t - k);
|
|
203
|
+
if (sign !== 0 && prevSign !== 0 && sign !== prevSign) {
|
|
204
|
+
tkCrossBarsAgo = n - 1 - i;
|
|
205
|
+
}
|
|
206
|
+
if (sign !== 0)
|
|
207
|
+
prevSign = sign;
|
|
208
|
+
}
|
|
209
|
+
return { available: true, cloud, tkCrossBarsAgo };
|
|
210
|
+
}
|
|
211
|
+
export function computeAtlas(rows) {
|
|
212
|
+
if (!rows || rows.length === 0)
|
|
213
|
+
return { available: false, sectors: [], leaders: [], laggards: [] };
|
|
214
|
+
const sorted = [...rows].sort((x, y) => y.change24hPct - x.change24hPct);
|
|
215
|
+
return {
|
|
216
|
+
available: true,
|
|
217
|
+
sectors: sorted,
|
|
218
|
+
leaders: sorted.slice(0, 1).map((s) => s.name),
|
|
219
|
+
laggards: sorted.slice(-1).map((s) => s.name),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/** Skew threshold — ratio outside [1/x, x] is heavy; inside is balanced. */
|
|
223
|
+
const DEPTH_SKEW_RATIO = 1.25;
|
|
224
|
+
/**
|
|
225
|
+
* Pure book-structure facts. mid = (bestBid+bestAsk)/2. Notional = price*qty
|
|
226
|
+
* summed within ±1%/±2% bands; largest single-level wall per side; widest
|
|
227
|
+
* adjacent-level gap as a "thin zone". NEVER a direction/target/signal — "skew"
|
|
228
|
+
* is a descriptive ratio word only.
|
|
229
|
+
*/
|
|
230
|
+
export function depthSurface(book) {
|
|
231
|
+
if (!book || book.bids.length === 0 || book.asks.length === 0) {
|
|
232
|
+
return { available: false };
|
|
233
|
+
}
|
|
234
|
+
const bestBid = book.bids[0][0];
|
|
235
|
+
const bestAsk = book.asks[0][0];
|
|
236
|
+
if (!(bestBid > 0) || !(bestAsk > 0))
|
|
237
|
+
return { available: false };
|
|
238
|
+
const mid = (bestBid + bestAsk) / 2;
|
|
239
|
+
const band1 = mid * 0.01;
|
|
240
|
+
const band2 = mid * 0.02;
|
|
241
|
+
let bid1 = 0;
|
|
242
|
+
let bid2 = 0;
|
|
243
|
+
let bidWallUsd = 0;
|
|
244
|
+
let bidWallPrice = 0;
|
|
245
|
+
// Bids: prices <= mid, walk down. Within-band = mid-price <= band.
|
|
246
|
+
const bidLevels = [];
|
|
247
|
+
for (const [p, q] of book.bids) {
|
|
248
|
+
const dist = mid - p;
|
|
249
|
+
if (dist > band2)
|
|
250
|
+
break; // bids descend → past ±2% we can stop
|
|
251
|
+
if (dist < 0)
|
|
252
|
+
continue; // crossed level (rare); skip
|
|
253
|
+
const notional = p * q;
|
|
254
|
+
if (dist <= band1)
|
|
255
|
+
bid1 += notional;
|
|
256
|
+
bid2 += notional;
|
|
257
|
+
bidLevels.push([p, notional]);
|
|
258
|
+
if (notional > bidWallUsd) {
|
|
259
|
+
bidWallUsd = notional;
|
|
260
|
+
bidWallPrice = p;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
let ask1 = 0;
|
|
264
|
+
let ask2 = 0;
|
|
265
|
+
let askWallUsd = 0;
|
|
266
|
+
let askWallPrice = 0;
|
|
267
|
+
const askLevels = [];
|
|
268
|
+
for (const [p, q] of book.asks) {
|
|
269
|
+
const dist = p - mid;
|
|
270
|
+
if (dist > band2)
|
|
271
|
+
break; // asks ascend → past ±2% stop
|
|
272
|
+
if (dist < 0)
|
|
273
|
+
continue;
|
|
274
|
+
const notional = p * q;
|
|
275
|
+
if (dist <= band1)
|
|
276
|
+
ask1 += notional;
|
|
277
|
+
ask2 += notional;
|
|
278
|
+
askLevels.push([p, notional]);
|
|
279
|
+
if (notional > askWallUsd) {
|
|
280
|
+
askWallUsd = notional;
|
|
281
|
+
askWallPrice = p;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Descriptive skew on ±1% notional (closed vocab, not a forecast).
|
|
285
|
+
let skew = "balanced";
|
|
286
|
+
if (ask1 > 0 && bid1 > 0) {
|
|
287
|
+
const ratio = bid1 / ask1;
|
|
288
|
+
skew =
|
|
289
|
+
ratio >= DEPTH_SKEW_RATIO
|
|
290
|
+
? "bid-heavy"
|
|
291
|
+
: ratio <= 1 / DEPTH_SKEW_RATIO
|
|
292
|
+
? "ask-heavy"
|
|
293
|
+
: "balanced";
|
|
294
|
+
}
|
|
295
|
+
// Thin zone — widest adjacent-level price gap across the merged ±2% window
|
|
296
|
+
// (low cumulative depth between two priced levels). Location only.
|
|
297
|
+
const merged = [
|
|
298
|
+
...bidLevels.map(([p]) => p),
|
|
299
|
+
...askLevels.map(([p]) => p),
|
|
300
|
+
].sort((a, b) => a - b);
|
|
301
|
+
let thinLo = 0;
|
|
302
|
+
let thinHi = 0;
|
|
303
|
+
let widest = 0;
|
|
304
|
+
for (let i = 1; i < merged.length; i++) {
|
|
305
|
+
const gap = merged[i] - merged[i - 1];
|
|
306
|
+
if (gap > widest) {
|
|
307
|
+
widest = gap;
|
|
308
|
+
thinLo = merged[i - 1];
|
|
309
|
+
thinHi = merged[i];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const round0 = (n) => Math.round(n);
|
|
313
|
+
const round1 = (n) => Number(n.toFixed(1)); // BTC-perp tick precision
|
|
314
|
+
const usdM = (n) => Number((n / 1_000_000).toFixed(1)); // $ millions, 1dp
|
|
315
|
+
// A thin zone is meaningful only when the widest gap clears multiple ticks —
|
|
316
|
+
// on a dense 1000-level book the gap is sub-dollar (no real vacuum). Honest:
|
|
317
|
+
// report the zone only when it is materially wider than the typical spacing
|
|
318
|
+
// (>= $5 here), else flag it as negligible so we never paint a fake vacuum.
|
|
319
|
+
const THIN_MIN_USD = 5;
|
|
320
|
+
const thinZone = widest >= THIN_MIN_USD && round1(thinLo) !== round1(thinHi);
|
|
321
|
+
return {
|
|
322
|
+
available: true,
|
|
323
|
+
mid: round0(mid),
|
|
324
|
+
bid1Pct: usdM(bid1),
|
|
325
|
+
bid2Pct: usdM(bid2),
|
|
326
|
+
ask1Pct: usdM(ask1),
|
|
327
|
+
ask2Pct: usdM(ask2),
|
|
328
|
+
skew,
|
|
329
|
+
bidWallPrice: round0(bidWallPrice),
|
|
330
|
+
bidWallUsd: usdM(bidWallUsd),
|
|
331
|
+
askWallPrice: round0(askWallPrice),
|
|
332
|
+
askWallUsd: usdM(askWallUsd),
|
|
333
|
+
thinLo: round1(thinLo),
|
|
334
|
+
thinHi: round1(thinHi),
|
|
335
|
+
thinZone,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Front-expiry max-pain. Selects the NEAREST not-yet-expired expiry, then for
|
|
340
|
+
* each listed strike S computes pain(S) = Σ_calls OI*max(0,S-K) +
|
|
341
|
+
* Σ_puts OI*max(0,K-S); max-pain = argmin. Also the put/call OI ratio + total
|
|
342
|
+
* OI for that expiry. This is an OI SNAPSHOT — NOT a price magnet/target. The
|
|
343
|
+
* render layer attaches the explicit no-magnet label.
|
|
344
|
+
*/
|
|
345
|
+
export function maxPainSurface(rows, nowMs) {
|
|
346
|
+
if (!rows || rows.length === 0)
|
|
347
|
+
return { available: false };
|
|
348
|
+
// Nearest expiry strictly in the future; fall back to nearest overall if all
|
|
349
|
+
// listed expiries are past (stale Deribit snapshot).
|
|
350
|
+
let frontMs = Infinity;
|
|
351
|
+
for (const r of rows) {
|
|
352
|
+
if (r.expiryMs >= nowMs && r.expiryMs < frontMs)
|
|
353
|
+
frontMs = r.expiryMs;
|
|
354
|
+
}
|
|
355
|
+
if (!Number.isFinite(frontMs)) {
|
|
356
|
+
for (const r of rows) {
|
|
357
|
+
if (r.expiryMs < frontMs || frontMs === Infinity)
|
|
358
|
+
frontMs = r.expiryMs;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const front = rows.filter((r) => r.expiryMs === frontMs);
|
|
362
|
+
if (front.length === 0)
|
|
363
|
+
return { available: false };
|
|
364
|
+
const expiry = front[0].expiry;
|
|
365
|
+
// Canonical ISO date for the narrated prose (date-exempt class). Derived from
|
|
366
|
+
// the authoritative expiryMs so it never depends on parsing the DDMMMYY token.
|
|
367
|
+
const expiryIso = new Date(frontMs).toISOString().slice(0, 10);
|
|
368
|
+
const strikes = Array.from(new Set(front.map((r) => r.strike))).sort((a, b) => a - b);
|
|
369
|
+
if (strikes.length === 0)
|
|
370
|
+
return { available: false };
|
|
371
|
+
let callOi = 0;
|
|
372
|
+
let putOi = 0;
|
|
373
|
+
for (const r of front) {
|
|
374
|
+
if (r.kind === "C")
|
|
375
|
+
callOi += r.openInterest;
|
|
376
|
+
else
|
|
377
|
+
putOi += r.openInterest;
|
|
378
|
+
}
|
|
379
|
+
const totalOi = callOi + putOi;
|
|
380
|
+
let bestStrike = strikes[0];
|
|
381
|
+
let bestPain = Infinity;
|
|
382
|
+
for (const S of strikes) {
|
|
383
|
+
let pain = 0;
|
|
384
|
+
for (const r of front) {
|
|
385
|
+
if (r.kind === "C")
|
|
386
|
+
pain += r.openInterest * Math.max(0, S - r.strike);
|
|
387
|
+
else
|
|
388
|
+
pain += r.openInterest * Math.max(0, r.strike - S);
|
|
389
|
+
}
|
|
390
|
+
if (pain < bestPain) {
|
|
391
|
+
bestPain = pain;
|
|
392
|
+
bestStrike = S;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const putCallRatio = callOi > 0 ? Number((putOi / callOi).toFixed(2)) : 0;
|
|
396
|
+
return {
|
|
397
|
+
available: true,
|
|
398
|
+
expiry,
|
|
399
|
+
expiryIso,
|
|
400
|
+
maxPainStrike: bestStrike,
|
|
401
|
+
putCallRatio,
|
|
402
|
+
totalOi: Number(totalOi.toFixed(1)),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
// ── MODELED LIQUIDATION GEOMETRY — leverage-bucket location (NOT a forecast) ──
|
|
406
|
+
/** Standard leverage buckets the geometry is modeled at (frozen). */
|
|
407
|
+
export const LIQ_LEVERAGE_BUCKETS = [10, 25, 50, 100];
|
|
408
|
+
/**
|
|
409
|
+
* Pure leverage-bucket geometry — NO network fetch, NO forecast. For each
|
|
410
|
+
* standard leverage N ∈ {10,25,50,100}: long-liq ≈ mid·(1−1/N), short-liq ≈
|
|
411
|
+
* mid·(1+1/N), rounded to whole dollars. The total perp OI $ is reported as the
|
|
412
|
+
* pool that COULD be exposed, NOT distributed (we do not know per-position entry
|
|
413
|
+
* or leverage). This is GEOMETRY/LOCATION, exactly like order-book walls — never
|
|
414
|
+
* a magnet, never a forecast, never directional. The render layer attaches the
|
|
415
|
+
* explicit no-forecast/no-magnet label.
|
|
416
|
+
*/
|
|
417
|
+
export function liqGeometrySurface(mid, oiNotional) {
|
|
418
|
+
if (mid === null || !(mid > 0) || !Number.isFinite(mid)) {
|
|
419
|
+
return { available: false };
|
|
420
|
+
}
|
|
421
|
+
const bands = LIQ_LEVERAGE_BUCKETS.map((n) => ({
|
|
422
|
+
n,
|
|
423
|
+
longLiq: Math.round(mid * (1 - 1 / n)),
|
|
424
|
+
shortLiq: Math.round(mid * (1 + 1 / n)),
|
|
425
|
+
}));
|
|
426
|
+
return {
|
|
427
|
+
available: true,
|
|
428
|
+
mid: Math.round(mid),
|
|
429
|
+
oiNotional: oiNotional !== null && Number.isFinite(oiNotional) && oiNotional > 0
|
|
430
|
+
? Math.round(oiNotional)
|
|
431
|
+
: null,
|
|
432
|
+
bands,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
/** Stop-vs-band proximity threshold (%). Pure structure, not a recommendation. */
|
|
436
|
+
export const STOP_BAND_NEAR_PCT = 5;
|
|
437
|
+
export function stopVsBand(trade, geo) {
|
|
438
|
+
if (!trade || !geo.available || !geo.bands)
|
|
439
|
+
return null;
|
|
440
|
+
const { side, stop } = trade;
|
|
441
|
+
if (!Number.isFinite(stop) || !(stop > 0))
|
|
442
|
+
return null;
|
|
443
|
+
let best = null;
|
|
444
|
+
for (const b of geo.bands) {
|
|
445
|
+
const bandPrice = side === "long" ? b.longLiq : b.shortLiq;
|
|
446
|
+
if (!(bandPrice > 0))
|
|
447
|
+
continue;
|
|
448
|
+
const pct = Number(((Math.abs(stop - bandPrice) / stop) * 100).toFixed(1));
|
|
449
|
+
if (best === null || pct < best.pct) {
|
|
450
|
+
best = {
|
|
451
|
+
n: b.n,
|
|
452
|
+
bandPrice,
|
|
453
|
+
pct,
|
|
454
|
+
within: pct <= STOP_BAND_NEAR_PCT,
|
|
455
|
+
side,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return best;
|
|
460
|
+
}
|
|
461
|
+
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
462
|
+
export function fmtSigned(n) {
|
|
463
|
+
return n > 0 ? `+${n}` : `${n}`;
|
|
464
|
+
}
|
|
465
|
+
function roundDigits(price) {
|
|
466
|
+
if (price >= 1000)
|
|
467
|
+
return 0;
|
|
468
|
+
if (price >= 1)
|
|
469
|
+
return 2;
|
|
470
|
+
return 4;
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=surfaces.js.map
|