@vellumai/assistant 0.3.19 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/ARCHITECTURE.md +151 -15
  2. package/Dockerfile +1 -0
  3. package/README.md +40 -4
  4. package/docs/architecture/integrations.md +7 -11
  5. package/package.json +1 -1
  6. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +54 -0
  7. package/src/__tests__/approval-primitive.test.ts +540 -0
  8. package/src/__tests__/assistant-feature-flag-guard.test.ts +206 -0
  9. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +198 -0
  10. package/src/__tests__/assistant-feature-flags-integration.test.ts +272 -0
  11. package/src/__tests__/call-controller.test.ts +439 -108
  12. package/src/__tests__/channel-invite-transport.test.ts +264 -0
  13. package/src/__tests__/cli.test.ts +42 -1
  14. package/src/__tests__/config-schema.test.ts +11 -127
  15. package/src/__tests__/config-watcher.test.ts +0 -8
  16. package/src/__tests__/daemon-lifecycle.test.ts +1 -0
  17. package/src/__tests__/daemon-server-session-init.test.ts +8 -2
  18. package/src/__tests__/diff.test.ts +22 -0
  19. package/src/__tests__/guardian-action-copy-generator.test.ts +5 -0
  20. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +300 -32
  21. package/src/__tests__/guardian-action-late-reply.test.ts +546 -1
  22. package/src/__tests__/guardian-actions-endpoint.test.ts +774 -0
  23. package/src/__tests__/guardian-control-plane-policy.test.ts +36 -3
  24. package/src/__tests__/guardian-dispatch.test.ts +124 -0
  25. package/src/__tests__/guardian-grant-minting.test.ts +6 -17
  26. package/src/__tests__/inbound-invite-redemption.test.ts +367 -0
  27. package/src/__tests__/invite-redemption-service.test.ts +306 -0
  28. package/src/__tests__/ipc-snapshot.test.ts +57 -0
  29. package/src/__tests__/notification-decision-fallback.test.ts +88 -0
  30. package/src/__tests__/sandbox-diagnostics.test.ts +6 -249
  31. package/src/__tests__/sandbox-host-parity.test.ts +6 -13
  32. package/src/__tests__/scoped-approval-grants.test.ts +6 -6
  33. package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -4
  34. package/src/__tests__/script-proxy-session-manager.test.ts +1 -19
  35. package/src/__tests__/session-load-history-repair.test.ts +169 -2
  36. package/src/__tests__/session-runtime-assembly.test.ts +33 -5
  37. package/src/__tests__/skill-feature-flags-integration.test.ts +171 -0
  38. package/src/__tests__/skill-feature-flags.test.ts +188 -0
  39. package/src/__tests__/skill-load-feature-flag.test.ts +141 -0
  40. package/src/__tests__/skill-mirror-parity.test.ts +1 -0
  41. package/src/__tests__/skill-projection-feature-flag.test.ts +363 -0
  42. package/src/__tests__/system-prompt.test.ts +1 -1
  43. package/src/__tests__/terminal-sandbox.test.ts +142 -9
  44. package/src/__tests__/terminal-tools.test.ts +2 -93
  45. package/src/__tests__/thread-seed-composer.test.ts +18 -0
  46. package/src/__tests__/tool-approval-handler.test.ts +350 -0
  47. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +8 -10
  48. package/src/__tests__/voice-scoped-grant-consumer.test.ts +46 -84
  49. package/src/agent/loop.ts +36 -1
  50. package/src/approvals/approval-primitive.ts +381 -0
  51. package/src/approvals/guardian-decision-primitive.ts +191 -0
  52. package/src/calls/call-controller.ts +252 -209
  53. package/src/calls/call-domain.ts +44 -6
  54. package/src/calls/guardian-dispatch.ts +48 -0
  55. package/src/calls/types.ts +1 -1
  56. package/src/calls/voice-session-bridge.ts +46 -30
  57. package/src/cli/core-commands.ts +0 -4
  58. package/src/cli.ts +76 -34
  59. package/src/config/__tests__/feature-flag-registry-guard.test.ts +179 -0
  60. package/src/config/assistant-feature-flags.ts +162 -0
  61. package/src/config/bundled-skills/api-mapping/icon.svg +18 -0
  62. package/src/config/bundled-skills/messaging/TOOLS.json +30 -0
  63. package/src/config/bundled-skills/messaging/tools/slack-delete-message.ts +24 -0
  64. package/src/config/bundled-skills/notifications/SKILL.md +1 -1
  65. package/src/config/bundled-skills/reminder/SKILL.md +49 -2
  66. package/src/config/bundled-skills/time-based-actions/SKILL.md +49 -2
  67. package/src/config/bundled-skills/voice-setup/SKILL.md +122 -0
  68. package/src/config/core-schema.ts +1 -1
  69. package/src/config/env-registry.ts +10 -0
  70. package/src/config/feature-flag-registry.json +61 -0
  71. package/src/config/loader.ts +22 -1
  72. package/src/config/sandbox-schema.ts +0 -39
  73. package/src/config/schema.ts +6 -2
  74. package/src/config/skill-state.ts +34 -0
  75. package/src/config/skills-schema.ts +0 -1
  76. package/src/config/skills.ts +9 -0
  77. package/src/config/system-prompt.ts +110 -46
  78. package/src/config/templates/SOUL.md +1 -1
  79. package/src/config/types.ts +19 -1
  80. package/src/config/vellum-skills/catalog.json +1 -1
  81. package/src/config/vellum-skills/guardian-verify-setup/SKILL.md +1 -0
  82. package/src/config/vellum-skills/sms-setup/SKILL.md +1 -1
  83. package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -1
  84. package/src/config/vellum-skills/trusted-contacts/SKILL.md +104 -3
  85. package/src/config/vellum-skills/twilio-setup/SKILL.md +1 -1
  86. package/src/daemon/config-watcher.ts +0 -1
  87. package/src/daemon/daemon-control.ts +1 -1
  88. package/src/daemon/guardian-invite-intent.ts +124 -0
  89. package/src/daemon/handlers/avatar.ts +68 -0
  90. package/src/daemon/handlers/browser.ts +2 -2
  91. package/src/daemon/handlers/guardian-actions.ts +120 -0
  92. package/src/daemon/handlers/index.ts +4 -0
  93. package/src/daemon/handlers/sessions.ts +19 -0
  94. package/src/daemon/handlers/shared.ts +3 -1
  95. package/src/daemon/install-cli-launchers.ts +58 -13
  96. package/src/daemon/ipc-contract/guardian-actions.ts +53 -0
  97. package/src/daemon/ipc-contract/sessions.ts +8 -2
  98. package/src/daemon/ipc-contract/settings.ts +25 -2
  99. package/src/daemon/ipc-contract-inventory.json +10 -0
  100. package/src/daemon/ipc-contract.ts +4 -0
  101. package/src/daemon/lifecycle.ts +6 -2
  102. package/src/daemon/main.ts +1 -0
  103. package/src/daemon/server.ts +1 -0
  104. package/src/daemon/session-lifecycle.ts +52 -7
  105. package/src/daemon/session-memory.ts +45 -0
  106. package/src/daemon/session-process.ts +258 -432
  107. package/src/daemon/session-runtime-assembly.ts +12 -0
  108. package/src/daemon/session-skill-tools.ts +14 -1
  109. package/src/daemon/session-tool-setup.ts +5 -0
  110. package/src/daemon/session.ts +11 -0
  111. package/src/daemon/tool-side-effects.ts +35 -9
  112. package/src/index.ts +0 -2
  113. package/src/memory/conversation-display-order-migration.ts +44 -0
  114. package/src/memory/conversation-queries.ts +2 -0
  115. package/src/memory/conversation-store.ts +91 -0
  116. package/src/memory/db-init.ts +5 -1
  117. package/src/memory/embedding-local.ts +13 -8
  118. package/src/memory/guardian-action-store.ts +125 -2
  119. package/src/memory/ingress-invite-store.ts +95 -1
  120. package/src/memory/migrations/035-guardian-action-supersession.ts +23 -0
  121. package/src/memory/migrations/index.ts +2 -1
  122. package/src/memory/schema.ts +5 -1
  123. package/src/memory/scoped-approval-grants.ts +14 -5
  124. package/src/messaging/providers/slack/client.ts +12 -0
  125. package/src/messaging/providers/slack/types.ts +5 -0
  126. package/src/notifications/decision-engine.ts +49 -12
  127. package/src/notifications/emit-signal.ts +7 -0
  128. package/src/notifications/signal.ts +7 -0
  129. package/src/notifications/thread-seed-composer.ts +2 -1
  130. package/src/runtime/channel-approval-types.ts +16 -6
  131. package/src/runtime/channel-approvals.ts +19 -15
  132. package/src/runtime/channel-invite-transport.ts +85 -0
  133. package/src/runtime/channel-invite-transports/telegram.ts +105 -0
  134. package/src/runtime/guardian-action-grant-minter.ts +92 -35
  135. package/src/runtime/guardian-action-message-composer.ts +30 -0
  136. package/src/runtime/guardian-decision-types.ts +91 -0
  137. package/src/runtime/http-server.ts +23 -1
  138. package/src/runtime/ingress-service.ts +22 -0
  139. package/src/runtime/invite-redemption-service.ts +181 -0
  140. package/src/runtime/invite-redemption-templates.ts +39 -0
  141. package/src/runtime/routes/call-routes.ts +2 -1
  142. package/src/runtime/routes/guardian-action-routes.ts +206 -0
  143. package/src/runtime/routes/guardian-approval-interception.ts +66 -190
  144. package/src/runtime/routes/inbound-message-handler.ts +486 -394
  145. package/src/runtime/routes/pairing-routes.ts +4 -0
  146. package/src/security/encrypted-store.ts +31 -17
  147. package/src/security/keychain.ts +176 -2
  148. package/src/security/secure-keys.ts +97 -0
  149. package/src/security/tool-approval-digest.ts +1 -1
  150. package/src/tools/browser/browser-execution.ts +2 -2
  151. package/src/tools/browser/browser-manager.ts +46 -32
  152. package/src/tools/browser/browser-screencast.ts +2 -2
  153. package/src/tools/calls/call-start.ts +1 -1
  154. package/src/tools/executor.ts +22 -17
  155. package/src/tools/network/script-proxy/session-manager.ts +1 -5
  156. package/src/tools/skills/load.ts +22 -8
  157. package/src/tools/system/avatar-generator.ts +119 -0
  158. package/src/tools/system/navigate-settings.ts +65 -0
  159. package/src/tools/system/open-system-settings.ts +75 -0
  160. package/src/tools/system/voice-config.ts +121 -32
  161. package/src/tools/terminal/backends/native.ts +40 -19
  162. package/src/tools/terminal/backends/types.ts +3 -3
  163. package/src/tools/terminal/parser.ts +1 -1
  164. package/src/tools/terminal/sandbox-diagnostics.ts +6 -87
  165. package/src/tools/terminal/sandbox.ts +1 -12
  166. package/src/tools/terminal/shell.ts +3 -31
  167. package/src/tools/tool-approval-handler.ts +141 -3
  168. package/src/tools/tool-manifest.ts +6 -0
  169. package/src/tools/types.ts +6 -0
  170. package/src/util/diff.ts +36 -13
  171. package/Dockerfile.sandbox +0 -5
  172. package/src/__tests__/doordash-client.test.ts +0 -187
  173. package/src/__tests__/doordash-session.test.ts +0 -154
  174. package/src/__tests__/signup-e2e.test.ts +0 -354
  175. package/src/__tests__/terminal-sandbox-docker.test.ts +0 -1065
  176. package/src/__tests__/terminal-sandbox.integration.test.ts +0 -180
  177. package/src/cli/doordash.ts +0 -1057
  178. package/src/config/bundled-skills/doordash/SKILL.md +0 -163
  179. package/src/config/templates/LOOKS.md +0 -25
  180. package/src/doordash/cart-queries.ts +0 -787
  181. package/src/doordash/client.ts +0 -1016
  182. package/src/doordash/order-queries.ts +0 -85
  183. package/src/doordash/queries.ts +0 -13
  184. package/src/doordash/query-extractor.ts +0 -94
  185. package/src/doordash/search-queries.ts +0 -203
  186. package/src/doordash/session.ts +0 -84
  187. package/src/doordash/store-queries.ts +0 -246
  188. package/src/doordash/types.ts +0 -367
  189. package/src/tools/terminal/backends/docker.ts +0 -379
