@agent-native/core 0.168.7 → 0.168.10

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 (91) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/actions/mutate-dashboard.ts +8 -1
  3. package/corpus/templates/calendar/actions/delete-event.ts +34 -18
  4. package/corpus/templates/calendar/actions/delete-events.ts +13 -1
  5. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +22 -3
  6. package/corpus/templates/calendar/app/lib/calendar-timezone.ts +19 -0
  7. package/corpus/templates/calendar/server/lib/google-api.ts +18 -1
  8. package/corpus/templates/clips/actions/finalize-meeting.ts +16 -0
  9. package/corpus/templates/clips/actions/list-meetings.ts +1 -0
  10. package/corpus/templates/clips/actions/sync-calendars.ts +10 -29
  11. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +28 -12
  12. package/corpus/templates/clips/desktop/src/lib/meeting-stop.ts +16 -0
  13. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +19 -9
  14. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +1 -0
  15. package/corpus/templates/content/app/global.css +5 -0
  16. package/corpus/templates/content/docs/solutions/2026-08-20-code-block-slash-production-regression-shape.md +492 -0
  17. package/corpus/templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md +273 -0
  18. package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +5 -0
  19. package/corpus/templates/factory/AGENTS.md +12 -22
  20. package/corpus/templates/factory/README.md +11 -8
  21. package/corpus/templates/factory/actions/approve-factory-item.ts +35 -8
  22. package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +24 -9
  23. package/corpus/templates/factory/actions/create-factory.ts +211 -0
  24. package/corpus/templates/factory/actions/evaluate-triage-item.ts +29 -5
  25. package/corpus/templates/factory/actions/get-factory-graph.ts +1 -1
  26. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -11
  27. package/corpus/templates/factory/actions/get-triage-config.ts +13 -12
  28. package/corpus/templates/factory/actions/get-triage-item.ts +28 -6
  29. package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +33 -17
  30. package/corpus/templates/factory/actions/ingest-github-observation.ts +10 -4
  31. package/corpus/templates/factory/actions/list-factory-audit.ts +11 -4
  32. package/corpus/templates/factory/actions/list-factory-automations.ts +34 -12
  33. package/corpus/templates/factory/actions/list-triage-items.ts +11 -3
  34. package/corpus/templates/factory/actions/list-triage-rules.ts +11 -4
  35. package/corpus/templates/factory/actions/poll-github-sources.ts +24 -10
  36. package/corpus/templates/factory/actions/poll-sentry-errors.ts +26 -11
  37. package/corpus/templates/factory/actions/poll-slack-channel.ts +31 -13
  38. package/corpus/templates/factory/actions/reconcile-triage-run.ts +59 -9
  39. package/corpus/templates/factory/actions/record-triage-feedback.ts +14 -3
  40. package/corpus/templates/factory/actions/run-factory-automation.ts +12 -2
  41. package/corpus/templates/factory/actions/save-factory-automation.ts +82 -21
  42. package/corpus/templates/factory/actions/save-factory-graph.ts +10 -1
  43. package/corpus/templates/factory/actions/save-triage-config.ts +90 -36
  44. package/corpus/templates/factory/actions/save-triage-rule.ts +16 -3
  45. package/corpus/templates/factory/actions/start-builder-for-item.ts +28 -20
  46. package/corpus/templates/factory/actions/suggest-factory-rules.ts +11 -4
  47. package/corpus/templates/factory/actions/view-screen.ts +22 -30
  48. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +7 -2
  49. package/corpus/templates/factory/app/components/factory/FactoryWorkspaceActions.tsx +7 -22
  50. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +260 -0
  51. package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
  52. package/corpus/templates/factory/app/components/layout/Sidebar.tsx +2 -1
  53. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +3 -3
  54. package/corpus/templates/factory/app/i18n/en-US.ts +18 -1
  55. package/corpus/templates/factory/app/routes/factory.tsx +78 -62
  56. package/corpus/templates/factory/app/routes/{factory-settings.tsx → new-factory.tsx} +12 -9
  57. package/corpus/templates/factory/server/db/schema.ts +18 -3
  58. package/corpus/templates/factory/server/factory-graph/contracts.ts +24 -0
  59. package/corpus/templates/factory/server/factory-graph/store.ts +16 -9
  60. package/corpus/templates/factory/server/lib/factory-automation-plan.ts +136 -0
  61. package/corpus/templates/factory/server/lib/factory-automation-repair.ts +31 -0
  62. package/corpus/templates/factory/server/lib/factory-scope.ts +416 -0
  63. package/corpus/templates/factory/server/lib/require-factory-automation.ts +11 -0
  64. package/corpus/templates/factory/server/plugins/agent-chat.ts +4 -2
  65. package/corpus/templates/factory/server/plugins/factory-migrations.ts +80 -0
  66. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +142 -43
  67. package/corpus/templates/factory/server/triage/audit.ts +4 -0
  68. package/corpus/templates/factory/server/triage/ids.ts +4 -0
  69. package/dist/cli/native-dependencies.js +4 -1
  70. package/dist/client/AgentPanel.d.ts +5 -1
  71. package/dist/client/AgentPanel.js +9 -4
  72. package/dist/client/agent-chat/index.d.ts +1 -1
  73. package/dist/client/agent-chat/index.js +1 -1
  74. package/dist/client/chat-first/apps-rail.js +6 -6
  75. package/dist/client/chat-first/primary-nav.js +14 -6
  76. package/dist/client/integrations/IntegrationsPanel.d.ts +15 -0
  77. package/dist/client/integrations/IntegrationsPanel.js +29 -21
  78. package/dist/client/integrations/index.d.ts +1 -1
  79. package/dist/client/integrations/index.js +1 -1
  80. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  81. package/dist/collab/struct-routes.d.ts +1 -1
  82. package/dist/deploy/build.js +1 -1
  83. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  84. package/dist/observability/routes.d.ts +3 -3
  85. package/dist/progress/routes.d.ts +1 -1
  86. package/dist/secrets/routes.d.ts +6 -6
  87. package/dist/server/realtime-token.d.ts +1 -1
  88. package/dist/server/transcribe-voice.d.ts +1 -1
  89. package/dist/shared/mcp-embed-headers.d.ts +1 -1
  90. package/dist/shared/mcp-embed-headers.js +10 -3
  91. package/package.json +1 -1
