@agent-native/core 0.147.0 → 0.148.1
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/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/analytics/DEVELOPING.md +50 -3
- package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
- package/corpus/templates/analytics/app/i18n/index.ts +14 -29
- package/corpus/templates/analytics/app/i18n-data.ts +10 -10
- package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +197 -18
- package/corpus/templates/analytics/server/db/schema.ts +23 -0
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
- package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
- package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
- package/corpus/templates/analytics/server/plugins/db.ts +42 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/assets/app/i18n/index.ts +14 -29
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/brain/app/i18n/index.ts +14 -29
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/app/i18n/index.ts +14 -29
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
- package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/content/app/i18n/index.ts +14 -29
- package/corpus/templates/crm/app/i18n/index.ts +14 -29
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/design/actions/import-code.ts +2 -43
- package/corpus/templates/design/app/i18n/index.ts +14 -29
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/dispatch/app/i18n-data.ts +1 -1
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/factory/AGENTS.md +40 -49
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
- package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
- package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
- package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
- package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
- package/corpus/templates/factory/app/routes/factory.tsx +95 -42
- package/corpus/templates/factory/server/db/schema.ts +37 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
- package/corpus/templates/factory/server/triage/audit.ts +79 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/forms/app/i18n/index.ts +14 -29
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/macros/app/i18n/index.ts +14 -29
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/mail/app/i18n/index.ts +14 -29
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
- package/corpus/templates/plan/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/slides/actions/import-code.ts +2 -43
- package/corpus/templates/slides/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
- package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
- package/corpus/templates/tasks/app/i18n/index.ts +14 -29
- package/dist/agent/engine/ai-sdk-engine.js +2 -1
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
- package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
- package/dist/agent/engine/provider-endpoint-validation.js +26 -0
- package/dist/agent/engine/provider-env-vars.d.ts +1 -1
- package/dist/agent/engine/provider-env-vars.js +1 -1
- package/dist/agent/engine/registry.d.ts +8 -6
- package/dist/agent/engine/registry.js +37 -24
- package/dist/agent/tool-search.d.ts +1 -0
- package/dist/agent/tool-search.js +17 -1
- package/dist/automations/service.js +4 -10
- package/dist/brand-kit/brand-signals.d.ts +13 -0
- package/dist/brand-kit/brand-signals.js +15 -0
- package/dist/brand-kit/index.d.ts +2 -2
- package/dist/brand-kit/index.js +1 -1
- package/dist/cli/plan-blocks.d.ts +3 -18
- package/dist/cli/plan-blocks.js +2 -95
- package/dist/cli/plan-publish-store.d.ts +2 -61
- package/dist/cli/plan-publish-store.js +2 -127
- package/dist/cli/skills-content/connection.d.ts +1 -1
- package/dist/cli/skills-content/connection.js +1 -52
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +1 -553
- package/dist/client/agent-engine-key.d.ts +14 -4
- package/dist/client/agent-engine-key.js +51 -5
- package/dist/client/agent-provider-catalog.d.ts +20 -0
- package/dist/client/agent-provider-catalog.js +100 -0
- package/dist/client/blocks/index.d.ts +1 -0
- package/dist/client/blocks/index.js +1 -0
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/sanitize-html.js +66 -2
- package/dist/client/blocks/library/wireframe-kit.js +69 -0
- package/dist/client/chat/run-recovery.js +4 -48
- package/dist/client/chat-first/apps-rail.d.ts +1 -1
- package/dist/client/chat-first/apps-rail.js +4 -4
- package/dist/client/chat-first/copy.js +1 -0
- package/dist/client/chat-first/types.d.ts +1 -0
- package/dist/client/chat-first.js +4 -3
- package/dist/client/i18n.d.ts +14 -0
- package/dist/client/i18n.js +18 -0
- package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
- package/dist/client/settings/ProviderSetupForm.js +145 -0
- package/dist/client/settings/SettingsPanel.js +52 -49
- package/dist/client/settings/index.d.ts +2 -0
- package/dist/client/settings/index.js +2 -0
- package/dist/coding-tools/run-code.d.ts +5 -0
- package/dist/coding-tools/run-code.js +196 -36
- package/dist/coding-tools/tool-orchestration.d.ts +10 -0
- package/dist/coding-tools/tool-orchestration.js +107 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/jobs/frontmatter.d.ts +9 -0
- package/dist/jobs/frontmatter.js +16 -0
- package/dist/jobs/scheduler.js +8 -8
- package/dist/jobs/tools.d.ts +1 -1
- package/dist/jobs/tools.js +2 -7
- package/dist/localization/default-messages.d.ts +20 -0
- package/dist/localization/default-messages.js +25 -5
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +2 -2
- package/dist/onboarding/app-profile.js +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
- package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
- package/dist/server/agent-chat/run-code-tools.js +3 -1
- package/dist/server/agent-chat-plugin.js +6 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.js +43 -12
- package/dist/server/agents-bundle.js +2 -1
- package/dist/server/auth.js +21 -5
- package/dist/server/credential-provider.js +1 -0
- package/dist/server/design-token-utils.d.ts +18 -0
- package/dist/server/design-token-utils.js +31 -0
- package/dist/server/onboarding-html.js +22 -2
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/styles/blocks.css +132 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/chat/app/i18n/index.ts +14 -29
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/default/app/i18n/index.ts +14 -29
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/triggers/dispatcher.js +1 -8
- package/docs/content/actions.mdx +4 -1
- package/docs/content/agent-surfaces.mdx +8 -6
- package/docs/content/automations.mdx +1 -1
- package/docs/content/database.mdx +6 -1
- package/docs/content/docs-components.mdx +22 -14
- package/docs/content/drop-in-agent.mdx +1 -1
- package/docs/content/environment-variables.mdx +39 -38
- package/docs/content/getting-started-actions.mdx +5 -4
- package/docs/content/getting-started-pages.mdx +7 -6
- package/docs/content/getting-started.mdx +4 -3
- package/docs/content/notifications.mdx +6 -6
- package/docs/content/progress.mdx +5 -5
- package/docs/content/routing.mdx +3 -1
- package/docs/content/server-database.mdx +13 -4
- package/docs/content/server-overview.mdx +9 -9
- package/docs/content/server-plugins.mdx +10 -4
- package/docs/content/server-routes.mdx +7 -2
- package/docs/content/tracking.mdx +4 -4
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/package.json +4 -4
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/chat/app/i18n/index.ts +14 -29
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/default/app/i18n/index.ts +14 -29
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
workspaceMemberIdentityFromContext,
|
|
17
17
|
} from "../server/lib/require-workspace-member.js";
|
|
18
18
|
import { createAiServicesGitReadClient } from "../server/triage/ai-services-git.js";
|
|
19
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
19
20
|
import { createGitHubClient } from "../server/triage/github-client.js";
|
|
20
21
|
import { stableId } from "../server/triage/ids.js";
|
|
21
22
|
import {
|
|
@@ -231,6 +232,34 @@ export default defineAction({
|
|
|
231
232
|
factoryTriggered,
|
|
232
233
|
});
|
|
233
234
|
|
|
235
|
+
await recordFactoryAudit(
|
|
236
|
+
context,
|
|
237
|
+
{ userEmail, orgId },
|
|
238
|
+
{
|
|
239
|
+
action: "govern-agent-native-pull-request",
|
|
240
|
+
kind: "governance",
|
|
241
|
+
status: governance.autoApprove ? "success" : "skipped",
|
|
242
|
+
itemId: itemId ?? null,
|
|
243
|
+
source: "github",
|
|
244
|
+
sourceUrl: pullRequest.htmlUrl,
|
|
245
|
+
summary: governance.reason,
|
|
246
|
+
details: {
|
|
247
|
+
repo,
|
|
248
|
+
pullRequestNumber,
|
|
249
|
+
clearBug,
|
|
250
|
+
productUxImplications,
|
|
251
|
+
internalBuilderMember: internalMember.isMember,
|
|
252
|
+
factoryTriggered,
|
|
253
|
+
checksPassed,
|
|
254
|
+
reviewFeedbackHandled,
|
|
255
|
+
autoApprove: governance.autoApprove,
|
|
256
|
+
autoMerge: governance.autoMerge,
|
|
257
|
+
ownerOwnedArea: governance.ownerOwnedArea ?? null,
|
|
258
|
+
guardResults: governance.guardResults,
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
);
|
|
262
|
+
|
|
234
263
|
if (itemId) {
|
|
235
264
|
const item = (
|
|
236
265
|
await getDb()
|
|
@@ -338,6 +367,19 @@ export default defineAction({
|
|
|
338
367
|
}
|
|
339
368
|
|
|
340
369
|
if (!governance.autoMerge) {
|
|
370
|
+
await recordFactoryAudit(
|
|
371
|
+
context,
|
|
372
|
+
{ userEmail, orgId },
|
|
373
|
+
{
|
|
374
|
+
action: "govern-agent-native-pull-request",
|
|
375
|
+
kind: "external_action",
|
|
376
|
+
itemId: itemId ?? null,
|
|
377
|
+
source: "github",
|
|
378
|
+
sourceUrl: approvalUrl,
|
|
379
|
+
summary: "Approved the pull request after governance checks passed.",
|
|
380
|
+
details: { repo, pullRequestNumber, approvalUrl },
|
|
381
|
+
},
|
|
382
|
+
);
|
|
341
383
|
return {
|
|
342
384
|
ok: true,
|
|
343
385
|
action: "approved",
|
|
@@ -374,6 +416,19 @@ export default defineAction({
|
|
|
374
416
|
})
|
|
375
417
|
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
|
|
376
418
|
}
|
|
419
|
+
await recordFactoryAudit(
|
|
420
|
+
context,
|
|
421
|
+
{ userEmail, orgId },
|
|
422
|
+
{
|
|
423
|
+
action: "govern-agent-native-pull-request",
|
|
424
|
+
kind: "external_action",
|
|
425
|
+
itemId: itemId ?? null,
|
|
426
|
+
source: "github",
|
|
427
|
+
sourceUrl: pullRequest.htmlUrl,
|
|
428
|
+
summary: "Merged the pull request after governance checks passed.",
|
|
429
|
+
details: { repo, pullRequestNumber, approvalUrl, mergeSha: merge.sha },
|
|
430
|
+
},
|
|
431
|
+
);
|
|
377
432
|
return {
|
|
378
433
|
ok: true,
|
|
379
434
|
action: "merged",
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
requireWorkspaceMember,
|
|
8
8
|
workspaceMemberIdentityFromContext,
|
|
9
9
|
} from "../server/lib/require-workspace-member.js";
|
|
10
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
10
11
|
import { pullRequestSnapshotToEnvelope } from "../server/triage/github-ingestion.js";
|
|
11
12
|
import { itemDedupeKey } from "../server/triage/ids.js";
|
|
12
13
|
import type {
|
|
@@ -90,6 +91,26 @@ export default defineAction({
|
|
|
90
91
|
},
|
|
91
92
|
});
|
|
92
93
|
|
|
94
|
+
await recordFactoryAudit(
|
|
95
|
+
context,
|
|
96
|
+
{ userEmail, orgId },
|
|
97
|
+
{
|
|
98
|
+
action: "ingest-github-observation",
|
|
99
|
+
kind: "observed",
|
|
100
|
+
itemId: id,
|
|
101
|
+
source: envelope.source,
|
|
102
|
+
sourceUrl: envelope.sourceUrl,
|
|
103
|
+
summary: envelope.title,
|
|
104
|
+
details: {
|
|
105
|
+
repository: envelope.repository,
|
|
106
|
+
pullRequestNumber: envelope.pullRequestNumber,
|
|
107
|
+
coverage: envelope.coverage,
|
|
108
|
+
reviewCount: input.reviews.length,
|
|
109
|
+
checkCount: input.checks.length,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
|
|
93
114
|
return {
|
|
94
115
|
ok: true,
|
|
95
116
|
id,
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import {
|
|
3
|
+
listAutomationDefinitions,
|
|
4
|
+
listAutomationRuns,
|
|
5
|
+
} from "@agent-native/core/triggers";
|
|
6
|
+
import { and, desc, eq, inArray } from "drizzle-orm";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
9
|
+
import { getDb } from "../server/db/index.js";
|
|
10
|
+
import { factoryAuditEvents } from "../server/db/schema.js";
|
|
11
|
+
import {
|
|
12
|
+
requireWorkspaceMember,
|
|
13
|
+
workspaceMemberIdentityFromContext,
|
|
14
|
+
} from "../server/lib/require-workspace-member.js";
|
|
15
|
+
|
|
16
|
+
export default defineAction({
|
|
17
|
+
description:
|
|
18
|
+
"List recent Factory automation runs with the bounded source observations, decisions, and external actions recorded for each run.",
|
|
19
|
+
agentTool: false,
|
|
20
|
+
schema: z.object({
|
|
21
|
+
factoryId: z.string().trim().min(1).optional(),
|
|
22
|
+
automation: z.string().trim().min(1).optional(),
|
|
23
|
+
limit: z.coerce.number().int().min(1).max(50).default(20),
|
|
24
|
+
}),
|
|
25
|
+
http: { method: "GET" },
|
|
26
|
+
readOnly: true,
|
|
27
|
+
run: async ({ automation, limit }, context) => {
|
|
28
|
+
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
29
|
+
workspaceMemberIdentityFromContext(context),
|
|
30
|
+
);
|
|
31
|
+
const definitions = await listAutomationDefinitions(
|
|
32
|
+
{ userEmail, orgId, appId: "factory" },
|
|
33
|
+
"organization",
|
|
34
|
+
);
|
|
35
|
+
const factoryDefinitions = definitions.filter(
|
|
36
|
+
({ meta, name }) =>
|
|
37
|
+
meta.domain === "factory" && (!automation || name === automation),
|
|
38
|
+
);
|
|
39
|
+
const runGroups = await Promise.all(
|
|
40
|
+
factoryDefinitions.map(async ({ name, resource }) =>
|
|
41
|
+
listAutomationRuns({
|
|
42
|
+
owners: [resource.owner],
|
|
43
|
+
automation: name,
|
|
44
|
+
appId: "factory",
|
|
45
|
+
limit,
|
|
46
|
+
}),
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
const runs = runGroups.flat().sort((a, b) => b.startedAt - a.startedAt);
|
|
50
|
+
const boundedRuns = runs.slice(0, limit);
|
|
51
|
+
const runIds = boundedRuns
|
|
52
|
+
.map((run) => run.runId)
|
|
53
|
+
.filter((runId): runId is string => Boolean(runId));
|
|
54
|
+
|
|
55
|
+
const db = getDb();
|
|
56
|
+
const events = runIds.length
|
|
57
|
+
? await db
|
|
58
|
+
.select()
|
|
59
|
+
.from(factoryAuditEvents)
|
|
60
|
+
.where(
|
|
61
|
+
and(
|
|
62
|
+
eq(factoryAuditEvents.orgId, orgId),
|
|
63
|
+
inArray(factoryAuditEvents.automationRunId, runIds),
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
.orderBy(desc(factoryAuditEvents.createdAt))
|
|
67
|
+
: [];
|
|
68
|
+
const eventsByRun = new Map<string, typeof events>();
|
|
69
|
+
for (const event of events) {
|
|
70
|
+
if (!event.automationRunId) continue;
|
|
71
|
+
const current = eventsByRun.get(event.automationRunId) ?? [];
|
|
72
|
+
current.push(event);
|
|
73
|
+
eventsByRun.set(event.automationRunId, current);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
runs: boundedRuns.map((run) => ({
|
|
78
|
+
id: run.id,
|
|
79
|
+
automation: run.automation,
|
|
80
|
+
runId: run.runId,
|
|
81
|
+
threadId: run.threadId,
|
|
82
|
+
status: run.status,
|
|
83
|
+
startedAt: run.startedAt,
|
|
84
|
+
finishedAt: run.finishedAt,
|
|
85
|
+
error: run.error,
|
|
86
|
+
events: (eventsByRun.get(run.runId ?? "") ?? []).map((event) => ({
|
|
87
|
+
id: event.id,
|
|
88
|
+
automationRunId: event.automationRunId,
|
|
89
|
+
automationThreadId: event.automationThreadId,
|
|
90
|
+
automationName: event.automationName,
|
|
91
|
+
itemId: event.itemId,
|
|
92
|
+
source: event.source,
|
|
93
|
+
sourceUrl: event.sourceUrl,
|
|
94
|
+
action: event.action,
|
|
95
|
+
kind: event.kind,
|
|
96
|
+
status: event.status,
|
|
97
|
+
summary: event.summary,
|
|
98
|
+
details: parseDetails(event.detailsJson),
|
|
99
|
+
createdAt: event.createdAt,
|
|
100
|
+
})),
|
|
101
|
+
})),
|
|
102
|
+
count: boundedRuns.length,
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
function parseDetails(value: string): Record<string, unknown> {
|
|
108
|
+
let parsed: unknown;
|
|
109
|
+
try {
|
|
110
|
+
parsed = JSON.parse(value);
|
|
111
|
+
} catch {
|
|
112
|
+
throw new Error("Factory audit details are unreadable.");
|
|
113
|
+
}
|
|
114
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
115
|
+
throw new Error("Factory audit details are unreadable.");
|
|
116
|
+
}
|
|
117
|
+
return parsed as Record<string, unknown>;
|
|
118
|
+
}
|
|
@@ -22,7 +22,7 @@ export default defineAction({
|
|
|
22
22
|
workspaceMemberIdentityFromContext(context),
|
|
23
23
|
);
|
|
24
24
|
const definitions = await listAutomationDefinitions(
|
|
25
|
-
{ userEmail, orgId },
|
|
25
|
+
{ userEmail, orgId, appId: "factory" },
|
|
26
26
|
"organization",
|
|
27
27
|
);
|
|
28
28
|
return Promise.all(
|
|
@@ -45,6 +45,7 @@ export default defineAction({
|
|
|
45
45
|
runs: await listAutomationRuns({
|
|
46
46
|
owners: [resource.owner],
|
|
47
47
|
automation: name,
|
|
48
|
+
appId: "factory",
|
|
48
49
|
limit: 20,
|
|
49
50
|
}),
|
|
50
51
|
})),
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
requireWorkspaceMember,
|
|
9
9
|
workspaceMemberIdentityFromContext,
|
|
10
10
|
} from "../server/lib/require-workspace-member.js";
|
|
11
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
11
12
|
import {
|
|
12
13
|
triageItemStatusSchema,
|
|
13
14
|
triageSourceSchema,
|
|
@@ -24,7 +25,7 @@ export default defineAction({
|
|
|
24
25
|
http: { method: "GET" },
|
|
25
26
|
readOnly: true,
|
|
26
27
|
run: async ({ status, source, limit }, context) => {
|
|
27
|
-
const { orgId } = await requireWorkspaceMember(
|
|
28
|
+
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
28
29
|
workspaceMemberIdentityFromContext(context),
|
|
29
30
|
);
|
|
30
31
|
const db = getDb();
|
|
@@ -54,7 +55,7 @@ export default defineAction({
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
const listedItems = items.map((item) => {
|
|
58
59
|
const latestDecision = latestByItem.get(item.id);
|
|
59
60
|
return {
|
|
60
61
|
id: item.id,
|
|
@@ -86,5 +87,26 @@ export default defineAction({
|
|
|
86
87
|
: null,
|
|
87
88
|
};
|
|
88
89
|
});
|
|
90
|
+
|
|
91
|
+
for (const item of listedItems) {
|
|
92
|
+
await recordFactoryAudit(
|
|
93
|
+
context,
|
|
94
|
+
{ userEmail, orgId },
|
|
95
|
+
{
|
|
96
|
+
action: "list-triage-items",
|
|
97
|
+
kind: "read",
|
|
98
|
+
itemId: item.itemId,
|
|
99
|
+
source: item.source,
|
|
100
|
+
sourceUrl: item.sourceUrl,
|
|
101
|
+
summary: item.title,
|
|
102
|
+
details: {
|
|
103
|
+
status: item.status,
|
|
104
|
+
coverage: item.coverage,
|
|
105
|
+
decision: item.latestDecision?.outcome ?? null,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return listedItems;
|
|
89
111
|
},
|
|
90
112
|
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
requireWorkspaceMember,
|
|
10
10
|
workspaceMemberIdentityFromContext,
|
|
11
11
|
} from "../server/lib/require-workspace-member.js";
|
|
12
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
12
13
|
import { createGitHubClient } from "../server/triage/github-client.js";
|
|
13
14
|
import { itemDedupeKey } from "../server/triage/ids.js";
|
|
14
15
|
import { mergeTriageMetadata } from "../server/triage/metadata.js";
|
|
@@ -193,6 +194,65 @@ export default defineAction({
|
|
|
193
194
|
}
|
|
194
195
|
});
|
|
195
196
|
|
|
197
|
+
if (issues.length === 0 && pullRequests.length === 0) {
|
|
198
|
+
await recordFactoryAudit(
|
|
199
|
+
context,
|
|
200
|
+
{ userEmail, orgId },
|
|
201
|
+
{
|
|
202
|
+
action: "poll-github-sources",
|
|
203
|
+
kind: "observed",
|
|
204
|
+
source: "github",
|
|
205
|
+
summary: "No open GitHub issues or pull requests were observed.",
|
|
206
|
+
details: { repository: repositoryName },
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
} else {
|
|
210
|
+
for (const issue of issues) {
|
|
211
|
+
await recordFactoryAudit(
|
|
212
|
+
context,
|
|
213
|
+
{ userEmail, orgId },
|
|
214
|
+
{
|
|
215
|
+
action: "poll-github-sources",
|
|
216
|
+
kind: "observed",
|
|
217
|
+
itemId: itemDedupeKey(
|
|
218
|
+
{
|
|
219
|
+
source: "github_issue",
|
|
220
|
+
externalId: `${repositoryName}#${issue.number}`,
|
|
221
|
+
},
|
|
222
|
+
orgId,
|
|
223
|
+
),
|
|
224
|
+
source: "github_issue",
|
|
225
|
+
sourceUrl: issue.htmlUrl,
|
|
226
|
+
summary: issue.title,
|
|
227
|
+
details: { repository: repositoryName, number: issue.number },
|
|
228
|
+
},
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
for (const pullRequest of pullRequests) {
|
|
232
|
+
await recordFactoryAudit(
|
|
233
|
+
context,
|
|
234
|
+
{ userEmail, orgId },
|
|
235
|
+
{
|
|
236
|
+
action: "poll-github-sources",
|
|
237
|
+
kind: "observed",
|
|
238
|
+
itemId: itemDedupeKey(
|
|
239
|
+
{
|
|
240
|
+
source: "github",
|
|
241
|
+
externalId: `${repositoryName}#${pullRequest.number}`,
|
|
242
|
+
repository: repositoryName,
|
|
243
|
+
pullRequestNumber: pullRequest.number,
|
|
244
|
+
},
|
|
245
|
+
orgId,
|
|
246
|
+
),
|
|
247
|
+
source: "github",
|
|
248
|
+
sourceUrl: pullRequest.htmlUrl,
|
|
249
|
+
summary: pullRequest.title,
|
|
250
|
+
details: { repository: repositoryName, number: pullRequest.number },
|
|
251
|
+
},
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
196
256
|
return {
|
|
197
257
|
ok: true,
|
|
198
258
|
repository: repositoryName,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
requireWorkspaceMember,
|
|
10
10
|
workspaceMemberIdentityFromContext,
|
|
11
11
|
} from "../server/lib/require-workspace-member.js";
|
|
12
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
12
13
|
import { itemDedupeKey } from "../server/triage/ids.js";
|
|
13
14
|
import { mergeTriageMetadata } from "../server/triage/metadata.js";
|
|
14
15
|
import { createSentryClient } from "../server/triage/sentry-client.js";
|
|
@@ -151,6 +152,44 @@ export default defineAction({
|
|
|
151
152
|
.where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)));
|
|
152
153
|
});
|
|
153
154
|
|
|
155
|
+
if (observedIssues.length === 0) {
|
|
156
|
+
await recordFactoryAudit(
|
|
157
|
+
context,
|
|
158
|
+
{ userEmail, orgId },
|
|
159
|
+
{
|
|
160
|
+
action: "poll-sentry-errors",
|
|
161
|
+
kind: "observed",
|
|
162
|
+
source: "sentry",
|
|
163
|
+
summary: "No unresolved Sentry errors were observed.",
|
|
164
|
+
details: { sentryOrgSlug: config.sentryOrgSlug },
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
} else {
|
|
168
|
+
for (const issue of observedIssues) {
|
|
169
|
+
await recordFactoryAudit(
|
|
170
|
+
context,
|
|
171
|
+
{ userEmail, orgId },
|
|
172
|
+
{
|
|
173
|
+
action: "poll-sentry-errors",
|
|
174
|
+
kind: "observed",
|
|
175
|
+
itemId: itemDedupeKey(
|
|
176
|
+
{ source: "sentry", externalId: issue.id },
|
|
177
|
+
orgId,
|
|
178
|
+
),
|
|
179
|
+
source: "sentry",
|
|
180
|
+
sourceUrl: issue.permalink,
|
|
181
|
+
summary: issue.title,
|
|
182
|
+
details: {
|
|
183
|
+
shortId: issue.shortId,
|
|
184
|
+
level: issue.level,
|
|
185
|
+
count: issue.count,
|
|
186
|
+
projectSlug: issue.projectSlug,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
154
193
|
return {
|
|
155
194
|
ok: true,
|
|
156
195
|
observed: observedIssues.length,
|
|
@@ -4,10 +4,12 @@ import { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
import { getDb } from "../server/db/index.js";
|
|
6
6
|
import { triageConfig, triageItems } from "../server/db/schema.js";
|
|
7
|
+
import { requireFactoryAutomation } from "../server/lib/require-factory-automation.js";
|
|
7
8
|
import {
|
|
8
9
|
requireWorkspaceMember,
|
|
9
10
|
workspaceMemberIdentityFromContext,
|
|
10
11
|
} from "../server/lib/require-workspace-member.js";
|
|
12
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
11
13
|
import { itemDedupeKey } from "../server/triage/ids.js";
|
|
12
14
|
import { pollSlackChannel } from "../server/triage/slack-poller.js";
|
|
13
15
|
|
|
@@ -17,11 +19,16 @@ export default defineAction({
|
|
|
17
19
|
schema: z.object({
|
|
18
20
|
channelId: z.string().trim().min(1).max(128).optional(),
|
|
19
21
|
}),
|
|
20
|
-
http:
|
|
22
|
+
http: false,
|
|
21
23
|
run: async ({ channelId: requestedChannelId }, context) => {
|
|
22
24
|
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
23
25
|
workspaceMemberIdentityFromContext(context),
|
|
24
26
|
);
|
|
27
|
+
await requireFactoryAutomation(
|
|
28
|
+
context,
|
|
29
|
+
{ userEmail, orgId },
|
|
30
|
+
"sourcePolling",
|
|
31
|
+
);
|
|
25
32
|
const db = getDb();
|
|
26
33
|
const config = (
|
|
27
34
|
await db
|
|
@@ -106,6 +113,43 @@ export default defineAction({
|
|
|
106
113
|
}
|
|
107
114
|
});
|
|
108
115
|
|
|
116
|
+
if (result.envelopes.length === 0) {
|
|
117
|
+
await recordFactoryAudit(
|
|
118
|
+
context,
|
|
119
|
+
{ userEmail, orgId },
|
|
120
|
+
{
|
|
121
|
+
action: "poll-slack-channel",
|
|
122
|
+
kind: "observed",
|
|
123
|
+
source: "slack",
|
|
124
|
+
summary: "No new Slack feedback was observed.",
|
|
125
|
+
details: {
|
|
126
|
+
channelId,
|
|
127
|
+
coverage: result.hasMore ? "partial" : "complete",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
} else {
|
|
132
|
+
for (const envelope of result.envelopes) {
|
|
133
|
+
await recordFactoryAudit(
|
|
134
|
+
context,
|
|
135
|
+
{ userEmail, orgId },
|
|
136
|
+
{
|
|
137
|
+
action: "poll-slack-channel",
|
|
138
|
+
kind: "observed",
|
|
139
|
+
itemId: itemDedupeKey(envelope, orgId),
|
|
140
|
+
source: envelope.source,
|
|
141
|
+
sourceUrl: envelope.sourceUrl ?? null,
|
|
142
|
+
summary: envelope.summary ?? envelope.title,
|
|
143
|
+
details: {
|
|
144
|
+
channelId,
|
|
145
|
+
threadTs: envelope.threadTs ?? null,
|
|
146
|
+
coverage: envelope.coverage,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
109
153
|
return {
|
|
110
154
|
ok: true,
|
|
111
155
|
source: "slack",
|
|
@@ -24,7 +24,7 @@ export default defineAction({
|
|
|
24
24
|
workspaceMemberIdentityFromContext(context),
|
|
25
25
|
);
|
|
26
26
|
const definitions = await listAutomationDefinitions(
|
|
27
|
-
{ userEmail, orgId },
|
|
27
|
+
{ userEmail, orgId, appId: "factory" },
|
|
28
28
|
"organization",
|
|
29
29
|
);
|
|
30
30
|
const definition = definitions.find(
|
|
@@ -32,7 +32,7 @@ export default defineAction({
|
|
|
32
32
|
workspaceMemberIdentityFromContext(context),
|
|
33
33
|
);
|
|
34
34
|
const definitions = await listAutomationDefinitions(
|
|
35
|
-
{ userEmail, orgId },
|
|
35
|
+
{ userEmail, orgId, appId: "factory" },
|
|
36
36
|
"organization",
|
|
37
37
|
);
|
|
38
38
|
const definition = definitions.find(
|
|
@@ -46,7 +46,7 @@ export default defineAction({
|
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
const updated = await updateAutomation(
|
|
49
|
-
{ userEmail, orgId },
|
|
49
|
+
{ userEmail, orgId, appId: "factory" },
|
|
50
50
|
{
|
|
51
51
|
name: definition.name,
|
|
52
52
|
scope: "organization",
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
requireWorkspaceMember,
|
|
15
15
|
workspaceMemberIdentityFromContext,
|
|
16
16
|
} from "../server/lib/require-workspace-member.js";
|
|
17
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
17
18
|
import { startBuilderRun } from "../server/triage/builder-executor.js";
|
|
18
19
|
import { stableId } from "../server/triage/ids.js";
|
|
19
20
|
import {
|
|
@@ -182,6 +183,26 @@ export default defineAction({
|
|
|
182
183
|
: reason,
|
|
183
184
|
guardResults,
|
|
184
185
|
});
|
|
186
|
+
await recordFactoryAudit(
|
|
187
|
+
context,
|
|
188
|
+
{ userEmail, orgId },
|
|
189
|
+
{
|
|
190
|
+
action: "start-builder-for-item",
|
|
191
|
+
kind: "decision",
|
|
192
|
+
itemId,
|
|
193
|
+
source: item.source,
|
|
194
|
+
sourceUrl: item.sourceUrl,
|
|
195
|
+
status: blocked ? "skipped" : "success",
|
|
196
|
+
summary: blocked ? "Factory kept this item for manual review." : reason,
|
|
197
|
+
details: {
|
|
198
|
+
decisionId,
|
|
199
|
+
clearBug,
|
|
200
|
+
productUxImplications,
|
|
201
|
+
ownerOwnedArea: ownerOwnedArea ?? null,
|
|
202
|
+
guardResults,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
);
|
|
185
206
|
if (blocked) {
|
|
186
207
|
await db
|
|
187
208
|
.update(triageItems)
|
|
@@ -332,6 +353,19 @@ export default defineAction({
|
|
|
332
353
|
updatedAt: new Date().toISOString(),
|
|
333
354
|
})
|
|
334
355
|
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
|
|
356
|
+
await recordFactoryAudit(
|
|
357
|
+
context,
|
|
358
|
+
{ userEmail, orgId },
|
|
359
|
+
{
|
|
360
|
+
action: "start-builder-for-item",
|
|
361
|
+
kind: "external_action",
|
|
362
|
+
itemId,
|
|
363
|
+
source: item.source,
|
|
364
|
+
sourceUrl: item.sourceUrl,
|
|
365
|
+
summary: "Tagged Builder in the Slack thread and requested a PR.",
|
|
366
|
+
details: { provider: "bot-tag", runId },
|
|
367
|
+
},
|
|
368
|
+
);
|
|
335
369
|
return {
|
|
336
370
|
ok: true,
|
|
337
371
|
started: true,
|
|
@@ -385,6 +419,23 @@ export default defineAction({
|
|
|
385
419
|
updatedAt: new Date().toISOString(),
|
|
386
420
|
})
|
|
387
421
|
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
|
|
422
|
+
await recordFactoryAudit(
|
|
423
|
+
context,
|
|
424
|
+
{ userEmail, orgId },
|
|
425
|
+
{
|
|
426
|
+
action: "start-builder-for-item",
|
|
427
|
+
kind: "external_action",
|
|
428
|
+
itemId,
|
|
429
|
+
source: item.source,
|
|
430
|
+
sourceUrl: item.sourceUrl,
|
|
431
|
+
summary: "Submitted the clear bug to Builder.",
|
|
432
|
+
details: {
|
|
433
|
+
provider: "builder-http",
|
|
434
|
+
runId,
|
|
435
|
+
providerTaskId: result.providerTaskId ?? null,
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
);
|
|
388
439
|
return {
|
|
389
440
|
ok: true,
|
|
390
441
|
started: true,
|