@agent-native/core 0.209.1 → 0.209.2-nightly-20261016005836

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 (97) hide show
  1. package/dist/agent/actions/list-model-providers.js +15 -2
  2. package/dist/agent/app-model-defaults.d.ts +9 -13
  3. package/dist/agent/app-model-defaults.js +23 -5
  4. package/dist/agent/default-agent-engine.d.ts +5 -3
  5. package/dist/agent/default-agent-engine.js +38 -8
  6. package/dist/agent/durable-background.d.ts +2 -0
  7. package/dist/agent/durable-background.js +2 -0
  8. package/dist/agent/engine/registry.js +6 -0
  9. package/dist/agent/production-agent.js +58 -5
  10. package/dist/app-config/clips.d.ts +43 -0
  11. package/dist/app-config/clips.js +91 -0
  12. package/dist/app-config/index.d.ts +1 -0
  13. package/dist/app-config/index.js +1 -0
  14. package/dist/app-config/schema.d.ts +17 -0
  15. package/dist/app-config/schema.js +2 -0
  16. package/dist/automations/service.d.ts +2 -0
  17. package/dist/automations/service.js +4 -1
  18. package/dist/client/analytics.js +48 -1
  19. package/dist/client/application-state.js +7 -2
  20. package/dist/client/chat/agentkit-protocol.js +12 -3
  21. package/dist/client/client-bootstrap.js +2 -0
  22. package/dist/client/problem-report.d.ts +11 -0
  23. package/dist/client/problem-report.js +19 -0
  24. package/dist/client/recorder.d.ts +88 -0
  25. package/dist/client/recorder.js +585 -0
  26. package/dist/client/route-chunk-recovery.js +4 -1
  27. package/dist/client/sign-out.js +2 -0
  28. package/dist/client/use-action.js +3 -0
  29. package/dist/deploy/workspace-deploy.js +77 -3
  30. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  31. package/dist/integrations/google-docs-poller.js +12 -5
  32. package/dist/integrations/plugin.js +86 -19
  33. package/dist/integrations/request-scope.d.ts +16 -0
  34. package/dist/integrations/request-scope.js +27 -0
  35. package/dist/integrations/webhook-handler.d.ts +2 -0
  36. package/dist/integrations/webhook-handler.js +38 -18
  37. package/dist/jobs/background-automation-runner.d.ts +2 -0
  38. package/dist/jobs/background-automation-runner.js +25 -2
  39. package/dist/jobs/scheduler.js +36 -22
  40. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  41. package/dist/notifications/routes.d.ts +2 -2
  42. package/dist/observability/routes.d.ts +1 -1
  43. package/dist/org/context.d.ts +12 -0
  44. package/dist/org/context.js +26 -11
  45. package/dist/org/index.d.ts +1 -1
  46. package/dist/problem-report/actions/read-problem-report.d.ts +27 -0
  47. package/dist/problem-report/actions/read-problem-report.js +103 -0
  48. package/dist/problem-report/actions/save-problem-report.d.ts +35 -0
  49. package/dist/problem-report/actions/save-problem-report.js +36 -0
  50. package/dist/problem-report/format.d.ts +7 -0
  51. package/dist/problem-report/format.js +110 -0
  52. package/dist/problem-report/schema.d.ts +41 -0
  53. package/dist/problem-report/schema.js +34 -0
  54. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  55. package/dist/provider-api/actions/provider-api.d.ts +14 -14
  56. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  57. package/dist/scripts/agent-engines/manage-agent-engine.js +9 -4
  58. package/dist/scripts/agent-engines/set-agent-engine.js +7 -1
  59. package/dist/server/action-discovery.js +11 -0
  60. package/dist/server/action-routes.js +2 -0
  61. package/dist/server/agent-chat-ai-setup.d.ts +2 -3
  62. package/dist/server/agent-chat-ai-setup.js +18 -4
  63. package/dist/server/agent-chat-plugin.js +97 -22
  64. package/dist/server/agent-chat-stream.d.ts +17 -5
  65. package/dist/server/agent-chat-stream.js +15 -0
  66. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  67. package/dist/server/agent-engine-default-model-route.d.ts +2 -2
  68. package/dist/server/agent-engine-default-model-route.js +39 -6
  69. package/dist/server/agent-engine-status-cache.d.ts +4 -0
  70. package/dist/server/agent-engine-status-cache.js +2 -0
  71. package/dist/server/agent-run-context.d.ts +9 -0
  72. package/dist/server/agent-run-context.js +82 -17
  73. package/dist/server/auth.js +6 -1
  74. package/dist/server/builder-browser.js +18 -3
  75. package/dist/server/chatgpt-subscription-oauth.js +12 -17
  76. package/dist/server/core-routes-plugin.d.ts +1 -0
  77. package/dist/server/core-routes-plugin.js +46 -9
  78. package/dist/server/index.d.ts +1 -1
  79. package/dist/server/index.js +1 -1
  80. package/dist/server/loopback.d.ts +1 -0
  81. package/dist/server/loopback.js +30 -0
  82. package/dist/server/origin-allowlist.d.ts +2 -0
  83. package/dist/server/origin-allowlist.js +13 -1
  84. package/dist/server/realtime-token.d.ts +1 -1
  85. package/dist/server/request-context.d.ts +4 -0
  86. package/dist/templates/chat/app/components/layout/Sidebar.tsx +11 -1
  87. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +2 -2
  88. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +31 -0
  89. package/dist/triggers/dispatcher.js +117 -31
  90. package/docs/content/recorder.mdx +259 -0
  91. package/docs/content/template-clips-developers.mdx +9 -8
  92. package/docs/content/template-clips-features.mdx +8 -7
  93. package/package.json +7 -4
  94. package/src/templates/chat/app/components/layout/Sidebar.tsx +11 -1
  95. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +2 -2
  96. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +31 -0
  97. package/third-party-licenses/TABLER-ICONS.txt +21 -0