@@ -0,0 +1,273 @@
1
+ # Ordinary Code Block surface contrast
2
+
3
+ ## Decision
4
+
5
+ Give ordinary native Code Blocks a quiet semantic surface that is visibly
6
+ distinct from the Page canvas in both light and dark themes. Reuse Content's
7
+ existing `--muted` theme token and restore the existing six-pixel radius and
8
+ block spacing directly on `pre.notion-code-block`.
9
+
10
+ This is a separate local refinement from the code-block insertion regression.
11
+ It must not delay, rewrite, or expand that repair, which remains committed at
12
+ `fbe8c9c9060944e3514fd1f2b1a43edc88115199` and land-ready.
13
+
14
+ ## Current truth
15
+
16
+ Direct source evidence:
17
+
18
+ - The Page canvas uses `--background`: white in light mode and 13% lightness in
19
+ dark mode.
20
+ - Content already defines `--muted`: 96% lightness in light mode and 16% in
21
+ dark mode.
22
+ - `.notion-code-block-wrapper` uses `background: hsl(var(--muted))`, a six-pixel
23
+ radius, and `0.6em` vertical margins.
24
+ - Ordinary Code Blocks now use Tiptap's native DOM renderer and carry the class
25
+ `notion-code-block`; they do not render the old wrapper.
26
+ - The shared `pre` rule explicitly gives `.notion-code-block` a transparent
27
+ background, zero radius, and zero margin. It therefore visually collapses
28
+ into the Page canvas.
29
+
30
+ Inference: the missing contrast is a styling seam left behind when ordinary
31
+ Code Blocks moved from the former wrapper/node view to Tiptap's native renderer.
32
+ No new Code Block product contract or color system is required.
33
+
34
+ ## Scope
35
+
36
+ Owned outcome: an ordinary native Code Block reads as a contained code surface
37
+ against the surrounding Page in light and dark themes while preserving current
38
+ source editing, syntax highlighting, selection, keyboard behavior, and
39
+ persistence.
40
+
41
+ Explicit exclusions:
42
+
43
+ - language controls, headers, tabs, execution, output, or other Code Block UX;
44
+ - Mermaid or registry-backed Code blocks;
45
+ - slash-command catalog or insertion behavior;
46
+ - syntax-highlight token redesign;
47
+ - Page, card, popover, sidebar, or global theme palette changes;
48
+ - image insertion or media styling.
49
+
50
+ ## Smallest compatible repair
51
+
52
+ Keep the shared typography and overflow rule. Add a native-block-specific rule
53
+ after it that applies:
54
+
55
+ - `background: hsl(var(--muted))`;
56
+ - `border-radius: 6px`;
57
+ - `margin: 0.6em 0`.
58
+
59
+ Do not add raw light/dark colors or a new token. The existing semantic token
60
+ already expresses the intended quiet secondary surface and automatically
61
+ tracks both themes.
62
+
63
+ ## Successful-user-story acceptance plan
64
+
65
+ Use the current task-owned local Content runtime or an equivalent disposable
66
+ runtime built from the exact Work artifact.
67
+
68
+ 1. Open an ordinary Page in light mode and insert a native Code Block.
69
+ 2. Confirm the block has a subtle non-white surface distinct from the Page,
70
+ with visible rounded bounds and normal vertical separation.
71
+ 3. Type representative plain and highlighted code; confirm text contrast,
72
+ syntax colors, caret, selection, horizontal overflow, and Tab remain usable.
73
+ 4. Switch to dark mode and confirm the same block has a subtle non-black/dark
74
+ canvas distinction without becoming a high-contrast black panel.
75
+ 5. Reload and confirm the Code Block source persists and the themed surface
76
+ returns.
77
+ 6. Confirm an ordinary paragraph, inline code, registry `Code`, and Mermaid
78
+ presentation are unchanged.
79
+ 7. Run formatter, Content typecheck, and the focused editor/style tests on the
80
+ exact review artifact.
81
+
82
+ Acceptance is human-facing and visual, so it uses a real interface with
83
+ preferred independence and same-context custody. Independent technical review
84
+ is not required for this bounded CSS-only refinement.
85
+
86
+ ## Lifecycle envelope
87
+
88
+ ```yaml
89
+ authoritySchemaVersion: 3
90
+ stage: shape
91
+ authority-source: "Alice: While at it, we should give the code block background a background that's different than the white of the page and the black of the page. $shape"
92
+ authorized-scope:
93
+ repositories:
94
+ - BuilderIO/agent-native
95
+ product-surfaces:
96
+ - Content ordinary native Code Block presentation
97
+ outcome: Give ordinary native Code Blocks a subtle theme-aware surface distinct from the Page canvas.
98
+ allowed-mutations:
99
+ - artifact-write
100
+ write-targets:
101
+ artifacts:
102
+ - templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md
103
+ prototype-sandboxes: []
104
+ test-resources: []
105
+ governing-artifact:
106
+ path: templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md
107
+ revision: content-code-block-surface-shape-v1
108
+ architecture-fingerprint:
109
+ outcome: Give ordinary native Code Blocks a subtle theme-aware surface distinct from the Page canvas.
110
+ shipping-surfaces:
111
+ - id: content-native-code-block-surface
112
+ repository: BuilderIO/agent-native
113
+ product-surface: Content visual Page editor ordinary native Code Block presentation
114
+ constituency: signed-in Content writers and readers
115
+ durable-destination: public Content template behavior in BuilderIO/agent-native
116
+ integration-action: merge
117
+ governing-architecture: Style the existing native Tiptap Code Block through Content's existing semantic theme tokens without adding a renderer, wrapper, block type, or palette.
118
+ acceptance-story:
119
+ id: content-native-code-block-surface-v1
120
+ summary: A writer sees the same ordinary Code Block as a quiet contained surface distinct from the Page in light and dark themes, with editing and persistence unchanged.
121
+ required-assertions:
122
+ - light mode Code Block surface is visibly distinct from the white Page canvas
123
+ - dark mode Code Block surface is visibly distinct from the dark Page canvas without becoming a black panel
124
+ - existing code text syntax highlighting caret selection overflow and Tab remain usable
125
+ - reload preserves source and restores the same theme-aware presentation
126
+ - paragraphs inline code registry Code Mermaid insertion and persistence behavior remain unchanged
127
+ - focused technical checks and exact-artifact real-interface acceptance pass
128
+ acceptance-policy:
129
+ modality: real-interface
130
+ independence: preferred
131
+ custody: same-context-allowed
132
+ interface: Disposable local Content Page built from the exact review artifact, exercised in light and dark themes.
133
+ rationale: The outcome is a bounded visual refinement whose success depends on rendered contrast in both themes; same-context real-interface judgment is proportionate.
134
+ risk-strategy:
135
+ kind: system-ready
136
+ production-validation-after-merge: false
137
+ architecture-grounding:
138
+ applicability: not-required
139
+ reason: Bounded local CSS refinement using an existing Content-owned class and existing semantic theme token; no shared contract, schema, renderer, identity, or persistence boundary changes.
140
+ status: grounded
141
+ demonstrated-callers:
142
+ - Signed-in Content writer or reader viewing an ordinary native Code Block in a Page.
143
+ existing-primitives:
144
+ - pre.notion-code-block from CodeBlockNode.tsx
145
+ - --background and --muted theme tokens in app/global.css
146
+ - existing wrapper radius and spacing treatment
147
+ ownership-boundaries:
148
+ - Content global editor CSS owns ordinary Code Block presentation
149
+ - Tiptap owns native Code Block structure and editing behavior
150
+ - Content theme tokens own light and dark surface values
151
+ legacy-contracts:
152
+ - portable fenced-code source and Lowlight syntax highlighting
153
+ - ordinary editor keyboard and persistence behavior
154
+ - registry Code Mermaid inline code and unrelated Page surfaces
155
+ shared-vocabulary:
156
+ - ordinary native Code Block means Tiptap codeBlock rendered as pre.notion-code-block
157
+ smallest-compatible-delta: Add one native-block-specific semantic background radius and margin rule after the shared pre typography rule.
158
+ deferred-capabilities:
159
+ - executable Code Block UX
160
+ - language headers and controls
161
+ - syntax palette redesign
162
+ - registry and Mermaid presentation
163
+ reversibility: One local CSS rule using existing tokens; removal restores the prior presentation with no data migration.
164
+ direct-evidence:
165
+ - repository revision fbe8c9c9060944e3514fd1f2b1a43edc88115199
166
+ - CodeBlockNode.tsx assigns notion-code-block to the native renderer
167
+ - global.css gives the old wrapper muted background but the native block transparent background
168
+ inferences:
169
+ - the contrast regression followed removal of the former React wrapper from the native renderer
170
+ unresolved-owner-questions: []
171
+ delegation-ceiling:
172
+ - artifact-write
173
+ product-boundary-gates:
174
+ agent-native-public-constituency: Any source-blind Content writer or reader benefits without Alice-private data credentials or orchestration; this belongs in the public Content template.
175
+ bowerbird-product-boundary: not-applicable
176
+ acceptance-state:
177
+ status: land-ready
178
+ summary: Work added the bounded semantic CSS rule and passed light/dark real-interface acceptance without changing adjacent Code Block behavior.
179
+ blockers: []
180
+ last-land-packet: null
181
+ ledger-revision: content-code-block-surface-shape-v1
182
+ status: work-complete
183
+ ```
184
+
185
+ ## Exact handoff
186
+
187
+ `/work templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md`
188
+
189
+ Execution placement: local. The expected Work is one CSS rule, focused checks,
190
+ and light/dark browser acceptance; framework compute is unnecessary. The
191
+ currently running local server and Page remain available for Alice's manual
192
+ testing and were not mutated or stopped by Shape.
193
+
194
+ ## Work execution record
195
+
196
+ Work lane: `codex/code-block-surface-background` in
197
+ `/Users/alicemoore/.codex/worktrees/content-code-block-surface-background`,
198
+ refreshed from `origin/main` at
199
+ `8617890c4b9688ebcca5075efb74774f7ac39918` on 2026-08-20.
200
+
201
+ Acceptance reconciliation: consistent. Schema v3 freezes real-interface
202
+ acceptance, preferred independence, and same-context custody.
203
+
204
+ Work mutations are bounded to the CSS refinement, focused tests, this evidence
205
+ artifact, a local commit, and the following disposable test resource:
206
+
207
+ - resource id: `content-codeblock-surface-work-20260820`
208
+ - kind: local server, SQLite database, browser session, and task-created Page
209
+ - surface: `http://127.0.0.1:4189` backed by
210
+ `/tmp/content-codeblock-surface-work-20260820/content.db`
211
+ - ownership marker: Page title `Code Block Surface Acceptance 2026-08-20`
212
+ - baseline: port 4189 unbound and sandbox path absent before creation
213
+ - allowed actions: create, update, exercise, read back, reload, and delete
214
+ - cleanup trigger: after light/dark acceptance and evidence capture
215
+ - cleanup method: close the task browser tab, stop the server, confirm port
216
+ 4189 unbound, and move the exact sandbox to Trash
217
+ - cleanup proof: independent port and original-path absence checks
218
+ - shared impact: none
219
+ - isolation: local runtime
220
+ - ownership: task-created and task-exclusive
221
+ - production data: false
222
+ - customer data: false
223
+ - cost: none
224
+ - maximum lifetime: 240 minutes
225
+ - status: declared
226
+
227
+ ## Work evidence
228
+
229
+ Implementation:
230
+
231
+ - added one `.notion-editor .notion-code-block` rule using `hsl(var(--muted))`,
232
+ the existing 6px radius, and the existing `0.6em` vertical rhythm
233
+ - did not change the renderer, command transaction, persistence, registry Code,
234
+ Mermaid, inline code, syntax palette, or slash-command catalog
235
+
236
+ Exact real-interface acceptance on the task-created Content Page:
237
+
238
+ - light theme: block `rgb(245, 245, 245)` against Page
239
+ `rgb(255, 255, 255)`; text `rgb(38, 38, 38)`
240
+ - dark theme: block `rgb(41, 41, 41)` against Page `rgb(33, 33, 33)`;
241
+ text `rgb(230, 230, 230)`
242
+ - both themes: `6px` radius and `8.16px` top/bottom computed margins
243
+ - the persisted fenced source rendered through `pre.notion-code-block` as
244
+ `const greeting = "hello";// `
245
+
246
+ Technical checks:
247
+
248
+ - `oxfmt` passed for the modified CSS and this artifact
249
+ - `git diff --check` passed
250
+ - focused editor suite passed: 31/31 tests in
251
+ `SlashCommandMenu.test.ts`
252
+ - repository typecheck exited 0; it also printed the expected local-production
253
+ warnings for absent `BETTER_AUTH_SECRET` and persistent database URL
254
+ - changelog command was attempted and reported that changelogs are disabled in
255
+ the Content app configuration; no changelog file was created
256
+
257
+ Framework compute preflight could not reach the configured framework host
258
+ (Tailscale stopped and the host did not resolve), so the proportionate checks
259
+ ran locally on the actual execution host. This visual-only delta does not rely
260
+ on remote-host behavior.
261
+
262
+ Cleanup completed: the task browser tab was closed, the port-4189 server was
263
+ stopped, port 4189 was confirmed unbound, the original sandbox path was
264
+ confirmed absent, and the exact sandbox was moved to
265
+ `/Users/alicemoore/.Trash/content-codeblock-surface-work-20260820`. The fixture
266
+ is recoverable from Trash. The separate port-4188 insertion-test server and its
267
+ fixture were not touched.
268
+
269
+ Acceptance result: successful-user-story schema v3 is satisfied in the same
270
+ context allowed by the frozen custody policy. Independent human review remains
271
+ preferred but is not a completion gate for this bounded visual refinement.
272
+
273
+ ledger-revision: content-code-block-surface-work-v1
@@ -16,6 +16,11 @@ explains them, but never hides a topology change in prose. Until an execution
16
16
  binding is explicitly added, the blueprint must not be described as the runtime
