patchr 0.1.0__py3-none-any.whl

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.
Files changed (116) hide show
  1. apps/__init__.py +2 -0
  2. apps/api/__init__.py +2 -0
  3. apps/api/main.py +652 -0
  4. apps/benchmarks/__init__.py +1 -0
  5. apps/benchmarks/main.py +20 -0
  6. apps/sandbox/__init__.py +1 -0
  7. apps/sandbox/main.py +20 -0
  8. apps/worker/__init__.py +2 -0
  9. apps/worker/main.py +15 -0
  10. apps/worker/verify.py +14 -0
  11. patchr/__init__.py +12 -0
  12. patchr/sdk/__init__.py +20 -0
  13. patchr/sdk/client.py +12 -0
  14. patchr-0.1.0.dist-info/METADATA +137 -0
  15. patchr-0.1.0.dist-info/RECORD +116 -0
  16. patchr-0.1.0.dist-info/WHEEL +5 -0
  17. patchr-0.1.0.dist-info/entry_points.txt +5 -0
  18. patchr-0.1.0.dist-info/licenses/LICENSE +17 -0
  19. patchr-0.1.0.dist-info/top_level.txt +3 -0
  20. picux/__init__.py +6 -0
  21. picux/agents/__init__.py +5 -0
  22. picux/agents/registry.py +204 -0
  23. picux/api/__init__.py +5 -0
  24. picux/api/service.py +5075 -0
  25. picux/audit/__init__.py +31 -0
  26. picux/audit/activity.py +97 -0
  27. picux/audit/observability.py +55 -0
  28. picux/audit/verification/__init__.py +21 -0
  29. picux/audit/verification/ledger.py +633 -0
  30. picux/benchmarks/__init__.py +5 -0
  31. picux/benchmarks/local.py +286 -0
  32. picux/config.py +140 -0
  33. picux/contracts/__init__.py +22 -0
  34. picux/contracts/handshake.py +122 -0
  35. picux/contracts/integration.py +385 -0
  36. picux/contracts/openapi.py +187 -0
  37. picux/contracts/protocol_map.py +152 -0
  38. picux/contracts/routes.py +980 -0
  39. picux/contracts/schema_catalog.py +125 -0
  40. picux/core/__init__.py +17 -0
  41. picux/core/models.py +148 -0
  42. picux/core/router.py +131 -0
  43. picux/core/runtime.py +42 -0
  44. picux/core/state_machine.py +38 -0
  45. picux/domains/__init__.py +2 -0
  46. picux/domains/bridge/HostRun.py +1104 -0
  47. picux/domains/bridge/__init__.py +6 -0
  48. picux/domains/bridge/engine.py +345 -0
  49. picux/domains/hunt/__init__.py +6 -0
  50. picux/domains/hunt/engine.py +307 -0
  51. picux/domains/hunt/models.py +88 -0
  52. picux/domains/pay/__init__.py +16 -0
  53. picux/domains/pay/adapters.py +607 -0
  54. picux/domains/pay/engine.py +950 -0
  55. picux/domains/pay/models.py +95 -0
  56. picux/domains/proxy/__init__.py +5 -0
  57. picux/domains/proxy/engine.py +466 -0
  58. picux/domains/resolve/__init__.py +5 -0
  59. picux/domains/resolve/engine.py +546 -0
  60. picux/orchestrator/__init__.py +3 -0
  61. picux/orchestrator/engine.py +2840 -0
  62. picux/portals/__init__.py +17 -0
  63. picux/portals/templates.py +272 -0
  64. picux/protocols/__init__.py +1 -0
  65. picux/protocols/a2a/__init__.py +6 -0
  66. picux/protocols/a2a/client.py +51 -0
  67. picux/protocols/a2a/envelope.py +132 -0
  68. picux/protocols/mcp/__init__.py +7 -0
  69. picux/protocols/mcp/client.py +69 -0
  70. picux/protocols/mcp/contract.py +67 -0
  71. picux/protocols/mcp/server.py +76 -0
  72. picux/sandbox/__init__.py +6 -0
  73. picux/sandbox/midnight_arbitrage.py +215 -0
  74. picux/sandbox/models.py +90 -0
  75. picux/sdk/__init__.py +13 -0
  76. picux/sdk/client.py +768 -0
  77. picux/sdk/external.py +245 -0
  78. picux/security/__init__.py +18 -0
  79. picux/security/auth.py +86 -0
  80. picux/security/config_validator.py +58 -0
  81. picux/security/policy.py +158 -0
  82. picux/security/secrets.py +144 -0
  83. picux/signals/__init__.py +1 -0
  84. picux/signals/community/__init__.py +24 -0
  85. picux/signals/community/adapters/__init__.py +7 -0
  86. picux/signals/community/adapters/reddit.py +37 -0
  87. picux/signals/community/adapters/shopify.py +23 -0
  88. picux/signals/community/adapters/web.py +23 -0
  89. picux/signals/community/disambiguation.py +51 -0
  90. picux/signals/community/intake.py +227 -0
  91. picux/signals/community/models.py +102 -0
  92. picux/signals/community/rules.py +91 -0
  93. picux/signals/community/scoring.py +64 -0
  94. picux/storage/__init__.py +41 -0
  95. picux/storage/agents.py +50 -0
  96. picux/storage/cases.py +440 -0
  97. picux/storage/channels.py +476 -0
  98. picux/storage/connectors.py +411 -0
  99. picux/storage/envelopes.py +137 -0
  100. picux/storage/escrows.py +168 -0
  101. picux/storage/events.py +989 -0
  102. picux/storage/keyspace.py +60 -0
  103. picux/storage/mandates.py +107 -0
  104. picux/storage/portals.py +222 -0
  105. picux/storage/postgres.py +2049 -0
  106. picux/storage/providers.py +148 -0
  107. picux/storage/proxy.py +231 -0
  108. picux/storage/receipts.py +131 -0
  109. picux/storage/signals.py +147 -0
  110. picux/storage/tasks.py +179 -0
  111. picux/tools/__init__.py +11 -0
  112. picux/tools/shared.py +2048 -0
  113. picux/verification/__init__.py +5 -0
  114. picux/verification/rollout.py +183 -0
  115. picux/workflows/__init__.py +5 -0
  116. picux/workflows/templates.py +74 -0
