@agent-native/core 0.111.3 → 0.112.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.
Files changed (109) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +18 -0
  3. package/corpus/core/package.json +3 -1
  4. package/corpus/core/src/cli/code-agent-executor.ts +17 -5
  5. package/corpus/core/src/cli/code-agent-runs.ts +43 -2
  6. package/corpus/core/src/cli/migration-codemod.ts +59 -9
  7. package/corpus/core/src/cli/multi-frontier-runs.ts +841 -0
  8. package/corpus/core/src/coding-tools/index.ts +27 -8
  9. package/corpus/core/src/embeddings/index.ts +233 -0
  10. package/corpus/core/src/index.ts +2 -0
  11. package/corpus/core/src/search/index.ts +413 -0
  12. package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +48 -5
  13. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +46 -14
  14. package/corpus/templates/brain/README.md +34 -3
  15. package/corpus/templates/brain/actions/approve-proposal.ts +2 -0
  16. package/corpus/templates/brain/actions/claim-distillation.ts +24 -27
  17. package/corpus/templates/brain/actions/create-source.ts +1 -1
  18. package/corpus/templates/brain/actions/get-knowledge.ts +6 -2
  19. package/corpus/templates/brain/actions/get-pilot-report.ts +44 -8
  20. package/corpus/templates/brain/actions/import-capture.ts +21 -9
  21. package/corpus/templates/brain/actions/import-transcript.ts +42 -14
  22. package/corpus/templates/brain/actions/list-captures.ts +10 -1
  23. package/corpus/templates/brain/actions/list-distillation-queue.ts +39 -14
  24. package/corpus/templates/brain/actions/list-projects.ts +51 -0
  25. package/corpus/templates/brain/actions/list-proposals.ts +80 -4
  26. package/corpus/templates/brain/actions/list-sources.ts +17 -3
  27. package/corpus/templates/brain/actions/manage-project.ts +118 -0
  28. package/corpus/templates/brain/actions/mark-capture-distilled.ts +68 -20
  29. package/corpus/templates/brain/actions/navigate.ts +1 -0
  30. package/corpus/templates/brain/actions/reject-proposal.ts +6 -1
  31. package/corpus/templates/brain/actions/resanitize-captures.ts +159 -33
  32. package/corpus/templates/brain/actions/review-proposal.ts +2 -0
  33. package/corpus/templates/brain/actions/search-everything.ts +10 -1
  34. package/corpus/templates/brain/actions/search-knowledge.ts +1 -1
  35. package/corpus/templates/brain/actions/set-settings.ts +36 -1
  36. package/corpus/templates/brain/actions/update-proposal.ts +2 -0
  37. package/corpus/templates/brain/app/hooks/use-distillation-bridge.ts +18 -9
  38. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +3 -0
  39. package/corpus/templates/brain/app/i18n-data.ts +731 -2
  40. package/corpus/templates/brain/app/lib/brain.ts +33 -1
  41. package/corpus/templates/brain/app/routes/ops.tsx +47 -0
  42. package/corpus/templates/brain/app/routes/review.tsx +41 -2
  43. package/corpus/templates/brain/app/routes/search.tsx +33 -2
  44. package/corpus/templates/brain/app/routes/settings.tsx +158 -0
  45. package/corpus/templates/brain/app/routes/sources.tsx +31 -0
  46. package/corpus/templates/brain/changelog/2026-07-19-added-private-source-safe-semantic-search.md +6 -0
  47. package/corpus/templates/brain/jobs/process-ingest-queue.ts +270 -36
  48. package/corpus/templates/brain/package.json +1 -0
  49. package/corpus/templates/brain/server/db/index.ts +18 -0
  50. package/corpus/templates/brain/server/db/schema.ts +197 -1
  51. package/corpus/templates/brain/server/jobs/distillation-queue.ts +12 -5
  52. package/corpus/templates/brain/server/lib/audiences.ts +708 -0
  53. package/corpus/templates/brain/server/lib/brain-health.ts +251 -38
  54. package/corpus/templates/brain/server/lib/brain.ts +877 -50
  55. package/corpus/templates/brain/server/lib/capture-sanitization.ts +217 -53
  56. package/corpus/templates/brain/server/lib/connectors.ts +556 -70
  57. package/corpus/templates/brain/server/lib/demo.ts +17 -4
  58. package/corpus/templates/brain/server/lib/hybrid-search.ts +363 -0
  59. package/corpus/templates/brain/server/lib/ingest-queue.ts +104 -0
  60. package/corpus/templates/brain/server/lib/privacy-readiness.ts +24 -0
  61. package/corpus/templates/brain/server/lib/search-index-contracts.ts +72 -0
  62. package/corpus/templates/brain/server/lib/search-index.ts +714 -0
  63. package/corpus/templates/brain/server/lib/search.ts +120 -4
  64. package/corpus/templates/brain/server/lib/sensitivity-policy.ts +174 -0
  65. package/corpus/templates/brain/server/lib/slack-events.ts +281 -0
  66. package/corpus/templates/brain/server/onboarding.ts +29 -0
  67. package/corpus/templates/brain/server/plugins/db.ts +204 -0
  68. package/corpus/templates/brain/server/register-secrets.ts +46 -0
  69. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +36 -16
  70. package/corpus/templates/brain/server/routes/api/_agent-native/brain/slack-events.post.ts +28 -0
  71. package/corpus/templates/brain/shared/types.ts +10 -0
  72. package/dist/cli/code-agent-executor.d.ts +8 -9
  73. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  74. package/dist/cli/code-agent-executor.js +9 -3
  75. package/dist/cli/code-agent-executor.js.map +1 -1
  76. package/dist/cli/code-agent-runs.d.ts +5 -0
  77. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  78. package/dist/cli/code-agent-runs.js +33 -2
  79. package/dist/cli/code-agent-runs.js.map +1 -1
  80. package/dist/cli/migration-codemod.d.ts.map +1 -1
  81. package/dist/cli/migration-codemod.js +48 -10
  82. package/dist/cli/migration-codemod.js.map +1 -1
  83. package/dist/cli/multi-frontier-runs.d.ts +131 -0
  84. package/dist/cli/multi-frontier-runs.d.ts.map +1 -0
  85. package/dist/cli/multi-frontier-runs.js +529 -0
  86. package/dist/cli/multi-frontier-runs.js.map +1 -0
  87. package/dist/coding-tools/index.d.ts +1 -0
  88. package/dist/coding-tools/index.d.ts.map +1 -1
  89. package/dist/coding-tools/index.js +25 -7
  90. package/dist/coding-tools/index.js.map +1 -1
  91. package/dist/collab/awareness.d.ts +2 -2
  92. package/dist/collab/awareness.d.ts.map +1 -1
  93. package/dist/embeddings/index.d.ts +24 -0
  94. package/dist/embeddings/index.d.ts.map +1 -0
  95. package/dist/embeddings/index.js +172 -0
  96. package/dist/embeddings/index.js.map +1 -0
  97. package/dist/index.d.ts +2 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +2 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/notifications/routes.d.ts +3 -3
  102. package/dist/progress/routes.d.ts +1 -1
  103. package/dist/resources/handlers.d.ts +1 -1
  104. package/dist/search/index.d.ts +88 -0
  105. package/dist/search/index.d.ts.map +1 -0
  106. package/dist/search/index.js +267 -0
  107. package/dist/search/index.js.map +1 -0
  108. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  109. package/package.json +3 -1