17
17
  router.
18
18
 
19
+ Runtime work — settings, inbox, rules, automations, and activity — is scoped by
20
+ `factoryId`. Reusable agents stay workspace-wide; graph nodes may reference any
21
+ workspace agent as blueprint only. Pass `factoryId` on triage, config, automation,
22
+ and audit actions for the factory the user is viewing.
23
+
19
24
  ## Workflow
20
25
 
21
26
  1. Read `view-screen` to identify the selected Factory, tab, node, or edge.
@@ -21,22 +21,11 @@ decisions, feedback, agent runs, and provider audit records.
21
21
  reconciliation is not success; preserve typed failure or
22
22
  `reconciliation_required` state.
23
23
  - Deduplicate by Factory item and rule/run identity, not provider comment ID.
24
- - Slack clear bugs go through `start-builder-for-item` (👀 and a Slack user
25
- mention for `/address-feedback`); never post Slack messages or `@handles`.
26
- Group repeats into one Builder thread. GitHub/Sentry use the Builder run
27
- API. Follow `review-latest-feedback` for full-thread evidence, existing
28
- reaction and owner checks, answered-clarification priority, one-question
29
- clarification limits, durable rechecks, and the required `@agent-native`
30
- disposition after every actionable 👀. Clips, Design, and Content stay
31
- owner-managed outside autonomous dispatch and PR governance.
32
- - PR governance follows `review-prs`: verify BuilderIO membership and complete
33
- diff/review/check evidence; skip drafts/current approvals and never approve
34
- external authors. Keep ultra-scary security, auth, tenant-isolation,
35
- secrets, data-loss, execution, payment, and deployment risks manual.
36
- Verified members may pass ordinary uncertain checks or review feedback, but
37
- record exact states and never call them clean. Apply the Alice/Content,
38
- Nick/Slides, Enzo/Factory, Sid/Design, and docs-only exceptions only after
39
- membership and the ultra-scary gate. Never auto-merge.
24
+ - Slack clear bugs go through `start-builder-for-item`; never post Slack
25
+ messages or `@handles`. GitHub/Sentry use the Builder run API. Read
26
+ `review-latest-feedback` for thread evidence and disposition rules.
27
+ - PR governance follows `review-prs`: verify membership and evidence; skip
28
+ drafts and external authors; keep ultra-scary risks manual; never auto-merge.
40
29
  - Graph edits create immutable blueprint versions. AI proposes with `source=ai`;
