@dev.fast/whiteboard 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +146 -2
- package/THIRD_PARTY_NOTICES.md +93 -0
- package/dist/account-alias-DOHN1RSH.js +973 -0
- package/dist/agent-cli-ChOq0ZuO.js +117 -0
- package/dist/agent-cli-DzWfZr6G.js +2 -0
- package/dist/agent-client-CPQo7iTI.js +305 -0
- package/dist/authoring-tools-Cr6Kpjsx.js +234 -0
- package/dist/build-info.json +1 -0
- package/dist/cli-hVgHcdsv.js +47 -0
- package/dist/cli-runner-D8y2_luU.js +5095 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +128 -0
- package/dist/client-DFoh50W3.js +950 -0
- package/dist/desktop-discovery-DBO-PM2V.js +164 -0
- package/dist/error-message-OtiDonty.js +6 -0
- package/dist/fs-utils-BMPLt0cr.js +22 -0
- package/dist/fuzzy-match-BoAmcyak.js +30 -0
- package/dist/headless-host-BJxf4dUU.js +94 -0
- package/dist/input-error-OLgB_h31.js +11 -0
- package/dist/local-data-CxLk75rx.js +4491 -0
- package/dist/mcp-QeF8vkdf.js +140 -0
- package/dist/package-paths-B6-zxvIO.js +47 -0
- package/dist/process-error-telemetry-v9e5h6D7.js +3952 -0
- package/dist/profile-4ry2f3AM.js +76 -0
- package/dist/profile-Bh5FIrmf.js +2 -0
- package/dist/request-origin-D_4QIdoN.js +811 -0
- package/dist/review-agent-traces-DNJFYzc8.js +3866 -0
- package/dist/review-home-paths-6zZH-1c9.js +2560 -0
- package/dist/review-telemetry-DEFnQsQ2.js +1195 -0
- package/dist/runtime-CKiWhGrf.js +52 -0
- package/dist/runtime.d.ts +9 -0
- package/dist/runtime.js +2 -0
- package/dist/s3-SzLpeCG6.js +345 -0
- package/dist/s3-config-BgxkSoOy.js +2 -0
- package/dist/s3-config-CAxhO9u_.js +676 -0
- package/dist/server/desktop-host.d.ts +4 -0
- package/dist/server/desktop-host.js +1702 -0
- package/dist/server-discovery-Dbzn3w6Z.js +66 -0
- package/dist/sharing/index.d.ts +1977 -0
- package/dist/sharing/index.js +2 -0
- package/dist/src-CGP5ytbV.js +283 -0
- package/dist/src-CmdiBL20.js +3676 -0
- package/dist/src-DnwdaQ2r.js +865 -0
- package/dist/src-X9phtB2j.js +68 -0
- package/dist/stored-document-migration-DHeMpLMb.js +2671 -0
- package/dist/tool-failure-C8zB73HV.js +98 -0
- package/dist/tutorial-trace-DrBvkaeL.js +43 -0
- package/instructions/authoring.md +36 -0
- package/instructions/file-lenses.md +13 -0
- package/instructions/scratchpad.md +23 -0
- package/instructions/trace-archaeology.md +113 -0
- package/onboarding.md +8 -0
- package/package.json +106 -3
- package/src/agent-selection.ts +100 -0
- package/src/agent-session-ref.ts +80 -0
- package/src/ask/agents.ts +351 -0
- package/src/ask/checkout-files.ts +47 -0
- package/src/ask/file-refs.ts +111 -0
- package/src/ask/pi-mcp.ts +154 -0
- package/src/ask/protocol.ts +244 -0
- package/src/ask/thread-state.ts +350 -0
- package/src/ask/thread.ts +1400 -0
- package/src/ask/threads.ts +219 -0
- package/src/ask/watch.ts +79 -0
- package/src/cli-install.ts +1041 -0
- package/src/cli-runner.ts +1461 -0
- package/src/cli-runtime-info.ts +35 -0
- package/src/cli.ts +222 -0
- package/src/connect-prompts.ts +248 -0
- package/src/cursor-deeplink.ts +11 -0
- package/src/desktop-discovery.ts +355 -0
- package/src/diff-selection-migration.ts +63 -0
- package/src/embedded-posthog-key.ts +6 -0
- package/src/error-telemetry.ts +247 -0
- package/src/evidence.ts +14 -0
- package/src/exception-telemetry.ts +126 -0
- package/src/fixtures/blocks/call_stack_diff.json +27 -0
- package/src/fixtures/blocks/callout.json +11 -0
- package/src/fixtures/blocks/code.json +9 -0
- package/src/fixtures/blocks/code_peek.json +8 -0
- package/src/fixtures/blocks/database_lens.json +51 -0
- package/src/fixtures/blocks/divider.json +1 -0
- package/src/fixtures/blocks/fixtures.ts +33 -0
- package/src/fixtures/blocks/flow_diagram.json +36 -0
- package/src/fixtures/blocks/ids.ts +8 -0
- package/src/fixtures/blocks/image.json +9 -0
- package/src/fixtures/blocks/markdown.json +7 -0
- package/src/fixtures/blocks/section.json +11 -0
- package/src/fixtures/blocks/sequence.json +31 -0
- package/src/fixtures/blocks/software_map.json +7 -0
- package/src/fixtures/blocks/trace_quote.json +9 -0
- package/src/fixtures/blocks/tutorial.json +51 -0
- package/src/fs-utils.ts +32 -0
- package/src/fuzzy-match.ts +94 -0
- package/src/install.ts +29 -0
- package/src/legacy-skills.ts +133 -0
- package/src/lens-selection.ts +230 -0
- package/src/markdown-latex-math.ts +230 -0
- package/src/markdown.ts +81 -0
- package/src/package-paths.ts +53 -0
- package/src/posthog-capture-client.ts +610 -0
- package/src/review-api/README.md +295 -0
- package/src/review-api/activity.ts +340 -0
- package/src/review-api/agent-cli.ts +219 -0
- package/src/review-api/agent-client.ts +188 -0
- package/src/review-api/anchor-quotes.ts +88 -0
- package/src/review-api/ask-history.ts +242 -0
- package/src/review-api/authoring-tools.ts +211 -0
- package/src/review-api/blocks/call_stack_diff.ts +75 -0
- package/src/review-api/blocks/callout.ts +24 -0
- package/src/review-api/blocks/code.ts +9 -0
- package/src/review-api/blocks/code_peek.ts +13 -0
- package/src/review-api/blocks/database_lens.ts +150 -0
- package/src/review-api/blocks/definition.ts +40 -0
- package/src/review-api/blocks/divider.ts +6 -0
- package/src/review-api/blocks/flow_diagram.ts +111 -0
- package/src/review-api/blocks/image.ts +10 -0
- package/src/review-api/blocks/index.ts +90 -0
- package/src/review-api/blocks/markdown.ts +17 -0
- package/src/review-api/blocks/section.ts +24 -0
- package/src/review-api/blocks/sequence.ts +56 -0
- package/src/review-api/blocks/software_map.ts +9 -0
- package/src/review-api/blocks/trace_quote.ts +10 -0
- package/src/review-api/blocks/tutorial.ts +39 -0
- package/src/review-api/checkout-fs.ts +14 -0
- package/src/review-api/client.ts +1 -0
- package/src/review-api/comparison-coverage.ts +304 -0
- package/src/review-api/component-reference.ts +30 -0
- package/src/review-api/diff-lenses.ts +175 -0
- package/src/review-api/document-headings.ts +51 -0
- package/src/review-api/document-text.ts +200 -0
- package/src/review-api/document.ts +906 -0
- package/src/review-api/file-lenses.ts +100 -0
- package/src/review-api/http.ts +1877 -0
- package/src/review-api/image-decode.ts +29 -0
- package/src/review-api/input-error.ts +9 -0
- package/src/review-api/instructions.ts +89 -0
- package/src/review-api/lens-alignment.ts +52 -0
- package/src/review-api/local-data.ts +1837 -0
- package/src/review-api/map-input.ts +154 -0
- package/src/review-api/mcp-client-agent.ts +32 -0
- package/src/review-api/mcp.ts +240 -0
- package/src/review-api/origin.ts +43 -0
- package/src/review-api/profile.ts +146 -0
- package/src/review-api/public-tools.ts +102 -0
- package/src/review-api/pull-request.ts +389 -0
- package/src/review-api/read-schemas.ts +85 -0
- package/src/review-api/recovery.ts +2 -0
- package/src/review-api/request-origin.ts +33 -0
- package/src/review-api/review-progress.ts +382 -0
- package/src/review-api/status-tool.ts +10 -0
- package/src/review-api/store-schema.ts +22 -0
- package/src/review-api/store.ts +1647 -0
- package/src/review-api/tool-failure.ts +64 -0
- package/src/review-api/trace-schema.ts +13 -0
- package/src/review-api/traces.ts +119 -0
- package/src/review-api/unsupported-files.integration.ts +91 -0
- package/src/review-api/workspaces.ts +692 -0
- package/src/review-api/worktree-source.ts +170 -0
- package/src/review-api/worktree-structural.integration.ts +320 -0
- package/src/review-app-launcher.ts +432 -0
- package/src/review-app-picker.ts +168 -0
- package/src/review-app.ts +134 -0
- package/src/review-bundled-tools.ts +249 -0
- package/src/review-checkout-paths.ts +37 -0
- package/src/review-diff-files.ts +89 -0
- package/src/review-head-checkout.ts +300 -0
- package/src/review-home-paths.ts +73 -0
- package/src/review-info.ts +59 -0
- package/src/review-instances.ts +113 -0
- package/src/review-logger.ts +183 -0
- package/src/review-preferences.ts +88 -0
- package/src/review-prepare.ts +291 -0
- package/src/review-stack.ts +112 -0
- package/src/review-telemetry.ts +1066 -0
- package/src/runtime.ts +74 -0
- package/src/server/account-alias.ts +30 -0
- package/src/server/bounded-stream.ts +34 -0
- package/src/server/bug-report.ts +301 -0
- package/src/server/client-error-budget.ts +45 -0
- package/src/server/crash-report.ts +273 -0
- package/src/server/desktop-host-shutdown.ts +64 -0
- package/src/server/desktop-host.ts +190 -0
- package/src/server/desktop-server.ts +703 -0
- package/src/server/diffr-config.ts +509 -0
- package/src/server/diffr-languages.ts +97 -0
- package/src/server/global-verb-relay.ts +190 -0
- package/src/server/headless-host.ts +149 -0
- package/src/server/hono-http.ts +162 -0
- package/src/server/http-json.ts +24 -0
- package/src/server/json-review-reporting.ts +174 -0
- package/src/server/process-error-telemetry.ts +174 -0
- package/src/server/review-api-parsers.ts +90 -0
- package/src/server/review-lifecycle-telemetry.ts +73 -0
- package/src/server/review-open-watchdog.ts +46 -0
- package/src/server/review-server-core.ts +290 -0
- package/src/server/structural-comparisons.ts +153 -0
- package/src/server/structural-diff.ts +186 -0
- package/src/server/tutorial-service.ts +241 -0
- package/src/server/ui-telemetry.ts +198 -0
- package/src/server-discovery.ts +95 -0
- package/src/session-markers.ts +132 -0
- package/src/sharing/auth.ts +41 -0
- package/src/sharing/cli.ts +83 -0
- package/src/sharing/client.ts +334 -0
- package/src/sharing/export.ts +195 -0
- package/src/sharing/host.ts +316 -0
- package/src/sharing/import.ts +787 -0
- package/src/sharing/index.ts +16 -0
- package/src/sharing/repository.ts +145 -0
- package/src/sharing/routes.ts +34 -0
- package/src/slug.ts +23 -0
- package/src/software-map-diff-counts.ts +517 -0
- package/src/software-map-model.ts +1147 -0
- package/src/software-map-topology-diff.ts +260 -0
- package/src/source.ts +92 -0
- package/src/startup-trace.ts +232 -0
- package/src/stored-document-migration.ts +151 -0
- package/src/telemetry-clean-text.ts +257 -0
- package/src/telemetry-config.ts +298 -0
- package/src/telemetry-debug-sink.ts +38 -0
- package/src/telemetry.ts +13 -0
- package/src/trace-cli.ts +156 -0
- package/src/trace-storage-cli.ts +509 -0
- package/src/tutorial-conversation.ts +18 -0
- package/src/ui-telemetry-events.ts +765 -0
- package/src/unified-diff.ts +71 -0
- package/src/viewed-coverage.ts +259 -0
- package/src/windows-cli.ts +125 -0
- package/tutorial/document.json +275 -0
- package/tutorial/runtime-manifest.json +12 -0
- package/tutorial/sample-service/package.json +9 -0
- package/tutorial/sample-service/src/api/checkout-api.ts +17 -0
- package/tutorial/sample-service/src/app.ts +26 -0
- package/tutorial/sample-service/src/database/schema.ts +10 -0
- package/tutorial/sample-service/src/fulfillment/fulfillment-queue.ts +15 -0
- package/tutorial/sample-service/src/fulfillment/fulfillment-worker.ts +24 -0
- package/tutorial/sample-service/src/inventory/inventory-service.ts +11 -0
- package/tutorial/sample-service/src/orders/order-service.ts +34 -0
- package/tutorial/sample-service/src/orders/order.ts +21 -0
- package/tutorial/sample-service/src/orders/orders-repository.ts +24 -0
- package/tutorial/sample-service/src/payments/payment-gateway.ts +12 -0
- package/tutorial/sample-service/src/shipping/shipping-gateway.ts +15 -0
- package/tutorial/sample-service/tsconfig.json +12 -0
- package/tutorial/software-map.json +139 -0
- package/tutorial/trace.json +20 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Whiteboard Desktop: three-minute tour",
|
|
3
|
+
"document": [
|
|
4
|
+
{
|
|
5
|
+
"type": "markdown",
|
|
6
|
+
"markdown": "# Whiteboard Desktop: three-minute tour\n"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"type": "section",
|
|
10
|
+
"title": "Welcome",
|
|
11
|
+
"children": [
|
|
12
|
+
{
|
|
13
|
+
"type": "markdown",
|
|
14
|
+
"markdown": "A Review is a guided, interactive explanation of a code change. The document\nkeeps the important code and system views in one place.\n"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "tutorial",
|
|
18
|
+
"kind": "conversation",
|
|
19
|
+
"conversation": {
|
|
20
|
+
"version": 1,
|
|
21
|
+
"title": "How this Review was made",
|
|
22
|
+
"messages": [
|
|
23
|
+
{
|
|
24
|
+
"role": "user",
|
|
25
|
+
"body": "Create a Review of the feature we just worked on."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"role": "assistant",
|
|
29
|
+
"body": "Ok, I'm on it..."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "markdown",
|
|
36
|
+
"markdown": "### Your keybindings\n\nChoose your editor keys. Whiteboard highlights the active choice and uses its\nexisting extension and reload flow for Vim, Emacs, and Sublime Text.\n"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "tutorial",
|
|
40
|
+
"kind": "keymap"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "markdown",
|
|
44
|
+
"markdown": "### Put the keybindings to work\n\nThe editor below is live. Try hover, **Go to Definition**, or **Go to\nReferences** with the same commands you use in VS Code.\n"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "code_peek",
|
|
48
|
+
"source": "head/src/orders/order-service.ts#L13-L29",
|
|
49
|
+
"caption": "Order service creates the order"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "markdown",
|
|
53
|
+
"markdown": "Prose in the review also supports [links to code](review-source:head/src/orders/order-service.ts#L13-L29).\n"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "section",
|
|
59
|
+
"title": "Commits and diffs",
|
|
60
|
+
"children": [
|
|
61
|
+
{
|
|
62
|
+
"type": "markdown",
|
|
63
|
+
"markdown": "Whiteboard pins an exact base and head before the agent starts writing. Open\n**Commits** to see the change in author order. Expand the sample commit to see\nits files, then choose the **<>** button to inspect only that commit.\n\nThe **Diff** tab shows the complete change between the pinned base and head.\nChoose **Review** when you are ready to return to this tour.\n"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"type": "tutorial",
|
|
67
|
+
"kind": "view",
|
|
68
|
+
"view": "commits",
|
|
69
|
+
"label": "Explore the sample commits"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"type": "section",
|
|
75
|
+
"title": "Interactive Diagrams",
|
|
76
|
+
"children": [
|
|
77
|
+
{
|
|
78
|
+
"type": "markdown",
|
|
79
|
+
"markdown": "The sequence diagram connects the checkout request to fulfillment. Select any\nmessage to open its supporting code.\n"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "sequence",
|
|
83
|
+
"title": "Checkout to fulfillment",
|
|
84
|
+
"actors": {
|
|
85
|
+
"checkout": "Checkout API",
|
|
86
|
+
"orderService": "Order service",
|
|
87
|
+
"repository": "Orders repository",
|
|
88
|
+
"queue": "Fulfillment queue",
|
|
89
|
+
"worker": "Fulfillment worker",
|
|
90
|
+
"shipping": "Shipping gateway"
|
|
91
|
+
},
|
|
92
|
+
"steps": [
|
|
93
|
+
{
|
|
94
|
+
"type": "step",
|
|
95
|
+
"from": "checkout",
|
|
96
|
+
"to": "orderService",
|
|
97
|
+
"label": "Place order",
|
|
98
|
+
"style": "call",
|
|
99
|
+
"source": "head/src/api/checkout-api.ts#L12-L15"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"type": "step",
|
|
103
|
+
"from": "orderService",
|
|
104
|
+
"to": "repository",
|
|
105
|
+
"label": "Save order",
|
|
106
|
+
"style": "call",
|
|
107
|
+
"source": "head/src/orders/order-service.ts#L13-L29"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"type": "step",
|
|
111
|
+
"from": "repository",
|
|
112
|
+
"to": "queue",
|
|
113
|
+
"label": "Enqueue fulfillment",
|
|
114
|
+
"style": "call",
|
|
115
|
+
"source": "head/src/orders/orders-repository.ts#L9-L12"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": "step",
|
|
119
|
+
"from": "queue",
|
|
120
|
+
"to": "worker",
|
|
121
|
+
"label": "Deliver job",
|
|
122
|
+
"style": "call",
|
|
123
|
+
"source": "head/src/fulfillment/fulfillment-worker.ts#L13-L14"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"type": "step",
|
|
127
|
+
"from": "worker",
|
|
128
|
+
"to": "shipping",
|
|
129
|
+
"label": "Create shipment",
|
|
130
|
+
"style": "call",
|
|
131
|
+
"source": "head/src/fulfillment/fulfillment-worker.ts#L17-L19"
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": "markdown",
|
|
137
|
+
"markdown": "The database view groups writes by use case. Its operations open code too.\n"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "database_lens",
|
|
141
|
+
"title": "Order storage",
|
|
142
|
+
"actors": {
|
|
143
|
+
"orderService": {
|
|
144
|
+
"label": "Order service",
|
|
145
|
+
"softwareMapPath": "orderService.application.orders"
|
|
146
|
+
},
|
|
147
|
+
"worker": {
|
|
148
|
+
"label": "Fulfillment worker",
|
|
149
|
+
"softwareMapPath": "orderService.fulfillment.worker"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"stores": {
|
|
153
|
+
"orderDatabase": {
|
|
154
|
+
"label": "Order database",
|
|
155
|
+
"storage": "relational",
|
|
156
|
+
"softwareMapPath": "orderService.data.ordersDatabase",
|
|
157
|
+
"collections": {
|
|
158
|
+
"orders": {
|
|
159
|
+
"label": "orders",
|
|
160
|
+
"fields": {
|
|
161
|
+
"customerId": {
|
|
162
|
+
"label": "customerId",
|
|
163
|
+
"dataType": "text",
|
|
164
|
+
"example": "customer-42"
|
|
165
|
+
},
|
|
166
|
+
"totalCents": {
|
|
167
|
+
"label": "totalCents",
|
|
168
|
+
"dataType": "integer",
|
|
169
|
+
"example": 12500
|
|
170
|
+
},
|
|
171
|
+
"status": {
|
|
172
|
+
"label": "status",
|
|
173
|
+
"dataType": "text",
|
|
174
|
+
"example": "fulfilled"
|
|
175
|
+
},
|
|
176
|
+
"createdAt": {
|
|
177
|
+
"label": "createdAt",
|
|
178
|
+
"dataType": "timestamp",
|
|
179
|
+
"example": "2026-08-10T12:00:00Z"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"useCases": [
|
|
187
|
+
{
|
|
188
|
+
"label": "Create an order",
|
|
189
|
+
"operations": [
|
|
190
|
+
{
|
|
191
|
+
"kind": "write",
|
|
192
|
+
"store": "orderDatabase",
|
|
193
|
+
"collection": "orders",
|
|
194
|
+
"field": "status",
|
|
195
|
+
"actor": "orderService",
|
|
196
|
+
"label": "write pending order",
|
|
197
|
+
"source": "head/src/orders/orders-repository.ts#L9-L12"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"label": "Fulfill an order",
|
|
203
|
+
"operations": [
|
|
204
|
+
{
|
|
205
|
+
"kind": "write",
|
|
206
|
+
"store": "orderDatabase",
|
|
207
|
+
"collection": "orders",
|
|
208
|
+
"field": "status",
|
|
209
|
+
"actor": "worker",
|
|
210
|
+
"label": "write fulfilled status",
|
|
211
|
+
"source": "head/src/fulfillment/fulfillment-worker.ts#L17-L19"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"type": "tutorial",
|
|
219
|
+
"kind": "feature",
|
|
220
|
+
"feature": "softwareMap",
|
|
221
|
+
"children": [
|
|
222
|
+
{
|
|
223
|
+
"type": "markdown",
|
|
224
|
+
"markdown": "The experimental **Map** moves from the order system to its components and\ncode. Select a node to explore the sample service.\n"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"type": "tutorial",
|
|
228
|
+
"kind": "view",
|
|
229
|
+
"view": "map",
|
|
230
|
+
"label": "Open the software map"
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"type": "section",
|
|
238
|
+
"title": "Agent traces",
|
|
239
|
+
"children": [
|
|
240
|
+
{
|
|
241
|
+
"type": "markdown",
|
|
242
|
+
"markdown": "Trace quotes connect a Review to the agent conversation behind a change.\nSelect this quote from an illustrative session to read it in context:\n"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"type": "trace_quote",
|
|
246
|
+
"traceId": "tutorial-trace",
|
|
247
|
+
"eventId": "0",
|
|
248
|
+
"text": "we want to have one shared server / source of truth for all agent chats."
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"type": "markdown",
|
|
252
|
+
"markdown": "To capture your own sessions, open **Preferences → Settings → Experimental\nFeatures → Trace capture**. Enter your S3/R2 bucket credentials and choose\n**Enable**. Have everyone on your team do this (with the same bucket credentials) to sync and review each other's traces.\n\nTrace capture is off by default; this sample works without setup.\n"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "section",
|
|
258
|
+
"title": "Get help",
|
|
259
|
+
"children": [
|
|
260
|
+
{
|
|
261
|
+
"type": "markdown",
|
|
262
|
+
"markdown": "To connect Whiteboard to your agents, open **Preferences →\nSettings**. To revisit setup or take this tour again, open **Preferences →\nGetting Started**.\n"
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"type": "software_map",
|
|
268
|
+
"mapVersionId": "tutorial-map-base"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"type": "software_map",
|
|
272
|
+
"mapVersionId": "tutorial-map-head"
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OrderService } from "../orders/order-service.js";
|
|
2
|
+
import type { CheckoutRequest, Order } from "../orders/order.js";
|
|
3
|
+
|
|
4
|
+
export interface CheckoutResponse {
|
|
5
|
+
status: 201;
|
|
6
|
+
order: Order;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class CheckoutApi {
|
|
10
|
+
constructor(private readonly orderService: OrderService) {}
|
|
11
|
+
|
|
12
|
+
checkout(request: CheckoutRequest): CheckoutResponse {
|
|
13
|
+
const order = this.orderService.placeOrder(request);
|
|
14
|
+
|
|
15
|
+
return { status: 201, order };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CheckoutApi } from "./api/checkout-api.js";
|
|
2
|
+
import { FulfillmentQueue } from "./fulfillment/fulfillment-queue.js";
|
|
3
|
+
import { FulfillmentWorker } from "./fulfillment/fulfillment-worker.js";
|
|
4
|
+
import { InventoryService } from "./inventory/inventory-service.js";
|
|
5
|
+
import { OrderService } from "./orders/order-service.js";
|
|
6
|
+
import { OrdersRepository } from "./orders/orders-repository.js";
|
|
7
|
+
import { PaymentGateway } from "./payments/payment-gateway.js";
|
|
8
|
+
import { ShippingGateway } from "./shipping/shipping-gateway.js";
|
|
9
|
+
|
|
10
|
+
const queue = new FulfillmentQueue();
|
|
11
|
+
|
|
12
|
+
const orders = new OrdersRepository(queue);
|
|
13
|
+
|
|
14
|
+
const orderService = new OrderService(
|
|
15
|
+
new InventoryService(),
|
|
16
|
+
new PaymentGateway(),
|
|
17
|
+
orders,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const checkoutApi = new CheckoutApi(orderService);
|
|
21
|
+
|
|
22
|
+
export const fulfillmentWorker = new FulfillmentWorker(
|
|
23
|
+
queue,
|
|
24
|
+
orders,
|
|
25
|
+
new ShippingGateway(),
|
|
26
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface FulfillmentJob {
|
|
2
|
+
orderId: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export class FulfillmentQueue {
|
|
6
|
+
private readonly jobs: FulfillmentJob[] = [];
|
|
7
|
+
|
|
8
|
+
enqueue(job: FulfillmentJob): void {
|
|
9
|
+
this.jobs.push(job);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
dequeue(): FulfillmentJob | undefined {
|
|
13
|
+
return this.jobs.shift();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OrdersRepository } from "../orders/orders-repository.js";
|
|
2
|
+
import type { ShippingGateway } from "../shipping/shipping-gateway.js";
|
|
3
|
+
import type { FulfillmentQueue } from "./fulfillment-queue.js";
|
|
4
|
+
|
|
5
|
+
export class FulfillmentWorker {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly queue: FulfillmentQueue,
|
|
8
|
+
private readonly orders: OrdersRepository,
|
|
9
|
+
private readonly shipping: ShippingGateway,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
runNext(): string | null {
|
|
13
|
+
const job = this.queue.dequeue();
|
|
14
|
+
|
|
15
|
+
if (!job) return null;
|
|
16
|
+
const order = this.orders.find(job.orderId);
|
|
17
|
+
|
|
18
|
+
if (!order) throw new Error(`Order not found: ${job.orderId}`);
|
|
19
|
+
const shipment = this.shipping.createShipment(order);
|
|
20
|
+
this.orders.setStatus(order.id, "fulfilled");
|
|
21
|
+
|
|
22
|
+
return shipment.trackingNumber;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CheckoutItem } from "../orders/order.js";
|
|
2
|
+
|
|
3
|
+
export class InventoryService {
|
|
4
|
+
reserve(items: readonly CheckoutItem[]): void {
|
|
5
|
+
const unavailable = items.find((item) => item.quantity < 1);
|
|
6
|
+
|
|
7
|
+
if (unavailable) {
|
|
8
|
+
throw new Error(`Invalid quantity for ${unavailable.sku}`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InventoryService } from "../inventory/inventory-service.js";
|
|
2
|
+
import type { PaymentGateway } from "../payments/payment-gateway.js";
|
|
3
|
+
import type { CheckoutRequest, Order } from "./order.js";
|
|
4
|
+
import type { OrdersRepository } from "./orders-repository.js";
|
|
5
|
+
|
|
6
|
+
export class OrderService {
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly inventory: InventoryService,
|
|
9
|
+
private readonly payments: PaymentGateway,
|
|
10
|
+
private readonly orders: OrdersRepository,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
placeOrder(request: CheckoutRequest): Order {
|
|
14
|
+
const totalCents = request.items.reduce(
|
|
15
|
+
(sum, item) => sum + item.quantity * item.unitPriceCents,
|
|
16
|
+
0,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
this.inventory.reserve(request.items);
|
|
20
|
+
this.payments.charge(request.paymentToken, totalCents);
|
|
21
|
+
|
|
22
|
+
const order: Order = {
|
|
23
|
+
id: `order-${request.customerId}`,
|
|
24
|
+
customerId: request.customerId,
|
|
25
|
+
items: request.items,
|
|
26
|
+
totalCents,
|
|
27
|
+
status: "pending",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
this.orders.insert(order);
|
|
31
|
+
|
|
32
|
+
return order;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type OrderStatus = "pending" | "queued" | "fulfilled";
|
|
2
|
+
|
|
3
|
+
export interface CheckoutItem {
|
|
4
|
+
sku: string;
|
|
5
|
+
quantity: number;
|
|
6
|
+
unitPriceCents: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface Order {
|
|
10
|
+
id: string;
|
|
11
|
+
customerId: string;
|
|
12
|
+
items: readonly CheckoutItem[];
|
|
13
|
+
totalCents: number;
|
|
14
|
+
status: OrderStatus;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CheckoutRequest {
|
|
18
|
+
customerId: string;
|
|
19
|
+
items: readonly CheckoutItem[];
|
|
20
|
+
paymentToken: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FulfillmentQueue } from "../fulfillment/fulfillment-queue.js";
|
|
2
|
+
import type { Order, OrderStatus } from "./order.js";
|
|
3
|
+
|
|
4
|
+
export class OrdersRepository {
|
|
5
|
+
private readonly rows = new Map<string, Order>();
|
|
6
|
+
|
|
7
|
+
constructor(private readonly queue: FulfillmentQueue) {}
|
|
8
|
+
|
|
9
|
+
insert(order: Order): void {
|
|
10
|
+
this.rows.set(order.id, order);
|
|
11
|
+
this.queue.enqueue({ orderId: order.id });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
find(orderId: string): Order | undefined {
|
|
15
|
+
return this.rows.get(orderId);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setStatus(orderId: string, status: OrderStatus): void {
|
|
19
|
+
const order = this.find(orderId);
|
|
20
|
+
|
|
21
|
+
if (!order) throw new Error(`Order not found: ${orderId}`);
|
|
22
|
+
this.rows.set(orderId, { ...order, status });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface PaymentReceipt {
|
|
2
|
+
chargeId: string;
|
|
3
|
+
amountCents: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export class PaymentGateway {
|
|
7
|
+
charge(paymentToken: string, amountCents: number): PaymentReceipt {
|
|
8
|
+
if (!paymentToken) throw new Error("A payment token is required");
|
|
9
|
+
|
|
10
|
+
return { chargeId: `charge-${amountCents}`, amountCents };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Order } from "../orders/order.js";
|
|
2
|
+
|
|
3
|
+
export interface Shipment {
|
|
4
|
+
trackingNumber: string;
|
|
5
|
+
orderId: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class ShippingGateway {
|
|
9
|
+
createShipment(order: Order): Shipment {
|
|
10
|
+
return {
|
|
11
|
+
trackingNumber: `track-${order.id}`,
|
|
12
|
+
orderId: order.id,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"people": {},
|
|
3
|
+
"systems": {
|
|
4
|
+
"orderService": {
|
|
5
|
+
"label": "Order service",
|
|
6
|
+
"description": "Accepts checkout requests, records orders, and completes fulfillment.",
|
|
7
|
+
"containers": {
|
|
8
|
+
"api": {
|
|
9
|
+
"label": "Checkout API",
|
|
10
|
+
"description": "Provides the typed checkout entry point.",
|
|
11
|
+
"components": {
|
|
12
|
+
"checkout": {
|
|
13
|
+
"label": "Checkout API",
|
|
14
|
+
"description": "Accepts a checkout request and delegates order creation.",
|
|
15
|
+
"coverage": {
|
|
16
|
+
"files": ["src/api/checkout-api.ts"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"application": {
|
|
22
|
+
"label": "Order application",
|
|
23
|
+
"description": "Applies the rules for creating an order.",
|
|
24
|
+
"components": {
|
|
25
|
+
"orders": {
|
|
26
|
+
"label": "Order service",
|
|
27
|
+
"description": "Calculates the total, reserves stock, charges payment, and creates the order.",
|
|
28
|
+
"coverage": {
|
|
29
|
+
"files": [
|
|
30
|
+
"src/orders/order-service.ts",
|
|
31
|
+
"src/orders/order.ts",
|
|
32
|
+
"src/inventory/inventory-service.ts",
|
|
33
|
+
"src/payments/payment-gateway.ts"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"data": {
|
|
40
|
+
"label": "Order data",
|
|
41
|
+
"description": "Stores orders and defines their persisted shape.",
|
|
42
|
+
"components": {
|
|
43
|
+
"ordersRepository": {
|
|
44
|
+
"label": "Orders repository",
|
|
45
|
+
"description": "Persists orders in memory and submits fulfillment jobs.",
|
|
46
|
+
"coverage": {
|
|
47
|
+
"files": ["src/orders/orders-repository.ts"]
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"ordersDatabase": {
|
|
51
|
+
"label": "Orders table",
|
|
52
|
+
"description": "Defines the columns in the orders table.",
|
|
53
|
+
"coverage": {
|
|
54
|
+
"files": ["src/database/schema.ts"]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"fulfillment": {
|
|
60
|
+
"label": "Fulfillment",
|
|
61
|
+
"description": "Queues orders and runs one fulfillment job at a time.",
|
|
62
|
+
"components": {
|
|
63
|
+
"queue": {
|
|
64
|
+
"label": "Fulfillment queue",
|
|
65
|
+
"description": "Stores order identifiers until a worker can act.",
|
|
66
|
+
"coverage": {
|
|
67
|
+
"files": ["src/fulfillment/fulfillment-queue.ts"]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"worker": {
|
|
71
|
+
"label": "Fulfillment worker",
|
|
72
|
+
"description": "Loads a queued order, creates its shipment, and marks it fulfilled.",
|
|
73
|
+
"coverage": {
|
|
74
|
+
"files": ["src/fulfillment/fulfillment-worker.ts"]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"shipping": {
|
|
80
|
+
"label": "Shipping",
|
|
81
|
+
"description": "Creates shipment tracking records.",
|
|
82
|
+
"components": {
|
|
83
|
+
"gateway": {
|
|
84
|
+
"label": "Shipping gateway",
|
|
85
|
+
"description": "Creates a shipment for an order.",
|
|
86
|
+
"coverage": {
|
|
87
|
+
"files": ["src/shipping/shipping-gateway.ts"]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"relationships": [
|
|
96
|
+
{
|
|
97
|
+
"kind": "semantic",
|
|
98
|
+
"from": "orderService.api.checkout",
|
|
99
|
+
"to": "orderService.application.orders",
|
|
100
|
+
"label": "Creates an order"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"kind": "semantic",
|
|
104
|
+
"from": "orderService.application.orders",
|
|
105
|
+
"to": "orderService.data.ordersRepository",
|
|
106
|
+
"label": "Stores the order"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"kind": "semantic",
|
|
110
|
+
"from": "orderService.data.ordersRepository",
|
|
111
|
+
"to": "orderService.data.ordersDatabase",
|
|
112
|
+
"label": "Writes an order row"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"kind": "semantic",
|
|
116
|
+
"from": "orderService.data.ordersRepository",
|
|
117
|
+
"to": "orderService.fulfillment.queue",
|
|
118
|
+
"label": "Enqueues the order"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"kind": "semantic",
|
|
122
|
+
"from": "orderService.fulfillment.queue",
|
|
123
|
+
"to": "orderService.fulfillment.worker",
|
|
124
|
+
"label": "Dispatches the job"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"kind": "semantic",
|
|
128
|
+
"from": "orderService.fulfillment.worker",
|
|
129
|
+
"to": "orderService.shipping.gateway",
|
|
130
|
+
"label": "Creates a shipment"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"kind": "semantic",
|
|
134
|
+
"from": "orderService.fulfillment.worker",
|
|
135
|
+
"to": "orderService.data.ordersRepository",
|
|
136
|
+
"label": "Marks the order fulfilled"
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|