@@ -0,0 +1,259 @@
1
+ ---
2
+ title: "Recorder"
3
+ description: "The recorder is a short, redacted, in-memory record of what an app just did. It turns into a report for the app's agent, Clips, Sentry, or any destination you register."
4
+ ---
5
+
6
+ # Recorder
7
+
8
+ The recorder is a short, redacted, in-memory record of what an Agent-Native app just did. Every app records its actions, `application_state` writes, route changes, errors, and error toasts from the last two minutes, with no app code. When something goes wrong, that record becomes a report that the app's agent, a Clips recording, Sentry, or your own destination can read.
9
+
10
+ ```ts
11
+ import { recorder } from "@agent-native/core/client/recorder";
12
+
13
+ const report = recorder.report();
14
+ ```
15
+
16
+ Nothing is stored on the server and nothing leaves the browser until a report is sent somewhere. The recorder makes no network requests of its own.
17
+
18
+ ## What it captures {#captured}
19
+
20
+ | Type | Source | Example |
21
+ | -------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
22
+ | `action` | Every `useActionQuery()`, `useActionMutation()`, and `callAction()` call. Each action in a batched read is its own event. | `list-folders` failed with `403` and `forbidden_scope` inside a batch that returned `200` |
23
+ | `state` | Every `application_state` write and delete, including the ones that failed or were cancelled | `design-selection` changed `state` from `hover` to `focus` |
24
+ | `nav` | Route changes. Only the path is kept. | `/design/d_8f2c1a` |
25
+ | `error` | Uncaught errors and unhandled promise rejections, with the first stack frame | `TypeError` at `/app/pages/design-editor/commands/undo.ts:1715` |
26
+ | `toast` | Error and warning toasts the user saw | `This screen changed elsewhere. Your edit was not saved.` |
27
+ | `log` | Events the app adds with `recorder.log()` | `screen.restored` from `f_1` to `f_9` |
28
+
29
+ Each event has the same fields:
30
+
31
+ | Field | Meaning |
32
+ | ----------- | ------------------------------------------------------------------------------------------------ |
33
+ | `t` | Seconds before the report was made. It is negative. |
34
+ | `at` | Epoch milliseconds. Clips diagnostics use the same clock. |
35
+ | `type` | `action`, `state`, `nav`, `error`, `toast`, or `log` |
36
+ | `name` | The action name, state key, route path, error type, toast level, or log name |
37
+ | `ok` | Whether an action or state write succeeded |
38
+ | `status` | The HTTP status, when there was one |
39
+ | `errorCode` | The action's error code. A call or write the app cancelled has `errorCode: "cancelled"`. |
40
+ | `ms` | How long an action or state write took |
41
+ | `requestId` | The server's request id, which also appears in its logs and in its Sentry event |
42
+ | `data` | Redacted, bounded details. An action has its HTTP method and, when it failed, its error message. |
43
+
44
+ A state write records only what changed since the last value that key saved. The first write of a key records `data.value`. Later writes record `data.changed`, where a removed field reads `"[removed]"`. A write that changed nothing records `data.unchanged`, and a delete records `data.deleted`. A failed write also has `data.error`, and the next write is still compared with the last value that saved.
45
+
46
+ ## Reports {#reports}
47
+
48
+ A report is the events in the window plus the values the app watches and the work still in flight.
49
+
50
+ ```json
51
+ {
52
+ "app": "design",
53
+ "build": "59929e9",
54
+ "url": "/design/d_8f2c1a?file=[redacted]",
55
+ "at": "2026-10-14T16:20:05.120Z",
56
+ "reason": "user",
57
+ "windowSeconds": 120,
58
+ "events": [
59
+ {
60
+ "t": -12.4,
61
+ "at": 1791994792720,
62
+ "type": "state",
63
+ "name": "design-selection",
64
+ "ok": true,
65
+ "ms": 41,
66
+ "data": { "changed": { "state": "hover" } }
67
+ },
68
+ {
69
+ "t": -10.9,
70
+ "at": 1791994794220,
71
+ "type": "action",
72
+ "name": "update-file",
73
+ "ok": true,
74
+ "status": 200,
75
+ "ms": 180,
76
+ "requestId": "req_a1",
77
+ "data": { "method": "POST" }
78
+ }
79
+ ],
80
+ "watched": {
81
+ "inspector": {
82
+ "state": "focus",
83
+ "fields": [{ "label": "Opacity", "shown": "91%" }]
84
+ }
85
+ },
86
+ "pending": [],
87
+ "dropped": 0
88
+ }
89
+ ```
90
+
91
+ - **app**: the app id. Without one it falls back to the page's host, such as `localhost:8080`, so it is never empty.
92
+ - **url**: the route path. Every query value is redacted and the hash is left out.
93
+ - **windowSeconds**: how many seconds the report covers.
94
+ - **pending**: actions and state writes still in flight, each with its `ageMs`.
95
+ - **dropped**: events lost to the caps since the page loaded or the user signed out. Events that aged out of the window are not counted.
96
+
97
+ ## The SDK {#sdk}
98
+
99
+ ### `recorder.report()` {#report}
100
+
101
+ `recorder.report()` returns the current report. It is synchronous. It accepts one optional object:
102
+
103
+ - **seconds**: keep only the last `seconds` of the window.
104
+ - **reason**: `"user"`, `"error"`, `"test"`, or `"manual"`. The default is `"manual"`.
105
+
106
+ ```ts
107
+ const report = recorder.report();
108
+ ```
109
+
110
+ Pass `seconds` for a shorter slice, such as the half minute before a recording started:
111
+
112
+ ```ts
113
+ const before = recorder.report({ seconds: 30 });
114
+ ```
115
+
116
+ Every reason except `"manual"` also sends the report to the `recorder.onReport()` listeners. A plain `recorder.report()` call never does, so a listener can build a report without looping.
117
+
118
+ ### `recorder.log()` {#log}
119
+
120
+ `recorder.log()` adds an event in the app's own words. It accepts a name and optional data. Data that is not a plain object is recorded as `{ value }`.
121
+
122
+ Design logs the new id of each screen that undo brings back, because undo re-creates deleted screens with new ids:
123
+
124
+ ```ts
125
+ recorder.log("screen.restored", { from: file.id, to: result.id });
126
+ ```
127
+
128
+ ### `recorder.watch()` {#watch}
129
+
130
+ `recorder.watch()` adds a live value to every report. It accepts a name and a function that returns the value, and it returns a function that stops watching.
131
+
132
+ Design's inspector adds what it is showing and the interaction state it is editing. Neither is in `application_state`, so without this a report could not show them:
133
+
134
+ ```tsx
135
+ useEffect(
136
+ () =>
137
+ recorder.watch("inspector", () => ({
138
+ state: interactionState ?? "default",
139
+ fields: readVisualScrubInputs(),
140
+ })),
141
+ [interactionState],
142
+ );
143
+ ```
144
+
145
+ A function that throws is reported as `{ unreadable: "<message>" }` rather than left out.
146
+
147
+ ### `recorder.onReport()` {#on-report}
148
+
149
+ `recorder.onReport()` sends reports to a destination. It accepts a listener and returns a function that removes it. The listener receives every report built with a reason other than `"manual"`. That covers Report a problem (`"user"`), uncaught errors (`"error"`), and tests (`"test"`).
150
+
151
+ ```ts
152
+ recorder.onReport((report) => posthog.capture("problem_report", report));
153
+ ```
154
+
155
+ ```ts
156
+ recorder.onReport((report) =>
157
+ navigator.sendBeacon("/api/logs", JSON.stringify(report)),
158
+ );
159
+ ```
160
+
161
+ An uncaught error sends at most one report every ten seconds, so an error loop cannot flood a destination. A listener that throws is logged and the other listeners still run.
162
+
163
+ ### `recorder.redact()` {#redact}
164
+
165
+ `recorder.redact()` hides more fields from every event recorded after the call and from every watched value. Pass field names, or dotted paths that start with the event's name. A `*` matches any one field.
166
+
167
+ ```ts
168
+ recorder.redact("email");
169
+ recorder.redact("compose.body", "payment.*");
170
+ ```
171
+
172
+ ### `recorder.pending()` {#pending}
173
+
174
+ `recorder.pending()` lists the actions and state writes still in flight. Tests use it to wait for real idle instead of a fixed sleep. Design's end-to-end rails wait for it to be empty in `app.settled()`, and attach `recorder.json` to every failed test.
175
+
176
+ ```ts
177
+ await expect
178
+ .poll(() =>
179
+ page.evaluate(
180
+ () => window.__agentNativeRecorder?.report({ seconds: 0 }).pending,
181
+ ),
182
+ )
183
+ .toEqual([]);
184
+ ```
185
+
186
+ ### `recorder.disable()` {#disable}
187
+
188
+ `recorder.disable()` turns the recorder off. It does the same as `configureRecorder({ enabled: false })`.
189
+
190
+ ## `configureRecorder()` {#configure}
191
+
192
+ `configureRecorder()` is one optional call. These are the defaults:
193
+
194
+ ```ts
195
+ import { configureRecorder } from "@agent-native/core/client/recorder";
196
+
197
+ configureRecorder({
198
+ windowSeconds: 120,
199
+ maxEvents: 2000,
200
+ sentry: true,
201
+ enabled: true,
202
+ });
203
+ ```
204
+
205
+ - **windowSeconds**: how far back the recorder keeps events.
206
+ - **maxEvents**: the most events it keeps. When the cap is reached, the oldest events are dropped and counted in `dropped`.
207
+ - **sentry**: whether Sentry errors get the recent events. It only acts when the app has browser Sentry.
208
+ - **enabled**: whether the recorder runs at all.
209
+
210
+ A window or cap that is not a positive number throws a `RangeError` instead of falling back to a default. The recorder also caps its total size at about 512 KB of JSON, whatever `maxEvents` is, which keeps it under 2 MB of memory per tab.
211
+
212
+ ## Destinations {#destinations}
213
+
214
+ ### Report a problem {#report-a-problem}
215
+
216
+ Every app has **Report a problem**. It is at the bottom of the sidebar, in the agent panel's options menu, and in the command menu (⌘K).
217
+
218
+ - It asks whether to attach what the app did in the last two minutes, and previews the counts, the failures, and the first events. It asks every time.
219
+ - When the user agrees, the full report is stored as a private file that only that user can read. The app's agent receives a short summary with a reference to the file.
220
+ - The agent reads more of the report with the `read-problem-report` action, filtered by event type or time.
221
+ - When the page has no agent chat, the button copies the summary and the reference instead.
222
+ - The report needs file storage. Without it, the dialog says the report was not attached, and nothing is sent.
223
+
224
+ ### Sentry {#sentry}
225
+
226
+ When an app has browser Sentry configured through Agent-Native (see [Error reporting](/docs/observability#sentry)), every Sentry error event gets:
227
+
228
+ - the last 100 events as breadcrumbs in the `recorder.action`, `recorder.state`, and similar categories, each with its outcome, status, and request id
229
+ - the whole report as a `recorder.json` attachment
230
+
231
+ This needs no app code. `configureRecorder({ sentry: false })` turns it off.
232
+
233
+ ### Your own destination {#own-destination}
234
+
235
+ Register a listener with [`recorder.onReport()`](#on-report).
236
+
237
+ ### Clips and browser extensions {#extensions}
238
+
239
+ The page exposes `window.__agentNativeRecorder.report()`. A browser extension reads it from the page's main world.
240
+
241
+ When developer logs are on, the Clips extension reads it in the recorded tab when the recording starts (the last 30 seconds) and when it stops. The events join the recording's console and network entries on the same clock, and the clip's agent gets a summary of the failures. See [Clips browser logs](/docs/template-clips-features#chrome-extension-browser-logs).
242
+
243
+ ## Privacy {#privacy}
244
+
245
+ - **It stays in the browser.** A report leaves only when a destination sends it: Report a problem after the user agrees, a Clips recording the user started, Sentry, or a listener the developer registered.
246
+ - **Secrets are removed.** A field whose name looks secret (`password`, `token`, `secret`, `apiKey`, `authorization`, `cookie`, `session`, `card`, `cvv`) reads `"[redacted]"`. Token-looking text inside any value, such as JWTs, bearer tokens, and provider API keys, is replaced with `[redacted]` too. These are the same redactors core uses for error reports.
247
+ - **Values are bounded.** Strings are cut at 200 characters and each event at about 2 KB. A cut says what it dropped. Request and response bodies are never recorded.
248
+ - **It forgets.** It keeps only the window, up to its caps. It is cleared on reload and on sign-out.
249
+ - **No new access.** The recorder only sees what already passes through the app. Action calls already go to the server, and `application_state` is already stored and read by the agent.
250
+
251
+ ## Turning it off {#off}
252
+
253
+ ```ts
254
+ import { configureRecorder } from "@agent-native/core/client/recorder";
255
+
256
+ configureRecorder({ enabled: false });
257
+ ```
258
+
259
+ A disabled recorder forgets what it held, stops listening, and removes `window.__agentNativeRecorder` from the page. Its `recorder.report()` returns no events and no watched values, and it sends nothing to listeners. `configureRecorder({ enabled: true })` starts it again.
@@ -138,14 +138,15 @@ Every operation is a TypeScript file in `templates/clips/actions/`, auto-mounted
138
138
 
139
139
  The Chrome extension attaches console and network diagnostics to a recording, and `save-browser-diagnostics` stores them. Every console and network entry carries a `tabId`.
140
140
 
141
- | Topic | Behavior |
142
- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143
- | Tabs | Up to five per recording: the start tab, then tabs active in the last 10 minutes, most recent first. A tab the user switches to during the recording is attached too. |
144
- | Over five | The least recently active tab other than the focused one is detached. Its entries so far stay in the recording. |
145
- | Lookback | Up to 30 seconds before the recording started, limited by the page's own console history and resource timing list. These entries have negative `elapsedMs`. |
146
- | `tabId` | Set on every console and network entry. |
147
- | `method` | `"UNKNOWN"` on lookback network entries, which come from resource timing and have no HTTP method. Live requests report the method. |
148
- | Not collected | Request and response bodies and headers. Console and network entries are redacted before upload. |
141
+ | Topic | Behavior |
142
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
143
+ | Tabs | Up to five per recording: the start tab, then tabs active in the last 10 minutes, most recent first. A tab the user switches to during the recording is attached too. |
144
+ | Over five | The least recently active tab other than the focused one is detached. Its entries so far stay in the recording. |
145
+ | Lookback | Up to 30 seconds before the recording started, limited by the page's own console history and resource timing list. These entries have negative `elapsedMs`. |
146
+ | `tabId` | Set on every console and network entry. |
147
+ | `method` | `"UNKNOWN"` on lookback network entries, which come from resource timing and have no HTTP method. Live requests report the method. |
148
+ | App activity | On Agent-Native apps, the [recorder](/docs/recorder) events from the recorded tab. `save-recording-app-activity` stores them as a private file with a summary on the diagnostics row, and `get-recording-app-activity` reads them by time range. |
149
+ | Not collected | Request and response bodies and headers. Console and network entries are redacted before upload. |
149
150
 
150
151
  ## Data model
151
152
 
@@ -169,13 +169,14 @@ Earlier screen time attaches up to five minutes of local screen history from bef
169
169
 
170
170
  Install the Clips Chrome extension for a recording plus the browser logs and network activity from the tab you're debugging, useful for reporting product bugs and browser-only repros.
171
171
 
172
- | Topic | Behavior |
173
- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
174
- | Tabs | Up to five: the tab you started the recording from, then tabs you used in the last 10 minutes, most recent first. |
175
- | Switching | A tab you switch to during the recording is captured too. If more than five tabs are attached, the least recently used tab other than the one in focus is detached, and its logs so far stay in the recording. |
176
- | Lookback | Up to 30 seconds before the recording started, as far as the page still keeps its console history and resource timing. These entries have negative time offsets. |
177
- | Saved | Console messages, and fetch/XHR request info: method, a redacted URL, status, duration, and whether it failed. Each entry records the tab it came from. |
178
- | Never saved | Request or response bodies, headers, or cookies. |
172
+ | Topic | Behavior |
173
+ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
174
+ | Tabs | Up to five: the tab you started the recording from, then tabs you used in the last 10 minutes, most recent first. |
175
+ | Switching | A tab you switch to during the recording is captured too. If more than five tabs are attached, the least recently used tab other than the one in focus is detached, and its logs so far stay in the recording. |
176
+ | Lookback | Up to 30 seconds before the recording started, as far as the page still keeps its console history and resource timing. These entries have negative time offsets. |
177
+ | Saved | Console messages, and fetch/XHR request info: method, a redacted URL, status, duration, and whether it failed. Each entry records the tab it came from. |
178
+ | App activity | On Agent-Native apps, the recorded tab's own actions, state changes, navigation, and errors from the [recorder](/docs/recorder), including the 30 seconds before the recording started. |
179
+ | Never saved | Request or response bodies, headers, or cookies. |
179
180
 
180
181
  Lookback network entries have no HTTP method, so their method is recorded as `UNKNOWN`. Requests made during the recording include the method. Tabs are tracked while the extension is running, so for the first 10 minutes after it starts, fewer than five tabs may qualify.
181
182
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.209.1",
3
+ "version": "0.209.2-nightly-20261016005836",
4
4
  "description": "The agentic application framework for building autonomous agents with intuitive UIs",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -25,6 +25,7 @@
25
25
  "!docs/content/locales/**",
26
26
  "migration-manifest.json",
27
27
  "tsconfig.base.json",
28
+ "third-party-licenses",
28
29
  "src/eject",
29
30
  "src/integrations/eject",
30
31
  "src/assets/fonts/LICENSE_*",
@@ -216,6 +217,7 @@
216
217
  "./client/sign-in-landing": "./dist/client/sign-in-landing.js",
217
218
  "./client/oauth-popup": "./dist/client/oauth-popup.js",
218
219
  "./client/route-state": "./dist/client/route-state.js",
220
+ "./client/recorder": "./dist/client/recorder.js",
219
221
  "./observability/actions/list-observability-reviews": "./dist/observability/actions/list-observability-reviews.js",
220
222
  "./observability/actions/get-observability-review-app": "./dist/observability/actions/get-observability-review-app.js",
221
223
  "./observability/actions/get-observability-review-detail": "./dist/observability/actions/get-observability-review-detail.js",
@@ -469,6 +471,7 @@
469
471
  "./client/notifications": "./dist/client/notifications/index.js",
470
472
  "./progress": "./dist/progress/index.js",
471
473
  "./client/progress": "./dist/client/progress/index.js",
474
+ "./client/problem-report": "./dist/client/problem-report.js",
472
475
  "./triggers": "./dist/triggers/index.js",
473
476
  "./terminal": "./dist/client/terminal/index.js",
474
477
  "./terminal/server": "./dist/terminal/index.js",
@@ -704,8 +707,8 @@
704
707
  "yaml": "^2.9.0",
705
708
  "yjs": "^13.6.33",
706
709
  "zod": "^4.3.6",
707
- "@agent-native/agentkit": "^0.209.1",
708
- "@agent-native/recap-cli": "^0.5.73"
710
+ "@agent-native/recap-cli": "^0.5.73",
711
+ "@agent-native/agentkit": "^0.209.2-nightly-20261016005836"
709
712
  },
710
713
  "devDependencies": {
711
714
  "@ai-sdk/anthropic": "^3.0.71",
@@ -775,7 +778,7 @@
775
778
  "xlsx": "^0.18.5"
776
779
  },
777
780
  "peerDependencies": {
778
- "@agent-native/core-corpus": ">=0.196.0",
781
+ "@agent-native/core-corpus": "0.209.2-nightly-20261016005836",
779
782
  "@ai-sdk/anthropic": ">=3",
780
783
  "@ai-sdk/cohere": ">=3",
781
784
  "@ai-sdk/google": ">=3",
@@ -5,6 +5,7 @@ import {
5
5
  useChatThreads,
6
6
  type ChatThreadSummary,
7
7
  } from "@agent-native/toolkit/app/chat/agentkit-chat/rail";
8
+ import { ReportProblemButton } from "@agent-native/toolkit/app/feedback";
8
9
  import { OrgSwitcher } from "@agent-native/toolkit/app/org";
9
10
  import { openCommandMenu } from "@agent-native/toolkit/app/shared";
10
11
  import { AgentNativeIcon } from "@agent-native/toolkit/app/shared/AgentNativeIcon";
@@ -567,7 +568,16 @@ export function Sidebar({
567
568
  <ChatThreadsSection collapsed={collapsed} />
568
569
  </nav>
569
570
 
570
- <div className="mt-auto shrink-0 border-t border-sidebar-border p-2">
571
+ <div
572
+ className={cn(
573
+ "mt-auto shrink-0 px-2 pb-1",
574
+ collapsed && "flex justify-center",
575
+ )}
576
+ >
577
+ <ReportProblemButton variant={collapsed ? "icon" : "sidebar"} />
578
+ </div>
579
+
580
+ <div className="shrink-0 border-t border-sidebar-border p-2">
571
581
  <div
572
582
  className={cn(
573
583
  collapsed
@@ -126,8 +126,8 @@ record source, target, owner, exact action, and verification. Don't reopen
126
126
  closed fixes.
127
127
  **Clustered** closes one row but retains it.
128
128
 
129
- Enumerate channel parents newest backward through `next_cursor` until older
130
- than 5 days. Check reactions first; skip marked messages.
129
+ Enumerate channel parents newest-first for five days. For a permalink plus
130
+ newer scope, follow the [checked inventory procedure](references/channel-inventory.md).
131
131
 
132
132
  **`slack_search` can rank and truncate.** Use channel reads to enumerate parents
133
133
  and put their count in the recap. Sort targeted searches oldest-first and follow
@@ -0,0 +1,31 @@
1
+ # Channel parent inventory
2
+
3
+ Use this procedure before investigating, claiming, or using a CI rollup in
4
+ place of Slack source messages.
5
+
6
+ - Read each scoped channel newest-first, following `next_cursor` until the
7
+ five-day boundary, the inclusive permalink cutoff, or Slack exhaustion.
8
+ - For “this permalink and newer,” use the parent message's `ts` as the inclusive
9
+ `cutoffTs` and `permalinkTs`. Slack's `oldest` parameter is exclusive, so
10
+ query from at least one second earlier and filter locally by `ts >= cutoff`.
11
+ - Record every top-level parent returned in every fetched page before filtering
12
+ or triage. This includes duplicates, owned items, bots, and boundary overlap.
13
+ Reactions and ownership determine what to investigate, not what to inventory.
14
+ - Save `.tmp/feedback-inventory.json` with `cutoffTs`, optional `permalinkTs`,
15
+ and `channels`. Set `permalinkTs` when a supplied message anchors the scan. A channel
16
+ has `channelId`, `oldestQuery`, and `pages`. A page has its requested `cursor`,
17
+ returned `nextCursor`, `exhausted`, the full Slack `parentCount`, the complete
18
+ `sourceTimestamps` list copied from that response, and `parents`. Each parent
19
+ records `ts`, `reactionChecked: true`, `reactionSummary` (`none` if empty),
20
+ and `disposition`.
21
+ - Keep the source manifest separate from disposition rows. Copy every timestamp
22
+ and the count from the full Slack response before filtering; the checker
23
+ compares both lists, catches missing parents and requires the requested
24
+ permalink timestamp to appear. Continue until a fetched page contains a
25
+ parent older than cutoff or Slack reports exhaustion.
26
+ - Run `pnpm feedback:inventory-check -- .tmp/feedback-inventory.json`. It checks
27
+ boundary overlap, page/cursor order, count parity, timestamps, reaction state,
28
+ and dispositions. Include each channel's parent and page counts in the recap.
29
+
30
+ A grouped CI report or attachment is a discovery index, never a replacement for
31
+ the channel-parent inventory.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2026 Paweł Kuna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.