41
30
  a person reviews and publishes through the same action surface.
42
31
  - Provider credentials belong to Dispatch/shared workspace integrations, never
@@ -46,16 +35,16 @@ decisions, feedback, agent runs, and provider audit records.
46
35
 
47
36
  ## Application state
48
37
 
49
- - `navigation.view` is `factory`, `agents`, or `factory-settings`.
50
- Observation settings are workspace-scoped at `/factory-settings`.
51
- `factoryId`, `factoryTab`, `factoryAuditRunId`, `factoryNodeId`, and
52
- `factoryEdgeId` hold Factory context. Read `view-screen` first.
38
+ - `navigation.view` is `factory` or `agents`. Runtime data is scoped by
39
+ `factoryId`; reusable agents stay workspace-wide. Read `view-screen` and
40
+ `factory-graphs` for tab and selection keys.
53
41
 
54
42
  ## Action contract
55
43
 
56
44
  | Action | Purpose |
57
45
  | --- | --- |
58
- | `list-triage-items` / `get-triage-item` | Inspect bounded queue evidence; scheduled reviewers pass `needsReview: true`, `source`, and `limit`. |
46
+ | `list-triage-items` / `get-triage-item` | Inspect queue evidence; pass `factoryId`. |
47
+ | `get-triage-config` / `save-triage-config` | Read or save observation settings for one factory. |
59
48
  | `poll-slack-channel` | Observe Slack history; never writes to Slack. |