@@ -1,85 +0,0 @@
1
- /**
2
- * GraphQL queries for DoorDash checkout: order creation, delivery options, and payment methods.
3
- * Each query is fully self-contained with all required fragment definitions.
4
- */
5
-
6
- // ---------------------------------------------------------------------------
7
- // DROPOFF_OPTIONS_QUERY
8
- // ---------------------------------------------------------------------------
9
-
10
- export const DROPOFF_OPTIONS_QUERY = `
11
- query dropoffOptions($cartId: ID, $addressId: ID) {
12
- dropoffOptions(cartId: $cartId, addressId: $addressId) {
13
- id displayString isDefault isEnabled placeholderText disabledMessage
14
- proofOfDeliveryType __typename
15
- }
16
- }`;
17
-
18
- // ---------------------------------------------------------------------------
19
- // CREATE_ORDER_FROM_CART_QUERY
20
- // ---------------------------------------------------------------------------
21
-
22
- export const CREATE_ORDER_FROM_CART_QUERY = `
23
- mutation createOrderFromCart($cartId: ID!, $total: Int!, $sosDeliveryFee: Int!, $isPickupOrder: Boolean!, $verifiedAgeRequirement: Boolean!, $deliveryTime: String!, $menuOptions: [String], $stripeToken: String, $attributionData: String, $fulfillsOwnDeliveries: Boolean, $budgetId: String, $teamId: String, $giftOptions: GiftOptionsInput, $recipientShippingDetails: RecipientShippingDetails, $storeId: String, $tipAmounts: [TipAmount!], $paymentMethod: Int, $deliveryOptionType: DeliveryOptionType, $workOrderOptions: WorkOrderOptionsInput, $isCardPayment: Boolean, $clientFraudContext: PaymentClientFraudContextInput, $programId: String, $membershipId: String, $dropoffPreferences: String, $routineReorderDetails: RoutineReorderDetails, $supplementalPaymentDetailsList: [SupplementalPaymentDetails!], $monitoringContext: CreateOrderFromCartMonitoringContextInput, $rewardBalanceApplied: RewardBalanceDetailsInput, $deliveryOptionInfo: DeliveryOptionInfo, $hasAccessibilityRequirements: Boolean, $shouldApplyCredits: Boolean, $dasherPickupInstructions: String, $paymentMethodUuid: String, $paymentMethodType: PaymentMethodType, $deviceTimezone: String, $paymentMethodBrand: String, $submitPlatform: String) {
24
- createOrderFromCart(
25
- cartId: $cartId
26
- total: $total
27
- sosDeliveryFee: $sosDeliveryFee
28
- isPickupOrder: $isPickupOrder
29
- verifiedAgeRequirement: $verifiedAgeRequirement
30
- deliveryTime: $deliveryTime
31
- menuOptions: $menuOptions
32
- stripeToken: $stripeToken
33
- attributionData: $attributionData
34
- fulfillsOwnDeliveries: $fulfillsOwnDeliveries
35
- budgetId: $budgetId
36
- teamId: $teamId
37
- giftOptions: $giftOptions
38
- recipientShippingDetails: $recipientShippingDetails
39
- storeId: $storeId
40
- tipAmounts: $tipAmounts
41
- paymentMethod: $paymentMethod
42
- deliveryOptionType: $deliveryOptionType
43
- workOrderOptions: $workOrderOptions
44
- isCardPayment: $isCardPayment
45
- clientFraudContext: $clientFraudContext
46
- programId: $programId
47
- membershipId: $membershipId
48
- dropoffPreferences: $dropoffPreferences
49
- routineReorderDetails: $routineReorderDetails
50
- supplementalPaymentDetailsList: $supplementalPaymentDetailsList
51
- monitoringContext: $monitoringContext
52
- rewardBalanceApplied: $rewardBalanceApplied
53
- deliveryOptionInfo: $deliveryOptionInfo
54
- hasAccessibilityRequirements: $hasAccessibilityRequirements
55
- shouldApplyCredits: $shouldApplyCredits
56
- dasherPickupInstructions: $dasherPickupInstructions
57
- paymentMethodUuid: $paymentMethodUuid
58
- paymentMethodType: $paymentMethodType
59
- deviceTimezone: $deviceTimezone
60
- paymentMethodBrand: $paymentMethodBrand
61
- submitPlatform: $submitPlatform
62
- ) {
63
- cartId
64
- orderUuid
65
- isFirstOrderCart
66
- isFirstNewVerticalsOrderCart
67
- __typename
68
- }
69
- }`;
70
-
71
- // ---------------------------------------------------------------------------
72
- // PAYMENT_METHODS_QUERY
73
- // ---------------------------------------------------------------------------
74
-
75
- export const PAYMENT_METHODS_QUERY = `
76
- query paymentMethodQuery {
77
- getPaymentMethodList {
78
- id
79
- type
80
- last4
81
- isDefault
82
- paymentMethodUuid
83
- __typename
84
- }
85
- }`;
@@ -1,13 +0,0 @@
1
- /**
2
- * Barrel re-export of all DoorDash GraphQL queries.
3
- * Individual query modules are split by domain:
4
- * - search-queries.ts — search and homepage discovery
5
- * - store-queries.ts — store pages, item details, retail feeds
6
- * - cart-queries.ts — cart CRUD (add, remove, update, list, detail)
7
- * - order-queries.ts — checkout, delivery options, payment methods
8
- */
9
-
10
- export { ADD_CART_ITEM_QUERY, DETAILED_CART_QUERY, LIST_CARTS_QUERY,REMOVE_CART_ITEM_QUERY, UPDATE_CART_ITEM_QUERY } from './cart-queries.js';
11
- export { CREATE_ORDER_FROM_CART_QUERY, DROPOFF_OPTIONS_QUERY, PAYMENT_METHODS_QUERY } from './order-queries.js';
12
- export { HOME_PAGE_QUERY,SEARCH_QUERY } from './search-queries.js';
13
- export { ITEM_PAGE_QUERY, RETAIL_SEARCH_QUERY,RETAIL_STORE_FEED_QUERY, STORE_PAGE_QUERY } from './store-queries.js';
@@ -1,94 +0,0 @@
1
- /**
2
- * Extracts GraphQL queries from a session recording and persists them
3
- * to disk so the DoorDash client can use real, captured queries instead
4
- * of stale static fallbacks.
5
- *
6
- * Captured queries are saved to ~/.vellum/workspace/data/doordash/captured-queries.json
7
- */
8
-
9
- import { existsSync,mkdirSync, readFileSync, writeFileSync } from 'node:fs';
10
- import { join } from 'node:path';
11
-
12
- import type { SessionRecording } from '../tools/browser/network-recording-types.js';
13
- import { getDataDir } from '../util/platform.js';
14
-
15
- export interface CapturedQuery {
16
- operationName: string;
17
- query: string;
18
- exampleVariables: unknown;
19
- capturedAt: number;
20
- }
21
-
22
- function getCapturedQueriesPath(): string {
23
- return join(getDataDir(), 'doordash', 'captured-queries.json');
24
- }
25
-
26
- /**
27
- * Extract GraphQL queries from a session recording's network entries.
28
- * Filters for /graphql/ URLs, parses postData, deduplicates by operation name
29
- * (keeps last occurrence).
30
- */
31
- export function extractQueries(recording: SessionRecording): CapturedQuery[] {
32
- const byName = new Map<string, CapturedQuery>();
33
-
34
- for (const entry of recording.networkEntries) {
35
- const url = entry.request.url;
36
- if (!url.includes('/graphql/') && !url.includes('/graphql?')) continue;
37
- if (!entry.request.postData) continue;
38
-
39
- try {
40
- const body = JSON.parse(entry.request.postData) as {
41
- operationName?: string;
42
- query?: string;
43
- variables?: unknown;
44
- };
45
-
46
- if (!body.operationName || !body.query) continue;
47
-
48
- byName.set(body.operationName, {
49
- operationName: body.operationName,
50
- query: body.query,
51
- exampleVariables: body.variables ?? null,
52
- capturedAt: entry.timestamp,
53
- });
54
- } catch {
55
- // Skip entries with unparseable postData
56
- }
57
- }
58
-
59
- return Array.from(byName.values());
60
- }
61
-
62
- /**
63
- * Merge new captured queries with existing ones on disk (newer wins),
64
- * then write to disk.
65
- */
66
- export function saveQueries(queries: CapturedQuery[]): string {
67
- const existing = loadCapturedQueries();
68
-
69
- for (const q of queries) {
70
- const prev = existing[q.operationName];
71
- if (!prev || q.capturedAt >= prev.capturedAt) {
72
- existing[q.operationName] = q;
73
- }
74
- }
75
-
76
- const filePath = getCapturedQueriesPath();
77
- mkdirSync(join(filePath, '..'), { recursive: true });
78
- writeFileSync(filePath, JSON.stringify(existing, null, 2), 'utf-8');
79
- return filePath;
80
- }
81
-
82
- /**
83
- * Load captured queries from disk. Returns a map keyed by operation name.
84
- */
85
- export function loadCapturedQueries(): Record<string, CapturedQuery> {
86
- const filePath = getCapturedQueriesPath();
87
- if (!existsSync(filePath)) return {};
88
- try {
89
- const data = readFileSync(filePath, 'utf-8');
90
- return JSON.parse(data) as Record<string, CapturedQuery>;
91
- } catch {
92
- return {};
93
- }
94
- }
@@ -1,203 +0,0 @@
1
- /**
2
- * GraphQL queries for DoorDash search and homepage discovery.
3
- * Each query is fully self-contained with all required fragment definitions.
4
- */
5
-
6
- // ---------------------------------------------------------------------------
7
- // SEARCH_QUERY
8
- // ---------------------------------------------------------------------------
9
-
10
- export const SEARCH_QUERY = `
11
- query autocompleteFacetFeed($query: String!, $serializedBundleGlobalSearchContext: String) {
12
- autocompleteFacetFeed(
13
- query: $query
14
- serializedBundleGlobalSearchContext: $serializedBundleGlobalSearchContext
15
- ) {
16
- ...FacetFeedV2ResultFragment
17
- __typename
18
- }
19
- }
20
-
21
- fragment FacetFeedV2ResultFragment on FacetFeedV2Result {
22
- body {
23
- id
24
- header { ...FacetV2Fragment __typename }
25
- body { ...FacetV2Fragment __typename }
26
- layout { omitFooter __typename }
27
- __typename
28
- }
29
- page { ...FacetV2PageFragment __typename }
30
- header { ...FacetV2Fragment __typename }
31
- footer { ...FacetV2Fragment __typename }
32
- custom logging __typename
33
- }
34
-
35
- fragment FacetV2Fragment on FacetV2 {
36
- ...FacetV2BaseFragment
37
- childrenMap { ...FacetV2BaseFragment __typename }
38
- __typename
39
- }
40
-
41
- fragment FacetV2BaseFragment on FacetV2 {
42
- id childrenCount
43
- component { id category __typename }
44
- name
45
- text {
46
- title
47
- titleTextAttributes { textStyle textColor __typename }
48
- subtitle
49
- subtitleTextAttributes { textStyle textColor __typename }
50
- accessory
51
- accessoryTextAttributes { textStyle textColor __typename }
52
- description
53
- descriptionTextAttributes { textStyle textColor __typename }
54
- custom { key value __typename }
55
- __typename
56
- }
57
- images {
58
- main { ...FacetV2ImageFragment __typename }
59
- icon { ...FacetV2ImageFragment __typename }
60
- background { ...FacetV2ImageFragment __typename }
61
- accessory { ...FacetV2ImageFragment __typename }
62
- custom { key value { ...FacetV2ImageFragment __typename } __typename }
63
- __typename
64
- }
65
- events { click { name data __typename } __typename }
66
- style {
67
- spacing background_color
68
- border { color width style __typename }
69
- sizeClass dlsType __typename
70
- }
71
- layout {
72
- omitFooter
73
- gridSpecs {
74
- Mobile { ...FacetV2LayoutGridFragment __typename }
75
- Phablet { ...FacetV2LayoutGridFragment __typename }
76
- Tablet { ...FacetV2LayoutGridFragment __typename }
77
- Desktop { ...FacetV2LayoutGridFragment __typename }
78
- WideScreen { ...FacetV2LayoutGridFragment __typename }
79
- UltraWideScreen { ...FacetV2LayoutGridFragment __typename }
80
- __typename
81
- }
82
- dlsPadding { top right bottom left __typename }
83
- __typename
84
- }
85
- custom logging __typename
86
- }
87
-
88
- fragment FacetV2ImageFragment on FacetV2Image {
89
- uri videoUri placeholder local style logging
90
- events { click { name data __typename } __typename }
91
- __typename
92
- }
93
-
94
- fragment FacetV2LayoutGridFragment on FacetV2LayoutGrid {
95
- interRowSpacing interColumnSpacing minDimensionCount __typename
96
- }
97
-
98
- fragment FacetV2PageFragment on FacetV2Page {
99
- next { name data __typename }
100
- onLoad { name data __typename }
101
- __typename
102
- }`;
103
-
104
- // ---------------------------------------------------------------------------
105
- // HOME_PAGE_QUERY
106
- // ---------------------------------------------------------------------------
107
-
108
- export const HOME_PAGE_QUERY = `
109
- query homePageFacetFeed($cursor: String, $filterQuery: String, $displayHeader: Boolean, $isDebug: Boolean, $cuisineFilterVerticalIds: String) {
110
- homePageFacetFeed(
111
- cursor: $cursor
112
- filterQuery: $filterQuery
113
- displayHeader: $displayHeader
114
- isDebug: $isDebug
115
- cuisineFilterVerticalIds: $cuisineFilterVerticalIds
116
- ) {
117
- ...FacetFeedV2ResultFragment
118
- __typename
119
- }
120
- }
121
-
122
- fragment FacetFeedV2ResultFragment on FacetFeedV2Result {
123
- body {
124
- id
125
- header { ...FacetV2Fragment __typename }
126
- body { ...FacetV2Fragment __typename }
127
- layout { omitFooter __typename }
128
- __typename
129
- }
130
- page { ...FacetV2PageFragment __typename }
131
- header { ...FacetV2Fragment __typename }
132
- footer { ...FacetV2Fragment __typename }
133
- custom logging __typename
134
- }
135
-
136
- fragment FacetV2Fragment on FacetV2 {
137
- ...FacetV2BaseFragment
138
- childrenMap { ...FacetV2BaseFragment __typename }
139
- __typename
140
- }
141
-
142
- fragment FacetV2BaseFragment on FacetV2 {
143
- id childrenCount
144
- component { id category __typename }
145
- name
146
- text {
147
- title
148
- titleTextAttributes { textStyle textColor __typename }
149
- subtitle
150
- subtitleTextAttributes { textStyle textColor __typename }
151
- accessory
152
- accessoryTextAttributes { textStyle textColor __typename }
153
- description
154
- descriptionTextAttributes { textStyle textColor __typename }
155
- custom { key value __typename }
156
- __typename
157
- }
158
- images {
159
- main { ...FacetV2ImageFragment __typename }
160
- icon { ...FacetV2ImageFragment __typename }
161
- background { ...FacetV2ImageFragment __typename }
162
- accessory { ...FacetV2ImageFragment __typename }
163
- custom { key value { ...FacetV2ImageFragment __typename } __typename }
164
- __typename
165
- }
166
- events { click { name data __typename } __typename }
167
- style {
168
- spacing background_color
169
- border { color width style __typename }
170
- sizeClass dlsType __typename
171
- }
172
- layout {
173
- omitFooter
174
- gridSpecs {
175
- Mobile { ...FacetV2LayoutGridFragment __typename }
176
- Phablet { ...FacetV2LayoutGridFragment __typename }
177
- Tablet { ...FacetV2LayoutGridFragment __typename }
178
- Desktop { ...FacetV2LayoutGridFragment __typename }
179
- WideScreen { ...FacetV2LayoutGridFragment __typename }
180
- UltraWideScreen { ...FacetV2LayoutGridFragment __typename }
181
- __typename
182
- }
183
- dlsPadding { top right bottom left __typename }
184
- __typename
185
- }
186
- custom logging __typename
187
- }
188
-
189
- fragment FacetV2ImageFragment on FacetV2Image {
190
- uri videoUri placeholder local style logging
191
- events { click { name data __typename } __typename }
192
- __typename
193
- }
194
-
195
- fragment FacetV2LayoutGridFragment on FacetV2LayoutGrid {
196
- interRowSpacing interColumnSpacing minDimensionCount __typename
197
- }
198
-
199
- fragment FacetV2PageFragment on FacetV2Page {
200
- next { name data __typename }
201
- onLoad { name data __typename }
202
- __typename
203
- }`;
@@ -1,84 +0,0 @@
1
- /**
2
- * DoorDash session persistence.
3
- * Stores/loads auth cookies from a recording or manual login.
4
- */
5
-
6
- import { existsSync, mkdirSync, readFileSync, unlinkSync,writeFileSync } from 'node:fs';
7
- import { join } from 'node:path';
8
-
9
- import type { ExtractedCredential,SessionRecording } from '../tools/browser/network-recording-types.js';
10
- import { ConfigError } from '../util/errors.js';
11
- import { getDataDir } from '../util/platform.js';
12
-
13
- export interface DoorDashSession {
14
- cookies: ExtractedCredential[];
15
- importedAt: string;
16
- recordingId?: string;
17
- }
18
-
19
- function getSessionDir(): string {
20
- return join(getDataDir(), 'doordash');
21
- }
22
-
23
- function getSessionPath(): string {
24
- return join(getSessionDir(), 'session.json');
25
- }
26
-
27
- export function loadSession(): DoorDashSession | null {
28
- const path = getSessionPath();
29
- if (!existsSync(path)) return null;
30
- try {
31
- return JSON.parse(readFileSync(path, 'utf-8')) as DoorDashSession;
32
- } catch {
33
- return null;
34
- }
35
- }
36
-
37
- export function saveSession(session: DoorDashSession): void {
38
- const dir = getSessionDir();
39
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
40
- writeFileSync(getSessionPath(), JSON.stringify(session, null, 2));
41
- }
42
-
43
- export function clearSession(): void {
44
- const path = getSessionPath();
45
- if (existsSync(path)) {
46
- unlinkSync(path);
47
- }
48
- }
49
-
50
- /**
51
- * Import cookies from a Ride Shotgun recording file.
52
- */
53
- export function importFromRecording(recordingPath: string): DoorDashSession {
54
- if (!existsSync(recordingPath)) {
55
- throw new ConfigError(`Recording not found: ${recordingPath}`);
56
- }
57
- const recording = JSON.parse(readFileSync(recordingPath, 'utf-8')) as SessionRecording;
58
- if (!recording.cookies?.length) {
59
- throw new ConfigError('Recording contains no cookies');
60
- }
61
- const session: DoorDashSession = {
62
- cookies: recording.cookies,
63
- importedAt: new Date().toISOString(),
64
- recordingId: recording.id,
65
- };
66
- saveSession(session);
67
- return session;
68
- }
69
-
70
- /**
71
- * Build a Cookie header string from the session.
72
- */
73
- export function getCookieHeader(session: DoorDashSession): string {
74
- return session.cookies
75
- .map(c => `${c.name}=${c.value}`)
76
- .join('; ');
77
- }
78
-
79
- /**
80
- * Get the CSRF token from session cookies.
81
- */
82
- export function getCsrfToken(session: DoorDashSession): string | undefined {
83
- return session.cookies.find(c => c.name === 'csrf_token')?.value;
84
- }