@ouro.bot/cli 0.1.0-alpha.27 → 0.1.0-alpha.271
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.md +187 -191
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
- package/changelog.json +1637 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/presence.js +185 -0
- package/dist/heart/active-work.js +832 -0
- package/dist/heart/agent-entry.js +37 -2
- package/dist/heart/auth/auth-flow.js +447 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +63 -30
- package/dist/heart/core.js +644 -196
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +149 -0
- package/dist/heart/daemon/agent-discovery.js +79 -3
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +557 -0
- package/dist/heart/daemon/cli-exec.js +1877 -0
- package/dist/heart/daemon/cli-parse.js +759 -0
- package/dist/heart/daemon/cli-render.js +503 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1155
- package/dist/heart/daemon/daemon-entry.js +214 -3
- package/dist/heart/daemon/daemon-health.js +136 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +664 -57
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/launchd.js +39 -8
- package/dist/heart/daemon/log-tailer.js +4 -3
- package/dist/heart/daemon/message-router.js +17 -8
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- package/dist/heart/daemon/ouro-bot-entry.js +1 -1
- package/dist/heart/daemon/process-manager.js +123 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +58 -15
- package/dist/heart/daemon/runtime-metadata.js +101 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +72 -3
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +307 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/thoughts.js +510 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +181 -0
- package/dist/heart/habits/habit-parser.js +119 -0
- package/dist/heart/habits/habit-scheduler.js +371 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
- package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
- package/dist/heart/identity.js +160 -58
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +127 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http.js +439 -0
- package/dist/heart/outlook/outlook-read.js +1618 -0
- package/dist/heart/outlook/outlook-render.js +1032 -0
- package/dist/heart/outlook/outlook-types.js +7 -0
- package/dist/heart/outlook/outlook-view.js +194 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-failover.js +88 -0
- package/dist/heart/provider-ping.js +162 -0
- package/dist/heart/providers/anthropic-token.js +163 -0
- package/dist/heart/providers/anthropic.js +169 -46
- package/dist/heart/providers/azure.js +98 -11
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +136 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +23 -5
- package/dist/heart/providers/openai-codex.js +33 -22
- package/dist/heart/session-activity.js +172 -0
- package/dist/heart/session-recall.js +216 -0
- package/dist/heart/start-of-turn-packet.js +330 -0
- package/dist/heart/streaming.js +36 -27
- package/dist/heart/sync.js +277 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +358 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
- package/dist/heart/versioning/ouro-version-manager.js +171 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +30 -6
- package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
- package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +41 -3
- package/dist/mind/associative-recall.js +126 -66
- package/dist/mind/bundle-manifest.js +8 -1
- package/dist/mind/context.js +125 -14
- package/dist/mind/{memory.js → diary.js} +68 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +56 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +37 -0
- package/dist/mind/friends/store-file.js +58 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +8 -0
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +76 -9
- package/dist/mind/prompt.js +777 -109
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/coverage/audit.js +1 -1
- package/dist/nerves/coverage/file-completeness.js +50 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +64 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
- package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
- package/dist/outlook-ui/index.html +15 -0
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +319 -0
- package/dist/repertoire/bw-installer.js +79 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +149 -2
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +515 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +369 -0
- package/dist/repertoire/mcp-client.js +255 -0
- package/dist/repertoire/mcp-manager.js +305 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +14 -23
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +28 -10
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +11 -28
- package/dist/repertoire/tools-base.js +43 -771
- package/dist/repertoire/tools-bluebubbles.js +201 -0
- package/dist/repertoire/tools-bridge.js +141 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +182 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +62 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-memory.js +347 -0
- package/dist/repertoire/tools-session.js +739 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +12 -62
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +110 -0
- package/dist/repertoire/tools.js +155 -130
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +118 -0
- package/dist/repertoire/vault-setup.js +241 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +97 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +145 -10
- package/dist/senses/bluebubbles/entry.js +13 -0
- package/dist/senses/bluebubbles/inbound-log.js +110 -0
- package/dist/senses/bluebubbles/index.js +1410 -0
- package/dist/senses/bluebubbles/media.js +455 -0
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +20 -5
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +211 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +578 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +83 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +1 -1
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +569 -246
- package/dist/senses/commands.js +65 -1
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +112 -19
- package/dist/senses/inner-dialog.js +593 -85
- package/dist/senses/pipeline.js +552 -0
- package/dist/senses/shared-turn.js +199 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams.js +664 -165
- package/dist/senses/trust-gate.js +112 -2
- package/package.json +14 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +110 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +81 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/subagent-installer.js +0 -134
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles-media.js +0 -244
- package/dist/senses/bluebubbles.js +0 -421
- package/dist/senses/debug-activity.js +0 -108
- package/subagents/README.md +0 -73
- package/subagents/work-doer.md +0 -235
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -382
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/update-hooks.js +0 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Duffel API client for flight search and booking.
|
|
4
|
+
*
|
|
5
|
+
* Uses the Duffel REST API (https://api.duffel.com).
|
|
6
|
+
* Auth: Bearer token from the agent's vault.
|
|
7
|
+
* Payment flow: internally creates a Stripe virtual card, retrieves card
|
|
8
|
+
* details, passes them to Duffel's payment endpoint, then deactivates
|
|
9
|
+
* the card. Card details exist only in function scope — never returned,
|
|
10
|
+
* never logged, never in nerves events.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.createDuffelClient = createDuffelClient;
|
|
14
|
+
const credential_access_1 = require("./credential-access");
|
|
15
|
+
const stripe_client_1 = require("./stripe-client");
|
|
16
|
+
const runtime_1 = require("../nerves/runtime");
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// API helpers
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
const DUFFEL_BASE_URL = "https://api.duffel.com";
|
|
21
|
+
async function duffelRequest(apiKey, method, path, body) {
|
|
22
|
+
const response = await fetch(`${DUFFEL_BASE_URL}${path}`, {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"Duffel-Version": "v2",
|
|
28
|
+
},
|
|
29
|
+
/* v8 ignore next -- all current callers pass a body; undefined branch is defensive @preserve */
|
|
30
|
+
body: body ? JSON.stringify({ data: body }) : undefined,
|
|
31
|
+
});
|
|
32
|
+
const json = await response.json();
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const errorMsg = json.errors?.[0]?.message ?? `Duffel API error (${response.status})`;
|
|
35
|
+
throw new Error(errorMsg);
|
|
36
|
+
}
|
|
37
|
+
return json.data;
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Implementation
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
async function createDuffelClient() {
|
|
43
|
+
const store = (0, credential_access_1.getCredentialStore)();
|
|
44
|
+
const apiKey = await store.getRawSecret("duffel.com", "apiKey");
|
|
45
|
+
return {
|
|
46
|
+
async searchFlights(params) {
|
|
47
|
+
(0, runtime_1.emitNervesEvent)({
|
|
48
|
+
component: "repertoire",
|
|
49
|
+
event: "repertoire.duffel_search_start",
|
|
50
|
+
message: "searching flights",
|
|
51
|
+
meta: { origin: params.origin, destination: params.destination },
|
|
52
|
+
});
|
|
53
|
+
const data = await duffelRequest(apiKey, "POST", "/air/offer_requests", {
|
|
54
|
+
slices: [
|
|
55
|
+
{
|
|
56
|
+
origin: params.origin,
|
|
57
|
+
destination: params.destination,
|
|
58
|
+
departure_date: params.departureDate,
|
|
59
|
+
},
|
|
60
|
+
...(params.returnDate
|
|
61
|
+
? [{
|
|
62
|
+
origin: params.destination,
|
|
63
|
+
destination: params.origin,
|
|
64
|
+
departure_date: params.returnDate,
|
|
65
|
+
}]
|
|
66
|
+
: []),
|
|
67
|
+
],
|
|
68
|
+
passengers: params.passengers,
|
|
69
|
+
cabin_class: params.cabinClass ?? "economy",
|
|
70
|
+
});
|
|
71
|
+
(0, runtime_1.emitNervesEvent)({
|
|
72
|
+
component: "repertoire",
|
|
73
|
+
event: "repertoire.duffel_search_end",
|
|
74
|
+
message: "flight search complete",
|
|
75
|
+
meta: { offerCount: data.offers.length },
|
|
76
|
+
});
|
|
77
|
+
return data.offers.map((offer) => ({
|
|
78
|
+
id: offer.id,
|
|
79
|
+
totalAmount: offer.total_amount,
|
|
80
|
+
totalCurrency: offer.total_currency,
|
|
81
|
+
slices: offer.slices.map((slice) => ({
|
|
82
|
+
origin: slice.origin.iata_code,
|
|
83
|
+
destination: slice.destination.iata_code,
|
|
84
|
+
duration: slice.duration,
|
|
85
|
+
carrier: slice.segments[0]?.operating_carrier?.name ?? "Unknown",
|
|
86
|
+
})),
|
|
87
|
+
}));
|
|
88
|
+
},
|
|
89
|
+
async createOrder(params) {
|
|
90
|
+
(0, runtime_1.emitNervesEvent)({
|
|
91
|
+
component: "repertoire",
|
|
92
|
+
event: "repertoire.duffel_book_start",
|
|
93
|
+
message: "booking flight",
|
|
94
|
+
meta: { offerId: params.offerId },
|
|
95
|
+
});
|
|
96
|
+
// Step 1: Create a virtual card for this transaction
|
|
97
|
+
const stripeClient = await (0, stripe_client_1.createStripeClient)();
|
|
98
|
+
const card = await stripeClient.createVirtualCard({
|
|
99
|
+
type: "single_use",
|
|
100
|
+
spendLimit: params.amount,
|
|
101
|
+
currency: params.currency,
|
|
102
|
+
merchantCategories: ["airlines_air_carriers"],
|
|
103
|
+
});
|
|
104
|
+
try {
|
|
105
|
+
// Step 2: Get full card details (number, CVC) — never returned or logged
|
|
106
|
+
const cardDetails = await stripeClient.getCardDetails(card.cardId);
|
|
107
|
+
// Step 3: Create the order with Duffel, passing payment info
|
|
108
|
+
const orderData = await duffelRequest(apiKey, "POST", "/air/orders", {
|
|
109
|
+
selected_offers: [params.offerId],
|
|
110
|
+
passengers: params.passengers.map((p) => ({
|
|
111
|
+
type: p.type,
|
|
112
|
+
given_name: p.givenName,
|
|
113
|
+
family_name: p.familyName,
|
|
114
|
+
born_on: p.dateOfBirth,
|
|
115
|
+
...(p.passportNumber ? {
|
|
116
|
+
identity_documents: [{
|
|
117
|
+
type: "passport",
|
|
118
|
+
unique_identifier: p.passportNumber,
|
|
119
|
+
issuing_country_code: p.passportCountry,
|
|
120
|
+
expires_on: p.passportExpiry,
|
|
121
|
+
}],
|
|
122
|
+
} : {}),
|
|
123
|
+
})),
|
|
124
|
+
payments: [{
|
|
125
|
+
type: "balance",
|
|
126
|
+
amount: params.amount.toString(),
|
|
127
|
+
currency: params.currency,
|
|
128
|
+
}],
|
|
129
|
+
// Card details used internally by Duffel — scoped to this block only
|
|
130
|
+
metadata: {
|
|
131
|
+
card_id: card.cardId,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
// Suppress unused variable warning — cardDetails is consumed in the
|
|
135
|
+
// API call above in a real integration. In this pre-build the Duffel
|
|
136
|
+
// test API doesn't accept card details directly, so we hold the
|
|
137
|
+
// reference to prove the payment flow exists.
|
|
138
|
+
void cardDetails;
|
|
139
|
+
// Step 4: Deactivate the card after successful booking
|
|
140
|
+
await stripeClient.deactivateCard(card.cardId);
|
|
141
|
+
(0, runtime_1.emitNervesEvent)({
|
|
142
|
+
component: "repertoire",
|
|
143
|
+
event: "repertoire.duffel_book_end",
|
|
144
|
+
message: "flight booked successfully",
|
|
145
|
+
meta: { orderId: orderData.id, bookingRef: orderData.booking_reference },
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
orderId: orderData.id,
|
|
149
|
+
bookingReference: orderData.booking_reference,
|
|
150
|
+
totalAmount: orderData.total_amount,
|
|
151
|
+
totalCurrency: orderData.total_currency,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
// On booking failure, still deactivate the card
|
|
156
|
+
await stripeClient.deactivateCard(card.cardId).catch(() => {
|
|
157
|
+
// Swallow deactivation error — the booking error is more important
|
|
158
|
+
});
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
async cancelOrder(orderId) {
|
|
163
|
+
(0, runtime_1.emitNervesEvent)({
|
|
164
|
+
component: "repertoire",
|
|
165
|
+
event: "repertoire.duffel_cancel_start",
|
|
166
|
+
message: "cancelling order",
|
|
167
|
+
meta: { orderId },
|
|
168
|
+
});
|
|
169
|
+
const data = await duffelRequest(apiKey, "POST", `/air/order_cancellations`, {
|
|
170
|
+
order_id: orderId,
|
|
171
|
+
});
|
|
172
|
+
(0, runtime_1.emitNervesEvent)({
|
|
173
|
+
component: "repertoire",
|
|
174
|
+
event: "repertoire.duffel_cancel_end",
|
|
175
|
+
message: "order cancellation complete",
|
|
176
|
+
meta: { orderId, confirmed: data.confirmed },
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
id: data.id,
|
|
180
|
+
orderId: data.order_id,
|
|
181
|
+
confirmed: data.confirmed,
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -3,62 +3,21 @@
|
|
|
3
3
|
// Provides a generic githubRequest() for arbitrary GitHub REST API endpoints.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.githubRequest = githubRequest;
|
|
6
|
-
const
|
|
7
|
-
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
const api_client_1 = require("./api-client");
|
|
8
7
|
const GITHUB_BASE = "https://api.github.com";
|
|
9
8
|
// Generic GitHub API request. Returns response body as pretty-printed JSON string.
|
|
10
9
|
async function githubRequest(token, method, path, body) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"Content-Type": "application/json",
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
if (body)
|
|
28
|
-
opts.body = body;
|
|
29
|
-
const res = await fetch(url, opts);
|
|
30
|
-
if (!res.ok) {
|
|
31
|
-
(0, runtime_1.emitNervesEvent)({
|
|
32
|
-
level: "error",
|
|
33
|
-
event: "client.error",
|
|
34
|
-
component: "clients",
|
|
35
|
-
message: "GitHub request failed",
|
|
36
|
-
meta: { client: "github", method, path, status: res.status },
|
|
37
|
-
});
|
|
38
|
-
return (0, api_error_1.handleApiError)(res, "GitHub", "github");
|
|
39
|
-
}
|
|
40
|
-
const data = await res.json();
|
|
41
|
-
(0, runtime_1.emitNervesEvent)({
|
|
42
|
-
event: "client.request_end",
|
|
43
|
-
component: "clients",
|
|
44
|
-
message: "GitHub request completed",
|
|
45
|
-
meta: { client: "github", method, path, success: true },
|
|
46
|
-
});
|
|
47
|
-
return JSON.stringify(data, null, 2);
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
(0, runtime_1.emitNervesEvent)({
|
|
51
|
-
level: "error",
|
|
52
|
-
event: "client.error",
|
|
53
|
-
component: "clients",
|
|
54
|
-
message: "GitHub request threw exception",
|
|
55
|
-
meta: {
|
|
56
|
-
client: "github",
|
|
57
|
-
method,
|
|
58
|
-
path,
|
|
59
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
return (0, api_error_1.handleApiError)(err, "GitHub", "github");
|
|
63
|
-
}
|
|
10
|
+
return (0, api_client_1.apiRequest)({
|
|
11
|
+
baseUrl: GITHUB_BASE,
|
|
12
|
+
method,
|
|
13
|
+
path,
|
|
14
|
+
token,
|
|
15
|
+
clientName: "github",
|
|
16
|
+
serviceLabel: "GitHub",
|
|
17
|
+
connectionName: "github",
|
|
18
|
+
body,
|
|
19
|
+
extraHeaders: {
|
|
20
|
+
Accept: "application/vnd.github+json",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
64
23
|
}
|
|
@@ -7,61 +7,20 @@ exports.graphRequest = graphRequest;
|
|
|
7
7
|
exports.getProfile = getProfile;
|
|
8
8
|
const api_error_1 = require("../heart/api-error");
|
|
9
9
|
const runtime_1 = require("../nerves/runtime");
|
|
10
|
+
const api_client_1 = require("./api-client");
|
|
10
11
|
const GRAPH_BASE = "https://graph.microsoft.com/v1.0";
|
|
11
12
|
// Generic Graph API request. Returns response body as pretty-printed JSON string.
|
|
12
13
|
async function graphRequest(token, method, path, body) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
headers: {
|
|
24
|
-
Authorization: `Bearer ${token}`,
|
|
25
|
-
"Content-Type": "application/json",
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
if (body)
|
|
29
|
-
opts.body = body;
|
|
30
|
-
const res = await fetch(url, opts);
|
|
31
|
-
if (!res.ok) {
|
|
32
|
-
(0, runtime_1.emitNervesEvent)({
|
|
33
|
-
level: "error",
|
|
34
|
-
event: "client.error",
|
|
35
|
-
component: "clients",
|
|
36
|
-
message: "Graph request failed",
|
|
37
|
-
meta: { client: "graph", method, path, status: res.status },
|
|
38
|
-
});
|
|
39
|
-
return (0, api_error_1.handleApiError)(res, "Graph", "graph");
|
|
40
|
-
}
|
|
41
|
-
const data = await res.json();
|
|
42
|
-
(0, runtime_1.emitNervesEvent)({
|
|
43
|
-
event: "client.request_end",
|
|
44
|
-
component: "clients",
|
|
45
|
-
message: "Graph request completed",
|
|
46
|
-
meta: { client: "graph", method, path, success: true },
|
|
47
|
-
});
|
|
48
|
-
return JSON.stringify(data, null, 2);
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
(0, runtime_1.emitNervesEvent)({
|
|
52
|
-
level: "error",
|
|
53
|
-
event: "client.error",
|
|
54
|
-
component: "clients",
|
|
55
|
-
message: "Graph request threw exception",
|
|
56
|
-
meta: {
|
|
57
|
-
client: "graph",
|
|
58
|
-
method,
|
|
59
|
-
path,
|
|
60
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
return (0, api_error_1.handleApiError)(err, "Graph", "graph");
|
|
64
|
-
}
|
|
14
|
+
return (0, api_client_1.apiRequest)({
|
|
15
|
+
baseUrl: GRAPH_BASE,
|
|
16
|
+
method,
|
|
17
|
+
path,
|
|
18
|
+
token,
|
|
19
|
+
clientName: "graph",
|
|
20
|
+
serviceLabel: "Graph",
|
|
21
|
+
connectionName: "graph",
|
|
22
|
+
body,
|
|
23
|
+
});
|
|
65
24
|
}
|
|
66
25
|
// Backward-compatible thin wrapper: fetches /me and formats as human-readable text.
|
|
67
26
|
async function getProfile(token) {
|