@@ -183,6 +183,7 @@ const runBrainMigrations = runMigrations(
183
183
  priority INTEGER NOT NULL DEFAULT 0,
184
184
  attempts INTEGER NOT NULL DEFAULT 0,
185
185
  payload_json TEXT NOT NULL DEFAULT '{}',
186
+ lease_token TEXT,
186
187
  error TEXT,
187
188
  run_after TEXT,
188
189
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
@@ -270,6 +271,209 @@ const runBrainMigrations = runMigrations(
270
271
  `CREATE INDEX IF NOT EXISTS brain_ingest_queue_capture_operation_idx ON brain_ingest_queue (capture_id, operation)`,
271
272
  ].join(";\n"),
272
273
  },
274
+ {
275
+ version: 21,
276
+ name: "brain-privacy-semantic-search-contracts",
277
+ sql: [
278
+ `ALTER TABLE brain_raw_captures ADD COLUMN IF NOT EXISTS sensitivity_disposition TEXT NOT NULL DEFAULT 'pending'`,
279
+ `ALTER TABLE brain_raw_captures ADD COLUMN IF NOT EXISTS sensitivity_policy_version TEXT`,
280
+ `ALTER TABLE brain_raw_captures ADD COLUMN IF NOT EXISTS audience_acl_hash TEXT`,
281
+ `ALTER TABLE brain_knowledge ADD COLUMN IF NOT EXISTS audience_id TEXT`,
282
+ `ALTER TABLE brain_knowledge ADD COLUMN IF NOT EXISTS audience_acl_hash TEXT`,
283
+ `ALTER TABLE brain_proposals ADD COLUMN IF NOT EXISTS audience_id TEXT`,
284
+ `ALTER TABLE brain_proposals ADD COLUMN IF NOT EXISTS audience_acl_hash TEXT`,
285
+ `ALTER TABLE brain_ingest_queue ADD COLUMN IF NOT EXISTS dedupe_key TEXT`,
286
+ `ALTER TABLE brain_ingest_queue ADD COLUMN IF NOT EXISTS lease_expires_at TEXT`,
287
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_ingest_queue_dedupe_idx ON brain_ingest_queue (dedupe_key)`,
288
+ `CREATE TABLE IF NOT EXISTS brain_audiences (
289
+ id TEXT PRIMARY KEY,
290
+ source_id TEXT NOT NULL,
291
+ kind TEXT NOT NULL,
292
+ upstream_ref_hash TEXT,
293
+ acl_hash TEXT NOT NULL,
294
+ membership_state TEXT NOT NULL DEFAULT 'stale',
295
+ last_synced_at TEXT,
296
+ created_at TEXT NOT NULL,
297
+ updated_at TEXT NOT NULL
298
+ )`,
299
+ `CREATE TABLE IF NOT EXISTS brain_audience_members (
300
+ id TEXT PRIMARY KEY,
301
+ audience_id TEXT NOT NULL,
302
+ principal_type TEXT NOT NULL,
303
+ principal_id TEXT NOT NULL,
304
+ upstream_principal_hash TEXT,
305
+ status TEXT NOT NULL DEFAULT 'active',
306
+ synced_at TEXT NOT NULL,
307
+ created_at TEXT NOT NULL,
308
+ updated_at TEXT NOT NULL
309
+ )`,
310
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_audience_member_principal_idx ON brain_audience_members (audience_id, principal_type, principal_id)`,
311
+ `CREATE INDEX IF NOT EXISTS brain_audience_member_lookup_idx ON brain_audience_members (principal_type, principal_id, status)`,
312
+ `CREATE TABLE IF NOT EXISTS brain_capture_audiences (
313
+ id TEXT PRIMARY KEY,
314
+ capture_id TEXT NOT NULL,
315
+ audience_id TEXT NOT NULL,
316
+ acl_hash TEXT NOT NULL,
317
+ created_at TEXT NOT NULL
318
+ )`,
319
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_capture_audience_unique_idx ON brain_capture_audiences (capture_id, audience_id)`,
320
+ `CREATE INDEX IF NOT EXISTS brain_knowledge_audience_status_idx ON brain_knowledge (audience_id, status, updated_at)`,
321
+ `CREATE INDEX IF NOT EXISTS brain_proposal_audience_status_idx ON brain_proposals (audience_id, status, updated_at)`,
322
+ `CREATE TABLE IF NOT EXISTS brain_sensitivity_events (
323
+ id TEXT PRIMARY KEY,
324
+ source_id TEXT NOT NULL,
325
+ capture_id TEXT,
326
+ locator_hmac TEXT NOT NULL,
327
+ disposition TEXT NOT NULL,
328
+ categories_json TEXT NOT NULL DEFAULT '[]',
329
+ confidence_band TEXT NOT NULL,
330
+ policy_version TEXT NOT NULL,
331
+ upstream_provider TEXT NOT NULL,
332
+ quarantine_blob_handle TEXT,
333
+ expires_at TEXT,
334
+ reviewed_by TEXT,
335
+ reviewed_at TEXT,
336
+ created_at TEXT NOT NULL,
337
+ updated_at TEXT NOT NULL
338
+ )`,
339
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_sensitivity_locator_policy_idx ON brain_sensitivity_events (locator_hmac, policy_version)`,
340
+ `CREATE INDEX IF NOT EXISTS brain_sensitivity_source_created_idx ON brain_sensitivity_events (source_id, created_at)`,
341
+ `CREATE TABLE IF NOT EXISTS brain_search_artifacts (
342
+ id TEXT PRIMARY KEY,
343
+ capture_id TEXT NOT NULL,
344
+ source_id TEXT NOT NULL,
345
+ audience_id TEXT NOT NULL,
346
+ acl_hash TEXT NOT NULL,
347
+ title TEXT NOT NULL,
348
+ question TEXT NOT NULL DEFAULT '',
349
+ summary TEXT NOT NULL DEFAULT '',
350
+ resolution TEXT NOT NULL DEFAULT '',
351
+ systems_json TEXT NOT NULL DEFAULT '[]',
352
+ code_refs_json TEXT NOT NULL DEFAULT '[]',
353
+ content_hash TEXT NOT NULL,
354
+ sensitivity_policy_version TEXT NOT NULL,
355
+ index_version TEXT NOT NULL,
356
+ status TEXT NOT NULL DEFAULT 'active',
357
+ captured_at TEXT NOT NULL,
358
+ created_at TEXT NOT NULL,
359
+ updated_at TEXT NOT NULL
360
+ )`,
361
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_search_artifact_version_idx ON brain_search_artifacts (capture_id, content_hash, index_version)`,
362
+ `CREATE INDEX IF NOT EXISTS brain_search_artifact_audience_idx ON brain_search_artifacts (audience_id, status, updated_at)`,
363
+ `CREATE TABLE IF NOT EXISTS brain_search_bursts (
364
+ id TEXT PRIMARY KEY,
365
+ artifact_id TEXT NOT NULL,
366
+ capture_id TEXT NOT NULL,
367
+ source_id TEXT NOT NULL,
368
+ audience_id TEXT NOT NULL,
369
+ acl_hash TEXT NOT NULL,
370
+ ordinal INTEGER NOT NULL,
371
+ start_offset INTEGER NOT NULL,
372
+ end_offset INTEGER NOT NULL,
373
+ content TEXT NOT NULL,
374
+ contextual_text TEXT NOT NULL,
375
+ char_count INTEGER NOT NULL,
376
+ rare_term_score INTEGER NOT NULL DEFAULT 0,
377
+ reaction_count INTEGER NOT NULL DEFAULT 0,
378
+ indexed INTEGER NOT NULL DEFAULT 0,
379
+ content_hash TEXT NOT NULL,
380
+ index_version TEXT NOT NULL,
381
+ created_at TEXT NOT NULL,
382
+ updated_at TEXT NOT NULL
383
+ )`,
384
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_search_burst_version_idx ON brain_search_bursts (capture_id, content_hash, index_version, ordinal)`,
385
+ `CREATE INDEX IF NOT EXISTS brain_search_burst_audience_idx ON brain_search_bursts (audience_id, indexed, updated_at)`,
386
+ `CREATE TABLE IF NOT EXISTS brain_search_embeddings (
387
+ id TEXT PRIMARY KEY,
388
+ target_type TEXT NOT NULL,
389
+ target_id TEXT NOT NULL,
390
+ vector_key TEXT NOT NULL,
391
+ source_id TEXT NOT NULL,
392
+ audience_id TEXT NOT NULL,
393
+ acl_hash TEXT NOT NULL,
394
+ embedding_set_id TEXT NOT NULL,
395
+ dimensions INTEGER NOT NULL,
396
+ content_hash TEXT NOT NULL,
397
+ sensitivity_policy_version TEXT NOT NULL,
398
+ index_version TEXT NOT NULL,
399
+ status TEXT NOT NULL DEFAULT 'active',
400
+ created_at TEXT NOT NULL,
401
+ updated_at TEXT NOT NULL
402
+ )`,
403
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_search_embedding_target_idx ON brain_search_embeddings (embedding_set_id, target_type, target_id)`,
404
+ `CREATE INDEX IF NOT EXISTS brain_search_embedding_audience_idx ON brain_search_embeddings (audience_id, status, updated_at)`,
405
+ `CREATE TABLE IF NOT EXISTS brain_term_stats (
406
+ term TEXT PRIMARY KEY,
407
+ document_count INTEGER NOT NULL DEFAULT 0,
408
+ updated_at TEXT NOT NULL
409
+ )`,
410
+ `CREATE TABLE IF NOT EXISTS brain_search_corpus_stats (
411
+ id TEXT PRIMARY KEY,
412
+ document_count INTEGER NOT NULL DEFAULT 0,
413
+ updated_at TEXT NOT NULL
414
+ )`,
415
+ `CREATE TABLE IF NOT EXISTS brain_projects (
416
+ id TEXT PRIMARY KEY,
417
+ title TEXT NOT NULL,
418
+ description TEXT NOT NULL DEFAULT '',
419
+ created_at TEXT NOT NULL,
420
+ updated_at TEXT NOT NULL,
421
+ owner_email TEXT NOT NULL DEFAULT 'local@localhost',
422
+ org_id TEXT,
423
+ visibility TEXT NOT NULL DEFAULT 'private'
424
+ )`,
425
+ `CREATE TABLE IF NOT EXISTS brain_project_shares (
426
+ id TEXT PRIMARY KEY,
427
+ resource_id TEXT NOT NULL,
428
+ principal_type TEXT NOT NULL,
429
+ principal_id TEXT NOT NULL,
430
+ role TEXT NOT NULL DEFAULT 'viewer',
431
+ created_by TEXT NOT NULL,
432
+ created_at TEXT NOT NULL
433
+ )`,
434
+ `CREATE TABLE IF NOT EXISTS brain_project_sources (
435
+ id TEXT PRIMARY KEY,
436
+ project_id TEXT NOT NULL,
437
+ source_id TEXT NOT NULL,
438
+ created_at TEXT NOT NULL
439
+ )`,
440
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_project_source_unique_idx ON brain_project_sources (project_id, source_id)`,
441
+ `CREATE INDEX IF NOT EXISTS brain_project_shares_principal_idx ON brain_project_shares (resource_id, principal_type, principal_id)`,
442
+ ].join(";\n"),
443
+ },
444
+ {
445
+ version: 22,
446
+ name: "brain-ingest-queue-lease-token",
447
+ sql: `ALTER TABLE brain_ingest_queue ADD COLUMN IF NOT EXISTS lease_token TEXT`,
448
+ },
449
+ {
450
+ version: 23,
451
+ name: "brain-audience-dependencies",
452
+ sql: [
453
+ `CREATE TABLE IF NOT EXISTS brain_audience_dependencies (
454
+ id TEXT PRIMARY KEY,
455
+ audience_id TEXT NOT NULL,
456
+ depends_on_audience_id TEXT NOT NULL,
457
+ created_at TEXT NOT NULL
458
+ )`,
459
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_audience_dependency_unique_idx ON brain_audience_dependencies (audience_id, depends_on_audience_id)`,
460
+ `CREATE INDEX IF NOT EXISTS brain_audience_dependency_upstream_idx ON brain_audience_dependencies (depends_on_audience_id, audience_id)`,
461
+ ].join(";\n"),
462
+ },
463
+ {
464
+ version: 24,
465
+ name: "brain-audience-source-dependencies",
466
+ sql: [
467
+ `CREATE TABLE IF NOT EXISTS brain_audience_source_dependencies (
468
+ id TEXT PRIMARY KEY,
469
+ audience_id TEXT NOT NULL,
470
+ source_id TEXT NOT NULL,
471
+ created_at TEXT NOT NULL
472
+ )`,
473
+ `CREATE UNIQUE INDEX IF NOT EXISTS brain_audience_source_dependency_unique_idx ON brain_audience_source_dependencies (audience_id, source_id)`,
474
+ `CREATE INDEX IF NOT EXISTS brain_audience_source_dependency_source_idx ON brain_audience_source_dependencies (source_id, audience_id)`,
475
+ ].join(";\n"),
476
+ },
273
477
  ],
274
478
  { table: "brain_migrations" },
275
479
  );
@@ -1,5 +1,7 @@
1
1
  import { registerRequiredSecret } from "@agent-native/core/secrets";
2
2
 
3
+ import "./onboarding.js";
4
+
3
5
  registerRequiredSecret({
4
6
  key: "SLACK_BOT_TOKEN",
5
7
  label: "Slack Bot Token (local fallback)",
@@ -11,6 +13,17 @@ registerRequiredSecret({
11
13
  required: false,
12
14
  });
13
15
 
16
+ registerRequiredSecret({
17
+ key: "SLACK_SIGNING_SECRET",
18
+ label: "Slack Signing Secret",
19
+ description:
20
+ "Optional for Slack Events API delivery. Brain verifies signed events before refreshing an allow-listed channel thread.",
21
+ docsUrl: "https://api.slack.com/authentication/verifying-requests-from-slack",
22
+ scope: "workspace",
23
+ kind: "api-key",
24
+ required: false,
25
+ });
26
+
14
27
  registerRequiredSecret({
15
28
  key: "GRANOLA_API_KEY",
16
29
  label: "Granola Enterprise API Key",
@@ -34,3 +47,36 @@ registerRequiredSecret({
34
47
  kind: "api-key",
35
48
  required: false,
36
49
  });
50
+
51
+ registerRequiredSecret({
52
+ key: "GEMINI_API_KEY",
53
+ label: "Gemini API Key",
54
+ description:
55
+ "Optional shared embedding provider for Brain semantic retrieval. Lexical search remains available without it.",
56
+ docsUrl: "https://aistudio.google.com/apikey",
57
+ scope: "workspace",
58
+ kind: "api-key",
59
+ required: false,
60
+ });
61
+
62
+ registerRequiredSecret({
63
+ key: "COHERE_API_KEY",
64
+ label: "Cohere API Key",
65
+ description:
66
+ "Optional shared embedding provider for Brain semantic retrieval. Lexical search remains available without it.",
67
+ docsUrl: "https://dashboard.cohere.com/api-keys",
68
+ scope: "workspace",
69
+ kind: "api-key",
70
+ required: false,
71
+ });
72
+
73
+ registerRequiredSecret({
74
+ key: "VOYAGE_API_KEY",
75
+ label: "Voyage API Key",
76
+ description:
77
+ "Optional shared embedding provider for Brain semantic retrieval. Lexical search remains available without it.",
78
+ docsUrl: "https://dashboard.voyageai.com/api-keys",
79
+ scope: "workspace",
80
+ kind: "api-key",
81
+ required: false,
82
+ });
@@ -8,6 +8,7 @@ import { z } from "zod";
8
8
 
9
9
  import { getDb, schema } from "../../../../db/index.js";
10
10
  import {
11
+ BrainCaptureBlockedError,
11
12
  createCapture,
12
13
  parseJson,
13
14
  serializeCapture,
@@ -110,22 +111,41 @@ export default defineEventHandler(async (event) => {
110
111
  orgId: source.orgId ?? undefined,
111
112
  },
112
113
  async () => {
113
- const capture = await createCapture({
114
- sourceId: source.id,
115
- externalId: payload.externalId,
116
- title: payload.title,
117
- kind: "transcript",
118
- content: textFromPayload(payload),
119
- capturedAt: payload.occurredAt,
120
- metadata: {
121
- sourceKey: payload.sourceKey,
122
- participants: payload.participants,
123
- segments: payload.segments ?? [],
124
- sourceUrl: payload.sourceUrl,
125
- tags: payload.tags,
126
- raw: payload.raw,
127
- },
128
- });
114
+ let capture;
115
+ try {
116
+ capture = await createCapture({
117
+ sourceId: source.id,
118
+ externalId: payload.externalId,
119
+ title: payload.title,
120
+ kind: "transcript",
121
+ content: textFromPayload(payload),
122
+ capturedAt: payload.occurredAt,
123
+ metadata: {
124
+ sourceKey: payload.sourceKey,
125
+ participants: payload.participants,
126
+ segments: payload.segments ?? [],
127
+ sourceUrl: payload.sourceUrl,
128
+ tags: payload.tags,
129
+ raw: payload.raw,
130
+ },
131
+ audience: {
132
+ kind: "meeting",
133
+ memberEmails: payload.participants.filter(
134
+ (participant): participant is string =>
135
+ typeof participant === "string",
136
+ ),
137
+ upstreamRefHash: payload.externalId,
138
+ },
139
+ });
140
+ } catch (error) {
141
+ if (!(error instanceof BrainCaptureBlockedError)) throw error;
142
+ return {
143
+ ok: true,
144
+ sourceId: source.id,
145
+ capture: null,
146
+ sensitivityReceipt: error.receipt,
147
+ };
148
+ }
129
149
 
130
150
  return {
131
151
  ok: true,
@@ -0,0 +1,28 @@
1
+ import {
2
+ defineEventHandler,
3
+ getHeader,
4
+ readRawBody,
5
+ setResponseStatus,
6
+ } from "h3";
7
+
8
+ import { enqueueSlackThreadRefreshFromEvent } from "../../../../lib/slack-events.js";
9
+
10
+ export default defineEventHandler(async (event) => {
11
+ const rawBody = (await readRawBody(event)) ?? "";
12
+ const result = await enqueueSlackThreadRefreshFromEvent({
13
+ rawBody,
14
+ timestamp: getHeader(event, "x-slack-request-timestamp"),
15
+ signature: getHeader(event, "x-slack-signature"),
16
+ });
17
+
18
+ if (result.status === "invalid") {
19
+ setResponseStatus(event, 401);
20
+ return { ok: false, error: "invalid Slack signature or payload" };
21
+ }
22
+ if (result.status === "missing-signing-secret") {
23
+ setResponseStatus(event, 503);
24
+ return { ok: false, error: "Slack signing secret is not configured" };
25
+ }
26
+ if (result.challenge) return result.challenge;
27
+ return { ok: true };
28
+ });
@@ -62,6 +62,11 @@ export interface BrainSettings {
62
62
  captureSanitizationEnabled?: boolean;
63
63
  captureSanitizationModel?: string;
64
64
  captureSanitizationInstructions?: string;
65
+ privacyClassifierModel?: string;
66
+ privacyClassifierEngine?: string;
67
+ sensitivityCustomInstructions?: string;
68
+ publicChannelExclusionPatterns?: string[];
69
+ quarantineRetentionHours?: number;
65
70
  connectorPollMinutes: number;
66
71
  requireCitations?: boolean;
67
72
  autoArchiveResolved?: boolean;
@@ -82,6 +87,11 @@ export const DEFAULT_BRAIN_SETTINGS: BrainSettings = {
82
87
  captureSanitizationModel: "",
83
88
  captureSanitizationInstructions:
84
89
  "Keep durable company-relevant information and remove personal, recruiting, hiring, candidate-evaluation, sensitive, or casual content before storage.",
90
+ privacyClassifierModel: "",
91
+ privacyClassifierEngine: "",
92
+ sensitivityCustomInstructions: "",
93
+ publicChannelExclusionPatterns: [],
94
+ quarantineRetentionHours: 72,
85
95
  connectorPollMinutes: 60,
86
96
  requireCitations: true,
87
97
  autoArchiveResolved: true,
@@ -15,6 +15,10 @@ export interface ExecuteCodeAgentRunOptions {
15
15
  stdout?: NodeJS.WritableStream;
16
16
  signal?: AbortSignal;
17
17
  }
18
+ interface CodeAgentApprovalExecutionOptions {
19
+ stdout?: NodeJS.WritableStream;
20
+ signal?: AbortSignal;
21
+ }
18
22
  export declare function executeCodeAgentRun(options: ExecuteCodeAgentRunOptions): Promise<CodeAgentRunRecord | null>;
19
23
  export declare function codeAgentMcpInvocationPolicy(permissionMode: CodeAgentPermissionMode): McpToolInvocationPolicy;
20
24
  export declare function executeExistingCodeAgentRun(runId: string, options?: Omit<ExecuteCodeAgentRunOptions, "runId">): Promise<CodeAgentRunRecord | null>;
@@ -23,20 +27,14 @@ export declare function executeExistingCodeAgentRun(runId: string, options?: Omi
23
27
  * and auto-resume. Future occurrences of this exact command will bypass the
24
28
  * approval gate without prompting.
25
29
  */
26
- export declare function executeApproveAlwaysCodeAgentApproval(runId: string, options?: {
27
- stdout?: NodeJS.WritableStream;
28
- }): Promise<CodeAgentRunRecord | null>;
29
- export declare function executePendingCodeAgentApproval(runId: string, options?: {
30
- stdout?: NodeJS.WritableStream;
31
- }): Promise<CodeAgentRunRecord | null>;
30
+ export declare function executeApproveAlwaysCodeAgentApproval(runId: string, options?: CodeAgentApprovalExecutionOptions): Promise<CodeAgentRunRecord | null>;
31
+ export declare function executePendingCodeAgentApproval(runId: string, options?: CodeAgentApprovalExecutionOptions): Promise<CodeAgentRunRecord | null>;
32
32
  /**
33
33
  * Deny a pending approval: record the denial, feed it back to the model as a
34
34
  * "command denied by user" result, and immediately resume the run so the model
35
35
  * can adapt its plan without leaving the run dangling.
36
36
  */
37
- export declare function executeDenyCodeAgentApproval(runId: string, options?: {
38
- stdout?: NodeJS.WritableStream;
39
- }): Promise<CodeAgentRunRecord | null>;
37
+ export declare function executeDenyCodeAgentApproval(runId: string, options?: CodeAgentApprovalExecutionOptions): Promise<CodeAgentRunRecord | null>;
40
38
  /**
41
39
  * Reconstruct a sequence of EngineMessage objects from transcript events,
42
40
  * preserving the native tool-call / tool-result pair structure that models
@@ -86,4 +84,5 @@ export type CodeAgentCommandPermission = {
86
84
  };
87
85
  export declare function classifyCodeAgentCommandPermission(command: string): CodeAgentCommandPermission;
88
86
  export declare function writeCodeAgentUsageSnapshot(cwd: string, usage: AgentLoopUsage | null): void;
87
+ export {};
89
88
  //# sourceMappingURL=code-agent-executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-agent-executor.d.ts","sourceRoot":"","sources":["../../src/cli/code-agent-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-agent-executor.d.ts","sourceRoot":"","sources":["../../src/cli/code-agent-executor.ts"],"names":[],"mappings":"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"}
@@ -729,7 +729,7 @@ export async function executePendingCodeAgentApproval(runId, options = {}) {
729
729
  command: approval.command,
730
730
  },
731
731
  });
732
- const result = await runCodingCommand(approval.command, record.cwd || process.cwd(), DEFAULT_COMMAND_TIMEOUT_MS);
732
+ const result = await runCodingCommand(approval.command, record.cwd || process.cwd(), DEFAULT_COMMAND_TIMEOUT_MS, { signal: options.signal });
733
733
  const summary = truncateCodingOutput([
734
734
  `Approved command finished with exit code ${result.code}.`,
735
735
  result.timedOut ? "Timed out: true" : "",
@@ -772,7 +772,10 @@ export async function executePendingCodeAgentApproval(runId, options = {}) {
772
772
  message: "Resuming run after approval.",
773
773
  metadata: { status: "running", phase: "approval-resuming" },
774
774
  });
775
- return executeExistingCodeAgentRun(runId, { stdout: options.stdout });
775
+ return executeExistingCodeAgentRun(runId, {
776
+ stdout: options.stdout,
777
+ signal: options.signal,
778
+ });
776
779
  }
777
780
  /**
778
781
  * Deny a pending approval: record the denial, feed it back to the model as a
@@ -820,7 +823,10 @@ export async function executeDenyCodeAgentApproval(runId, options = {}) {
820
823
  message: "Resuming run after denial — model will adapt its plan.",
821
824
  metadata: { status: "running", phase: "approval-denied-resuming" },
822
825
  });
823
- return executeExistingCodeAgentRun(runId, { stdout: options.stdout });
826
+ return executeExistingCodeAgentRun(runId, {
827
+ stdout: options.stdout,
828
+ signal: options.signal,
829
+ });
824
830
  }
825
831
  function latestUserPrompt(runId) {
826
832
  const events = listCodeAgentTranscriptEvents(runId);