stagent 0.9.6 → 0.11.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/README.md +20 -44
- package/dist/cli.js +66 -18
- package/docs/.coverage-gaps.json +144 -56
- package/docs/.last-generated +1 -1
- package/docs/features/agent-intelligence.md +12 -2
- package/docs/features/chat.md +40 -5
- package/docs/features/cost-usage.md +1 -1
- package/docs/features/documents.md +5 -2
- package/docs/features/inbox-notifications.md +10 -2
- package/docs/features/keyboard-navigation.md +12 -3
- package/docs/features/provider-runtimes.md +20 -2
- package/docs/features/schedules.md +32 -4
- package/docs/features/settings.md +28 -5
- package/docs/features/shared-components.md +7 -3
- package/docs/features/tables.md +11 -2
- package/docs/features/tool-permissions.md +6 -2
- package/docs/features/workflows.md +14 -4
- package/docs/index.md +1 -1
- package/docs/journeys/developer.md +39 -2
- package/docs/journeys/personal-use.md +32 -8
- package/docs/journeys/power-user.md +45 -14
- package/docs/journeys/work-use.md +17 -8
- package/docs/manifest.json +15 -15
- package/docs/superpowers/plans/2026-04-07-instance-bootstrap.md +1691 -0
- package/docs/superpowers/plans/2026-04-08-schedule-orchestration.md +2983 -0
- package/docs/superpowers/plans/2026-04-11-schedule-maxturns-api-control.md +551 -0
- package/docs/superpowers/plans/2026-04-11-task-create-profile-validation.md +864 -0
- package/docs/superpowers/plans/2026-04-11-task-runtime-stagent-mcp-injection.md +739 -0
- package/docs/superpowers/plans/2026-04-14-chat-command-namespace-refactor.md +1390 -0
- package/docs/superpowers/plans/2026-04-14-chat-environment-integration.md +1561 -0
- package/docs/superpowers/plans/2026-04-14-chat-polish-bundle-v1.md +1219 -0
- package/docs/superpowers/plans/2026-04-14-chat-session-persistence-provider-closeout.md +399 -0
- package/docs/superpowers/specs/2026-04-08-chat-sse-resilience-hotfix-design.md +201 -0
- package/docs/superpowers/specs/2026-04-08-schedule-orchestration-design.md +371 -0
- package/docs/superpowers/specs/2026-04-08-swarm-visibility-design.md +213 -0
- package/next.config.mjs +1 -0
- package/package.json +3 -2
- package/src/__tests__/instrumentation-smoke.test.ts +15 -0
- package/src/app/analytics/page.tsx +1 -21
- package/src/app/api/chat/conversations/[id]/messages/route.ts +22 -1
- package/src/app/api/chat/conversations/[id]/skills/__tests__/activate.test.ts +141 -0
- package/src/app/api/chat/conversations/[id]/skills/activate/route.ts +74 -0
- package/src/app/api/chat/conversations/[id]/skills/deactivate/route.ts +33 -0
- package/src/app/api/chat/export/route.ts +52 -0
- package/src/app/api/chat/files/search/route.ts +50 -0
- package/src/app/api/diagnostics/chat-streams/route.ts +65 -0
- package/src/app/api/environment/rescan-if-stale/__tests__/route.test.ts +45 -0
- package/src/app/api/environment/rescan-if-stale/route.ts +23 -0
- package/src/app/api/environment/skills/route.ts +13 -0
- package/src/app/api/instance/config/route.ts +41 -0
- package/src/app/api/instance/init/route.ts +34 -0
- package/src/app/api/instance/upgrade/check/route.ts +26 -0
- package/src/app/api/instance/upgrade/route.ts +96 -0
- package/src/app/api/instance/upgrade/status/route.ts +35 -0
- package/src/app/api/memory/route.ts +0 -11
- package/src/app/api/notifications/route.ts +4 -2
- package/src/app/api/projects/[id]/route.ts +5 -155
- package/src/app/api/projects/__tests__/delete-project.test.ts +10 -19
- package/src/app/api/schedules/[id]/execute/route.ts +111 -0
- package/src/app/api/schedules/[id]/route.ts +9 -1
- package/src/app/api/schedules/__tests__/execute-route.test.ts +118 -0
- package/src/app/api/schedules/route.ts +3 -12
- package/src/app/api/settings/chat/pins/route.ts +94 -0
- package/src/app/api/settings/chat/saved-searches/__tests__/route.test.ts +119 -0
- package/src/app/api/settings/chat/saved-searches/route.ts +79 -0
- package/src/app/api/settings/environment/route.ts +26 -0
- package/src/app/api/settings/openai/login/route.ts +22 -0
- package/src/app/api/settings/openai/logout/route.ts +7 -0
- package/src/app/api/settings/openai/route.ts +21 -1
- package/src/app/api/settings/providers/route.ts +35 -8
- package/src/app/api/tables/[id]/enrich/__tests__/route.test.ts +153 -0
- package/src/app/api/tables/[id]/enrich/plan/route.ts +98 -0
- package/src/app/api/tables/[id]/enrich/route.ts +147 -0
- package/src/app/api/tables/[id]/enrich/runs/route.ts +25 -0
- package/src/app/api/tasks/[id]/execute/route.ts +52 -33
- package/src/app/api/tasks/[id]/respond/route.ts +31 -15
- package/src/app/api/tasks/[id]/resume/route.ts +24 -3
- package/src/app/api/workflows/[id]/resume/route.ts +59 -0
- package/src/app/api/workflows/[id]/status/route.ts +22 -8
- package/src/app/api/workspace/context/route.ts +2 -0
- package/src/app/api/workspace/fix-data-dir/route.ts +81 -0
- package/src/app/chat/page.tsx +11 -0
- package/src/app/documents/page.tsx +4 -1
- package/src/app/inbox/page.tsx +12 -5
- package/src/app/layout.tsx +42 -21
- package/src/app/page.tsx +0 -2
- package/src/app/settings/page.tsx +8 -9
- package/src/components/chat/__tests__/capability-banner.test.tsx +38 -0
- package/src/components/chat/__tests__/chat-session-provider.test.tsx +573 -0
- package/src/components/chat/__tests__/skill-row.test.tsx +91 -0
- package/src/components/chat/capability-banner.tsx +68 -0
- package/src/components/chat/chat-command-popover.tsx +670 -49
- package/src/components/chat/chat-input.tsx +104 -10
- package/src/components/chat/chat-message.tsx +12 -3
- package/src/components/chat/chat-session-provider.tsx +790 -0
- package/src/components/chat/chat-shell.tsx +151 -401
- package/src/components/chat/command-tab-bar.tsx +68 -0
- package/src/components/chat/conversation-template-picker.tsx +421 -0
- package/src/components/chat/help-dialog.tsx +39 -0
- package/src/components/chat/skill-composition-conflict-dialog.tsx +96 -0
- package/src/components/chat/skill-row.tsx +147 -0
- package/src/components/documents/document-browser.tsx +37 -19
- package/src/components/instance/__tests__/instance-section.test.tsx +125 -0
- package/src/components/instance/instance-section.tsx +382 -0
- package/src/components/instance/upgrade-badge.tsx +219 -0
- package/src/components/notifications/__tests__/batch-proposal-review.test.tsx +95 -0
- package/src/components/notifications/__tests__/notification-item.test.tsx +106 -0
- package/src/components/notifications/__tests__/permission-response-actions.test.tsx +70 -0
- package/src/components/notifications/batch-proposal-review.tsx +20 -5
- package/src/components/notifications/inbox-list.tsx +11 -2
- package/src/components/notifications/notification-item.tsx +56 -2
- package/src/components/notifications/pending-approval-host.tsx +56 -37
- package/src/components/notifications/permission-response-actions.tsx +155 -1
- package/src/components/schedules/schedule-create-sheet.tsx +19 -1
- package/src/components/schedules/schedule-edit-sheet.tsx +20 -1
- package/src/components/schedules/schedule-form.tsx +31 -0
- package/src/components/settings/__tests__/providers-runtimes-section.test.tsx +149 -0
- package/src/components/settings/auth-method-selector.tsx +19 -4
- package/src/components/settings/auth-status-badge.tsx +28 -3
- package/src/components/settings/environment-section.tsx +102 -0
- package/src/components/settings/openai-chatgpt-auth-control.tsx +278 -0
- package/src/components/settings/openai-runtime-section.tsx +7 -1
- package/src/components/settings/providers-runtimes-section.tsx +138 -19
- package/src/components/shared/__tests__/filter-hint.test.tsx +40 -0
- package/src/components/shared/__tests__/saved-searches-manager.test.tsx +147 -0
- package/src/components/shared/app-sidebar.tsx +4 -3
- package/src/components/shared/command-palette.tsx +266 -7
- package/src/components/shared/filter-hint.tsx +70 -0
- package/src/components/shared/filter-input.tsx +59 -0
- package/src/components/shared/saved-searches-manager.tsx +199 -0
- package/src/components/shared/theme-toggle.tsx +5 -24
- package/src/components/shared/workspace-indicator.tsx +61 -2
- package/src/components/tables/__tests__/table-enrichment-sheet.test.tsx +130 -0
- package/src/components/tables/table-create-sheet.tsx +4 -0
- package/src/components/tables/table-enrichment-runs.tsx +103 -0
- package/src/components/tables/table-enrichment-sheet.tsx +538 -0
- package/src/components/tables/table-spreadsheet.tsx +29 -5
- package/src/components/tables/table-toolbar.tsx +10 -1
- package/src/components/tasks/kanban-board.tsx +1 -0
- package/src/components/tasks/kanban-column.tsx +53 -14
- package/src/components/tasks/task-bento-grid.tsx +31 -2
- package/src/components/tasks/task-card.tsx +29 -3
- package/src/components/tasks/task-chip-bar.tsx +54 -1
- package/src/components/tasks/task-result-renderer.tsx +1 -1
- package/src/components/workflows/delay-step-body.tsx +109 -0
- package/src/components/workflows/hooks/use-workflow-status.ts +50 -0
- package/src/components/workflows/loop-status-view.tsx +1 -1
- package/src/components/workflows/shared/step-result.tsx +78 -0
- package/src/components/workflows/shared/workflow-header.tsx +141 -0
- package/src/components/workflows/shared/workflow-loading-skeleton.tsx +36 -0
- package/src/components/workflows/swarm-dashboard.tsx +2 -15
- package/src/components/workflows/views/loop-pattern-view.tsx +137 -0
- package/src/components/workflows/views/sequence-pattern-view.tsx +511 -0
- package/src/components/workflows/workflow-form-view.tsx +133 -16
- package/src/components/workflows/workflow-status-view.tsx +30 -740
- package/src/hooks/__tests__/use-chat-autocomplete-tabs.test.ts +47 -0
- package/src/hooks/__tests__/use-saved-searches.test.ts +70 -0
- package/src/hooks/use-active-skills.ts +110 -0
- package/src/hooks/use-chat-autocomplete.ts +120 -7
- package/src/hooks/use-enriched-skills.ts +19 -0
- package/src/hooks/use-pinned-entries.ts +104 -0
- package/src/hooks/use-recent-user-messages.ts +19 -0
- package/src/hooks/use-saved-searches.ts +142 -0
- package/src/instrumentation-node.ts +94 -0
- package/src/instrumentation.ts +4 -48
- package/src/lib/agents/__tests__/claude-agent-sdk-options.test.ts +56 -0
- package/src/lib/agents/__tests__/claude-agent.test.ts +212 -0
- package/src/lib/agents/__tests__/execution-manager.test.ts +1 -27
- package/src/lib/agents/__tests__/failure-reason.test.ts +68 -0
- package/src/lib/agents/__tests__/learned-context.test.ts +0 -11
- package/src/lib/agents/__tests__/learning-session.test.ts +158 -0
- package/src/lib/agents/__tests__/pattern-extractor.test.ts +48 -0
- package/src/lib/agents/__tests__/task-dispatch.test.ts +166 -0
- package/src/lib/agents/__tests__/tool-permissions.test.ts +60 -0
- package/src/lib/agents/claude-agent.ts +217 -21
- package/src/lib/agents/execution-manager.ts +0 -35
- package/src/lib/agents/handoff/bus.ts +2 -2
- package/src/lib/agents/learned-context.ts +0 -12
- package/src/lib/agents/learning-session.ts +18 -5
- package/src/lib/agents/profiles/__tests__/list-fused-profiles.test.ts +110 -0
- package/src/lib/agents/profiles/__tests__/registry.test.ts +53 -4
- package/src/lib/agents/profiles/builtins/upgrade-assistant/SKILL.md +97 -0
- package/src/lib/agents/profiles/builtins/upgrade-assistant/profile.yaml +36 -0
- package/src/lib/agents/profiles/list-fused-profiles.ts +104 -0
- package/src/lib/agents/profiles/registry.ts +18 -0
- package/src/lib/agents/profiles/types.ts +7 -1
- package/src/lib/agents/router.ts +3 -6
- package/src/lib/agents/runtime/__tests__/catalog.test.ts +130 -0
- package/src/lib/agents/runtime/__tests__/execution-target.test.ts +183 -0
- package/src/lib/agents/runtime/__tests__/openai-codex-auth.test.ts +118 -0
- package/src/lib/agents/runtime/anthropic-direct.ts +8 -0
- package/src/lib/agents/runtime/catalog.ts +121 -0
- package/src/lib/agents/runtime/claude-sdk.ts +32 -0
- package/src/lib/agents/runtime/codex-app-server-client.ts +11 -5
- package/src/lib/agents/runtime/execution-target.ts +456 -0
- package/src/lib/agents/runtime/index.ts +4 -0
- package/src/lib/agents/runtime/launch-failure.ts +101 -0
- package/src/lib/agents/runtime/openai-codex-auth.ts +389 -0
- package/src/lib/agents/runtime/openai-codex.ts +64 -60
- package/src/lib/agents/runtime/openai-direct.ts +8 -0
- package/src/lib/agents/runtime/types.ts +8 -0
- package/src/lib/agents/task-dispatch.ts +220 -0
- package/src/lib/agents/tool-permissions.ts +16 -1
- package/src/lib/book/chapter-mapping.ts +11 -0
- package/src/lib/book/content.ts +10 -0
- package/src/lib/chat/__tests__/active-skill-injection.test.ts +261 -0
- package/src/lib/chat/__tests__/active-streams.test.ts +49 -0
- package/src/lib/chat/__tests__/clean-filter-input.test.ts +68 -0
- package/src/lib/chat/__tests__/command-tabs.test.ts +68 -0
- package/src/lib/chat/__tests__/context-builder-files.test.ts +112 -0
- package/src/lib/chat/__tests__/dismissals.test.ts +65 -0
- package/src/lib/chat/__tests__/engine-sdk-options.test.ts +117 -0
- package/src/lib/chat/__tests__/finalize-safety-net.test.ts +139 -0
- package/src/lib/chat/__tests__/reconcile.test.ts +137 -0
- package/src/lib/chat/__tests__/skill-conflict.test.ts +35 -0
- package/src/lib/chat/__tests__/stream-telemetry.test.ts +151 -0
- package/src/lib/chat/__tests__/types.test.ts +28 -0
- package/src/lib/chat/active-skills.ts +31 -0
- package/src/lib/chat/active-streams.ts +27 -0
- package/src/lib/chat/clean-filter-input.ts +30 -0
- package/src/lib/chat/codex-engine.ts +46 -24
- package/src/lib/chat/command-tabs.ts +61 -0
- package/src/lib/chat/context-builder.ts +146 -4
- package/src/lib/chat/dismissals.ts +73 -0
- package/src/lib/chat/engine.ts +159 -18
- package/src/lib/chat/files/__tests__/search.test.ts +135 -0
- package/src/lib/chat/files/expand-mention.ts +76 -0
- package/src/lib/chat/files/search.ts +99 -0
- package/src/lib/chat/reconcile.ts +117 -0
- package/src/lib/chat/skill-composition.ts +210 -0
- package/src/lib/chat/skill-conflict.ts +105 -0
- package/src/lib/chat/stagent-tools.ts +7 -19
- package/src/lib/chat/stream-telemetry.ts +137 -0
- package/src/lib/chat/suggested-prompts.ts +28 -1
- package/src/lib/chat/system-prompt.ts +48 -1
- package/src/lib/chat/tool-catalog.ts +35 -4
- package/src/lib/chat/tools/__tests__/enrich-table-tool.test.ts +127 -0
- package/src/lib/chat/tools/__tests__/profile-tools.test.ts +51 -0
- package/src/lib/chat/tools/__tests__/schedule-tools.test.ts +261 -0
- package/src/lib/chat/tools/__tests__/settings-tools.test.ts +294 -0
- package/src/lib/chat/tools/__tests__/skill-tools.test.ts +474 -0
- package/src/lib/chat/tools/__tests__/task-tools.test.ts +399 -0
- package/src/lib/chat/tools/__tests__/workflow-tools-dedup.test.ts +351 -0
- package/src/lib/chat/tools/blueprint-tools.ts +190 -0
- package/src/lib/chat/tools/document-tools.ts +29 -13
- package/src/lib/chat/tools/helpers.ts +41 -0
- package/src/lib/chat/tools/notification-tools.ts +9 -5
- package/src/lib/chat/tools/profile-tools.ts +120 -23
- package/src/lib/chat/tools/project-tools.ts +33 -0
- package/src/lib/chat/tools/schedule-tools.ts +44 -11
- package/src/lib/chat/tools/skill-tools.ts +183 -0
- package/src/lib/chat/tools/table-tools.ts +71 -0
- package/src/lib/chat/tools/task-tools.ts +89 -21
- package/src/lib/chat/tools/workflow-tools.ts +275 -32
- package/src/lib/chat/types.ts +15 -0
- package/src/lib/constants/settings.ts +10 -18
- package/src/lib/data/__tests__/clear.test.ts +56 -2
- package/src/lib/data/clear.ts +17 -16
- package/src/lib/data/delete-project.ts +171 -0
- package/src/lib/db/__tests__/bootstrap.test.ts +1 -1
- package/src/lib/db/bootstrap.ts +62 -16
- package/src/lib/db/index.ts +5 -0
- package/src/lib/db/migrations/0009_add_app_instances.sql +25 -0
- package/src/lib/db/migrations/0024_add_workflow_resume_at.sql +10 -0
- package/src/lib/db/migrations/0025_drop_app_instances.sql +3 -0
- package/src/lib/db/migrations/0026_drop_license.sql +3 -0
- package/src/lib/db/migrations/meta/_journal.json +21 -0
- package/src/lib/db/schema.ts +94 -23
- package/src/lib/environment/__tests__/auto-promote.test.ts +132 -0
- package/src/lib/environment/__tests__/list-skills-enriched.test.ts +55 -0
- package/src/lib/environment/__tests__/skill-enrichment.test.ts +129 -0
- package/src/lib/environment/__tests__/skill-recommendations.test.ts +87 -0
- package/src/lib/environment/data.ts +9 -0
- package/src/lib/environment/list-skills.ts +176 -0
- package/src/lib/environment/parsers/__tests__/skill.test.ts +54 -0
- package/src/lib/environment/parsers/skill.ts +26 -5
- package/src/lib/environment/profile-generator.ts +54 -0
- package/src/lib/environment/skill-enrichment.ts +106 -0
- package/src/lib/environment/skill-recommendations.ts +66 -0
- package/src/lib/environment/workspace-context.ts +13 -1
- package/src/lib/filters/__tests__/parse.quoted.test.ts +40 -0
- package/src/lib/filters/__tests__/parse.test.ts +135 -0
- package/src/lib/filters/parse.ts +86 -0
- package/src/lib/import/dedup.ts +4 -54
- package/src/lib/instance/__tests__/bootstrap.test.ts +362 -0
- package/src/lib/instance/__tests__/detect.test.ts +115 -0
- package/src/lib/instance/__tests__/fingerprint.test.ts +48 -0
- package/src/lib/instance/__tests__/git-ops.test.ts +95 -0
- package/src/lib/instance/__tests__/settings.test.ts +83 -0
- package/src/lib/instance/__tests__/upgrade-poller.test.ts +181 -0
- package/src/lib/instance/bootstrap.ts +270 -0
- package/src/lib/instance/detect.ts +49 -0
- package/src/lib/instance/fingerprint.ts +76 -0
- package/src/lib/instance/git-ops.ts +95 -0
- package/src/lib/instance/settings.ts +61 -0
- package/src/lib/instance/types.ts +77 -0
- package/src/lib/instance/upgrade-poller.ts +205 -0
- package/src/lib/notifications/__tests__/visibility.test.ts +51 -0
- package/src/lib/notifications/visibility.ts +33 -0
- package/src/lib/schedules/__tests__/collision-check.test.ts +93 -0
- package/src/lib/schedules/__tests__/config.test.ts +62 -0
- package/src/lib/schedules/__tests__/firing-metrics.test.ts +99 -0
- package/src/lib/schedules/__tests__/integration.test.ts +82 -0
- package/src/lib/schedules/__tests__/slot-claim.test.ts +242 -0
- package/src/lib/schedules/__tests__/tick-scheduler.test.ts +102 -0
- package/src/lib/schedules/__tests__/turn-budget.test.ts +228 -0
- package/src/lib/schedules/collision-check.ts +105 -0
- package/src/lib/schedules/config.ts +53 -0
- package/src/lib/schedules/scheduler.ts +236 -17
- package/src/lib/schedules/slot-claim.ts +105 -0
- package/src/lib/settings/__tests__/openai-auth.test.ts +101 -0
- package/src/lib/settings/__tests__/openai-login-manager.test.ts +64 -0
- package/src/lib/settings/__tests__/runtime-setup.test.ts +33 -0
- package/src/lib/settings/openai-auth.ts +105 -10
- package/src/lib/settings/openai-login-manager.ts +260 -0
- package/src/lib/settings/runtime-setup.ts +14 -4
- package/src/lib/tables/__tests__/enrichment-planner.test.ts +124 -0
- package/src/lib/tables/__tests__/enrichment.test.ts +147 -0
- package/src/lib/tables/enrichment-planner.ts +454 -0
- package/src/lib/tables/enrichment.ts +328 -0
- package/src/lib/tables/query-builder.ts +5 -2
- package/src/lib/tables/trigger-evaluator.ts +3 -2
- package/src/lib/theme.ts +71 -0
- package/src/lib/usage/ledger.ts +2 -18
- package/src/lib/util/__tests__/similarity.test.ts +106 -0
- package/src/lib/util/similarity.ts +77 -0
- package/src/lib/utils/format-timestamp.ts +24 -0
- package/src/lib/utils/stagent-paths.ts +12 -0
- package/src/lib/validators/__tests__/blueprint.test.ts +172 -0
- package/src/lib/validators/__tests__/settings.test.ts +10 -0
- package/src/lib/validators/blueprint.ts +70 -9
- package/src/lib/validators/profile.ts +2 -2
- package/src/lib/validators/settings.ts +3 -1
- package/src/lib/workflows/__tests__/delay.test.ts +196 -0
- package/src/lib/workflows/__tests__/engine.test.ts +8 -0
- package/src/lib/workflows/__tests__/loop-executor.test.ts +54 -0
- package/src/lib/workflows/__tests__/post-action.test.ts +108 -0
- package/src/lib/workflows/blueprints/__tests__/render-prompt.test.ts +124 -0
- package/src/lib/workflows/blueprints/instantiator.ts +22 -1
- package/src/lib/workflows/blueprints/render-prompt.ts +71 -0
- package/src/lib/workflows/blueprints/types.ts +16 -2
- package/src/lib/workflows/delay.ts +106 -0
- package/src/lib/workflows/engine.ts +212 -7
- package/src/lib/workflows/loop-executor.ts +349 -24
- package/src/lib/workflows/post-action.ts +91 -0
- package/src/lib/workflows/types.ts +166 -1
- package/src/test/setup.ts +10 -0
- package/src/app/api/license/checkout/route.ts +0 -28
- package/src/app/api/license/portal/route.ts +0 -26
- package/src/app/api/license/route.ts +0 -89
- package/src/app/api/license/usage/route.ts +0 -63
- package/src/app/api/marketplace/browse/route.ts +0 -15
- package/src/app/api/marketplace/import/route.ts +0 -28
- package/src/app/api/marketplace/publish/route.ts +0 -40
- package/src/app/api/onboarding/email/route.ts +0 -53
- package/src/app/api/settings/telemetry/route.ts +0 -14
- package/src/app/api/sync/export/route.ts +0 -54
- package/src/app/api/sync/restore/route.ts +0 -37
- package/src/app/api/sync/sessions/route.ts +0 -24
- package/src/app/auth/callback/route.ts +0 -73
- package/src/app/marketplace/page.tsx +0 -19
- package/src/components/analytics/analytics-gate-card.tsx +0 -101
- package/src/components/marketplace/blueprint-card.tsx +0 -61
- package/src/components/marketplace/marketplace-browser.tsx +0 -131
- package/src/components/onboarding/email-capture-card.tsx +0 -104
- package/src/components/settings/activation-form.tsx +0 -95
- package/src/components/settings/cloud-account-section.tsx +0 -147
- package/src/components/settings/cloud-sync-section.tsx +0 -155
- package/src/components/settings/subscription-section.tsx +0 -410
- package/src/components/settings/telemetry-section.tsx +0 -80
- package/src/components/shared/premium-gate-overlay.tsx +0 -50
- package/src/components/shared/schedule-gate-dialog.tsx +0 -64
- package/src/components/shared/upgrade-banner.tsx +0 -112
- package/src/hooks/use-supabase-auth.ts +0 -79
- package/src/lib/billing/email.ts +0 -54
- package/src/lib/billing/products.ts +0 -80
- package/src/lib/billing/stripe.ts +0 -101
- package/src/lib/cloud/supabase-browser.ts +0 -32
- package/src/lib/cloud/supabase-client.ts +0 -56
- package/src/lib/license/__tests__/features.test.ts +0 -56
- package/src/lib/license/__tests__/key-format.test.ts +0 -88
- package/src/lib/license/__tests__/manager.test.ts +0 -64
- package/src/lib/license/__tests__/tier-limits.test.ts +0 -79
- package/src/lib/license/cloud-validation.ts +0 -60
- package/src/lib/license/features.ts +0 -44
- package/src/lib/license/key-format.ts +0 -101
- package/src/lib/license/limit-check.ts +0 -111
- package/src/lib/license/limit-queries.ts +0 -51
- package/src/lib/license/manager.ts +0 -345
- package/src/lib/license/notifications.ts +0 -59
- package/src/lib/license/tier-limits.ts +0 -71
- package/src/lib/marketplace/marketplace-client.ts +0 -107
- package/src/lib/sync/cloud-sync.ts +0 -235
- package/src/lib/telemetry/conversion-events.ts +0 -71
- package/src/lib/telemetry/queue.ts +0 -122
- package/src/lib/validators/license.ts +0 -33
package/README.md
CHANGED
|
@@ -39,47 +39,6 @@ The AI agent stack is broken for business operators. You can spin up an agent in
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
## Community & Premium Editions
|
|
43
|
-
|
|
44
|
-
Stagent is **free and fully functional** as a local-first tool. The Community Edition (Apache 2.0) includes everything you need to run AI agents, workflows, and schedules on your machine. Premium tiers add cloud sync, expanded limits, marketplace access, and analytics for power users and teams.
|
|
45
|
-
|
|
46
|
-
### Feature Comparison
|
|
47
|
-
|
|
48
|
-
| Capability | Community (Free) | Premium |
|
|
49
|
-
|---|---|---|
|
|
50
|
-
| Local tasks & workflows | Unlimited | Unlimited |
|
|
51
|
-
| Agent profiles | All built-in | All built-in |
|
|
52
|
-
| Human-in-the-loop approval | Full | Full |
|
|
53
|
-
| Agent memories per profile | 50 | 200 - Unlimited |
|
|
54
|
-
| Learned context versions | 10 | 50 - Unlimited |
|
|
55
|
-
| Active schedules | 5 | 20 - Unlimited |
|
|
56
|
-
| History retention | 30 days | 180 days - Unlimited |
|
|
57
|
-
| Cloud sync & backup | — | Solo and above |
|
|
58
|
-
| Marketplace blueprints | Browse only | Import & Publish |
|
|
59
|
-
| Outcome analytics | — | Operator and above |
|
|
60
|
-
|
|
61
|
-
### Soft Limits
|
|
62
|
-
|
|
63
|
-
| Resource | Community Limit | At Limit |
|
|
64
|
-
|---|---|---|
|
|
65
|
-
| Agent memories | 50 per profile | New writes blocked, existing preserved |
|
|
66
|
-
| Context versions | 10 per profile | New proposals blocked |
|
|
67
|
-
| Active schedules | 5 | New schedule creation returns 402 |
|
|
68
|
-
| Task history | 30 days | Older entries pruned daily |
|
|
69
|
-
|
|
70
|
-
### Pricing
|
|
71
|
-
|
|
72
|
-
| Tier | Price | Best For |
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| Community | Free forever | Individual developers, evaluation |
|
|
75
|
-
| Solo | $19/mo | Power users, expanded limits |
|
|
76
|
-
| Operator | $49/mo | Professionals, analytics, cloud sync |
|
|
77
|
-
| Scale | $99/mo | Teams, marketplace publishing, unlimited |
|
|
78
|
-
|
|
79
|
-
[Get Premium →](https://stagent.io/pricing)
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
42
|
## Runtime Bridge
|
|
84
43
|
|
|
85
44
|
Run the same business process on different AI providers without changing a line of configuration. Stagent's shared runtime registry routes tasks, schedules, and workflow steps through **Claude Code** (Anthropic Claude Agent SDK) and **OpenAI Codex App Server**, landing everything in the same inbox, monitoring, and cost surfaces. Switching providers is a settings change, not a rewrite.
|
|
@@ -114,6 +73,9 @@ Run the same business process on different AI providers without changing a line
|
|
|
114
73
|
| 📦 | **[Workflow Context Batching](#workflow-context-batching)** | Workflow-scoped proposal buffering with batch approve/reject for learned context |
|
|
115
74
|
| 🧪 | **[E2E Test Automation](#e2e-test-automation)** | API-level end-to-end test suite covering both runtimes, 4 profiles, and 4 workflow patterns |
|
|
116
75
|
| ⌨️ | **[Command Palette](#command-palette)** | Global `⌘K` search for fast navigation across tasks, projects, workflows, and settings |
|
|
76
|
+
| 🧱 | **[Skill Composition](#skill-composition)** | Activate up to 3 skills at once with conflict detection and runtime-aware capability gates |
|
|
77
|
+
| 🔎 | **[Filters & Saved Searches](#filters--saved-searches)** | `#key:value` filter grammar, pinned and saved searches surfaced in `⌘K` palette |
|
|
78
|
+
| 🛡️ | **[Upgrade Detection](#upgrade-detection)** | Hourly upstream check with in-app notifications and guided merge sessions |
|
|
117
79
|
| 📖 | **[Playbook](#playbook)** | Built-in documentation with usage-stage awareness, adoption heatmap, and guided learning journeys |
|
|
118
80
|
| 📚 | **[Living Book](#living-book)** | AI-native book reader with 9 chapters, agent-powered regeneration, staleness detection, and reading paths |
|
|
119
81
|
| 🌐 | **[Environment](#environment)** | Control plane for Claude Code and Codex CLI environments with scanning, caching, sync, and templates |
|
|
@@ -123,7 +85,11 @@ Run the same business process on different AI providers without changing a line
|
|
|
123
85
|
|
|
124
86
|
## Architecture
|
|
125
87
|
|
|
126
|
-
<
|
|
88
|
+
<picture>
|
|
89
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/architecture-dark.svg">
|
|
90
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/architecture-light.svg">
|
|
91
|
+
<img src="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/architecture-light.svg" alt="Stagent architecture diagram" width="900" />
|
|
92
|
+
</picture>
|
|
127
93
|
|
|
128
94
|
**Key design decisions:**
|
|
129
95
|
|
|
@@ -313,6 +279,9 @@ Pending permission requests now surface through a shell-level approval presenter
|
|
|
313
279
|
#### Tool Permission Presets
|
|
314
280
|
Pre-configured permission bundles that reduce friction for common tool approval patterns. Three layered presets — read-only (file reads, glob, grep), git-safe (adds git operations), and full-auto (adds write, edit, bash) — compose with existing "Always Allow" patterns. Presets are layered: enabling git-safe automatically includes read-only patterns; removing git-safe only strips its unique additions. Risk badges indicate the trust level of each preset. Manage presets from the Settings page alongside individual tool permissions.
|
|
315
281
|
|
|
282
|
+
#### Upgrade Detection
|
|
283
|
+
Hourly poller checks the upstream `origin/main` for new commits and surfaces them via an in-app `UpgradeBadge` + notification queue. If three consecutive checks fail, a single deduplicated "Upgrade check failing" notification is inserted (and cleared on the next successful tick). The `upgrade-assistant` profile drives guided merge sessions end-to-end — including free-form questions and 3-choice option cards when a merge conflict or drifted `main` requires operator input. Dev repos are fully gated via `STAGENT_DEV_MODE` and a `.git/stagent-dev-mode` sentinel so contributor pushes are never blocked.
|
|
284
|
+
|
|
316
285
|
#### Schedules
|
|
317
286
|
Time-based scheduling for agent tasks with human-friendly intervals (`5m`, `2h`, `1d`) and raw 5-field cron expressions. One-shot and recurring modes with pause/resume lifecycle, expiry limits, and max firings. Each firing creates a child task through the shared execution pipeline, and schedules can now target a runtime explicitly. Scheduler runs as a poll-based engine started via Next.js instrumentation hook.
|
|
318
287
|
|
|
@@ -346,6 +315,12 @@ Conversational control plane for all workspace primitives — projects, tasks, w
|
|
|
346
315
|
|:-:|:-:|:-:|
|
|
347
316
|
| <img src="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/chat-list.png" alt="Chat tool catalog with category tabs" width="380" /> | <img src="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/chat-model-selector.png" alt="Chat model selector with cost tiers" width="380" /> | <img src="https://raw.githubusercontent.com/navam-io/stagent/main/public/readme/chat-create-tab.png" alt="Chat Create category prompts" width="380" /> |
|
|
348
317
|
|
|
318
|
+
#### Skill Composition
|
|
319
|
+
Activate up to three skills in a single conversation with conflict detection and runtime-aware capability gates. The Skills tab in the chat popover surfaces `+ Add` buttons on inactive skills, active badges with deactivate actions, and an "N of M active" indicator. When two skills issue polarity-divergent directives on shared keywords, a conflict dialog previews the excerpts and lets you confirm with `force:true` or back out. Composition honors the runtime capability matrix — Claude Code and Codex App Server support up to 3 active skills, while Ollama stays at 1. Conversations persist active skills through an additive `active_skill_ids` column that preserves legacy single-skill reads.
|
|
320
|
+
|
|
321
|
+
#### Filters & Saved Searches
|
|
322
|
+
Structured `#key:value` filter grammar across chat, documents, and the `⌘K` palette. The shared `FilterInput` parser accepts bare clauses, quoted values (`#tag:"needs review"`), and free text — clauses AND with surface-specific Select filters and sync to URL params for shareable, refresh-persistent views. Save any filter expression with a rename footer; saved searches appear as a dedicated group in the mention popover and in the command palette, so views built in one surface are reachable from anywhere. Pinned saved searches sit at the top of both lists for zero-click recall.
|
|
323
|
+
|
|
349
324
|
#### Monitoring
|
|
350
325
|
Real-time agent log streaming via Server-Sent Events. Filter by task or event type, click entries to jump to task details, and auto-pause polling when the tab is hidden (Page Visibility API).
|
|
351
326
|
|
|
@@ -548,12 +523,13 @@ All 14 features shipped across three layers:
|
|
|
548
523
|
|----------|---------|
|
|
549
524
|
| **Documents** (5) | File attachments, preprocessing (5 formats), agent context injection, document browser, output generation |
|
|
550
525
|
| **Agent Intelligence** (6) | Multi-agent routing, autonomous loops, multi-agent swarm, AI assist→workflows, agent self-improvement, workflow context batching |
|
|
551
|
-
| **Agent Profiles** (2) | Agent profile catalog (21 profiles), workflow blueprints (
|
|
526
|
+
| **Agent Profiles** (2) | Agent profile catalog (<!-- STAT:builtinProfiles -->21<!-- /STAT --> profiles), workflow blueprints (<!-- STAT:workflowBlueprints -->13<!-- /STAT --> templates) |
|
|
552
527
|
| **UI Enhancement** (13) | Ambient approvals, learned context UX, micro-visualizations, command palette, operational surface, profile surface, accessibility, UI density, kanban operations, board persistence, detail view redesign, playbook documentation, workflow UX overhaul |
|
|
553
528
|
| **Platform** (8) | Scheduled prompt loops, tool permissions, provider runtimes, OpenAI Codex runtime, cross-provider profiles, parallel fork/join, tool permission presets, npm publish (deferred) |
|
|
554
529
|
| **Runtime Quality** (2) | SDK runtime hardening, E2E test automation |
|
|
555
530
|
| **Governance** (3) | Usage metering ledger, spend budget guardrails, cost & usage dashboard |
|
|
556
|
-
| **Chat** (
|
|
531
|
+
| **Chat** (10) | Chat data layer, chat engine (5-tier context, CRUD tools), API routes (SSE streaming), UI shell, message rendering (Quick Access pills), input composer (tool catalog, model selector), skill composition (multi-skill with conflict detection), filter namespace (`#key:value` grammar), pinned + saved searches, conversation templates |
|
|
532
|
+
| **Platform Hardening** (2) | Runtime validation hardening (MCP-tool runtime-id validation with safe fallbacks), upgrade detection (hourly upstream poll + guided merge sessions) |
|
|
557
533
|
| **Environment** (11) | Environment scanner, cache, dashboard, git checkpoint manager, sync engine, project onboarding, templates, cross-project comparison, skill portfolio, health scoring, agent profile from environment |
|
|
558
534
|
| **Living Book** (5) | Content merge (chapters → playbook), author's notes, reading paths, markdown pipeline, self-updating chapters |
|
|
559
535
|
|
package/dist/cli.js
CHANGED
|
@@ -130,8 +130,8 @@ var STAGENT_TABLES = [
|
|
|
130
130
|
"user_table_triggers",
|
|
131
131
|
"user_table_row_history",
|
|
132
132
|
"snapshots",
|
|
133
|
-
"
|
|
134
|
-
"
|
|
133
|
+
"workflow_execution_stats",
|
|
134
|
+
"schedule_firing_metrics"
|
|
135
135
|
];
|
|
136
136
|
function bootstrapStagentDatabase(sqlite2) {
|
|
137
137
|
sqlite2.exec(`
|
|
@@ -154,6 +154,9 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
154
154
|
status TEXT DEFAULT 'planned' NOT NULL,
|
|
155
155
|
assigned_agent TEXT,
|
|
156
156
|
agent_profile TEXT,
|
|
157
|
+
effective_runtime_id TEXT,
|
|
158
|
+
effective_model_id TEXT,
|
|
159
|
+
runtime_fallback_reason TEXT,
|
|
157
160
|
priority INTEGER DEFAULT 2 NOT NULL,
|
|
158
161
|
result TEXT,
|
|
159
162
|
session_id TEXT,
|
|
@@ -175,6 +178,7 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
175
178
|
status TEXT DEFAULT 'draft' NOT NULL,
|
|
176
179
|
run_number INTEGER DEFAULT 0 NOT NULL,
|
|
177
180
|
runtime_id TEXT,
|
|
181
|
+
resume_at INTEGER,
|
|
178
182
|
created_at INTEGER NOT NULL,
|
|
179
183
|
updated_at INTEGER NOT NULL,
|
|
180
184
|
FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION
|
|
@@ -276,6 +280,32 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
276
280
|
CREATE INDEX IF NOT EXISTS idx_schedules_next_fire_at ON schedules(next_fire_at);
|
|
277
281
|
CREATE INDEX IF NOT EXISTS idx_schedules_project_id ON schedules(project_id);
|
|
278
282
|
|
|
283
|
+
-- schedule_firing_metrics is placed here (between schedules indexes and
|
|
284
|
+
-- notifications indexes) to satisfy its foreign-key dependency on schedules.
|
|
285
|
+
-- Future tables with FK dependencies should follow the same "place after
|
|
286
|
+
-- parent table" discipline rather than batching all CREATE TABLE at the top.
|
|
287
|
+
CREATE TABLE IF NOT EXISTS schedule_firing_metrics (
|
|
288
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
289
|
+
schedule_id TEXT NOT NULL,
|
|
290
|
+
task_id TEXT,
|
|
291
|
+
fired_at INTEGER NOT NULL,
|
|
292
|
+
slot_claimed_at INTEGER,
|
|
293
|
+
completed_at INTEGER,
|
|
294
|
+
slot_wait_ms INTEGER,
|
|
295
|
+
duration_ms INTEGER,
|
|
296
|
+
turn_count INTEGER,
|
|
297
|
+
max_turns_at_firing INTEGER,
|
|
298
|
+
event_loop_lag_ms REAL,
|
|
299
|
+
peak_rss_mb INTEGER,
|
|
300
|
+
chat_streams_active INTEGER,
|
|
301
|
+
concurrent_schedules INTEGER,
|
|
302
|
+
failure_reason TEXT,
|
|
303
|
+
FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
|
|
304
|
+
FOREIGN KEY (task_id) REFERENCES tasks(id) ON UPDATE NO ACTION ON DELETE NO ACTION
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
CREATE INDEX IF NOT EXISTS idx_sfm_schedule_time ON schedule_firing_metrics(schedule_id, fired_at);
|
|
308
|
+
|
|
279
309
|
CREATE INDEX IF NOT EXISTS idx_notifications_task_id ON notifications(task_id);
|
|
280
310
|
CREATE INDEX IF NOT EXISTS idx_notifications_read ON notifications(read);
|
|
281
311
|
CREATE INDEX IF NOT EXISTS idx_documents_task_id ON documents(task_id);
|
|
@@ -344,6 +374,7 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
344
374
|
|
|
345
375
|
CREATE INDEX IF NOT EXISTS idx_views_surface ON views(surface);
|
|
346
376
|
CREATE INDEX IF NOT EXISTS idx_views_surface_default ON views(surface, is_default);
|
|
377
|
+
|
|
347
378
|
`);
|
|
348
379
|
const addColumnIfMissing = (ddl) => {
|
|
349
380
|
try {
|
|
@@ -357,6 +388,9 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
357
388
|
};
|
|
358
389
|
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN agent_profile TEXT;`);
|
|
359
390
|
sqlite2.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_agent_profile ON tasks(agent_profile);`);
|
|
391
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN effective_runtime_id TEXT;`);
|
|
392
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN effective_model_id TEXT;`);
|
|
393
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN runtime_fallback_reason TEXT;`);
|
|
360
394
|
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN workflow_id TEXT REFERENCES workflows(id);`);
|
|
361
395
|
sqlite2.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_workflow_id ON tasks(workflow_id);`);
|
|
362
396
|
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN schedule_id TEXT REFERENCES schedules(id);`);
|
|
@@ -380,6 +414,9 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
380
414
|
addColumnIfMissing(`ALTER TABLE documents ADD COLUMN source TEXT DEFAULT 'upload';`);
|
|
381
415
|
addColumnIfMissing(`ALTER TABLE documents ADD COLUMN conversation_id TEXT REFERENCES conversations(id);`);
|
|
382
416
|
addColumnIfMissing(`ALTER TABLE documents ADD COLUMN message_id TEXT;`);
|
|
417
|
+
addColumnIfMissing(`ALTER TABLE conversations ADD COLUMN active_skill_id TEXT;`);
|
|
418
|
+
addColumnIfMissing(`ALTER TABLE conversations ADD COLUMN active_skill_ids TEXT DEFAULT '[]';`);
|
|
419
|
+
addColumnIfMissing(`ALTER TABLE workflows ADD COLUMN resume_at INTEGER;`);
|
|
383
420
|
sqlite2.exec(`CREATE INDEX IF NOT EXISTS idx_documents_source ON documents(source);`);
|
|
384
421
|
sqlite2.exec(`CREATE INDEX IF NOT EXISTS idx_documents_conversation_id ON documents(conversation_id);`);
|
|
385
422
|
sqlite2.exec(`
|
|
@@ -491,6 +528,8 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
491
528
|
status TEXT DEFAULT 'active' NOT NULL,
|
|
492
529
|
session_id TEXT,
|
|
493
530
|
context_scope TEXT,
|
|
531
|
+
active_skill_id TEXT,
|
|
532
|
+
active_skill_ids TEXT DEFAULT '[]',
|
|
494
533
|
created_at INTEGER NOT NULL,
|
|
495
534
|
updated_at INTEGER NOT NULL,
|
|
496
535
|
FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION
|
|
@@ -605,6 +644,15 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
605
644
|
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN failure_streak INTEGER DEFAULT 0 NOT NULL;`);
|
|
606
645
|
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN last_failure_reason TEXT;`);
|
|
607
646
|
addColumnIfMissing(`ALTER TABLE channel_configs ADD COLUMN direction TEXT DEFAULT 'outbound' NOT NULL;`);
|
|
647
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN slot_claimed_at INTEGER;`);
|
|
648
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN lease_expires_at INTEGER;`);
|
|
649
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN failure_reason TEXT;`);
|
|
650
|
+
addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN max_turns INTEGER;`);
|
|
651
|
+
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN max_turns INTEGER;`);
|
|
652
|
+
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN max_turns_set_at INTEGER;`);
|
|
653
|
+
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN max_run_duration_sec INTEGER;`);
|
|
654
|
+
addColumnIfMissing(`ALTER TABLE schedules ADD COLUMN turn_budget_breach_streak INTEGER DEFAULT 0 NOT NULL;`);
|
|
655
|
+
sqlite2.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_running_scheduled ON tasks(status, source_type, lease_expires_at);`);
|
|
608
656
|
sqlite2.exec(`
|
|
609
657
|
CREATE TABLE IF NOT EXISTS channel_bindings (
|
|
610
658
|
id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -902,21 +950,6 @@ function bootstrapStagentDatabase(sqlite2) {
|
|
|
902
950
|
CREATE INDEX IF NOT EXISTS idx_snapshots_type ON snapshots(type);
|
|
903
951
|
CREATE INDEX IF NOT EXISTS idx_snapshots_created_at ON snapshots(created_at);
|
|
904
952
|
|
|
905
|
-
CREATE TABLE IF NOT EXISTS license (
|
|
906
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
907
|
-
supabase_user_id TEXT,
|
|
908
|
-
tier TEXT DEFAULT 'community' NOT NULL,
|
|
909
|
-
status TEXT DEFAULT 'inactive' NOT NULL,
|
|
910
|
-
email TEXT,
|
|
911
|
-
activated_at INTEGER,
|
|
912
|
-
expires_at INTEGER,
|
|
913
|
-
last_validated_at INTEGER,
|
|
914
|
-
grace_period_expires_at INTEGER,
|
|
915
|
-
encrypted_token TEXT,
|
|
916
|
-
created_at INTEGER NOT NULL,
|
|
917
|
-
updated_at INTEGER NOT NULL
|
|
918
|
-
);
|
|
919
|
-
|
|
920
953
|
CREATE TABLE IF NOT EXISTS workflow_execution_stats (
|
|
921
954
|
id TEXT PRIMARY KEY,
|
|
922
955
|
pattern TEXT NOT NULL,
|
|
@@ -989,6 +1022,20 @@ function markAllMigrationsApplied(sqlite2, migrationsFolder, migrationsTable = "
|
|
|
989
1022
|
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
990
1023
|
var appDir = join3(__dirname, "..");
|
|
991
1024
|
var launchCwd = process.cwd();
|
|
1025
|
+
var _envLocalPath = join3(launchCwd, ".env.local");
|
|
1026
|
+
if (existsSync2(_envLocalPath)) {
|
|
1027
|
+
for (const line of readFileSync(_envLocalPath, "utf-8").split("\n")) {
|
|
1028
|
+
const trimmed = line.trim();
|
|
1029
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1030
|
+
const eqIdx = trimmed.indexOf("=");
|
|
1031
|
+
if (eqIdx === -1) continue;
|
|
1032
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
1033
|
+
const val = trimmed.slice(eqIdx + 1).trim().replace(/^(['"])(.*)\1$/, "$2");
|
|
1034
|
+
if (key && !(key in process.env)) {
|
|
1035
|
+
process.env[key] = val;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
992
1039
|
var pkg = JSON.parse(readFileSync(join3(appDir, "package.json"), "utf-8"));
|
|
993
1040
|
function getHelpText() {
|
|
994
1041
|
const dir = getStagentDataDir();
|
|
@@ -1010,7 +1057,8 @@ Examples:
|
|
|
1010
1057
|
node dist/cli.js --data-dir ~/.stagent-dogfood --port 3100
|
|
1011
1058
|
`;
|
|
1012
1059
|
}
|
|
1013
|
-
program.name("stagent").description("AI Business Operating System").version(pkg.version).addHelpText("after", getHelpText).option("-p, --port <number>", "port to start on", "3000").option("--data-dir <path>", "custom data directory (overrides STAGENT_DATA_DIR)").option("--reset", "delete the local database before starting").option("--no-open", "don't auto-open browser")
|
|
1060
|
+
program.name("stagent").description("AI Business Operating System").version(pkg.version).addHelpText("after", getHelpText).option("-p, --port <number>", "port to start on", "3000").option("--data-dir <path>", "custom data directory (overrides STAGENT_DATA_DIR)").option("--reset", "delete the local database before starting").option("--no-open", "don't auto-open browser");
|
|
1061
|
+
program.parse();
|
|
1014
1062
|
var opts = program.opts();
|
|
1015
1063
|
if (opts.dataDir) {
|
|
1016
1064
|
process.env.STAGENT_DATA_DIR = opts.dataDir;
|
package/docs/.coverage-gaps.json
CHANGED
|
@@ -1,71 +1,159 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generated": "2026-04-
|
|
3
|
-
"summary": {
|
|
4
|
-
"totalFeatures": 82,
|
|
5
|
-
"coveredFeatures": 78,
|
|
6
|
-
"gapCount": 4,
|
|
7
|
-
"unusedScreenshotCount": 0,
|
|
8
|
-
"brokenReferences": 0,
|
|
9
|
-
"orphanedImages": 14
|
|
10
|
-
},
|
|
2
|
+
"generated": "2026-04-16T05:57:41Z",
|
|
11
3
|
"gaps": [
|
|
12
4
|
{
|
|
13
|
-
"feature": "
|
|
14
|
-
"category": "
|
|
15
|
-
"screenshots": [
|
|
5
|
+
"feature": "ai-assist-workflow-creation",
|
|
6
|
+
"category": "Agent Intelligence",
|
|
7
|
+
"screenshots": [
|
|
8
|
+
"dashboard-create-form-ai-assist.png",
|
|
9
|
+
"dashboard-create-form-ai-applied.png",
|
|
10
|
+
"dashboard-create-form-ai-breakdown.png",
|
|
11
|
+
"dashboard-workflow-confirm.png"
|
|
12
|
+
],
|
|
13
|
+
"journeyCoverage": [],
|
|
14
|
+
"suggestedPersona": "power-user"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"feature": "autonomous-loop-execution",
|
|
18
|
+
"category": "Schedules",
|
|
19
|
+
"screenshots": [
|
|
20
|
+
"schedules-detail.png"
|
|
21
|
+
],
|
|
22
|
+
"journeyCoverage": [],
|
|
23
|
+
"suggestedPersona": "power-user"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"feature": "chat-composition-ui-v1",
|
|
27
|
+
"category": "Chat",
|
|
28
|
+
"screenshots": [
|
|
29
|
+
"chat-skills-tab.png"
|
|
30
|
+
],
|
|
16
31
|
"journeyCoverage": [],
|
|
17
|
-
"suggestedPersona": "personal"
|
|
18
|
-
"note": "Book reader captured but not referenced in any journey"
|
|
32
|
+
"suggestedPersona": "personal"
|
|
19
33
|
},
|
|
20
34
|
{
|
|
21
|
-
"feature": "
|
|
22
|
-
"category": "
|
|
23
|
-
"screenshots": [
|
|
35
|
+
"feature": "chat-dedup-variant-tolerance",
|
|
36
|
+
"category": "Chat",
|
|
37
|
+
"screenshots": [
|
|
38
|
+
"chat-conversation.png"
|
|
39
|
+
],
|
|
24
40
|
"journeyCoverage": [],
|
|
25
|
-
"suggestedPersona": "personal"
|
|
26
|
-
"note": "Book navigation not in any journey"
|
|
41
|
+
"suggestedPersona": "personal"
|
|
27
42
|
},
|
|
28
43
|
{
|
|
29
|
-
"feature": "
|
|
30
|
-
"category": "
|
|
31
|
-
"screenshots": [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
"feature": "chat-file-mentions",
|
|
45
|
+
"category": "Chat",
|
|
46
|
+
"screenshots": [
|
|
47
|
+
"chat-mentions-popover.png",
|
|
48
|
+
"chat-entities-tab.png"
|
|
49
|
+
],
|
|
50
|
+
"journeyCoverage": [],
|
|
51
|
+
"suggestedPersona": "personal"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"feature": "chat-settings-tool",
|
|
55
|
+
"category": "Chat",
|
|
56
|
+
"screenshots": [
|
|
57
|
+
"chat-tools-tab.png"
|
|
58
|
+
],
|
|
59
|
+
"journeyCoverage": [],
|
|
60
|
+
"suggestedPersona": "personal"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"feature": "chat-skill-composition",
|
|
64
|
+
"category": "Agent Intelligence",
|
|
65
|
+
"screenshots": [
|
|
66
|
+
"chat-skills-tab.png",
|
|
67
|
+
"chat-slash-popover.png"
|
|
68
|
+
],
|
|
69
|
+
"journeyCoverage": [],
|
|
70
|
+
"suggestedPersona": "power-user"
|
|
35
71
|
},
|
|
36
72
|
{
|
|
37
|
-
"feature": "
|
|
38
|
-
"category": "Platform",
|
|
39
|
-
"screenshots": [
|
|
73
|
+
"feature": "instance-bootstrap",
|
|
74
|
+
"category": "Platform/Runtime",
|
|
75
|
+
"screenshots": [
|
|
76
|
+
"settings-instance.png"
|
|
77
|
+
],
|
|
40
78
|
"journeyCoverage": [],
|
|
41
|
-
"suggestedPersona": "developer"
|
|
42
|
-
|
|
79
|
+
"suggestedPersona": "developer"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"feature": "multi-agent-swarm",
|
|
83
|
+
"category": "Agent Intelligence",
|
|
84
|
+
"screenshots": [
|
|
85
|
+
"dashboard-create-form-ai-breakdown.png"
|
|
86
|
+
],
|
|
87
|
+
"journeyCoverage": [],
|
|
88
|
+
"suggestedPersona": "power-user"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"feature": "task-definition-ai",
|
|
92
|
+
"category": "Agent Intelligence",
|
|
93
|
+
"screenshots": [
|
|
94
|
+
"dashboard-create-form-ai-assist.png",
|
|
95
|
+
"dashboard-create-form-empty.png",
|
|
96
|
+
"dashboard-create-form-filled.png"
|
|
97
|
+
],
|
|
98
|
+
"journeyCoverage": [],
|
|
99
|
+
"suggestedPersona": "power-user"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"feature": "upgrade-detection",
|
|
103
|
+
"category": "Platform/Runtime",
|
|
104
|
+
"screenshots": [
|
|
105
|
+
"settings-instance.png"
|
|
106
|
+
],
|
|
107
|
+
"journeyCoverage": [],
|
|
108
|
+
"suggestedPersona": "developer"
|
|
43
109
|
}
|
|
44
110
|
],
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
111
|
+
"unusedScreenshots": [
|
|
112
|
+
"analytics-list.png",
|
|
113
|
+
"chat-actions-tab.png",
|
|
114
|
+
"chat-conversation.png",
|
|
115
|
+
"chat-entities-tab.png",
|
|
116
|
+
"chat-mentions-popover.png",
|
|
117
|
+
"chat-model-picker.png",
|
|
118
|
+
"chat-search-filter.png",
|
|
119
|
+
"chat-skills-tab.png",
|
|
120
|
+
"chat-slash-popover.png",
|
|
121
|
+
"chat-tools-tab.png",
|
|
122
|
+
"dashboard-below-fold.png",
|
|
123
|
+
"dashboard-create-form-ai-applied.png",
|
|
124
|
+
"dashboard-create-form-ai-assist.png",
|
|
125
|
+
"dashboard-create-form-ai-breakdown.png",
|
|
126
|
+
"dashboard-create-form-empty.png",
|
|
127
|
+
"dashboard-create-form-filled.png",
|
|
128
|
+
"dashboard-workflow-confirm.png",
|
|
129
|
+
"schedules-create-form-empty.png",
|
|
130
|
+
"schedules-create-form-filled.png",
|
|
131
|
+
"schedules-detail.png",
|
|
132
|
+
"settings-browser-tools.png",
|
|
133
|
+
"settings-channels-add-form.png",
|
|
134
|
+
"settings-instance.png",
|
|
135
|
+
"settings-ollama-connected.png",
|
|
136
|
+
"settings-ollama.png",
|
|
137
|
+
"tables-detail-details.png",
|
|
138
|
+
"tables-detail-triggers.png",
|
|
139
|
+
"tables-detail.png",
|
|
140
|
+
"trust-tier-popover.png",
|
|
141
|
+
"workflows-create-form-delay.png"
|
|
142
|
+
],
|
|
143
|
+
"contentMismatches": [
|
|
144
|
+
{
|
|
145
|
+
"journey": "work-use.md",
|
|
146
|
+
"step": "Step 14",
|
|
147
|
+
"screenshot": "inbox-expanded.png",
|
|
148
|
+
"severity": "WRONG",
|
|
149
|
+
"issue": "Shows task detail page, not expanded inbox notification. Needs recapture."
|
|
150
|
+
}
|
|
60
151
|
],
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"settings-ollama-connected.png"
|
|
70
|
-
]
|
|
71
|
-
}
|
|
152
|
+
"summary": {
|
|
153
|
+
"totalFeatures": 50,
|
|
154
|
+
"coveredFeatures": 39,
|
|
155
|
+
"gapCount": 11,
|
|
156
|
+
"unusedScreenshotCount": 30,
|
|
157
|
+
"contentMismatchCount": 1
|
|
158
|
+
}
|
|
159
|
+
}
|
package/docs/.last-generated
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2026-04-
|
|
1
|
+
2026-04-16T06:32:25Z
|
|
@@ -4,9 +4,9 @@ category: "feature-reference"
|
|
|
4
4
|
section: "agent-intelligence"
|
|
5
5
|
route: "cross-cutting"
|
|
6
6
|
tags: [ai-assist, routing, autonomous, swarm, self-improvement, context, parallel, episodic-memory, handoffs]
|
|
7
|
-
features: ["task-definition-ai", "multi-agent-routing", "autonomous-loop-execution", "multi-agent-swarm", "agent-self-improvement", "workflow-context-batching", "parallel-research-fork-join", "agent-episodic-memory", "agent-async-handoffs"]
|
|
7
|
+
features: ["task-definition-ai", "multi-agent-routing", "autonomous-loop-execution", "multi-agent-swarm", "agent-self-improvement", "workflow-context-batching", "parallel-research-fork-join", "agent-episodic-memory", "agent-async-handoffs", "chat-skill-composition"]
|
|
8
8
|
screengrabCount: 0
|
|
9
|
-
lastUpdated: "2026-
|
|
9
|
+
lastUpdated: "2026-04-15"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Agent Intelligence
|
|
@@ -65,6 +65,16 @@ Agents can hand off work to other agents asynchronously through a message bus:
|
|
|
65
65
|
|
|
66
66
|
This enables multi-agent workflows where a researcher discovers a code issue and hands it off to the code reviewer without requiring a pre-built workflow definition.
|
|
67
67
|
|
|
68
|
+
### Skill Composition
|
|
69
|
+
|
|
70
|
+
Chat conversations on capable runtimes can run multiple skills simultaneously, layering specialized behaviors (research, code review, document drafting) onto a single session. The composition engine enforces three guardrails:
|
|
71
|
+
|
|
72
|
+
- **Capability gating** — only runtimes that advertise `supportsSkillComposition` accept more than one active skill; others fall back to single-skill mode with a visible hint.
|
|
73
|
+
- **Conflict heuristic** — new skills whose tools or instructions overlap with an active one trigger a confirmation dialog before the swap is applied.
|
|
74
|
+
- **Prompt-budget eviction** — when the combined skill prompts approach the model's context budget, the oldest low-priority skill is evicted automatically so the conversation stays responsive.
|
|
75
|
+
|
|
76
|
+
The active stack persists on the conversation row (`conversations.active_skill_ids`), and the `mergeActiveSkillIds` helper keeps updates atomic across concurrent activations. See the [Chat](./chat.md) feature doc for the user-facing flow.
|
|
77
|
+
|
|
68
78
|
### Workflow Context Batching
|
|
69
79
|
|
|
70
80
|
In multi-step workflows, context from earlier steps is batched and forwarded to downstream steps. This prevents information loss across the workflow and ensures each step has the full picture of prior results.
|
package/docs/features/chat.md
CHANGED
|
@@ -3,10 +3,10 @@ title: "Chat"
|
|
|
3
3
|
category: "feature-reference"
|
|
4
4
|
section: "chat"
|
|
5
5
|
route: "/chat"
|
|
6
|
-
tags: ["chat", "conversation", "ai", "tool-catalog", "mentions", "channels", "bidirectional"]
|
|
7
|
-
features: ["chat-data-layer", "chat-engine", "chat-api-routes", "chat-ui-shell", "chat-message-rendering", "chat-input-composer", "bidirectional-channel-chat"]
|
|
6
|
+
tags: ["chat", "conversation", "ai", "tool-catalog", "mentions", "channels", "bidirectional", "skills", "templates", "filters", "saved-searches"]
|
|
7
|
+
features: ["chat-data-layer", "chat-engine", "chat-api-routes", "chat-ui-shell", "chat-message-rendering", "chat-input-composer", "bidirectional-channel-chat", "chat-skill-composition", "chat-composition-ui-v1", "chat-conversation-templates", "chat-filter-namespace", "chat-pinned-saved-searches", "saved-search-polish-v1"]
|
|
8
8
|
screengrabCount: 4
|
|
9
|
-
lastUpdated: "2026-
|
|
9
|
+
lastUpdated: "2026-04-15"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Chat
|
|
@@ -18,10 +18,10 @@ The Chat page is your AI-powered command center for everything in your workspace
|
|
|
18
18
|

|
|
19
19
|
*Tool catalog with hero heading, category tabs (Explore / Create / Debug / Automate), Smart Picks row, and conversation sidebar*
|
|
20
20
|
|
|
21
|
-

|
|
22
22
|
*Model selector dropdown showing Claude and Codex models organized by provider with cost tiers*
|
|
23
23
|
|
|
24
|
-

|
|
25
25
|
*Create category selected, showing prompts for spinning up tasks, workflows, and projects*
|
|
26
26
|
|
|
27
27
|

|
|
@@ -61,6 +61,41 @@ Every chat starts a new conversation that is saved automatically. Your conversat
|
|
|
61
61
|
|
|
62
62
|
When bidirectional chat is enabled on a Slack or Telegram delivery channel, messages sent to Stagent from those platforms create conversations visible in the Chat sidebar. The same chat engine handles both web and channel conversations, including tool access, permission handling, and multi-turn context.
|
|
63
63
|
|
|
64
|
+
### Skill Composition
|
|
65
|
+
|
|
66
|
+
On runtimes that support multiple active skills, you can stack specialized behaviors onto a single conversation. Open the slash (`/`) popover and switch to the **Skills** tab — each skill card has an **+ Add** button. Active skills show a badge, and the header reads "N of M active" so you always know where you stand against the runtime's cap (`maxActiveSkills`).
|
|
67
|
+
|
|
68
|
+
- **Modes** — add a skill in `replace` mode to swap it in, or `add` mode to layer it on top of the current stack.
|
|
69
|
+
- **Conflict heuristic** — if a new skill clashes with one already active (overlapping tool needs, contradictory instructions), a confirmation dialog surfaces the conflict so you can choose which to keep.
|
|
70
|
+
- **Prompt-budget eviction** — when the active skill set approaches the model's context budget, the oldest or lowest-priority skill is evicted automatically and shown in a lightweight toast.
|
|
71
|
+
- **Capability gating** — runtimes that do not support composition (currently gated by `RuntimeFeatures.supportsSkillComposition`) render the Skills tab read-only with a "composition disabled on this runtime" hint.
|
|
72
|
+
|
|
73
|
+
The currently active skills are persisted on the conversation itself (`conversations.active_skill_ids`) so re-opening a conversation restores the exact same stack.
|
|
74
|
+
|
|
75
|
+
### Conversation Templates
|
|
76
|
+
|
|
77
|
+
Rather than starting every conversation from a blank prompt, you can kick one off from a saved blueprint. Three entry points:
|
|
78
|
+
|
|
79
|
+
- **Empty-state button** — the chat hero shows a "Start from template" button when no conversation is active.
|
|
80
|
+
- **Slash command** — type `/new-from-template` in the composer to open the picker inline.
|
|
81
|
+
- **Command palette** — press `⌘K` and pick the **Templates** group to browse by name.
|
|
82
|
+
|
|
83
|
+
Each template resolves its opening prompt from the blueprint's optional `chatPrompt` field (falling back to the first step's prompt template if `chatPrompt` is not set). Variables in the prompt are filled in at launch so the conversation opens already primed with context.
|
|
84
|
+
|
|
85
|
+
### Filter Namespace
|
|
86
|
+
|
|
87
|
+
Type `#` in the chat search, the `@` popover, or the Skills popover to filter by namespace. Values can be double-quoted to include spaces — for example, `#scope:"customer support"` matches only entries whose scope equals that phrase. Supported qualifiers include `#scope:`, `#type:`, and surface-specific keys. The same `FilterInput` component powers the `/documents` list page and the `⌘K` palette, so the syntax is identical everywhere.
|
|
88
|
+
|
|
89
|
+
### Saved Searches
|
|
90
|
+
|
|
91
|
+
Frequently used filter + query combinations can be pinned and reused:
|
|
92
|
+
|
|
93
|
+
- **Save a view** — run any search, then click **Save view** in the footer to name and pin it.
|
|
94
|
+
- **Reuse from the palette** — `⌘K` shows a **Saved** group at the top; pick one to re-apply instantly.
|
|
95
|
+
- **Reuse from mentions** — the `@` popover also surfaces saved searches in a dedicated group for in-composer reuse.
|
|
96
|
+
|
|
97
|
+
Saved searches round-trip via `GET/PUT /api/settings/chat/saved-searches`, and the `cleanFilterInput()` helper strips any mention-trigger residue (`@`, `#`, `/`) so a pinned query stays clean no matter where you saved it from.
|
|
98
|
+
|
|
64
99
|
### Streaming Responses
|
|
65
100
|
|
|
66
101
|
Responses stream in token by token with a blinking cursor. Markdown formatting -- headings, lists, code blocks with syntax highlighting, tables, and links -- renders as the text streams in. Code blocks include a copy button and language label.
|
|
@@ -15,7 +15,7 @@ Track spend across providers and monitor token consumption with the cost and usa
|
|
|
15
15
|
|
|
16
16
|
## Screenshots
|
|
17
17
|
|
|
18
|
-

|
|
19
19
|
*The cost and usage dashboard showing spend metrics, provider breakdown, and budget pacing indicators.*
|
|
20
20
|
|
|
21
21
|

|
|
@@ -4,9 +4,9 @@ category: "feature-reference"
|
|
|
4
4
|
section: "documents"
|
|
5
5
|
route: "/documents"
|
|
6
6
|
tags: [documents, upload, preprocessing, pdf, office, text-extraction, agent-context]
|
|
7
|
-
features: ["document-manager", "file-attachment-data-layer", "document-preprocessing", "agent-document-context", "document-output-generation"]
|
|
7
|
+
features: ["document-manager", "file-attachment-data-layer", "document-preprocessing", "agent-document-context", "document-output-generation", "chat-filter-namespace", "chat-pinned-saved-searches"]
|
|
8
8
|
screengrabCount: 2
|
|
9
|
-
lastUpdated: "2026-
|
|
9
|
+
lastUpdated: "2026-04-15"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Documents
|
|
@@ -26,6 +26,9 @@ The Document Library is where you upload, manage, and organize files that agents
|
|
|
26
26
|
### Table and Grid Views
|
|
27
27
|
Toggle between a table view for dense scanning (file name, type, size, processing status, timestamps) and a grid view with visual cards. Both views support selection for bulk operations.
|
|
28
28
|
|
|
29
|
+
### FilterInput and Saved Searches
|
|
30
|
+
The `/documents` list page is the reference consumer for the shared **FilterInput** component. Type `#type:pdf` or `#scope:"legal review"` to filter by namespace — double-quoted values cleanly handle phrases with spaces. Combine filters with a free-text search, then click **Save view** in the footer to pin the combination as a saved search. Saved searches are available across surfaces (Chat, Tables, Documents) via the `⌘K` palette **Saved** group.
|
|
31
|
+
|
|
29
32
|
### Upload Dialog with Drag-and-Drop
|
|
30
33
|
The upload dialog accepts files via drag-and-drop or file picker. A visual indicator shows supported file types. Multiple files can be uploaded in a single batch.
|
|
31
34
|
|