@agent-native/core 0.136.4 → 0.137.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/corpus/README.md +1 -1
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +53 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +7 -0
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +24 -4
- package/corpus/templates/clips/app/components/import-menu.tsx +109 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +8 -18
- package/corpus/templates/clips/app/components/library/library-layout.tsx +14 -50
- package/corpus/templates/clips/app/components/library/sort-menu.tsx +20 -6
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +10 -34
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +0 -2
- package/corpus/templates/clips/changelog/2026-08-03-restart-during-a-recording-now-immediately-starts-a-fresh-ta.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-04-cleaner-library-controls-with-an-icon-only-sort-button.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-04-upload-and-loom-imports-now-live-under-one-import-menu.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +81 -30
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +436 -158
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +14 -1
- package/corpus/templates/clips/server/plugins/auth.ts +9 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +13 -0
- package/corpus/templates/content/actions/_database-utils.ts +6 -0
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +273 -97
- package/corpus/templates/content/actions/change-content-database-source-role.ts +65 -29
- package/corpus/templates/content/actions/configure-document-property.ts +113 -32
- package/corpus/templates/content/actions/delete-content-database.ts +5 -7
- package/corpus/templates/content/actions/delete-document-property.ts +109 -62
- package/corpus/templates/content/actions/delete-document.ts +178 -36
- package/corpus/templates/content/actions/duplicate-database-item.ts +27 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +31 -1
- package/corpus/templates/content/actions/permanently-delete-document.ts +4 -6
- package/corpus/templates/content/actions/remove-database-items.ts +13 -0
- package/corpus/templates/content/actions/set-document-property.ts +69 -1
- package/corpus/templates/content/actions/upsert-database-item-by-key.ts +814 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/server/db/schema.ts +27 -0
- package/corpus/templates/content/server/plugins/db.ts +24 -0
- package/corpus/templates/design/app/components/design/BreakpointBar.tsx +122 -114
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
- package/corpus/templates/design/app/components/design/EditPanel.tsx +68 -34
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +78 -4
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +8 -0
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +5 -2
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +10 -9
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +31 -69
- package/corpus/templates/design/app/components/design/inspector/design-icons.tsx +80 -106
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +4 -0
- package/corpus/templates/design/app/hooks/use-editor-preferences.ts +75 -0
- package/corpus/templates/design/app/i18n-data.ts +8 -0
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +61 -0
- package/corpus/templates/design/app/pages/design-editor/editor-preferences.ts +98 -0
- package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +491 -0
- package/corpus/templates/design/app/pages/design-editor/paste-placement.ts +133 -0
- package/corpus/templates/design/app/pages/design-editor/png-export-render.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -12
- package/corpus/templates/design/changelog/2026-08-03-arrow-keys-now-reorder-a-layer-inside-an-auto-layout-frame.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-auto-layout-flow-icons-show-the-direction-at-a-glance-instea.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-auto-layout-icons-share-one-outlined-square-style-so-flow-ga.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-export-has-a-named-preview-section-you-can-expand-replacing-.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-export-preview-shows-the-selected-element-instead-of-the-who.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-inspector-sections-show-an-expand-indicator-so-it-is-clear-w.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-paste-lands-inside-a-selected-frame-instead-of-beside-it.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-the-add-breakpoint-button-sits-outside-the-breakpoint-select.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-the-agent-s-follow-up-questions-keep-space-below-the-continu.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-the-agent-s-follow-up-questions-share-the-chat-panel-s-backg.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-the-export-panel-no-longer-stacks-a-duplicate-export-block-o.md +6 -0
- package/corpus/templates/design/changelog/2026-08-03-the-text-tool-uses-a-t-icon-matching-the-letter-it-inserts.md +6 -0
- package/corpus/templates/factory/.env.example +17 -0
- package/corpus/templates/factory/AGENTS.md +27 -17
- package/corpus/templates/factory/README.md +19 -9
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +90 -0
- package/corpus/templates/factory/actions/get-triage-config.ts +14 -3
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +386 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +53 -0
- package/corpus/templates/factory/actions/list-triage-items.ts +7 -2
- package/corpus/templates/factory/actions/poll-github-sources.ts +203 -0
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +161 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +4 -2
- package/corpus/templates/factory/actions/run-factory-automation.ts +42 -0
- package/corpus/templates/factory/actions/save-factory-automation.ts +69 -0
- package/corpus/templates/factory/actions/save-triage-config.ts +28 -2
- package/corpus/templates/factory/actions/start-builder-for-item.ts +411 -0
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +14 -3
- package/corpus/templates/factory/app/components/ui/checkbox.tsx +1 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +7 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +35 -1
- package/corpus/templates/factory/app/routes/factory.tsx +462 -9
- package/corpus/templates/factory/changelog/2026-08-04-added-organization-owned-factory-automations-for-slack-bug-t.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-04-automation-editor-controls-and-model-picker.md +6 -0
- package/corpus/templates/factory/netlify.toml +2 -2
- package/corpus/templates/factory/server/connectors/credentials.ts +6 -5
- package/corpus/templates/factory/server/connectors/slack.ts +133 -5
- package/corpus/templates/factory/server/db/schema.ts +6 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +65 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +29 -11
- package/corpus/templates/factory/server/plugins/auth.ts +1 -0
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +12 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +218 -67
- package/corpus/templates/factory/server/triage/builder-executor.ts +4 -0
- package/corpus/templates/factory/server/triage/contracts.ts +14 -1
- package/corpus/templates/factory/server/triage/github-client.ts +404 -0
- package/corpus/templates/factory/server/triage/metadata.ts +44 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +5 -5
- package/corpus/templates/factory/server/triage/pr-policy.ts +144 -0
- package/corpus/templates/factory/server/triage/sentry-client.ts +180 -0
- package/corpus/templates/factory/server/triage/slack-client.ts +43 -0
- package/corpus/templates/factory/server/triage/slack-poller.ts +9 -2
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +27 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +14 -4
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -0
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -0
- package/corpus/templates/plan/actions/create-plan-design.ts +8 -6
- package/corpus/templates/plan/actions/create-prototype-plan.ts +8 -6
- package/corpus/templates/plan/actions/create-ui-plan.ts +7 -7
- package/corpus/templates/plan/actions/get-plan-blocks.ts +7 -1
- package/corpus/templates/plan/actions/validate-plan-input.ts +39 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +167 -11
- package/corpus/templates/plan/app/i18n/en-US.ts +1 -0
- package/corpus/templates/plan/changelog/2026-08-04-canvas-zoom-controls-now-explain-the-command-ctrl-plus-scrol.md +6 -0
- package/corpus/templates/plan/changelog/2026-08-04-pinch-to-zoom-is-now-supported-on-touchscreens-in-visual-pla.md +6 -0
- package/corpus/templates/plan/shared/plan-content.ts +17 -2
- package/dist/cli/skills-content/canvas.d.ts +3 -3
- package/dist/cli/skills-content/canvas.js +16 -5
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +27 -0
- package/dist/cli/skills-content/wireframe.d.ts +2 -2
- package/dist/cli/skills-content/wireframe.js +7 -0
- package/dist/client/AgentPanel.js +23 -8
- package/dist/client/api-path.d.ts +6 -0
- package/dist/client/api-path.js +55 -0
- package/dist/client/onboarding/FirstRunOnboarding.d.ts +3 -0
- package/dist/client/onboarding/FirstRunOnboarding.js +93 -0
- package/dist/client/onboarding/first-run-enabled.d.ts +2 -0
- package/dist/client/onboarding/first-run-enabled.js +9 -0
- package/dist/client/onboarding/index.d.ts +2 -1
- package/dist/client/onboarding/index.js +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +6 -1
- package/dist/client/onboarding/use-onboarding.js +32 -1
- package/dist/client/route-state.js +10 -0
- package/dist/client/settings/SecretsSection.js +32 -8
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +4 -4
- package/dist/connections/catalog.js +3 -3
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +1 -1
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.js +5 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.d.ts +4 -0
- package/dist/onboarding/app-profile.js +378 -0
- package/dist/onboarding/index.d.ts +2 -1
- package/dist/onboarding/index.js +1 -0
- package/dist/onboarding/plugin.d.ts +2 -0
- package/dist/onboarding/plugin.js +21 -1
- package/dist/onboarding/types.d.ts +19 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +12 -12
- package/dist/secrets/routes.d.ts +2 -2
- package/dist/secrets/routes.js +41 -17
- package/dist/server/auth.js +21 -1
- package/dist/server/better-auth-instance.d.ts +3 -2
- package/dist/server/better-auth-instance.js +9 -7
- package/dist/server/email-markdown.js +3 -8
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/first-run-onboarding.d.ts +3 -0
- package/dist/shared/first-run-onboarding.js +3 -0
- package/dist/triggers/index.d.ts +3 -0
- package/dist/triggers/index.js +5 -0
- package/docs/content/cross-app-sso.mdx +26 -0
- package/package.json +1 -1
|
@@ -4,6 +4,15 @@ PING_MESSAGE=pong
|
|
|
4
4
|
# Email stamped as the creator of the deployment-owned observation scheduler.
|
|
5
5
|
WORKSPACE_OWNER_EMAIL=
|
|
6
6
|
|
|
7
|
+
# Optional explicit id of the Dispatch vault organization. Leave blank when
|
|
8
|
+
# the deployment owner is a member of the organization where Dispatch synced
|
|
9
|
+
# the shared keys. This is an org id, not a secret.
|
|
10
|
+
AGENT_VAULT_ORG_ID=
|
|
11
|
+
|
|
12
|
+
# Use the same stable workspace key as Dispatch and sibling apps so they can
|
|
13
|
+
# decrypt shared app_secrets rows. Do not rotate this independently per app.
|
|
14
|
+
WORKSPACE_SECRETS_ENCRYPTION_KEY=
|
|
15
|
+
|
|
7
16
|
# Public URL used for signed Builder completion callbacks after an explicit
|
|
8
17
|
# approval. Keep this aligned with the deployed Netlify URL until a custom
|
|
9
18
|
# domain is explicitly approved and configured.
|
|
@@ -20,5 +29,13 @@ BUILDER_PROJECT_ID=
|
|
|
20
29
|
BUILDER_PRIVATE_KEY=
|
|
21
30
|
FACTORY_BUILDER_WEBHOOK_SECRET=
|
|
22
31
|
|
|
32
|
+
# Optional deployment fallbacks. Prefer Dispatch Vault and leave these blank
|
|
33
|
+
# when the shared workspace secret rows are available.
|
|
34
|
+
SLACK_BOT_TOKEN=
|
|
35
|
+
GITHUB_TOKEN=
|
|
36
|
+
SENTRY_SERVER_TOKEN=
|
|
37
|
+
SENTRY_AUTH_TOKEN=
|
|
38
|
+
SENTRY_ORG_SLUG=
|
|
39
|
+
|
|
23
40
|
# Skip login/signup (local dev / preview only)
|
|
24
41
|
# AUTH_DISABLED=true
|
|
@@ -27,27 +27,30 @@ ladder.
|
|
|
27
27
|
`packages/*` changes always require human review.
|
|
28
28
|
- All work is deduped by Factory item and rule/run identity. Provider comment IDs
|
|
29
29
|
are not the idempotency boundary.
|
|
30
|
-
- Slack interaction uses the generic Agent-Native Slack adapter.
|
|
31
|
-
|
|
30
|
+
- Slack interaction uses the generic Agent-Native Slack adapter. Clear-bug Slack
|
|
31
|
+
automations add 👀 and tag `@builderio` in the source thread; GitHub and Sentry
|
|
32
|
+
clear bugs use the Builder run API. Clips, Design, and Content are always
|
|
33
|
+
owner-managed and never enter autonomous dispatch or PR governance.
|
|
34
|
+
- PR governance requires verified internal BuilderIO membership, a clear bug,
|
|
35
|
+
passing CI, and handled review feedback. Product or UX implications stay
|
|
36
|
+
manual. Auto-merge additionally requires a verified Factory Builder run.
|
|
32
37
|
- Reuse the existing ai-services GitHub read and Builder execution APIs. Do not
|
|
33
38
|
duplicate GitHub installation/webhook infrastructure in this template.
|
|
34
39
|
- Do not add CRUD routes under `server/routes/api/`; actions are the domain
|
|
35
40
|
surface. Provider callbacks are the only exception and must verify signatures.
|
|
36
41
|
- Factory graph edits create immutable blueprint versions. AI proposes a
|
|
37
42
|
complete graph with `source=ai`; a person reviews and publishes it through
|
|
38
|
-
the same action surface as manual edits.
|
|
39
|
-
rules in parallel, so graph edges describe intended handoffs until a runtime
|
|
40
|
-
binding exists.
|
|
41
|
-
- A selected graph node or edge is part of `navigation` context. Read
|
|
42
|
-
`view-screen` before answering why a route exists or changing the selected
|
|
43
|
-
Factory.
|
|
43
|
+
the same action surface as manual edits.
|
|
44
44
|
|
|
45
45
|
## Application state
|
|
46
46
|
|
|
47
47
|
- `navigation.view`: `factory` when the visual workspace is open.
|
|
48
48
|
- `navigation.factoryId`: selected Factory id when present.
|
|
49
|
-
- `navigation.factoryTab`: `map` | `inbox` | `rules` | `settings`.
|
|
49
|
+
- `navigation.factoryTab`: `map` | `inbox` | `rules` | `automations` | `settings`.
|
|
50
50
|
- `navigation.factoryNodeId` / `navigation.factoryEdgeId`: selected graph target.
|
|
51
|
+
- A selected graph node or edge is part of `navigation` context. Read
|
|
52
|
+
`view-screen` before answering why a route exists or changing the selected
|
|
53
|
+
Factory.
|
|
51
54
|
|
|
52
55
|
## Action contract
|
|
53
56
|
|
|
@@ -55,20 +58,26 @@ ladder.
|
|
|
55
58
|
| --- | --- |
|
|
56
59
|
| `list-triage-items` / `get-triage-item` | Inspect the queue and evidence. |
|
|
57
60
|
| `poll-slack-channel` | Observe Slack history; never writes to Slack. |
|
|
61
|
+
| `get-slack-feedback-context` | Read the bounded full Slack thread before classification. |
|
|
62
|
+
| `poll-github-sources` / `poll-sentry-errors` | Observe bounded GitHub and Sentry source queues. |
|
|
58
63
|
| `ingest-github-observation` | Store read-only PR evidence. |
|
|
59
64
|
| `list-triage-rules` / `save-triage-rule` | Tune prompt rules and guards. |
|
|
60
65
|
| `evaluate-triage-item` | Append a structured decision. |
|
|
61
66
|
| `record-triage-feedback` | Capture human correction for learning. |
|
|
62
67
|
| `approve-factory-item` | Explicitly authorize one bounded run. |
|
|
68
|
+
| `start-builder-for-item` | Govern clear-bug dispatch; Slack tags Builder in-thread, other sources use Builder API. |
|
|
69
|
+
| `govern-agent-native-pull-request` | Apply CI, review, internal-author, product, and owner gates to PR approval/merge. |
|
|
70
|
+
| `list-factory-automations` / `save-factory-automation` / `run-factory-automation` | Inspect and edit organization-owned Factory prompts, models, schedules, and runs. |
|
|
63
71
|
| `suggest-factory-rules` | Mine feedback and fast approvals into proposals. |
|
|
64
72
|
| `reconcile-triage-run` | Persist callback/provider reconciliation. |
|
|
65
73
|
| `list-factories` / `get-factory-graph` | Inspect Factory definitions, graph versions, and live evidence metrics. |
|
|
66
74
|
| `save-factory-graph` | Create or version a complete visual graph; never starts provider work. |
|
|
67
75
|
| `list-factory-comments` / `add-factory-comment` | Read or attach comments to a canvas, node, or edge. |
|
|
68
76
|
|
|
69
|
-
Rules start in shadow mode
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
Rules start in shadow mode; hard guards always apply. Editable organization
|
|
78
|
+
automations execute stored prompts; every external mutation needs a durable run,
|
|
79
|
+
idempotency key, and provider confirmation. The legacy observer is disabled
|
|
80
|
+
when organization automations are seeded.
|
|
72
81
|
|
|
73
82
|
Use the visual editor for direct blueprint changes. Use the agent chat for
|
|
74
83
|
natural language design, explanations, and proposals; it must preserve a
|
|
@@ -78,13 +87,14 @@ actions, never through graph JSON.
|
|
|
78
87
|
|
|
79
88
|
## Scheduler identity
|
|
80
89
|
|
|
81
|
-
`WORKSPACE_OWNER_EMAIL` is read only at startup to
|
|
82
|
-
|
|
83
|
-
authorization or credential resolution.
|
|
90
|
+
`WORKSPACE_OWNER_EMAIL` is read only at startup to find the deployment
|
|
91
|
+
organization and stamp seeded automation `createdBy`; it is never caller
|
|
92
|
+
identity and must not enter request authorization or credential resolution.
|
|
84
93
|
|
|
85
94
|
## Hosting
|
|
86
95
|
|
|
87
96
|
Production needs `DATABASE_URL`, `WORKSPACE_OWNER_EMAIL`, and
|
|
88
97
|
`FACTORY_PUBLIC_URL`. Builder execution additionally needs the service URL and
|
|
89
|
-
project ID plus workspace-resolved Builder credentials.
|
|
90
|
-
|
|
98
|
+
project ID plus workspace-resolved Builder credentials. GitHub and Sentry
|
|
99
|
+
polling use workspace-resolved provider credentials. Provider callbacks and
|
|
100
|
+
external writes must remain auditable and fail closed when evidence is partial.
|
|
@@ -29,11 +29,19 @@ without a terminal record.
|
|
|
29
29
|
|
|
30
30
|
## Configure Slack
|
|
31
31
|
|
|
32
|
-
Set `WORKSPACE_OWNER_EMAIL` to an existing
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
Set `WORKSPACE_OWNER_EMAIL` to an existing member of the Builder.io organization
|
|
33
|
+
that Dispatch uses. Factory does not need a separate organization: startup
|
|
34
|
+
finds that existing organization and seeds its organization-owned automations.
|
|
35
|
+
If Dispatch synced the vault into a different organization, set
|
|
36
|
+
`AGENT_VAULT_ORG_ID` to that existing org id instead of creating a new org.
|
|
37
|
+
|
|
38
|
+
Connect Slack in Dispatch or in Settings -> Connections. Factory resolves
|
|
39
|
+
Slack, GitHub, Sentry, and Builder credentials from the shared workspace vault
|
|
40
|
+
and only uses matching deployment env vars as a last-resort fallback. All apps
|
|
41
|
+
that read shared `app_secrets` rows must use the same
|
|
42
|
+
`WORKSPACE_SECRETS_ENCRYPTION_KEY` (or the workspace's existing shared
|
|
43
|
+
encryption fallback). Never copy raw tokens between apps or add a second
|
|
44
|
+
env-only read in a provider client.
|
|
37
45
|
|
|
38
46
|
In Factory, set the Slack workspace, channel ID, channel name, repository, and
|
|
39
47
|
polling switch. The default scheduler polls once per minute, evaluates a
|
|
@@ -47,11 +55,13 @@ inspectable Factory link when a human decision is required.
|
|
|
47
55
|
## Hosting
|
|
48
56
|
|
|
49
57
|
Production expects a direct PostgreSQL `DATABASE_URL`,
|
|
50
|
-
`WORKSPACE_OWNER_EMAIL`, and `FACTORY_PUBLIC_URL`.
|
|
58
|
+
`WORKSPACE_OWNER_EMAIL`, and `FACTORY_PUBLIC_URL`. `AGENT_VAULT_ORG_ID` is
|
|
59
|
+
optional and is only needed when the deployment owner cannot reach the existing
|
|
60
|
+
Dispatch vault organization through membership. The Builder executor also
|
|
51
61
|
needs `BUILDER_AI_SERVICES_URL` and `BUILDER_PROJECT_ID`; its private key and
|
|
52
|
-
signed callback secret belong in workspace credentials and are
|
|
53
|
-
runtime. The app remains observe-only until a human explicitly
|
|
54
|
-
Factory item.
|
|
62
|
+
signed callback secret belong in Dispatch workspace credentials and are
|
|
63
|
+
resolved at runtime. The app remains observe-only until a human explicitly
|
|
64
|
+
approves a Factory item.
|
|
55
65
|
|
|
56
66
|
## Development
|
|
57
67
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { and, eq } from "drizzle-orm";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import type { SlackMessage } from "../server/connectors/slack.js";
|
|
6
|
+
import { getDb } from "../server/db/index.js";
|
|
7
|
+
import { triageConfig, triageItems } from "../server/db/schema.js";
|
|
8
|
+
import {
|
|
9
|
+
requireWorkspaceMember,
|
|
10
|
+
workspaceMemberIdentityFromContext,
|
|
11
|
+
} from "../server/lib/require-workspace-member.js";
|
|
12
|
+
import { createSlackReader } from "../server/triage/slack-client.js";
|
|
13
|
+
|
|
14
|
+
const MAX_THREAD_PAGES = 5;
|
|
15
|
+
|
|
16
|
+
export default defineAction({
|
|
17
|
+
description:
|
|
18
|
+
"Read the bounded full Slack thread for one Factory feedback item. Use this before deciding whether a report is a clear bug; unreadable or truncated context is not a green light.",
|
|
19
|
+
schema: z.object({ itemId: z.string().min(1) }),
|
|
20
|
+
http: { method: "GET" },
|
|
21
|
+
readOnly: true,
|
|
22
|
+
run: async ({ itemId }, context) => {
|
|
23
|
+
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
24
|
+
workspaceMemberIdentityFromContext(context),
|
|
25
|
+
);
|
|
26
|
+
const item = (
|
|
27
|
+
await getDb()
|
|
28
|
+
.select()
|
|
29
|
+
.from(triageItems)
|
|
30
|
+
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)))
|
|
31
|
+
.limit(1)
|
|
32
|
+
)[0];
|
|
33
|
+
if (!item) throw new Error("Factory item not found.");
|
|
34
|
+
if (item.source !== "slack" || !item.channelId || !item.threadTs) {
|
|
35
|
+
throw new Error("Factory item is not a readable Slack feedback item.");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const config = (
|
|
39
|
+
await getDb()
|
|
40
|
+
.select({ slackWorkspace: triageConfig.slackWorkspace })
|
|
41
|
+
.from(triageConfig)
|
|
42
|
+
.where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)))
|
|
43
|
+
.limit(1)
|
|
44
|
+
)[0];
|
|
45
|
+
const workspace =
|
|
46
|
+
config?.slackWorkspace === "secondary" ? "secondary" : "primary";
|
|
47
|
+
const slack = createSlackReader({ ownerEmail: userEmail, orgId });
|
|
48
|
+
const messages: SlackMessage[] = [];
|
|
49
|
+
let cursor: string | undefined;
|
|
50
|
+
let hasMore = false;
|
|
51
|
+
for (let page = 0; page < MAX_THREAD_PAGES; page += 1) {
|
|
52
|
+
const result = await slack.getThread(
|
|
53
|
+
workspace,
|
|
54
|
+
item.channelId,
|
|
55
|
+
item.threadTs,
|
|
56
|
+
100,
|
|
57
|
+
cursor,
|
|
58
|
+
);
|
|
59
|
+
messages.push(...result.messages);
|
|
60
|
+
if (result.has_more && !result.next_cursor) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
"Slack thread pagination is incomplete because the provider omitted its next cursor.",
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (!result.has_more) {
|
|
66
|
+
hasMore = false;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
hasMore = page === MAX_THREAD_PAGES - 1;
|
|
70
|
+
if (hasMore) break;
|
|
71
|
+
cursor = result.next_cursor;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
ok: true,
|
|
76
|
+
itemId,
|
|
77
|
+
sourceUrl: item.sourceUrl,
|
|
78
|
+
channelId: item.channelId,
|
|
79
|
+
threadTs: item.threadTs,
|
|
80
|
+
coverage: hasMore ? "partial" : "complete",
|
|
81
|
+
messages: messages.map((message) => ({
|
|
82
|
+
user: message.user ?? message.username ?? message.bot_id ?? null,
|
|
83
|
+
text: message.text,
|
|
84
|
+
ts: message.ts,
|
|
85
|
+
threadTs: message.thread_ts ?? item.threadTs,
|
|
86
|
+
replyCount: message.reply_count ?? 0,
|
|
87
|
+
})),
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core/action";
|
|
2
|
-
import { eq } from "drizzle-orm";
|
|
2
|
+
import { and, eq } from "drizzle-orm";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
import { getDb } from "../server/db/index.js";
|
|
@@ -23,7 +23,7 @@ export default defineAction({
|
|
|
23
23
|
await getDb()
|
|
24
24
|
.select()
|
|
25
25
|
.from(triageConfig)
|
|
26
|
-
.where(eq(triageConfig.id, orgId))
|
|
26
|
+
.where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)))
|
|
27
27
|
.limit(1)
|
|
28
28
|
)[0];
|
|
29
29
|
if (!row) {
|
|
@@ -35,8 +35,19 @@ export default defineAction({
|
|
|
35
35
|
lastSlackTs: null,
|
|
36
36
|
slackHistoryCursor: null,
|
|
37
37
|
repository: null,
|
|
38
|
+
githubPollingEnabled: false,
|
|
39
|
+
sentryPollingEnabled: false,
|
|
40
|
+
sentryOrgSlug: null,
|
|
41
|
+
sentryProjectSlug: null,
|
|
42
|
+
sentryEnvironment: null,
|
|
43
|
+
lastSentrySeenAt: null,
|
|
38
44
|
};
|
|
39
45
|
}
|
|
40
|
-
return {
|
|
46
|
+
return {
|
|
47
|
+
...row,
|
|
48
|
+
pollingEnabled: row.pollingEnabled === 1,
|
|
49
|
+
githubPollingEnabled: row.githubPollingEnabled === 1,
|
|
50
|
+
sentryPollingEnabled: row.sentryPollingEnabled === 1,
|
|
51
|
+
};
|
|
41
52
|
},
|
|
42
53
|
});
|