@@ -0,0 +1,6 @@
1
+ """BRIDGE domain primitives."""
2
+
3
+ from .engine import BridgeDomain
4
+ from .HostRun import HostedBridgeAdapters
5
+
6
+ __all__ = ["BridgeDomain", "HostedBridgeAdapters"]
@@ -0,0 +1,345 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class BridgeDomain:
9
+ """External connector domain for APIs, MCP, A2A, webhooks, and systems."""
10
+
11
+ def contract(self) -> dict[str, Any]:
12
+ return {
13
+ "domain": "bridge",
14
+ "purpose": "externalConnectors",
15
+ "kinds": ["api", "mcp", "a2a", "webhook", "database", "erp", "browser", "custom"],
16
+ "caps": ["register", "match", "preflight", "route"],
17
+ "humanLoop": "proxy",
18
+ }
19
+
20
+ def readyConnectors(self) -> dict[str, Any]:
21
+ connectors = [self._connector(item) for item in READY_CONNECTORS]
22
+ return {
23
+ "ok": True,
24
+ "domain": "bridge",
25
+ "kind": "readyConnectorCatalog",
26
+ "count": len(connectors),
27
+ "connectors": connectors,
28
+ }
29
+
30
+ @staticmethod
31
+ def _connector(item: dict[str, Any]) -> dict[str, Any]:
32
+ connectorId = str(item["connectorId"])
33
+ hosted = bool(item.get("hostedAdapter", connectorId in HOSTED_CONNECTOR_IDS))
34
+ return {
35
+ "connectorId": connectorId,
36
+ "kind": str(item.get("kind", "api")),
37
+ "name": str(item.get("name", connectorId)),
38
+ "domain": "bridge",
39
+ "endpoint": str(item.get("endpoint", f"bridge://{connectorId}")),
40
+ "caps": list(item.get("caps", [])),
41
+ "credential": {
42
+ "type": str(item.get("credentialType", "oauth2")),
43
+ "tokenRef": str(item.get("tokenRef", f"vault:connectors/{connectorId}")),
44
+ "env": str(item.get("env", "")),
45
+ "rotation": "external",
46
+ },
47
+ "scopes": [
48
+ {
49
+ "scopeId": str(scope.get("scopeId", "")),
50
+ "actions": list(scope.get("actions", [])),
51
+ "resources": list(scope.get("resources", [])),
52
+ "tokenRef": str(scope.get("tokenRef", item.get("tokenRef", f"vault:connectors/{connectorId}"))),
53
+ }
54
+ for scope in item.get("scopes", [])
55
+ ],
56
+ "meta": {
57
+ "provider": str(item.get("provider", connectorId)),
58
+ "readyMade": True,
59
+ "adapterNeutral": bool(item.get("adapterNeutral", not hosted)),
60
+ "hostedAdapter": hosted,
61
+ "executionMode": "picuxHostedAdapter" if hosted else "clientHostedAdapter",
62
+ "docs": str(item.get("docs", "")),
63
+ "envAliases": list(item.get("envAliases", [])),
64
+ "credentialMode": str(item.get("credentialMode", "clientRegisteredBridgeResource")),
65
+ "channelProfile": {
66
+ "category": str(item.get("category", "connector")),
67
+ "channels": list(item.get("channels", [])),
68
+ "touchpoints": list(item.get("touchpoints", [])),
69
+ "systemOfRecord": bool(item.get("systemOfRecord", False)),
70
+ },
71
+ },
72
+ }
73
+
74
+
75
+ HOSTED_CONNECTOR_IDS = {
76
+ "browserCheckout",
77
+ "gmail",
78
+ "googleDocs",
79
+ "googlePlaces",
80
+ "hubspot",
81
+ "jira",
82
+ "notion",
83
+ "salesforce",
84
+ "sap",
85
+ "slack",
86
+ "twilioVoice",
87
+ "whatsapp",
88
+ "zendesk",
89
+ }
90
+
91
+
92
+ READY_CONNECTORS: tuple[dict[str, Any], ...] = (
93
+ {
94
+ "connectorId": "gmail",
95
+ "name": "Gmail",
96
+ "provider": "google",
97
+ "category": "email",
98
+ "channels": ["email"],
99
+ "touchpoints": ["inboundMessage", "outboundMessage", "threadSync", "evidenceImport"],
100
+ "systemOfRecord": True,
101
+ "endpoint": "bridge://gmail",
102
+ "caps": ["email.read", "email.send", "messages.send", "contact.write", "evidence.import"],
103
+ "tokenRef": "vault:connectors/gmail",
104
+ "envAliases": ["GMAIL_ACCESS_TOKEN", "GOOGLE_GMAIL_ACCESS_TOKEN", "GOOGLE_ACCESS_TOKEN", "PICUX_SMTP_HOST", "PICUX_SMTP_PORT", "PICUX_SMTP_USER", "PICUX_SMTP_PASSWORD", "PICUX_SMTP_FROM", "SMTP_HOST", "SMTP_PORT", "SMTP_USER", "SMTP_PASSWORD", "SMTP_FROM"],
105
+ "scopes": [
106
+ {"scopeId": "gmail_messages", "actions": ["read", "send", "search"], "resources": ["gmail.messages", "email"]},
107
+ ],
108
+ },
109
+ {
110
+ "connectorId": "outlookMail",
111
+ "name": "Outlook Mail",
112
+ "provider": "microsoft",
113
+ "category": "email",
114
+ "channels": ["email"],
115
+ "touchpoints": ["inboundMessage", "outboundMessage", "threadSync", "evidenceImport"],
116
+ "systemOfRecord": True,
117
+ "endpoint": "bridge://outlook-mail",
118
+ "caps": ["email.read", "email.send", "messages.read", "messages.send", "contact.write", "calendar.read", "evidence.import"],
119
+ "tokenRef": "vault:connectors/outlookMail",
120
+ "scopes": [
121
+ {"scopeId": "outlook_messages", "actions": ["read", "send", "search"], "resources": ["outlook.messages", "email"]},
122
+ {"scopeId": "outlook_calendar", "actions": ["read"], "resources": ["outlook.calendar", "calendar"]},
123
+ ],
124
+ },
125
+ {
126
+ "connectorId": "googleDocs",
127
+ "name": "Google Docs",
128
+ "provider": "google",
129
+ "category": "documents",
130
+ "channels": ["document"],
131
+ "touchpoints": ["documentRead", "documentWrite", "evidenceExport"],
132
+ "endpoint": "bridge://google-docs",
133
+ "caps": ["docs.read", "docs.write", "documents.search", "evidence.export"],
134
+ "tokenRef": "vault:connectors/googleDocs",
135
+ "envAliases": ["GOOGLE_DOCS_ACCESS_TOKEN", "GOOGLE_ACCESS_TOKEN"],
136
+ "scopes": [
137
+ {"scopeId": "google_docs", "actions": ["read", "write", "search"], "resources": ["google.docs", "documents"]},
138
+ ],
139
+ },
140
+ {
141
+ "connectorId": "googlePlaces",
142
+ "name": "Google Places",
143
+ "provider": "google",
144
+ "category": "maps",
145
+ "channels": ["maps"],
146
+ "touchpoints": ["placeSearch", "businessLookup", "sourceSnapshot"],
147
+ "endpoint": "bridge://google-places",
148
+ "caps": ["places.search", "maps.search", "localBusiness.search", "geo.lookup", "proof.capture"],
149
+ "credentialType": "apiKey",
150
+ "tokenRef": "vault:connectors/googlePlaces",
151
+ "env": "GOOGLE_PLACES_API_KEY",
152
+ "envAliases": ["PICUX_GOOGLE_PLACES_API_KEY", "PICUX_GOOGLE_MAPS_API_KEY", "PICUX_GOOGLE_PLACES_BASE_URL", "GOOGLE_PLACES_API_KEY", "GOOGLE_MAPS_API_KEY"],
153
+ "scopes": [
154
+ {"scopeId": "google_places", "actions": ["search", "read"], "resources": ["google.places", "google.maps", "localBusiness"]},
155
+ ],
156
+ },
157
+ {
158
+ "connectorId": "twilioVoice",
159
+ "kind": "custom",
160
+ "name": "Twilio Voice",
161
+ "provider": "twilio",
162
+ "category": "telephony",
163
+ "channels": ["voice", "phone"],
164
+ "touchpoints": ["outboundCall", "callStatus", "transcript", "recording", "proofCapture"],
165
+ "endpoint": "bridge://twilio-voice",
166
+ "caps": ["voice.call", "call.create", "call.status", "voice.transcript", "availability.confirm", "identity.verify", "consent.capture", "proof.capture"],
167
+ "credentialType": "basicRef",
168
+ "tokenRef": "vault:connectors/twilioVoice/authToken",
169
+ "env": "TWILIO_AUTH_TOKEN",
170
+ "envAliases": [
171
+ "TWILIO_ACCOUNT_SID",
172
+ "PICUX_TWILIO_ACCOUNT_SID",
173
+ "TWILIO_AUTH_TOKEN",
174
+ "PICUX_TWILIO_AUTH_TOKEN",
175
+ "PICUX_TWILIO_VOICE_FROM",
176
+ "TWILIO_PHONE_NUMBER",
177
+ "PICUX_TWILIO_VERIFIED_CALLER_ID",
178
+ "PICUX_VOICE_PUBLIC_BASE_URL",
179
+ "PICUX_TWILIO_MACHINE_DETECTION",
180
+ "PICUX_TWILIO_VOICE_TIMEOUT_SECONDS",
181
+ ],
182
+ "scopes": [
183
+ {"scopeId": "twilio_calls", "actions": ["call", "read", "status"], "resources": ["twilio.calls", "voice.call"], "tokenRef": "vault:connectors/twilioVoice/accountSid"},
184
+ {"scopeId": "twilio_voice_from", "actions": ["call"], "resources": ["twilio.from"], "tokenRef": "vault:connectors/twilioVoice/fromNumber"},
185
+ {"scopeId": "twilio_public_callbacks", "actions": ["callback"], "resources": ["twilio.callbacks"], "tokenRef": "vault:connectors/twilioVoice/publicBaseUrl"},
186
+ ],
187
+ },
188
+ {
189
+ "connectorId": "whatsapp",
190
+ "name": "WhatsApp",
191
+ "provider": "meta",
192
+ "category": "messaging",
193
+ "channels": ["whatsapp", "chat"],
194
+ "touchpoints": ["inboundMessage", "outboundMessage", "identityCheck", "consentCapture"],
195
+ "endpoint": "bridge://whatsapp",
196
+ "caps": ["messages.read", "messages.send", "contact.write", "identity.verify", "consent.capture", "voice.call"],
197
+ "tokenRef": "vault:connectors/whatsapp",
198
+ "envAliases": ["WHATSAPP_ACCESS_TOKEN", "META_WHATSAPP_TOKEN", "WHATSAPP_PHONE_NUMBER_ID", "META_WHATSAPP_PHONE_NUMBER_ID"],
199
+ "scopes": [
200
+ {"scopeId": "whatsapp_messages", "actions": ["read", "send", "route"], "resources": ["whatsapp.messages", "chat", "contact"]},
201
+ ],
202
+ },
203
+ {
204
+ "connectorId": "microsoftTeams",
205
+ "name": "Microsoft Teams",
206
+ "provider": "microsoft",
207
+ "category": "collaboration",
208
+ "channels": ["teams", "chat"],
209
+ "touchpoints": ["inboundMessage", "outboundMessage", "approvalRoute", "threadSync"],
210
+ "endpoint": "bridge://microsoft-teams",
211
+ "caps": ["messages.read", "messages.send", "approvals.route", "meetings.read", "contact.write", "casefile.export"],
212
+ "tokenRef": "vault:connectors/microsoftTeams",
213
+ "scopes": [
214
+ {"scopeId": "teams_messages", "actions": ["read", "send", "search"], "resources": ["teams.messages", "chat"]},
215
+ {"scopeId": "teams_approvals", "actions": ["route", "read"], "resources": ["teams.approvals", "approvals"]},
216
+ ],
217
+ },
218
+ {
219
+ "connectorId": "notion",
220
+ "name": "Notion",
221
+ "provider": "notion",
222
+ "category": "knowledge",
223
+ "channels": ["workspace"],
224
+ "touchpoints": ["pageRead", "pageWrite", "casefileExport"],
225
+ "endpoint": "bridge://notion",
226
+ "caps": ["docs.read", "docs.write", "knowledge.search", "casefile.export"],
227
+ "tokenRef": "vault:connectors/notion",
228
+ "envAliases": ["NOTION_TOKEN", "PICUX_NOTION_TOKEN", "NOTION_DATABASE_ID", "PICUX_NOTION_DATABASE_ID"],
229
+ "scopes": [
230
+ {"scopeId": "notion_pages", "actions": ["read", "write", "search"], "resources": ["notion.pages", "knowledge"]},
231
+ ],
232
+ },
233
+ {
234
+ "connectorId": "jira",
235
+ "name": "Jira",
236
+ "provider": "atlassian",
237
+ "category": "workManagement",
238
+ "channels": ["ticketing"],
239
+ "touchpoints": ["ticketRead", "ticketWrite", "statusSync"],
240
+ "endpoint": "bridge://jira",
241
+ "caps": ["ticket.read", "ticket.write", "status.sync", "casefile.export"],
242
+ "tokenRef": "vault:connectors/jira",
243
+ "envAliases": ["JIRA_BASE_URL", "ATLASSIAN_BASE_URL", "JIRA_EMAIL", "ATLASSIAN_EMAIL", "JIRA_ACCESS_TOKEN", "ATLASSIAN_ACCESS_TOKEN", "JIRA_API_TOKEN", "ATLASSIAN_API_TOKEN", "JIRA_PROJECT_KEY", "PICUX_JIRA_PROJECT_KEY"],
244
+ "scopes": [
245
+ {"scopeId": "jira_issues", "actions": ["read", "write", "search"], "resources": ["jira.issues", "tickets"]},
246
+ ],
247
+ },
248
+ {
249
+ "connectorId": "slack",
250
+ "name": "Slack",
251
+ "provider": "slack",
252
+ "category": "chat",
253
+ "channels": ["slack", "chat"],
254
+ "touchpoints": ["inboundMessage", "outboundMessage", "approvalRoute", "threadSync"],
255
+ "endpoint": "bridge://slack",
256
+ "caps": ["messages.read", "messages.send", "approvals.route", "contact.write"],
257
+ "tokenRef": "vault:connectors/slack",
258
+ "envAliases": ["SLACK_WEBHOOK_URL", "PICUX_SLACK_WEBHOOK_URL", "SLACK_BOT_TOKEN", "PICUX_SLACK_BOT_TOKEN"],
259
+ "scopes": [
260
+ {"scopeId": "slack_messages", "actions": ["read", "send", "search"], "resources": ["slack.messages", "chat"]},
261
+ ],
262
+ },
263
+ {
264
+ "connectorId": "salesforce",
265
+ "name": "Salesforce",
266
+ "provider": "salesforce",
267
+ "category": "crm",
268
+ "channels": ["crm", "case"],
269
+ "touchpoints": ["caseRead", "caseWrite", "contactSync", "statusSync", "evidenceImport"],
270
+ "systemOfRecord": True,
271
+ "endpoint": "bridge://salesforce",
272
+ "caps": ["crm.read", "crm.write", "case.read", "case.write", "contact.read", "contact.write", "status.sync", "casefile.sync"],
273
+ "tokenRef": "vault:connectors/salesforce",
274
+ "envAliases": ["SALESFORCE_ACCESS_TOKEN", "PICUX_SALESFORCE_ACCESS_TOKEN", "SALESFORCE_INSTANCE_URL", "PICUX_SALESFORCE_INSTANCE_URL"],
275
+ "scopes": [
276
+ {"scopeId": "salesforce_cases", "actions": ["read", "write", "search"], "resources": ["salesforce.cases", "crm.cases"]},
277
+ {"scopeId": "salesforce_contacts", "actions": ["read", "write"], "resources": ["salesforce.contacts", "crm.contacts"]},
278
+ ],
279
+ },
280
+ {
281
+ "connectorId": "hubspot",
282
+ "name": "HubSpot",
283
+ "provider": "hubspot",
284
+ "category": "crm",
285
+ "channels": ["crm", "ticketing"],
286
+ "touchpoints": ["ticketRead", "ticketWrite", "contactSync", "statusSync", "evidenceImport"],
287
+ "systemOfRecord": True,
288
+ "endpoint": "bridge://hubspot",
289
+ "caps": ["crm.read", "crm.write", "ticket.read", "ticket.write", "contact.read", "contact.write", "status.sync", "casefile.sync"],
290
+ "tokenRef": "vault:connectors/hubspot",
291
+ "envAliases": ["HUBSPOT_ACCESS_TOKEN", "PICUX_HUBSPOT_ACCESS_TOKEN", "HUBSPOT_BASE_URL", "PICUX_HUBSPOT_BASE_URL"],
292
+ "scopes": [
293
+ {"scopeId": "hubspot_tickets", "actions": ["read", "write", "search", "sync"], "resources": ["hubspot.tickets", "crm.tickets", "casefile"]},
294
+ {"scopeId": "hubspot_contacts", "actions": ["read", "write"], "resources": ["hubspot.contacts", "crm.contacts"]},
295
+ ],
296
+ },
297
+ {
298
+ "connectorId": "zendesk",
299
+ "name": "Zendesk",
300
+ "provider": "zendesk",
301
+ "category": "support",
302
+ "channels": ["support", "ticketing"],
303
+ "touchpoints": ["ticketRead", "ticketWrite", "statusSync", "evidenceImport"],
304
+ "systemOfRecord": True,
305
+ "endpoint": "bridge://zendesk",
306
+ "caps": ["support.read", "support.write", "ticket.read", "ticket.write", "status.sync", "casefile.sync"],
307
+ "tokenRef": "vault:connectors/zendesk",
308
+ "envAliases": ["ZENDESK_ACCESS_TOKEN", "PICUX_ZENDESK_ACCESS_TOKEN", "ZENDESK_API_TOKEN", "ZENDESK_EMAIL", "ZENDESK_BASE_URL", "PICUX_ZENDESK_BASE_URL"],
309
+ "scopes": [
310
+ {"scopeId": "zendesk_tickets", "actions": ["read", "write", "search", "sync"], "resources": ["zendesk.tickets", "support.tickets", "casefile"]},
311
+ ],
312
+ },
313
+ {
314
+ "connectorId": "sap",
315
+ "kind": "erp",
316
+ "name": "SAP",
317
+ "provider": "sap",
318
+ "category": "erp",
319
+ "channels": ["erp"],
320
+ "touchpoints": ["orderRead", "invoiceRead", "casefileSync"],
321
+ "systemOfRecord": True,
322
+ "endpoint": "bridge://sap",
323
+ "caps": ["erp.read", "erp.write", "orders.read", "invoice.read", "casefile.sync"],
324
+ "tokenRef": "vault:connectors/sap",
325
+ "envAliases": ["SAP_ACCESS_TOKEN", "PICUX_SAP_ACCESS_TOKEN", "SAP_BASE_URL", "PICUX_SAP_BASE_URL"],
326
+ "scopes": [
327
+ {"scopeId": "sap_ops", "actions": ["read", "write", "search", "sync"], "resources": ["sap.orders", "sap.invoices", "sap.casefiles", "casefile", "erp"]},
328
+ ],
329
+ },
330
+ {
331
+ "connectorId": "browserCheckout",
332
+ "kind": "custom",
333
+ "name": "Browser Checkout",
334
+ "provider": "picux",
335
+ "category": "browser",
336
+ "channels": ["browser", "marketplace"],
337
+ "touchpoints": ["checkoutAttempt", "receiptCapture", "proofCapture"],
338
+ "endpoint": "bridge://browser-checkout",
339
+ "caps": ["browser.checkout", "marketplace.checkout", "purchase.execute", "proof.capture"],
340
+ "tokenRef": "vault:connectors/browserCheckout",
341
+ "scopes": [
342
+ {"scopeId": "browser_checkout", "actions": ["execute", "read", "capture"], "resources": ["browser", "marketplace.checkout", "purchase"]},
343
+ ],
344
+ },
345
+ )
@@ -0,0 +1,6 @@
1
+ """HUNT domain primitives."""
2
+
3
+ from .engine import HuntDomain
4
+ from .models import HuntCriteria, HuntOffer
5
+
6
+ __all__ = ["HuntCriteria", "HuntDomain", "HuntOffer"]