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
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { db } from "@/lib/db";
|
|
2
2
|
import { workflows, tasks, agentLogs, notifications } from "@/lib/db/schema";
|
|
3
|
-
import { eq } from "drizzle-orm";
|
|
4
|
-
import {
|
|
3
|
+
import { and, eq } from "drizzle-orm";
|
|
4
|
+
import { startTaskExecution } from "@/lib/agents/task-dispatch";
|
|
5
5
|
import { classifyTaskProfile } from "@/lib/agents/router";
|
|
6
6
|
import type { WorkflowDefinition, WorkflowState, StepState, LoopState } from "./types";
|
|
7
7
|
import { createInitialState } from "./types";
|
|
8
8
|
import { executeLoop } from "./loop-executor";
|
|
9
|
+
import { checkDelayStep } from "./delay";
|
|
9
10
|
import {
|
|
10
11
|
buildParallelSynthesisPrompt,
|
|
11
12
|
getParallelWorkflowStructure,
|
|
@@ -138,6 +139,24 @@ export async function executeWorkflow(workflowId: string): Promise<void> {
|
|
|
138
139
|
break;
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
// A delay step may have paused the workflow. The sequence executor already
|
|
143
|
+
// persisted the paused state and wrote resume_at; we just need to log the
|
|
144
|
+
// pause and return without marking the workflow "completed".
|
|
145
|
+
if (state.status === "paused") {
|
|
146
|
+
await db.insert(agentLogs).values({
|
|
147
|
+
id: crypto.randomUUID(),
|
|
148
|
+
taskId: null,
|
|
149
|
+
agentType: "workflow-engine",
|
|
150
|
+
event: "workflow_paused_for_delay",
|
|
151
|
+
payload: JSON.stringify({
|
|
152
|
+
workflowId,
|
|
153
|
+
delayedStepIndex: state.currentStepIndex,
|
|
154
|
+
}),
|
|
155
|
+
timestamp: new Date(),
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
141
160
|
state.status = "completed";
|
|
142
161
|
state.completedAt = new Date().toISOString();
|
|
143
162
|
await updateWorkflowState(workflowId, state, "completed");
|
|
@@ -179,20 +198,56 @@ export async function executeWorkflow(workflowId: string): Promise<void> {
|
|
|
179
198
|
|
|
180
199
|
/**
|
|
181
200
|
* Sequence pattern: execute steps one after another, passing output forward.
|
|
201
|
+
*
|
|
202
|
+
* @param fromStepIndex Start index for resuming after a delay. Defaults to 0
|
|
203
|
+
* for fresh executions. resumeWorkflow passes the index
|
|
204
|
+
* of the step after the one that was delayed.
|
|
182
205
|
*/
|
|
183
206
|
async function executeSequence(
|
|
184
207
|
workflowId: string,
|
|
185
208
|
definition: WorkflowDefinition,
|
|
186
209
|
state: WorkflowState,
|
|
187
210
|
parentTaskId?: string,
|
|
188
|
-
workflowRuntimeId?: string
|
|
211
|
+
workflowRuntimeId?: string,
|
|
212
|
+
fromStepIndex: number = 0,
|
|
189
213
|
): Promise<void> {
|
|
190
214
|
let previousOutput = "";
|
|
191
215
|
|
|
192
|
-
for (let i =
|
|
216
|
+
for (let i = fromStepIndex; i < definition.steps.length; i++) {
|
|
193
217
|
const step = definition.steps[i];
|
|
194
218
|
state.currentStepIndex = i;
|
|
195
219
|
|
|
220
|
+
// Delay step: pause the workflow and return. The scheduler tick will call
|
|
221
|
+
// resumeWorkflow when workflows.resume_at <= now(). See features/workflow-step-delays.md.
|
|
222
|
+
const delayCheck = checkDelayStep(step, Date.now());
|
|
223
|
+
if (delayCheck.type === "delay") {
|
|
224
|
+
state.stepStates[i].status = "delayed";
|
|
225
|
+
state.stepStates[i].startedAt = new Date().toISOString();
|
|
226
|
+
state.status = "paused";
|
|
227
|
+
await updateWorkflowState(workflowId, state, "paused");
|
|
228
|
+
// Write resume_at to the indexed workflows column so the scheduler tick
|
|
229
|
+
// can find this workflow efficiently via the partial index.
|
|
230
|
+
await db
|
|
231
|
+
.update(workflows)
|
|
232
|
+
.set({ resumeAt: delayCheck.resumeAt, updatedAt: new Date() })
|
|
233
|
+
.where(eq(workflows.id, workflowId));
|
|
234
|
+
await db.insert(agentLogs).values({
|
|
235
|
+
id: crypto.randomUUID(),
|
|
236
|
+
taskId: null,
|
|
237
|
+
agentType: "workflow-engine",
|
|
238
|
+
event: "step_delayed",
|
|
239
|
+
payload: JSON.stringify({
|
|
240
|
+
workflowId,
|
|
241
|
+
stepId: step.id,
|
|
242
|
+
stepName: step.name,
|
|
243
|
+
delayDuration: step.delayDuration,
|
|
244
|
+
resumeAt: delayCheck.resumeAt,
|
|
245
|
+
}),
|
|
246
|
+
timestamp: new Date(),
|
|
247
|
+
});
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
196
251
|
// Build prompt with context from previous step
|
|
197
252
|
const contextPrompt = previousOutput
|
|
198
253
|
? `Previous step output:\n${previousOutput}\n\n---\n\n${step.prompt}`
|
|
@@ -861,7 +916,7 @@ export async function executeChildTask(
|
|
|
861
916
|
description: enrichedPrompt,
|
|
862
917
|
status: "queued",
|
|
863
918
|
priority: 1,
|
|
864
|
-
|
|
919
|
+
assignedAgent: assignedAgent ?? runtimeId ?? null,
|
|
865
920
|
agentProfile: resolvedProfile ?? null,
|
|
866
921
|
workflowRunNumber: workflow?.runNumber ?? null,
|
|
867
922
|
maxBudgetUsd: maxBudgetUsd ?? null,
|
|
@@ -875,7 +930,9 @@ export async function executeChildTask(
|
|
|
875
930
|
.where(eq(tasks.id, taskId));
|
|
876
931
|
|
|
877
932
|
try {
|
|
878
|
-
await
|
|
933
|
+
await startTaskExecution(taskId, {
|
|
934
|
+
requestedRuntimeId: runtimeId ?? assignedAgent,
|
|
935
|
+
});
|
|
879
936
|
} catch (err) {
|
|
880
937
|
console.error(`[workflow-engine] Runtime execution failed for task ${taskId}:`, err);
|
|
881
938
|
// Mark task as failed in DB so the status check below correctly detects failure
|
|
@@ -1101,7 +1158,20 @@ export async function updateWorkflowState(
|
|
|
1101
1158
|
|
|
1102
1159
|
if (!workflow) throw new Error(`Workflow ${workflowId} not found — cannot update state`);
|
|
1103
1160
|
|
|
1104
|
-
|
|
1161
|
+
// Defensive parse: a workflow row with a missing or corrupted definition
|
|
1162
|
+
// should not crash the engine. We still write the new _state on top, so a
|
|
1163
|
+
// recoverable run can continue even from a partially-written row.
|
|
1164
|
+
let definition: Record<string, unknown> = {};
|
|
1165
|
+
if (workflow.definition) {
|
|
1166
|
+
try {
|
|
1167
|
+
definition = JSON.parse(workflow.definition);
|
|
1168
|
+
} catch (err) {
|
|
1169
|
+
console.error(
|
|
1170
|
+
`[workflow-engine] Failed to parse definition for ${workflowId}, writing fresh state:`,
|
|
1171
|
+
err
|
|
1172
|
+
);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1105
1175
|
const combined = { ...definition, _state: state };
|
|
1106
1176
|
|
|
1107
1177
|
await db
|
|
@@ -1114,6 +1184,141 @@ export async function updateWorkflowState(
|
|
|
1114
1184
|
.where(eq(workflows.id, workflowId));
|
|
1115
1185
|
}
|
|
1116
1186
|
|
|
1187
|
+
/**
|
|
1188
|
+
* Resume a workflow that was paused at a delay step.
|
|
1189
|
+
*
|
|
1190
|
+
* Called by the scheduler tick when workflows.resume_at <= now(), and also
|
|
1191
|
+
* by the manual POST /api/workflows/[id]/resume endpoint when the user clicks
|
|
1192
|
+
* "Resume Now". The status transition is atomic (UPDATE ... WHERE status='paused')
|
|
1193
|
+
* so a scheduler tick and a user click racing each other produces exactly one
|
|
1194
|
+
* resume — the loser sees zero affected rows and returns silently.
|
|
1195
|
+
*
|
|
1196
|
+
* Only supports sequence-pattern workflows — other patterns never enter the
|
|
1197
|
+
* paused state in the first place (delay steps are sequence-only per spec).
|
|
1198
|
+
*/
|
|
1199
|
+
export async function resumeWorkflow(workflowId: string): Promise<void> {
|
|
1200
|
+
// Atomic status transition: only proceed if still paused.
|
|
1201
|
+
const updated = await db
|
|
1202
|
+
.update(workflows)
|
|
1203
|
+
.set({ status: "active", resumeAt: null, updatedAt: new Date() })
|
|
1204
|
+
.where(and(eq(workflows.id, workflowId), eq(workflows.status, "paused")))
|
|
1205
|
+
.returning();
|
|
1206
|
+
|
|
1207
|
+
if (updated.length === 0) {
|
|
1208
|
+
// Workflow is not paused — either already resumed (scheduler raced user,
|
|
1209
|
+
// or vice versa) or doesn't exist. Idempotent: no error, no action.
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
const workflow = updated[0];
|
|
1214
|
+
const { definition, state } = parseWorkflowState(workflow.definition);
|
|
1215
|
+
|
|
1216
|
+
if (!state) {
|
|
1217
|
+
throw new Error(
|
|
1218
|
+
`Workflow ${workflowId} is marked paused but has no persisted state to resume`,
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
if (definition.pattern !== "sequence") {
|
|
1223
|
+
throw new Error(
|
|
1224
|
+
`Workflow ${workflowId} has pattern "${definition.pattern}" — resume is only supported for sequence pattern`,
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
// Mark the delayed step as completed, advance to the next step.
|
|
1229
|
+
const delayedIdx = state.currentStepIndex;
|
|
1230
|
+
const delayedStepState = state.stepStates[delayedIdx];
|
|
1231
|
+
if (delayedStepState && delayedStepState.status === "delayed") {
|
|
1232
|
+
delayedStepState.status = "completed";
|
|
1233
|
+
delayedStepState.completedAt = new Date().toISOString();
|
|
1234
|
+
}
|
|
1235
|
+
state.status = "running";
|
|
1236
|
+
const resumeFromIndex = delayedIdx + 1;
|
|
1237
|
+
|
|
1238
|
+
await db.insert(agentLogs).values({
|
|
1239
|
+
id: crypto.randomUUID(),
|
|
1240
|
+
taskId: null,
|
|
1241
|
+
agentType: "workflow-engine",
|
|
1242
|
+
event: "workflow_resumed",
|
|
1243
|
+
payload: JSON.stringify({ workflowId, resumeFromIndex }),
|
|
1244
|
+
timestamp: new Date(),
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
const parentTaskId = definition.sourceTaskId;
|
|
1248
|
+
const workflowRuntimeId = workflow.runtimeId ?? undefined;
|
|
1249
|
+
|
|
1250
|
+
// Reopen the learning session for this resume. Context proposals gathered
|
|
1251
|
+
// during the pre-pause run were already flushed when the original execute
|
|
1252
|
+
// closed its session; resume starts a fresh batch.
|
|
1253
|
+
openLearningSession(workflowId);
|
|
1254
|
+
|
|
1255
|
+
try {
|
|
1256
|
+
await executeSequence(
|
|
1257
|
+
workflowId,
|
|
1258
|
+
definition,
|
|
1259
|
+
state,
|
|
1260
|
+
parentTaskId,
|
|
1261
|
+
workflowRuntimeId,
|
|
1262
|
+
resumeFromIndex,
|
|
1263
|
+
);
|
|
1264
|
+
|
|
1265
|
+
// Another delay step may have been encountered during resume. TS narrows
|
|
1266
|
+
// state.status to "running" at this point because of the assignment above,
|
|
1267
|
+
// but executeSequence mutates state.status to "paused" when it hits a delay
|
|
1268
|
+
// step — the `as` cast forces TS to forget the narrowing and evaluate the
|
|
1269
|
+
// comparison at runtime.
|
|
1270
|
+
if ((state.status as WorkflowState["status"]) === "paused") {
|
|
1271
|
+
await db.insert(agentLogs).values({
|
|
1272
|
+
id: crypto.randomUUID(),
|
|
1273
|
+
taskId: null,
|
|
1274
|
+
agentType: "workflow-engine",
|
|
1275
|
+
event: "workflow_paused_for_delay",
|
|
1276
|
+
payload: JSON.stringify({
|
|
1277
|
+
workflowId,
|
|
1278
|
+
delayedStepIndex: state.currentStepIndex,
|
|
1279
|
+
}),
|
|
1280
|
+
timestamp: new Date(),
|
|
1281
|
+
});
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
state.status = "completed";
|
|
1286
|
+
state.completedAt = new Date().toISOString();
|
|
1287
|
+
await updateWorkflowState(workflowId, state, "completed");
|
|
1288
|
+
|
|
1289
|
+
await db.insert(agentLogs).values({
|
|
1290
|
+
id: crypto.randomUUID(),
|
|
1291
|
+
taskId: null,
|
|
1292
|
+
agentType: "workflow-engine",
|
|
1293
|
+
event: "workflow_completed",
|
|
1294
|
+
payload: JSON.stringify({ workflowId }),
|
|
1295
|
+
timestamp: new Date(),
|
|
1296
|
+
});
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
state.status = "failed";
|
|
1299
|
+
await updateWorkflowState(workflowId, state, "failed");
|
|
1300
|
+
|
|
1301
|
+
await db.insert(agentLogs).values({
|
|
1302
|
+
id: crypto.randomUUID(),
|
|
1303
|
+
taskId: null,
|
|
1304
|
+
agentType: "workflow-engine",
|
|
1305
|
+
event: "workflow_failed",
|
|
1306
|
+
payload: JSON.stringify({
|
|
1307
|
+
workflowId,
|
|
1308
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1309
|
+
}),
|
|
1310
|
+
timestamp: new Date(),
|
|
1311
|
+
});
|
|
1312
|
+
} finally {
|
|
1313
|
+
updateExecutionStats(workflowId).catch((err) => {
|
|
1314
|
+
console.error("[workflow-engine] Stats update failed:", err);
|
|
1315
|
+
});
|
|
1316
|
+
await closeLearningSession(workflowId).catch((err) => {
|
|
1317
|
+
console.error("[workflow-engine] Failed to close learning session:", err);
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1117
1322
|
/**
|
|
1118
1323
|
* Get the current state of a workflow.
|
|
1119
1324
|
*/
|