60
49
  | `get-slack-feedback-context` | Read the bounded full Slack thread before classification. |
61
50
  | `poll-github-sources` / `poll-sentry-errors` | Observe bounded source queues. |
@@ -67,11 +56,12 @@ decisions, feedback, agent runs, and provider audit records.
67
56
  | `start-builder-for-item` | Govern clear-bug dispatch through Slack or Builder API, or record a skip reason. |
68
57
  | `govern-agent-native-pull-request` | Apply PR evidence and ownership gates. |
69
58
  | `list-factory-automations` / `save-factory-automation` / `run-factory-automation` | Inspect or edit org-owned automations. |
70
- | `list-factory-audit` | Inspect automation runs, evidence, decisions, and provider actions. |
59
+ | `list-factory-audit` | Inspect runs, evidence, and provider actions for one factory. |
71
60
  | `get-factory-automation-health` | Inspect scheduler heartbeat and last error. |
72
61
  | `suggest-factory-rules` | Mine feedback into proposals. |
73
62
  | `reconcile-triage-run` | Persist callback/provider reconciliation. |
74
63
  | `list-factories` / `get-factory-graph` | Inspect definitions, versions, and metrics. |
64
+ | `create-factory` | Create a factory from `/new-factory` with optional sources. |
75
65
  | `save-factory-graph` | Create/version a graph with inspected `expectedGraphVersion`; never starts provider work. |
