@agent-native/core 0.161.23 → 0.163.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/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +18 -2
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/calendar/server/handlers/google-auth.ts +1 -8
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +88 -35
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +36 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +4 -3
- package/corpus/templates/clips/app/lib/camera-composite.ts +15 -1
- package/corpus/templates/clips/changelog/2026-08-18-clips-no-longer-crashes-when-a-camera-bubble-starts-at-a-tin.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +30 -40
- package/corpus/templates/clips/desktop/src/components/MicOffConfirmation.tsx +47 -0
- package/corpus/templates/clips/desktop/src/styles.css +110 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +114 -7
- package/corpus/templates/clips/shared/recording-capture.ts +18 -13
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/content/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/content/actions/create-content-database.ts +1 -1
- package/corpus/templates/content/actions/create-document.ts +1 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -5
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +0 -3
- package/corpus/templates/content/app/components/editor/NotionConflictBanner.tsx +0 -4
- package/corpus/templates/content/app/components/editor/NotionSyncBar.tsx +4 -1
- package/corpus/templates/content/app/hooks/use-notion.ts +17 -15
- package/corpus/templates/crm/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/design/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/design/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +6 -1
- package/corpus/templates/dispatch/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/factory/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/macros/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +18 -3
- package/corpus/templates/mail/server/handlers/google-auth.ts +1 -8
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +4 -0
- package/corpus/templates/slides/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +27 -2
- package/corpus/templates/slides/actions/_await-fit-check.ts +30 -5
- package/corpus/templates/slides/actions/add-slide.ts +6 -2
- package/corpus/templates/slides/actions/create-deck.ts +2 -1
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +3 -3
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +3 -3
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +3 -1
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +1 -1
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +35 -2
- package/corpus/templates/slides/app/routes/p.$id.tsx +3 -1
- package/corpus/templates/slides/changelog/2026-08-18-generated-slides-preserve-speaker-notes.md +6 -0
- package/corpus/templates/slides/server/handlers/assets.ts +23 -12
- package/corpus/templates/slides/server/handlers/design-system-decode-job-status.ts +15 -6
- package/corpus/templates/slides/server/handlers/design-system-upload-start.ts +15 -6
- package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +34 -19
- package/corpus/templates/slides/server/handlers/request-auth-context.ts +1 -0
- package/corpus/templates/slides/server/handlers/share.ts +1 -1
- package/corpus/templates/slides/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/slides/server/routes/api/deck-agent-context.json.get.ts +1 -1
- package/corpus/templates/slides/server/routes/api/exports/[filename].get.ts +9 -3
- package/corpus/templates/slides/server/routes/api/exports/google-slides.post.ts +12 -5
- package/corpus/templates/slides/server/routes/api/exports/html.post.ts +9 -7
- package/corpus/templates/slides/server/routes/api/exports/pptx.post.ts +9 -7
- package/corpus/templates/slides/shared/api.ts +7 -1
- package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +27 -2
- package/dist/agent/engine/translate-anthropic.js +27 -2
- package/dist/agent/production-agent.d.ts +2 -2
- package/dist/agent/production-agent.js +16 -8
- package/dist/agent/thread-data-builder.d.ts +1 -0
- package/dist/agent/thread-data-builder.js +6 -4
- package/dist/agent/tool-approval-store.d.ts +10 -1
- package/dist/agent/tool-approval-store.js +19 -2
- package/dist/agent/types.d.ts +9 -0
- package/dist/app-config/schema.d.ts +1 -0
- package/dist/app-config/workspace.d.ts +1 -0
- package/dist/app-config/workspace.js +8 -0
- package/dist/chat-threads/schema.d.ts +2 -2
- package/dist/client/AssistantChat.js +14 -6
- package/dist/client/EnvironmentBadge.d.ts +15 -0
- package/dist/client/EnvironmentBadge.js +79 -0
- package/dist/client/MultiTabAssistantChat.js +73 -17
- package/dist/client/agent-chat-adapter.js +11 -1
- package/dist/client/api-path.js +14 -1
- package/dist/client/app-providers.js +2 -1
- package/dist/client/chat/tool-call-display.d.ts +12 -2
- package/dist/client/chat/tool-call-display.js +17 -7
- package/dist/client/chat/widgets/WorkspaceFileWidget.js +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts +6 -0
- package/dist/client/chat/widgets/builtin-tool-renderers.js +19 -0
- package/dist/client/onboarding/FirstRunOnboarding.js +46 -32
- package/dist/client/onboarding/use-onboarding.d.ts +8 -1
- package/dist/client/onboarding/use-onboarding.js +22 -7
- package/dist/client/org/TeamPage.js +15 -2
- package/dist/client/org/hooks.d.ts +2 -0
- package/dist/client/org/hooks.js +12 -0
- package/dist/client/org/index.d.ts +2 -2
- package/dist/client/org/index.js +1 -1
- package/dist/client/session-replay.js +58 -15
- package/dist/client/settings/SettingsTabsPage.js +19 -6
- package/dist/client/sharing/ShareButton.js +43 -18
- package/dist/client/sharing/useShareButtonController.d.ts +12 -2
- package/dist/client/sharing/useShareButtonController.js +38 -8
- package/dist/client/sse-event-processor.d.ts +7 -0
- package/dist/client/sse-event-processor.js +4 -1
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/client/use-action.js +26 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/config.d.ts +15 -0
- package/dist/config.js +53 -0
- package/dist/dashboard-storage/schema.d.ts +2 -2
- package/dist/data-programs/schema.d.ts +2 -2
- package/dist/extensions/fetch-tool.js +8 -2
- package/dist/extensions/schema.d.ts +2 -2
- package/dist/extensions/store.js +3 -0
- package/dist/localization/core-messages/ar-SA.js +1 -0
- package/dist/localization/core-messages/de-DE.js +1 -0
- package/dist/localization/core-messages/en-US.d.ts +1 -0
- package/dist/localization/core-messages/en-US.js +1 -0
- package/dist/localization/core-messages/es-ES.js +1 -0
- package/dist/localization/core-messages/fr-FR.js +1 -0
- package/dist/localization/core-messages/hi-IN.js +1 -0
- package/dist/localization/core-messages/ja-JP.js +1 -0
- package/dist/localization/core-messages/ko-KR.js +1 -0
- package/dist/localization/core-messages/pt-BR.js +1 -0
- package/dist/localization/core-messages/zh-CN.js +1 -0
- package/dist/localization/core-messages/zh-TW.js +1 -0
- package/dist/localization/core-messages.d.ts +1 -0
- package/dist/localization/default-messages.d.ts +4 -0
- package/dist/localization/default-messages.js +4 -0
- package/dist/mcp/embed-app.js +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/org/handlers.d.ts +6 -1
- package/dist/org/handlers.js +43 -0
- package/dist/org/index.d.ts +3 -3
- package/dist/org/index.js +2 -2
- package/dist/org/migrations.js +33 -0
- package/dist/org/plugin.js +10 -1
- package/dist/org/schema.d.ts +315 -0
- package/dist/org/schema.js +20 -1
- package/dist/org/types.d.ts +3 -0
- package/dist/org/workspace-app-access.d.ts +10 -0
- package/dist/org/workspace-app-access.js +179 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/index.d.ts +10 -0
- package/dist/provider-api/index.js +45 -9
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +24 -4
- package/dist/server/poll.js +13 -3
- package/dist/server/sentry.d.ts +1 -1
- package/dist/sharing/access.d.ts +2 -2
- package/dist/sharing/access.js +56 -3
- package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
- package/dist/sharing/actions/list-resource-shares.js +26 -1
- package/dist/sharing/actions/share-resource.d.ts +1 -1
- package/dist/sharing/actions/share-resource.js +23 -4
- package/dist/sharing/actions/unshare-resource.d.ts +1 -1
- package/dist/sharing/actions/unshare-resource.js +1 -1
- package/dist/sharing/registry.d.ts +12 -0
- package/dist/sharing/schema.d.ts +4 -4
- package/dist/sharing/schema.js +2 -2
- package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/chat/.agents/skills/sharing/SKILL.md +27 -2
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/default/.agents/skills/sharing/SKILL.md +27 -2
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +27 -2
- package/dist/vite/client.d.ts +5 -0
- package/dist/vite/client.js +64 -2
- package/dist/workspace-connections/actions/list-workspace-user-groups.d.ts +9 -1
- package/dist/workspace-connections/actions/list-workspace-user-groups.js +9 -4
- package/dist/workspace-connections/groups.d.ts +2 -0
- package/dist/workspace-connections/groups.js +16 -5
- package/dist/workspace-files/actions.d.ts +1 -8
- package/dist/workspace-files/actions.js +5 -21
- package/dist/workspace-files/index.d.ts +1 -1
- package/dist/workspace-files/index.js +1 -1
- package/dist/workspace-files/store.d.ts +18 -0
- package/dist/workspace-files/store.js +24 -3
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/chat/.agents/skills/sharing/SKILL.md +27 -2
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/default/.agents/skills/sharing/SKILL.md +27 -2
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +27 -2
package/dist/org/schema.d.ts
CHANGED
|
@@ -536,3 +536,318 @@ export declare const orgInvitations: import("drizzle-orm/sqlite-core").SQLiteTab
|
|
|
536
536
|
};
|
|
537
537
|
dialect: 'sqlite';
|
|
538
538
|
}>;
|
|
539
|
+
/** Workspace app access is framework-owned so every mounted app can enforce it. */
|
|
540
|
+
export declare const workspaceApps: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
541
|
+
name: "workspace_apps";
|
|
542
|
+
schema: undefined;
|
|
543
|
+
columns: {
|
|
544
|
+
ownerEmail: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
545
|
+
name: "owner_email";
|
|
546
|
+
tableName: "workspace_apps";
|
|
547
|
+
dataType: "string";
|
|
548
|
+
columnType: "SQLiteText";
|
|
549
|
+
data: string;
|
|
550
|
+
driverParam: string;
|
|
551
|
+
notNull: true;
|
|
552
|
+
hasDefault: true;
|
|
553
|
+
isPrimaryKey: false;
|
|
554
|
+
isAutoincrement: false;
|
|
555
|
+
hasRuntimeDefault: false;
|
|
556
|
+
enumValues: [string, ...string[]];
|
|
557
|
+
baseColumn: never;
|
|
558
|
+
identity: undefined;
|
|
559
|
+
generated: undefined;
|
|
560
|
+
}, {}, {
|
|
561
|
+
length: number;
|
|
562
|
+
}>;
|
|
563
|
+
orgId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
564
|
+
name: "org_id";
|
|
565
|
+
tableName: "workspace_apps";
|
|
566
|
+
dataType: "string";
|
|
567
|
+
columnType: "SQLiteText";
|
|
568
|
+
data: string;
|
|
569
|
+
driverParam: string;
|
|
570
|
+
notNull: false;
|
|
571
|
+
hasDefault: false;
|
|
572
|
+
isPrimaryKey: false;
|
|
573
|
+
isAutoincrement: false;
|
|
574
|
+
hasRuntimeDefault: false;
|
|
575
|
+
enumValues: [string, ...string[]];
|
|
576
|
+
baseColumn: never;
|
|
577
|
+
identity: undefined;
|
|
578
|
+
generated: undefined;
|
|
579
|
+
}, {}, {
|
|
580
|
+
length: number;
|
|
581
|
+
}>;
|
|
582
|
+
id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
583
|
+
name: "id";
|
|
584
|
+
tableName: "workspace_apps";
|
|
585
|
+
dataType: "string";
|
|
586
|
+
columnType: "SQLiteText";
|
|
587
|
+
data: string;
|
|
588
|
+
driverParam: string;
|
|
589
|
+
notNull: true;
|
|
590
|
+
hasDefault: false;
|
|
591
|
+
isPrimaryKey: true;
|
|
592
|
+
isAutoincrement: false;
|
|
593
|
+
hasRuntimeDefault: false;
|
|
594
|
+
enumValues: [string, ...string[]];
|
|
595
|
+
baseColumn: never;
|
|
596
|
+
identity: undefined;
|
|
597
|
+
generated: undefined;
|
|
598
|
+
}, {}, {
|
|
599
|
+
length: number;
|
|
600
|
+
}>;
|
|
601
|
+
visibility: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
602
|
+
name: "visibility";
|
|
603
|
+
tableName: "workspace_apps";
|
|
604
|
+
dataType: "string";
|
|
605
|
+
columnType: "SQLiteText";
|
|
606
|
+
data: "org" | "private" | "public";
|
|
607
|
+
driverParam: string;
|
|
608
|
+
notNull: true;
|
|
609
|
+
hasDefault: true;
|
|
610
|
+
isPrimaryKey: false;
|
|
611
|
+
isAutoincrement: false;
|
|
612
|
+
hasRuntimeDefault: false;
|
|
613
|
+
enumValues: ["private", "org", "public"];
|
|
614
|
+
baseColumn: never;
|
|
615
|
+
identity: undefined;
|
|
616
|
+
generated: undefined;
|
|
617
|
+
}, {}, {
|
|
618
|
+
length: number;
|
|
619
|
+
}>;
|
|
620
|
+
name: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
621
|
+
name: "name";
|
|
622
|
+
tableName: "workspace_apps";
|
|
623
|
+
dataType: "string";
|
|
624
|
+
columnType: "SQLiteText";
|
|
625
|
+
data: string;
|
|
626
|
+
driverParam: string;
|
|
627
|
+
notNull: true;
|
|
628
|
+
hasDefault: false;
|
|
629
|
+
isPrimaryKey: false;
|
|
630
|
+
isAutoincrement: false;
|
|
631
|
+
hasRuntimeDefault: false;
|
|
632
|
+
enumValues: [string, ...string[]];
|
|
633
|
+
baseColumn: never;
|
|
634
|
+
identity: undefined;
|
|
635
|
+
generated: undefined;
|
|
636
|
+
}, {}, {
|
|
637
|
+
length: number;
|
|
638
|
+
}>;
|
|
639
|
+
description: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
640
|
+
name: "description";
|
|
641
|
+
tableName: "workspace_apps";
|
|
642
|
+
dataType: "string";
|
|
643
|
+
columnType: "SQLiteText";
|
|
644
|
+
data: string;
|
|
645
|
+
driverParam: string;
|
|
646
|
+
notNull: false;
|
|
647
|
+
hasDefault: false;
|
|
648
|
+
isPrimaryKey: false;
|
|
649
|
+
isAutoincrement: false;
|
|
650
|
+
hasRuntimeDefault: false;
|
|
651
|
+
enumValues: [string, ...string[]];
|
|
652
|
+
baseColumn: never;
|
|
653
|
+
identity: undefined;
|
|
654
|
+
generated: undefined;
|
|
655
|
+
}, {}, {
|
|
656
|
+
length: number;
|
|
657
|
+
}>;
|
|
658
|
+
path: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
659
|
+
name: "path";
|
|
660
|
+
tableName: "workspace_apps";
|
|
661
|
+
dataType: "string";
|
|
662
|
+
columnType: "SQLiteText";
|
|
663
|
+
data: string;
|
|
664
|
+
driverParam: string;
|
|
665
|
+
notNull: true;
|
|
666
|
+
hasDefault: false;
|
|
667
|
+
isPrimaryKey: false;
|
|
668
|
+
isAutoincrement: false;
|
|
669
|
+
hasRuntimeDefault: false;
|
|
670
|
+
enumValues: [string, ...string[]];
|
|
671
|
+
baseColumn: never;
|
|
672
|
+
identity: undefined;
|
|
673
|
+
generated: undefined;
|
|
674
|
+
}, {}, {
|
|
675
|
+
length: number;
|
|
676
|
+
}>;
|
|
677
|
+
createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
678
|
+
name: "created_at";
|
|
679
|
+
tableName: "workspace_apps";
|
|
680
|
+
dataType: "number";
|
|
681
|
+
columnType: "SQLiteInteger";
|
|
682
|
+
data: number;
|
|
683
|
+
driverParam: number;
|
|
684
|
+
notNull: true;
|
|
685
|
+
hasDefault: false;
|
|
686
|
+
isPrimaryKey: false;
|
|
687
|
+
isAutoincrement: false;
|
|
688
|
+
hasRuntimeDefault: false;
|
|
689
|
+
enumValues: undefined;
|
|
690
|
+
baseColumn: never;
|
|
691
|
+
identity: undefined;
|
|
692
|
+
generated: undefined;
|
|
693
|
+
}, {}, {}>;
|
|
694
|
+
updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
695
|
+
name: "updated_at";
|
|
696
|
+
tableName: "workspace_apps";
|
|
697
|
+
dataType: "number";
|
|
698
|
+
columnType: "SQLiteInteger";
|
|
699
|
+
data: number;
|
|
700
|
+
driverParam: number;
|
|
701
|
+
notNull: true;
|
|
702
|
+
hasDefault: false;
|
|
703
|
+
isPrimaryKey: false;
|
|
704
|
+
isAutoincrement: false;
|
|
705
|
+
hasRuntimeDefault: false;
|
|
706
|
+
enumValues: undefined;
|
|
707
|
+
baseColumn: never;
|
|
708
|
+
identity: undefined;
|
|
709
|
+
generated: undefined;
|
|
710
|
+
}, {}, {}>;
|
|
711
|
+
};
|
|
712
|
+
dialect: 'sqlite';
|
|
713
|
+
}>;
|
|
714
|
+
export declare const workspaceAppShares: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
715
|
+
name: string;
|
|
716
|
+
schema: undefined;
|
|
717
|
+
columns: {
|
|
718
|
+
id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
719
|
+
name: "id";
|
|
720
|
+
tableName: string;
|
|
721
|
+
dataType: "string";
|
|
722
|
+
columnType: "SQLiteText";
|
|
723
|
+
data: string;
|
|
724
|
+
driverParam: string;
|
|
725
|
+
notNull: true;
|
|
726
|
+
hasDefault: false;
|
|
727
|
+
isPrimaryKey: true;
|
|
728
|
+
isAutoincrement: false;
|
|
729
|
+
hasRuntimeDefault: false;
|
|
730
|
+
enumValues: [string, ...string[]];
|
|
731
|
+
baseColumn: never;
|
|
732
|
+
identity: undefined;
|
|
733
|
+
generated: undefined;
|
|
734
|
+
}, {}, {
|
|
735
|
+
length: number;
|
|
736
|
+
}>;
|
|
737
|
+
resourceId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
738
|
+
name: "resource_id";
|
|
739
|
+
tableName: string;
|
|
740
|
+
dataType: "string";
|
|
741
|
+
columnType: "SQLiteText";
|
|
742
|
+
data: string;
|
|
743
|
+
driverParam: string;
|
|
744
|
+
notNull: true;
|
|
745
|
+
hasDefault: false;
|
|
746
|
+
isPrimaryKey: false;
|
|
747
|
+
isAutoincrement: false;
|
|
748
|
+
hasRuntimeDefault: false;
|
|
749
|
+
enumValues: [string, ...string[]];
|
|
750
|
+
baseColumn: never;
|
|
751
|
+
identity: undefined;
|
|
752
|
+
generated: undefined;
|
|
753
|
+
}, {}, {
|
|
754
|
+
length: number;
|
|
755
|
+
}>;
|
|
756
|
+
principalType: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
757
|
+
name: "principal_type";
|
|
758
|
+
tableName: string;
|
|
759
|
+
dataType: "string";
|
|
760
|
+
columnType: "SQLiteText";
|
|
761
|
+
data: "group" | "org" | "user";
|
|
762
|
+
driverParam: string;
|
|
763
|
+
notNull: true;
|
|
764
|
+
hasDefault: false;
|
|
765
|
+
isPrimaryKey: false;
|
|
766
|
+
isAutoincrement: false;
|
|
767
|
+
hasRuntimeDefault: false;
|
|
768
|
+
enumValues: ["user", "group", "org"];
|
|
769
|
+
baseColumn: never;
|
|
770
|
+
identity: undefined;
|
|
771
|
+
generated: undefined;
|
|
772
|
+
}, {}, {
|
|
773
|
+
length: number;
|
|
774
|
+
}>;
|
|
775
|
+
principalId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
776
|
+
name: "principal_id";
|
|
777
|
+
tableName: string;
|
|
778
|
+
dataType: "string";
|
|
779
|
+
columnType: "SQLiteText";
|
|
780
|
+
data: string;
|
|
781
|
+
driverParam: string;
|
|
782
|
+
notNull: true;
|
|
783
|
+
hasDefault: false;
|
|
784
|
+
isPrimaryKey: false;
|
|
785
|
+
isAutoincrement: false;
|
|
786
|
+
hasRuntimeDefault: false;
|
|
787
|
+
enumValues: [string, ...string[]];
|
|
788
|
+
baseColumn: never;
|
|
789
|
+
identity: undefined;
|
|
790
|
+
generated: undefined;
|
|
791
|
+
}, {}, {
|
|
792
|
+
length: number;
|
|
793
|
+
}>;
|
|
794
|
+
role: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
795
|
+
name: "role";
|
|
796
|
+
tableName: string;
|
|
797
|
+
dataType: "string";
|
|
798
|
+
columnType: "SQLiteText";
|
|
799
|
+
data: "admin" | "commenter" | "editor" | "viewer";
|
|
800
|
+
driverParam: string;
|
|
801
|
+
notNull: true;
|
|
802
|
+
hasDefault: true;
|
|
803
|
+
isPrimaryKey: false;
|
|
804
|
+
isAutoincrement: false;
|
|
805
|
+
hasRuntimeDefault: false;
|
|
806
|
+
enumValues: ["viewer", "commenter", "editor", "admin"];
|
|
807
|
+
baseColumn: never;
|
|
808
|
+
identity: undefined;
|
|
809
|
+
generated: undefined;
|
|
810
|
+
}, {}, {
|
|
811
|
+
length: number;
|
|
812
|
+
}>;
|
|
813
|
+
createdBy: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
814
|
+
name: "created_by";
|
|
815
|
+
tableName: string;
|
|
816
|
+
dataType: "string";
|
|
817
|
+
columnType: "SQLiteText";
|
|
818
|
+
data: string;
|
|
819
|
+
driverParam: string;
|
|
820
|
+
notNull: true;
|
|
821
|
+
hasDefault: true;
|
|
822
|
+
isPrimaryKey: false;
|
|
823
|
+
isAutoincrement: false;
|
|
824
|
+
hasRuntimeDefault: false;
|
|
825
|
+
enumValues: [string, ...string[]];
|
|
826
|
+
baseColumn: never;
|
|
827
|
+
identity: undefined;
|
|
828
|
+
generated: undefined;
|
|
829
|
+
}, {}, {
|
|
830
|
+
length: number;
|
|
831
|
+
}>;
|
|
832
|
+
createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
833
|
+
name: "created_at";
|
|
834
|
+
tableName: string;
|
|
835
|
+
dataType: "string";
|
|
836
|
+
columnType: "SQLiteText";
|
|
837
|
+
data: string;
|
|
838
|
+
driverParam: string;
|
|
839
|
+
notNull: true;
|
|
840
|
+
hasDefault: true;
|
|
841
|
+
isPrimaryKey: false;
|
|
842
|
+
isAutoincrement: false;
|
|
843
|
+
hasRuntimeDefault: false;
|
|
844
|
+
enumValues: [string, ...string[]];
|
|
845
|
+
baseColumn: never;
|
|
846
|
+
identity: undefined;
|
|
847
|
+
generated: undefined;
|
|
848
|
+
}, {}, {
|
|
849
|
+
length: number;
|
|
850
|
+
}>;
|
|
851
|
+
};
|
|
852
|
+
dialect: 'sqlite';
|
|
853
|
+
}>;
|
package/dist/org/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { table, text, integer } from "../db/schema.js";
|
|
1
|
+
import { table, text, integer, ownableColumns, createSharesTable, } from "../db/schema.js";
|
|
2
2
|
export const organizations = table("organizations", {
|
|
3
3
|
id: text("id").primaryKey(),
|
|
4
4
|
name: text("name").notNull(),
|
|
@@ -39,3 +39,22 @@ export const orgInvitations = table("org_invitations", {
|
|
|
39
39
|
status: text("status").notNull(),
|
|
40
40
|
role: text("role"),
|
|
41
41
|
});
|
|
42
|
+
/** Workspace app access is framework-owned so every mounted app can enforce it. */
|
|
43
|
+
export const workspaceApps = table("workspace_apps", {
|
|
44
|
+
id: text("id").primaryKey(),
|
|
45
|
+
...ownableColumns(),
|
|
46
|
+
// Workspace apps are visible to their organization by default. The generic
|
|
47
|
+
// ownable primitive remains private-by-default for user-created resources;
|
|
48
|
+
// app creation is a deliberate workspace-level exception.
|
|
49
|
+
visibility: text("visibility", {
|
|
50
|
+
enum: ["private", "org", "public"],
|
|
51
|
+
})
|
|
52
|
+
.notNull()
|
|
53
|
+
.default("org"),
|
|
54
|
+
name: text("name").notNull(),
|
|
55
|
+
description: text("description"),
|
|
56
|
+
path: text("path").notNull(),
|
|
57
|
+
createdAt: integer("created_at").notNull(),
|
|
58
|
+
updatedAt: integer("updated_at").notNull(),
|
|
59
|
+
});
|
|
60
|
+
export const workspaceAppShares = createSharesTable("workspace_app_shares");
|
package/dist/org/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type OrgRole = "owner" | "admin" | "member";
|
|
5
5
|
export type RequiredAuthProvider = "google" | null;
|
|
6
|
+
export type WorkspaceAppDefaultVisibility = "private" | "org";
|
|
6
7
|
export interface OrgContext {
|
|
7
8
|
email: string;
|
|
8
9
|
orgId: string | null;
|
|
@@ -43,6 +44,8 @@ export interface OrgInfo {
|
|
|
43
44
|
workspaceUrl: string | null;
|
|
44
45
|
/** Sign-in provider required for members of the active org. */
|
|
45
46
|
requiredAuthProvider: RequiredAuthProvider;
|
|
47
|
+
/** Default visibility applied when a new workspace app is first registered. */
|
|
48
|
+
workspaceAppDefaultVisibility?: WorkspaceAppDefaultVisibility;
|
|
46
49
|
/**
|
|
47
50
|
* Whether the active org has an A2A secret. The value itself is never part
|
|
48
51
|
* of this payload — owners/admins fetch it on demand from
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface WorkspaceAppAccessContext {
|
|
2
|
+
email: string;
|
|
3
|
+
orgId?: string | null;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Enforce the workspace-app ACL before a hosted app's authenticated API
|
|
7
|
+
* surface is reached. The app shell remains cacheable and anonymous; this
|
|
8
|
+
* check protects the session-backed APIs/actions that make the app useful.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isWorkspaceAppAccessAllowed(appId: string, context: WorkspaceAppAccessContext): Promise<boolean>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { signA2AToken } from "../a2a/client.js";
|
|
2
|
+
import { getAppConfig } from "../app-config/index.js";
|
|
3
|
+
import { getDbExec } from "../db/client.js";
|
|
4
|
+
import { workspaceUserGroupsIncludeUser } from "../workspace-connections/groups.js";
|
|
5
|
+
import { getOrgA2ASecret, getOrgDomain } from "./context.js";
|
|
6
|
+
const WORKSPACE_APPS_ACTION_PATH = "/_agent-native/actions/list-workspace-apps";
|
|
7
|
+
const WORKSPACE_APP_ACCESS_TIMEOUT_MS = 2_500;
|
|
8
|
+
function normalizedEmail(email) {
|
|
9
|
+
return email.trim().toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
function configuredWorkspaceDirectory() {
|
|
12
|
+
const workspace = getAppConfig().workspace;
|
|
13
|
+
return (workspace.orgDirectoryUrl?.trim() || workspace.gatewayUrl?.trim() || null);
|
|
14
|
+
}
|
|
15
|
+
function workspaceAppsActionUrl(base) {
|
|
16
|
+
try {
|
|
17
|
+
const baseUrl = new URL(base);
|
|
18
|
+
if (baseUrl.protocol !== "http:" && baseUrl.protocol !== "https:") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const basePath = baseUrl.pathname.replace(/\/+$/, "");
|
|
22
|
+
baseUrl.pathname = `${basePath}${WORKSPACE_APPS_ACTION_PATH}`;
|
|
23
|
+
baseUrl.search = "";
|
|
24
|
+
baseUrl.searchParams.set("includeAgentCards", "false");
|
|
25
|
+
baseUrl.searchParams.set("audience", "all");
|
|
26
|
+
baseUrl.hash = "";
|
|
27
|
+
return baseUrl;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// coercion-ok: malformed configured URL is a typed unavailable registry.
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function workspaceAppsFromResponse(value) {
|
|
35
|
+
if (Array.isArray(value))
|
|
36
|
+
return value;
|
|
37
|
+
if (value &&
|
|
38
|
+
typeof value === "object" &&
|
|
39
|
+
Array.isArray(value.apps)) {
|
|
40
|
+
return value.apps;
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Hosted app databases are not the authority for workspace-app rows. Ask the
|
|
46
|
+
* Dispatch registry action, which resolves the ACL against its shared store,
|
|
47
|
+
* so an app-scoped database cannot accidentally turn a missing local row into
|
|
48
|
+
* access. A configured registry is fail-closed on every network/auth error.
|
|
49
|
+
*/
|
|
50
|
+
async function hostedWorkspaceAppAccess(appId, context, email) {
|
|
51
|
+
const configuredDirectory = configuredWorkspaceDirectory();
|
|
52
|
+
if (!configuredDirectory)
|
|
53
|
+
return null;
|
|
54
|
+
const url = workspaceAppsActionUrl(configuredDirectory);
|
|
55
|
+
if (!url)
|
|
56
|
+
return false;
|
|
57
|
+
const orgId = context.orgId?.trim() || null;
|
|
58
|
+
const [orgDomain, orgSecret] = orgId
|
|
59
|
+
? await Promise.all([getOrgDomain(orgId), getOrgA2ASecret(orgId)])
|
|
60
|
+
: [null, null];
|
|
61
|
+
let token;
|
|
62
|
+
try {
|
|
63
|
+
token = await signA2AToken(email, orgDomain?.trim() || undefined, orgSecret?.trim() || undefined, {
|
|
64
|
+
expiresIn: "1m",
|
|
65
|
+
preferGlobalSecret: true,
|
|
66
|
+
...(orgId ? { extraClaims: { org_id: orgId } } : {}),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error("[workspace-app-access] registry token unavailable", error);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeout = setTimeout(() => controller.abort(), WORKSPACE_APP_ACCESS_TIMEOUT_MS);
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(url, {
|
|
77
|
+
headers: {
|
|
78
|
+
accept: "application/json",
|
|
79
|
+
Authorization: `Bearer ${token}`,
|
|
80
|
+
},
|
|
81
|
+
signal: controller.signal,
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok)
|
|
84
|
+
return false;
|
|
85
|
+
const apps = workspaceAppsFromResponse(
|
|
86
|
+
// coercion-ok: malformed registry JSON is an authorization failure.
|
|
87
|
+
await response.json().catch(() => null));
|
|
88
|
+
return apps.some((app) => app.id === appId);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error("[workspace-app-access] registry access check failed", error);
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
clearTimeout(timeout);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Enforce the workspace-app ACL before a hosted app's authenticated API
|
|
100
|
+
* surface is reached. The app shell remains cacheable and anonymous; this
|
|
101
|
+
* check protects the session-backed APIs/actions that make the app useful.
|
|
102
|
+
*/
|
|
103
|
+
export async function isWorkspaceAppAccessAllowed(appId, context) {
|
|
104
|
+
const normalizedAppId = appId.trim();
|
|
105
|
+
const email = normalizedEmail(context.email);
|
|
106
|
+
if (!normalizedAppId || normalizedAppId === "dispatch" || !email) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const hostedAccess = await hostedWorkspaceAppAccess(normalizedAppId, context, email);
|
|
110
|
+
if (hostedAccess !== null)
|
|
111
|
+
return hostedAccess;
|
|
112
|
+
// Standalone/local deployments have no Dispatch registry URL. Keep the
|
|
113
|
+
// direct lookup for that mode, but never let missing or malformed ACL state
|
|
114
|
+
// grant access.
|
|
115
|
+
try {
|
|
116
|
+
const db = getDbExec();
|
|
117
|
+
const appResult = await db.execute({
|
|
118
|
+
sql: `SELECT owner_email, org_id, visibility
|
|
119
|
+
FROM workspace_apps WHERE id = ? LIMIT 1`,
|
|
120
|
+
args: [normalizedAppId],
|
|
121
|
+
});
|
|
122
|
+
const app = appResult.rows[0];
|
|
123
|
+
if (!app)
|
|
124
|
+
return false;
|
|
125
|
+
const ownerEmail = normalizedEmail(typeof app.owner_email === "string" ? app.owner_email : "");
|
|
126
|
+
const resourceOrgId = (typeof app.org_id === "string" ? app.org_id : "").trim() || null;
|
|
127
|
+
const orgId = context.orgId?.trim() || null;
|
|
128
|
+
const sameOrg = !!resourceOrgId && resourceOrgId === orgId;
|
|
129
|
+
if (ownerEmail === email && (!resourceOrgId || sameOrg))
|
|
130
|
+
return true;
|
|
131
|
+
if (!sameOrg || !orgId)
|
|
132
|
+
return false;
|
|
133
|
+
const memberResult = await db.execute({
|
|
134
|
+
sql: `SELECT role FROM org_members
|
|
135
|
+
WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,
|
|
136
|
+
args: [orgId, email],
|
|
137
|
+
});
|
|
138
|
+
if (memberResult.rows.length === 0)
|
|
139
|
+
return false;
|
|
140
|
+
const memberRole = String(memberResult.rows[0]?.role ?? "");
|
|
141
|
+
if (memberRole === "owner" || memberRole === "admin")
|
|
142
|
+
return true;
|
|
143
|
+
if (app.visibility === "org")
|
|
144
|
+
return true;
|
|
145
|
+
if (app.visibility !== "private")
|
|
146
|
+
return false;
|
|
147
|
+
const userShare = await db.execute({
|
|
148
|
+
sql: `SELECT 1 FROM workspace_app_shares
|
|
149
|
+
WHERE resource_id = ? AND principal_type = 'user'
|
|
150
|
+
AND LOWER(principal_id) = ? LIMIT 1`,
|
|
151
|
+
args: [normalizedAppId, email],
|
|
152
|
+
});
|
|
153
|
+
if (userShare.rows.length > 0)
|
|
154
|
+
return true;
|
|
155
|
+
const orgShare = await db.execute({
|
|
156
|
+
sql: `SELECT 1 FROM workspace_app_shares
|
|
157
|
+
WHERE resource_id = ? AND principal_type = 'org'
|
|
158
|
+
AND principal_id = ? LIMIT 1`,
|
|
159
|
+
args: [normalizedAppId, orgId],
|
|
160
|
+
});
|
|
161
|
+
if (orgShare.rows.length > 0)
|
|
162
|
+
return true;
|
|
163
|
+
const groupShares = await db.execute({
|
|
164
|
+
sql: `SELECT principal_id FROM workspace_app_shares
|
|
165
|
+
WHERE resource_id = ? AND principal_type = 'group'`,
|
|
166
|
+
args: [normalizedAppId],
|
|
167
|
+
});
|
|
168
|
+
const groupIds = groupShares.rows
|
|
169
|
+
.map((row) => typeof row.principal_id === "string" ? row.principal_id : "")
|
|
170
|
+
.filter(Boolean);
|
|
171
|
+
return workspaceUserGroupsIncludeUser(resourceOrgId, groupIds, email);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// Missing migrations, missing rows, and every other DB failure deny
|
|
175
|
+
// protected app access until the authoritative ACL is available.
|
|
176
|
+
console.error("[workspace-app-access] access check failed", error);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -77,8 +77,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
78
|
message?: undefined;
|
|
79
79
|
id?: undefined;
|
|
80
|
+
provider?: undefined;
|
|
80
81
|
deleted?: undefined;
|
|
81
|
-
found?: undefined;
|
|
82
82
|
providers: {
|
|
83
83
|
id: string;
|
|
84
84
|
label: string;
|
|
@@ -89,7 +89,7 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
89
89
|
updatedAt: number;
|
|
90
90
|
}[];
|
|
91
91
|
count: number;
|
|
92
|
-
|
|
92
|
+
found?: undefined;
|
|
93
93
|
registered?: undefined;
|
|
94
94
|
label?: undefined;
|
|
95
95
|
} | {
|
|
@@ -105,9 +105,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
105
105
|
} | {
|
|
106
106
|
message?: undefined;
|
|
107
107
|
count?: undefined;
|
|
108
|
+
provider?: undefined;
|
|
108
109
|
deleted?: undefined;
|
|
109
110
|
providers?: undefined;
|
|
110
|
-
provider?: undefined;
|
|
111
111
|
found: boolean;
|
|
112
112
|
id: string;
|
|
113
113
|
registered?: undefined;
|
|
@@ -115,19 +115,19 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
115
115
|
} | {
|
|
116
116
|
message?: undefined;
|
|
117
117
|
count?: undefined;
|
|
118
|
-
found?: undefined;
|
|
119
|
-
providers?: undefined;
|
|
120
118
|
provider?: undefined;
|
|
119
|
+
providers?: undefined;
|
|
120
|
+
found?: undefined;
|
|
121
121
|
deleted: boolean;
|
|
122
122
|
id: string;
|
|
123
123
|
registered?: undefined;
|
|
124
124
|
label?: undefined;
|
|
125
125
|
} | {
|
|
126
126
|
count?: undefined;
|
|
127
|
+
provider?: undefined;
|
|
127
128
|
deleted?: undefined;
|
|
128
|
-
found?: undefined;
|
|
129
129
|
providers?: undefined;
|
|
130
|
-
|
|
130
|
+
found?: undefined;
|
|
131
131
|
registered: boolean;
|
|
132
132
|
id: string;
|
|
133
133
|
label: string;
|
|
@@ -313,8 +313,6 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
313
313
|
}, {
|
|
314
314
|
id?: undefined;
|
|
315
315
|
deleted?: undefined;
|
|
316
|
-
provider?: undefined;
|
|
317
|
-
found?: undefined;
|
|
318
316
|
providers: {
|
|
319
317
|
id: string;
|
|
320
318
|
label: string;
|
|
@@ -325,6 +323,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
325
323
|
updatedAt: number;
|
|
326
324
|
}[];
|
|
327
325
|
count: number;
|
|
326
|
+
provider?: undefined;
|
|
327
|
+
found?: undefined;
|
|
328
328
|
registered?: undefined;
|
|
329
329
|
label?: undefined;
|
|
330
330
|
message?: undefined;
|
|
@@ -340,19 +340,19 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
340
340
|
message?: undefined;
|
|
341
341
|
} | {
|
|
342
342
|
deleted?: undefined;
|
|
343
|
-
provider?: undefined;
|
|
344
343
|
providers?: undefined;
|
|
345
344
|
count?: undefined;
|
|
345
|
+
provider?: undefined;
|
|
346
346
|
found: boolean;
|
|
347
347
|
id: string;
|
|
348
348
|
registered?: undefined;
|
|
349
349
|
label?: undefined;
|
|
350
350
|
message?: undefined;
|
|
351
351
|
} | {
|
|
352
|
-
provider?: undefined;
|
|
353
|
-
found?: undefined;
|
|
354
352
|
providers?: undefined;
|
|
355
353
|
count?: undefined;
|
|
354
|
+
provider?: undefined;
|
|
355
|
+
found?: undefined;
|
|
356
356
|
deleted: boolean;
|
|
357
357
|
id: string;
|
|
358
358
|
registered?: undefined;
|
|
@@ -360,10 +360,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
360
360
|
message?: undefined;
|
|
361
361
|
} | {
|
|
362
362
|
deleted?: undefined;
|
|
363
|
-
provider?: undefined;
|
|
364
|
-
found?: undefined;
|
|
365
363
|
providers?: undefined;
|
|
366
364
|
count?: undefined;
|
|
365
|
+
provider?: undefined;
|
|
366
|
+
found?: undefined;
|
|
367
367
|
registered: boolean;
|
|
368
368
|
id: string;
|
|
369
369
|
label: string;
|
|
@@ -286,6 +286,16 @@ export interface ProviderApiConfig {
|
|
|
286
286
|
accessErrorGuidance?: string;
|
|
287
287
|
corpusRecipes?: readonly ProviderApiCorpusRecipe[];
|
|
288
288
|
templateUses?: readonly WorkspaceConnectionTemplateUse[];
|
|
289
|
+
/**
|
|
290
|
+
* Some provider APIs (Slack's Web API is the documented case) answer every
|
|
291
|
+
* request with HTTP 200 and encode the real outcome as a boolean field in
|
|
292
|
+
* the JSON body instead. When set, a response with this field explicitly
|
|
293
|
+
* `false` is treated as a failed request — `response.ok` is flipped to
|
|
294
|
+
* `false` — so a caller (or the agent) that only checks the transport-level
|
|
295
|
+
* `ok`, the same signal every other provider uses for success, can't
|
|
296
|
+
* mistake a rejected send for a delivered one.
|
|
297
|
+
*/
|
|
298
|
+
bodyOkField?: string;
|
|
289
299
|
}
|
|
290
300
|
export interface ProviderApiPlaceholder {
|
|
291
301
|
name: string;
|