76
66
  | graph history actions | Factory graph version history. |
77
67
  | `list-factory-comments` / `add-factory-comment` | Read or attach comments to a canvas, node, or edge. |
@@ -44,19 +44,22 @@ shared `app_secrets` rows must use the same
44
44
  encryption fallback). Never copy raw tokens between apps or add a second
45
45
  env-only read in a provider client.
46
46
 
47
- Factory's default observer still keeps organization-scoped source metadata -
48
- such as a Slack channel, repository, or Sentry project - for its normalized
49
- queue adapters. That metadata is not a credential or a per-factory integration
50
- setup. GitHub issue polling defaults to hourly; Slack and pull-request checks
51
- use shorter bounded cadences because those sources can need faster feedback.
52
- Every poll preserves errors for reconciliation.
47
+ Factory's observer keeps **per-factory** source metadata — Slack channel,
48
+ repository, Sentry project, and related polling settings for its normalized
49
+ queue adapters. Each factory has its own inbox, rules, automations, and activity.
50
+ Reusable agents and workspace credentials stay shared. Each factory's observation
51
+ settings live on its Settings tab in the factory detail view. That metadata is
52
+ not a credential or a per-factory
53
+ integration setup. GitHub issue polling defaults to hourly; Slack and
54
+ pull-request checks use shorter bounded cadences because those sources can need
55
+ faster feedback. Every poll preserves errors for reconciliation.
53
56
 
54
57
  Factory agents can discover connected provider APIs with
55
58
  `provider-api-catalog`, inspect their docs with `provider-api-docs`, and call
56
59
  them through `provider-api-request`. Scheduled Factory runs also receive the
57
60
  workspace's connected MCP tools, subject to the same workspace and request
58
- scope gates. The three normalized pollers are compatibility adapters for the
59
- default triage queue, not the agent's capability limit.
61
+ scope gates. The three normalized pollers are compatibility adapters scoped by
62
+ `factoryId`, not the agent's capability limit.
60
63
 
61
64
  The generic Slack bot is wired to Factory. Mention `@agent-native` in a feedback
62
65
  thread to inspect the linked item, explain its decision, tune a rule, or say
@@ -8,6 +8,13 @@ import {
8
8
  triageItems,
9
9
  triageRuns,
10
10
  } from "../server/db/schema.js";
11
+ import { DEFAULT_FACTORY_ID } from "../server/factory-graph/store.js";
12
+ import {
13
+ factoryIdSchema,
14
+ orgFactoryDecisionFilter,
15
+ orgFactoryItemFilter,
16
+ orgFactoryRunFilter,
17
+ } from "../server/lib/factory-scope.js";
11
18
  import {
12
19
  requireWorkspaceMember,
13
20
  workspaceMemberIdentityFromContext,
@@ -19,6 +26,7 @@ export default defineAction({
19
26
  description:
20
27
  "Explicitly approve one Factory item and start one deduplicated Builder coding run. The approver, decision, guard results, and callback state are recorded before provider work is considered successful.",
21
28
  schema: z.object({
29
+ factoryId: factoryIdSchema.default(DEFAULT_FACTORY_ID),
22
30
  itemId: z.string().min(1),
23
31
  decisionId: z.string().min(1).optional(),
24
32
  confirm: z.literal(true),
@@ -27,7 +35,7 @@ export default defineAction({
27
35
  // must remain paused until a human approves this exact agent tool call.
28
36
  needsApproval: true,
29
37
  http: { method: "POST" },
30
- run: async ({ itemId, decisionId, confirm }, context) => {
38
+ run: async ({ factoryId, itemId, decisionId, confirm }, context) => {
31
39
  if (!confirm) throw new Error("Explicit confirmation is required.");
32
40
  const { userEmail, orgId } = await requireWorkspaceMember(
33
41
  workspaceMemberIdentityFromContext(context),
@@ -37,7 +45,12 @@ export default defineAction({
37
45
  await db
38
46
  .select()
39
47
  .from(triageItems)
40
- .where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)))
48
+ .where(
49
+ and(
50
+ eq(triageItems.id, itemId),
51
+ orgFactoryItemFilter(orgId, factoryId),
52
+ ),
53
+ )
41
54
  .limit(1)
42
55
  )[0];
43
56
  if (!item) throw new Error("Factory item not found.");
@@ -47,8 +60,8 @@ export default defineAction({
47
60
  .from(triageDecisions)
48
61
  .where(
49
62
  and(
50
- eq(triageDecisions.orgId, orgId),
51
63
  eq(triageDecisions.itemId, itemId),
64
+ orgFactoryDecisionFilter(orgId, factoryId),
52
65
  ),
53
66
  )
54
67
  .orderBy(asc(triageDecisions.createdAt));
@@ -72,7 +85,9 @@ export default defineAction({
72
85
  await db
73
86
  .select()
74
87
  .from(triageRuns)
75
- .where(and(eq(triageRuns.id, runId), eq(triageRuns.orgId, orgId)))
88
+ .where(
89
+ and(eq(triageRuns.id, runId), orgFactoryRunFilter(orgId, factoryId)),
90
+ )
76
91
  .limit(1)
77
92
  )[0];
78
93
  if (
@@ -110,6 +125,7 @@ export default defineAction({
110
125
  error: null,
111
126
  ownerEmail: item.ownerEmail,
112
127
  orgId,
128
+ factoryId,
113
129
  })
114
130
  .onConflictDoNothing();
115
131
 
@@ -117,7 +133,9 @@ export default defineAction({
117
133
  await db
118
134
  .select()
119
135
  .from(triageRuns)
120
- .where(and(eq(triageRuns.id, runId), eq(triageRuns.orgId, orgId)))
136
+ .where(
137
+ and(eq(triageRuns.id, runId), orgFactoryRunFilter(orgId, factoryId)),
138
+ )
121
139
  .limit(1)
122
140
  )[0];
123
141
  if (!run) throw new Error("Factory run could not be recorded.");
@@ -155,11 +173,18 @@ export default defineAction({
155
173
  progressLogJson: JSON.stringify(progress),
156
174
  heartbeatAt: new Date().toISOString(),
157
175
  })
158
- .where(and(eq(triageRuns.id, runId), eq(triageRuns.orgId, orgId)));
176
+ .where(
177
+ and(eq(triageRuns.id, runId), orgFactoryRunFilter(orgId, factoryId)),
178
+ );
159
179
  await db
160
180
  .update(triageItems)
161
181
  .set({ status: "classified", updatedAt: new Date().toISOString() })
162
- .where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
182
+ .where(
183
+ and(
184
+ eq(triageItems.id, itemId),
185
+ orgFactoryItemFilter(orgId, factoryId),
186
+ ),
187
+ );
163
188
  return {
164
189
  ok: true,
165
190
  deduplicated: false,
@@ -176,7 +201,9 @@ export default defineAction({
176
201
  completedAt: new Date().toISOString(),
177
202
  heartbeatAt: new Date().toISOString(),
178
203
  })
179
- .where(and(eq(triageRuns.id, runId), eq(triageRuns.orgId, orgId)));
204
+ .where(
205
+ and(eq(triageRuns.id, runId), orgFactoryRunFilter(orgId, factoryId)),
206
+ );
180
207
  throw new Error(
181
208
  `Factory approval was recorded, but Builder dispatch failed: ${message}`,
182
209
  );
@@ -4,7 +4,12 @@ import { z } from "zod";
4
4
 
5
5
  import { resolveConnectorSecret } from "../server/connectors/credentials.js";
6
6
  import { getDb } from "../server/db/index.js";
7
- import { triageConfig, triageItems } from "../server/db/schema.js";
7
+ import { triageItems } from "../server/db/schema.js";
8
+ import { DEFAULT_FACTORY_ID } from "../server/factory-graph/store.js";
9
+ import {
10
+ factoryIdSchema,
11
+ readTriageConfigRow,
12
+ } from "../server/lib/factory-scope.js";
8
13
  import { requireFactoryAutomation } from "../server/lib/require-factory-automation.js";
9
14
  import {
10
15
  requireWorkspaceMember,
@@ -85,13 +90,13 @@ export default defineAction({
85
90
  "Watch one builder-io-bot pull request, post the bounded feedback-fix request when CI, mergeability, or review feedback needs work, and stop after 20 quiet minutes. The action never merges or approves.",
86
91
  schema: z.object({
87
92
  itemId: z.string().min(1),
93
+ factoryId: factoryIdSchema.optional(),
88
94
  }),
89
95
  http: false,
90
- run: async ({ itemId }, context) => {
96
+ run: async ({ itemId, factoryId: factoryIdInput }, context) => {
91
97
  const { userEmail, orgId } = await requireWorkspaceMember(
92
98
  workspaceMemberIdentityFromContext(context),
93
99
  );
94
- await requireFactoryAutomation(context, { userEmail, orgId }, "prBabysit");
95
100
 
96
101
  const db = getDb();
97
102
  const item = (
@@ -102,6 +107,16 @@ export default defineAction({
102
107
  .limit(1)
103
108
  )[0];
104
109
  if (!item) throw new Error("Factory item not found for PR babysitting.");
110
+ const factoryId = factoryIdInput ?? item.factoryId ?? DEFAULT_FACTORY_ID;
111
+ if ((item.factoryId ?? DEFAULT_FACTORY_ID) !== factoryId) {
112
+ throw new Error("Factory item does not belong to this factory.");
113
+ }
114
+ await requireFactoryAutomation(
115
+ context,
116
+ { userEmail, orgId },
117
+ "prBabysit",
118
+ factoryId,
119
+ );
105
120
  if (
106
121
  item.source !== "github" ||
107
122
  !item.repository ||
@@ -115,12 +130,8 @@ export default defineAction({
115
130
  }
116
131
 
117
132
  const configuredRepository = (
118
- await db
119
- .select({ repository: triageConfig.repository })
120
- .from(triageConfig)
121
- .where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)))
122
- .limit(1)
123
- )[0]?.repository;
133
+ await readTriageConfigRow(db, orgId, factoryId)
134
+ )?.repository;
124
135
  if (
125
136
  !configuredRepository ||
126
137
  configuredRepository.trim() !== item.repository.trim()
@@ -154,6 +165,7 @@ export default defineAction({
154
165
  summary: "Skipped because the pull request is closed or a draft.",
155
166
  details: { state: pullRequest.state, draft: pullRequest.draft },
156
167
  },
168
+ factoryId,
157
169
  );
158
170
  return { ok: true, action: "skipped", reason: "PR is closed or draft." };
159
171
  }
@@ -182,6 +194,7 @@ export default defineAction({
182
194
  summary: `${ownerOwnedArea} is owner-managed; no bot feedback was posted.`,
183
195
  details: { ownerOwnedArea },
184
196
  },
197
+ factoryId,
185
198
  );
186
199
  return {
187
200
  ok: true,
@@ -257,6 +270,7 @@ export default defineAction({
257
270
  reviewFeedbackClean: signal.isClean,
258
271
  },
259
272
  },
273
+ factoryId,
260
274
  );
261
275
  const now = new Date();
262
276
  const nowIso = now.toISOString();
@@ -326,6 +340,7 @@ export default defineAction({
326
340
  summary: "Posted the bounded feedback-fix request to builder-io-bot.",
327
341
  details: { commentUrl: comment.htmlUrl, quietForMinutes: 0 },
328
342
  },
343
+ factoryId,
329
344
  );
330
345
  await updateBabysitMetadata(itemId, orgId, {
331
346
  prBabysitState: "active",