denchclaw 2.3.21 → 2.4.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/apps/web/.next/standalone/apps/web/.next/BUILD_ID +1 -1
- package/apps/web/.next/standalone/apps/web/.next/app-build-manifest.json +233 -198
- package/apps/web/.next/standalone/apps/web/.next/app-path-routes-manifest.json +32 -27
- package/apps/web/.next/standalone/apps/web/.next/build-manifest.json +5 -5
- package/apps/web/.next/standalone/apps/web/.next/cache/config.json +3 -3
- package/apps/web/.next/standalone/apps/web/.next/prerender-manifest.json +3 -3
- package/apps/web/.next/standalone/apps/web/.next/react-loadable-manifest.json +1 -4
- package/apps/web/.next/standalone/apps/web/.next/required-server-files.json +1 -1
- package/apps/web/.next/standalone/apps/web/.next/routes-manifest.json +34 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/cron/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/proxy/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/serve/[...path]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/store/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/webhooks/[...path]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/active/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/runs/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stop/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stop/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stream/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/subagents/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/jobs/[jobId]/runs/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/jobs/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/runs/[sessionId]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/runs/search-transcript/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/feedback/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/feedback/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/channels/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/chat/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/chat/stream/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/sessions/[id]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/sessions/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/memories/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/profiles/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/profiles/switch/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/sessions/[sessionId]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/terminal/port/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/[id]/messages/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/[id]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/assets/[...path]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/browse/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/browse-file/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/context/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/copy/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/db/introspect/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/db/query/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/delete/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/delete/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/execute/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/file/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/init/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/init/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/link-preview/route.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/link-preview/route.js.nft.json +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/link-preview/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/list/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/mkdir/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/move/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/route.js +54 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/route.js.nft.json +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/runs/route.js +4 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/runs/route.js.nft.json +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/runs/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/display-field/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/content/route.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/content/route.js.nft.json +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/content/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/bulk-delete/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/options/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/[fieldId]/route.js +9 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/[fieldId]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/reorder/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/route.js +10 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/route.js.nft.json +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/views/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/open-file/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/path-info/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/query/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/raw-file/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/rename/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/reports/execute/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/reports/execute/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/search-index/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/suggest-files/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/switch/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/switch/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/thumbnail/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/tree/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/upload/route.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/upload/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/virtual-file/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/watch/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/write-binary/route_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/page.js +104 -55
- package/apps/web/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/app-paths-manifest.json +32 -27
- package/apps/web/.next/standalone/apps/web/.next/server/chunks/6787.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/chunks/687.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/chunks/8137.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/functions-config-manifest.json +15 -10
- package/apps/web/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/apps/web/.next/standalone/apps/web/.next/server/webpack-runtime.js +1 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/2716-475d96c202834586.js +135 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/cron/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/proxy/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/serve/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/store/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/webhooks/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/active/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/stop/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/stream/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/subagents/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/jobs/[jobId]/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/jobs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/runs/[sessionId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/runs/search-transcript/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/feedback/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/channels/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/chat/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/chat/stream/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/sessions/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/memories/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/profiles/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/profiles/switch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/sessions/[sessionId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/skills/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/terminal/port/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/[id]/messages/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/assets/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/browse/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/browse-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/context/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/copy/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/db/introspect/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/db/query/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/delete/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/execute/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/init/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/link-preview/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/list/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/mkdir/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/move/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/actions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/actions/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/display-field/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/content/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/bulk-delete/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/options/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/reorder/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/views/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/open-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/path-info/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/query/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/raw-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/rename/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/reports/execute/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/search-index/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/suggest-files/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/switch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/thumbnail/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/tree/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/upload/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/virtual-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/watch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/write-binary/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/{layout-2ada610571ddd42f.js → layout-f08988a91b85294a.js} +1 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/page-64cad81306c18be9.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/webpack-a769c08a3fea86bb.js +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/css/fb279c912601f360.css +1 -0
- package/apps/web/.next/standalone/apps/web/.next/static/xzgogMMcs02a6BQa5tMBA/_buildManifest.js +1 -0
- package/apps/web/.next/standalone/apps/web/lib/action-sdk-runtime.js +121 -0
- package/apps/web/.next/standalone/apps/web/package.json +1 -0
- package/apps/web/.next/standalone/apps/web/server.js +1 -1
- package/apps/web/.next/standalone/package.json +1 -1
- package/apps/web/.next/static/chunks/2716-475d96c202834586.js +135 -0
- package/apps/web/.next/static/chunks/app/api/apps/cron/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/apps/proxy/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/apps/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/apps/serve/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/apps/store/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/apps/webhooks/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/active/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/stop/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/stream/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/chat/subagents/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/cron/jobs/[jobId]/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/cron/jobs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/cron/runs/[sessionId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/cron/runs/search-transcript/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/feedback/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/gateway/channels/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/gateway/chat/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/gateway/chat/stream/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/gateway/sessions/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/gateway/sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/memories/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/profiles/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/profiles/switch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/sessions/[sessionId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/skills/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/terminal/port/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/web-sessions/[id]/messages/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/web-sessions/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/web-sessions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/assets/[...path]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/browse/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/browse-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/context/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/copy/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/db/introspect/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/db/query/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/delete/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/execute/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/init/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/link-preview/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/list/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/mkdir/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/move/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/actions/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/actions/runs/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/display-field/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/content/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/bulk-delete/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/options/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/reorder/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/views/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/open-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/path-info/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/query/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/raw-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/rename/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/reports/execute/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/search-index/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/suggest-files/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/switch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/thumbnail/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/tree/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/upload/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/virtual-file/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/watch/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/api/workspace/write-binary/route-d14ffafd970f186e.js +1 -0
- package/apps/web/.next/static/chunks/app/{layout-2ada610571ddd42f.js → layout-f08988a91b85294a.js} +1 -1
- package/apps/web/.next/static/chunks/app/page-64cad81306c18be9.js +1 -0
- package/apps/web/.next/static/chunks/webpack-a769c08a3fea86bb.js +1 -0
- package/apps/web/.next/static/css/fb279c912601f360.css +1 -0
- package/apps/web/.next/static/xzgogMMcs02a6BQa5tMBA/_buildManifest.js +1 -0
- package/assets/seed/schema.sql +15 -0
- package/dist/entry.js +1 -1
- package/dist/{program-IDoEjVLE.js → program-DcrLV9Z2.js} +8 -1
- package/dist/{run-main-D2k8GHwe.js → run-main-D7Ux65aN.js} +1 -1
- package/extensions/dench-identity/index.ts +1 -9
- package/extensions/posthog-analytics/lib/build-env.js +1 -1
- package/package.json +1 -1
- package/skills/crm/SKILL.md +49 -926
- package/skills/crm/actions/SKILL.md +600 -0
- package/skills/crm/documents/SKILL.md +64 -0
- package/skills/crm/duckdb-operations/SKILL.md +546 -0
- package/skills/crm/object-builder/SKILL.md +361 -0
- package/skills/crm/reports/SKILL.md +199 -0
- package/skills/crm/views-filters/SKILL.md +303 -0
- package/skills/gstack/SKILL.md +101 -0
- package/skills/gstack/benchmark/SKILL.md +86 -0
- package/skills/gstack/canary/SKILL.md +65 -0
- package/skills/gstack/careful/SKILL.md +66 -0
- package/skills/gstack/design-consultation/SKILL.md +90 -0
- package/skills/gstack/design-review/SKILL.md +72 -0
- package/skills/gstack/document-release/SKILL.md +112 -0
- package/skills/gstack/freeze/SKILL.md +57 -0
- package/skills/gstack/guard/SKILL.md +37 -0
- package/skills/gstack/investigate/SKILL.md +111 -0
- package/skills/gstack/land-and-deploy/SKILL.md +77 -0
- package/skills/gstack/office-hours/SKILL.md +105 -0
- package/skills/gstack/plan-ceo-review/SKILL.md +108 -0
- package/skills/gstack/plan-design-review/SKILL.md +99 -0
- package/skills/gstack/plan-eng-review/SKILL.md +129 -0
- package/skills/gstack/qa/SKILL.md +121 -0
- package/skills/gstack/qa-only/SKILL.md +51 -0
- package/skills/gstack/retro/SKILL.md +88 -0
- package/skills/gstack/review/SKILL.md +144 -0
- package/skills/gstack/ship/SKILL.md +126 -0
- package/skills/gstack/unfreeze/SKILL.md +23 -0
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/2597.f31531534ad0b96f.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/4652.ca2ab4e205060d84.js +0 -60
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/6861-58d368bcf4e23b55.js +0 -76
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/cron/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/proxy/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/serve/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/store/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/apps/webhooks/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/active/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/runs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/stop/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/stream/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/chat/subagents/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/jobs/[jobId]/runs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/jobs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/runs/[sessionId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/cron/runs/search-transcript/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/feedback/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/channels/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/chat/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/chat/stream/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/sessions/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/gateway/sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/memories/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/profiles/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/profiles/switch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/sessions/[sessionId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/skills/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/terminal/port/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/[id]/messages/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/web-sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/assets/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/browse/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/browse-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/context/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/copy/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/db/introspect/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/db/query/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/delete/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/execute/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/init/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/list/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/mkdir/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/move/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/display-field/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/bulk-delete/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/options/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/reorder/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/views/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/open-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/path-info/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/query/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/raw-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/rename/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/reports/execute/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/search-index/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/suggest-files/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/switch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/thumbnail/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/tree/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/upload/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/virtual-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/watch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/api/workspace/write-binary/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/page-a1a7eac29d935a3e.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/chunks/webpack-43066e1a249665ba.js +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/css/4c7acc74b29f04e2.css +0 -1
- package/apps/web/.next/standalone/apps/web/.next/static/kXwi5ZTYAYlvvWmNAsdo_/_buildManifest.js +0 -1
- package/apps/web/.next/static/chunks/2597.f31531534ad0b96f.js +0 -1
- package/apps/web/.next/static/chunks/4652.ca2ab4e205060d84.js +0 -60
- package/apps/web/.next/static/chunks/6861-58d368bcf4e23b55.js +0 -76
- package/apps/web/.next/static/chunks/app/api/apps/cron/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/apps/proxy/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/apps/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/apps/serve/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/apps/store/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/apps/webhooks/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/active/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/runs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/stop/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/stream/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/chat/subagents/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/cron/jobs/[jobId]/runs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/cron/jobs/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/cron/runs/[sessionId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/cron/runs/search-transcript/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/feedback/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/gateway/channels/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/gateway/chat/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/gateway/chat/stream/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/gateway/sessions/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/gateway/sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/memories/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/profiles/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/profiles/switch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/sessions/[sessionId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/skills/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/terminal/port/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/web-sessions/[id]/messages/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/web-sessions/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/web-sessions/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/assets/[...path]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/browse/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/browse-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/context/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/copy/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/db/introspect/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/db/query/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/delete/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/execute/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/init/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/list/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/mkdir/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/move/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/display-field/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/[id]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/bulk-delete/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/options/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/entries/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/[fieldId]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/fields/reorder/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/objects/[name]/views/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/open-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/path-info/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/query/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/raw-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/rename/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/reports/execute/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/search-index/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/suggest-files/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/switch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/thumbnail/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/tree/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/upload/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/virtual-file/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/watch/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/api/workspace/write-binary/route-580e9ace8a991c49.js +0 -1
- package/apps/web/.next/static/chunks/app/page-a1a7eac29d935a3e.js +0 -1
- package/apps/web/.next/static/chunks/webpack-43066e1a249665ba.js +0 -1
- package/apps/web/.next/static/css/4c7acc74b29f04e2.css +0 -1
- package/apps/web/.next/static/kXwi5ZTYAYlvvWmNAsdo_/_buildManifest.js +0 -1
- /package/apps/web/.next/standalone/apps/web/.next/static/{kXwi5ZTYAYlvvWmNAsdo_ → xzgogMMcs02a6BQa5tMBA}/_ssgManifest.js +0 -0
- /package/apps/web/.next/static/{kXwi5ZTYAYlvvWmNAsdo_ → xzgogMMcs02a6BQa5tMBA}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: object-builder
|
|
3
|
+
description: Full 3-step workflow for creating workspace objects (SQL → filesystem → verify), CRM patterns for common object types, kanban boards, and the post-mutation checklist.
|
|
4
|
+
metadata: { "openclaw": { "inject": true, "always": true, "emoji": "🏗️" } }
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# CRM Object Builder
|
|
8
|
+
|
|
9
|
+
This skill covers creating and modifying workspace objects end-to-end. For DuckDB schema and SQL reference, see **duckdb-operations** (`crm/duckdb-operations/SKILL.md`). For workspace fundamentals, see the parent **crm** skill (`crm/SKILL.md`).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Full Workflow: Create CRM Structure in One Shot
|
|
14
|
+
|
|
15
|
+
EVERY object creation MUST complete ALL THREE steps below. Never stop after the SQL.
|
|
16
|
+
|
|
17
|
+
**Step 1 — SQL: Create object + fields + view** (single exec call):
|
|
18
|
+
|
|
19
|
+
```sql
|
|
20
|
+
BEGIN TRANSACTION;
|
|
21
|
+
|
|
22
|
+
-- 1a. Create object
|
|
23
|
+
INSERT INTO objects (name, description, icon, default_view)
|
|
24
|
+
VALUES ('lead', 'Sales leads tracking', 'user-plus', 'table')
|
|
25
|
+
ON CONFLICT (name) DO NOTHING;
|
|
26
|
+
|
|
27
|
+
-- 1b. Create all fields
|
|
28
|
+
INSERT INTO fields (object_id, name, type, required, sort_order) VALUES
|
|
29
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Full Name', 'text', true, 0),
|
|
30
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Email Address', 'email', true, 1),
|
|
31
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Phone Number', 'phone', false, 2),
|
|
32
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Score', 'number', false, 4),
|
|
33
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Notes', 'richtext', false, 7)
|
|
34
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
35
|
+
|
|
36
|
+
INSERT INTO fields (object_id, name, type, enum_values, enum_colors, sort_order) VALUES
|
|
37
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Status', 'enum',
|
|
38
|
+
'["New","Contacted","Qualified","Converted"]'::JSON,
|
|
39
|
+
'["#94a3b8","#3b82f6","#f59e0b","#22c55e"]'::JSON, 3),
|
|
40
|
+
((SELECT id FROM objects WHERE name = 'lead'), 'Source', 'enum',
|
|
41
|
+
'["Website","Referral","Cold Call","Social"]'::JSON, NULL, 5)
|
|
42
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
43
|
+
|
|
44
|
+
-- 1b-2. Link to company object if it exists (proactive relation)
|
|
45
|
+
INSERT INTO fields (object_id, name, type, related_object_id, relationship_type, sort_order)
|
|
46
|
+
SELECT
|
|
47
|
+
(SELECT id FROM objects WHERE name = 'lead'),
|
|
48
|
+
'Company',
|
|
49
|
+
'relation',
|
|
50
|
+
(SELECT id FROM objects WHERE name = 'company'),
|
|
51
|
+
'many_to_one',
|
|
52
|
+
6
|
|
53
|
+
WHERE EXISTS (SELECT 1 FROM objects WHERE name = 'company')
|
|
54
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
55
|
+
|
|
56
|
+
-- 1c. MANDATORY: auto-generate PIVOT view (list all non-action fields in IN clause)
|
|
57
|
+
CREATE OR REPLACE VIEW v_lead AS
|
|
58
|
+
PIVOT (
|
|
59
|
+
SELECT e.id as entry_id, e.created_at, e.updated_at,
|
|
60
|
+
f.name as field_name, ef.value
|
|
61
|
+
FROM entries e
|
|
62
|
+
JOIN entry_fields ef ON ef.entry_id = e.id
|
|
63
|
+
JOIN fields f ON f.id = ef.field_id
|
|
64
|
+
WHERE e.object_id = (SELECT id FROM objects WHERE name = 'lead')
|
|
65
|
+
AND f.type != 'action'
|
|
66
|
+
) ON field_name IN ('Full Name', 'Email Address', 'Phone Number', 'Status', 'Score', 'Source', 'Company', 'Notes') USING first(value);
|
|
67
|
+
|
|
68
|
+
COMMIT;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Step 2 — Filesystem: Create object directory + .object.yaml** (exec call):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
mkdir -p {{WORKSPACE_PATH}}/lead
|
|
75
|
+
|
|
76
|
+
# Query actual values from DuckDB (do NOT use placeholder strings)
|
|
77
|
+
OBJ_ID=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT id FROM objects WHERE name = 'lead'")
|
|
78
|
+
ENTRY_COUNT=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT COUNT(*) FROM entries WHERE object_id = '$OBJ_ID'")
|
|
79
|
+
|
|
80
|
+
# Write .object.yaml using the actual queried values (note: no 'YAML' — we need variable expansion)
|
|
81
|
+
cat > {{WORKSPACE_PATH}}/lead/.object.yaml << EOF
|
|
82
|
+
id: "$OBJ_ID"
|
|
83
|
+
name: "lead"
|
|
84
|
+
description: "Sales leads tracking"
|
|
85
|
+
icon: "user-plus"
|
|
86
|
+
default_view: "table"
|
|
87
|
+
entry_count: $ENTRY_COUNT
|
|
88
|
+
fields:
|
|
89
|
+
- name: "Full Name"
|
|
90
|
+
type: text
|
|
91
|
+
required: true
|
|
92
|
+
- name: "Email Address"
|
|
93
|
+
type: email
|
|
94
|
+
required: true
|
|
95
|
+
- name: "Phone Number"
|
|
96
|
+
type: phone
|
|
97
|
+
- name: "Status"
|
|
98
|
+
type: enum
|
|
99
|
+
values: ["New", "Contacted", "Qualified", "Converted"]
|
|
100
|
+
- name: "Score"
|
|
101
|
+
type: number
|
|
102
|
+
- name: "Source"
|
|
103
|
+
type: enum
|
|
104
|
+
values: ["Website", "Referral", "Cold Call", "Social"]
|
|
105
|
+
- name: "Company"
|
|
106
|
+
type: relation
|
|
107
|
+
related_object: company
|
|
108
|
+
relationship_type: many_to_one
|
|
109
|
+
- name: "Notes"
|
|
110
|
+
type: richtext
|
|
111
|
+
EOF
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Step 3 — Verify**: Confirm both the view and filesystem exist:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Verify view works
|
|
118
|
+
duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_lead"
|
|
119
|
+
# Verify .object.yaml exists
|
|
120
|
+
cat {{WORKSPACE_PATH}}/lead/.object.yaml
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Kanban Boards
|
|
126
|
+
|
|
127
|
+
When creating task/board objects, use `default_view = 'kanban'` and auto-create Status + Assigned To fields. Set `view_settings.kanbanField` to the enum field that defines columns. Remember: ALL THREE STEPS are required.
|
|
128
|
+
|
|
129
|
+
**Step 1 — SQL:**
|
|
130
|
+
|
|
131
|
+
```sql
|
|
132
|
+
BEGIN TRANSACTION;
|
|
133
|
+
INSERT INTO objects (name, description, icon, default_view)
|
|
134
|
+
VALUES ('task', 'Task tracking board', 'check-square', 'kanban')
|
|
135
|
+
ON CONFLICT (name) DO NOTHING;
|
|
136
|
+
|
|
137
|
+
-- Auto-create Status field with kanban-appropriate values
|
|
138
|
+
INSERT INTO fields (object_id, name, type, enum_values, enum_colors, sort_order)
|
|
139
|
+
VALUES ((SELECT id FROM objects WHERE name = 'task'), 'Status', 'enum',
|
|
140
|
+
'["In Queue","In Progress","Done"]'::JSON,
|
|
141
|
+
'["#94a3b8","#3b82f6","#22c55e"]'::JSON, 0)
|
|
142
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
143
|
+
|
|
144
|
+
-- Auto-create Assigned To field (user type)
|
|
145
|
+
INSERT INTO fields (object_id, name, type, sort_order)
|
|
146
|
+
VALUES ((SELECT id FROM objects WHERE name = 'task'), 'Assigned To', 'user', 1)
|
|
147
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
148
|
+
|
|
149
|
+
-- Auto-create default statuses
|
|
150
|
+
INSERT INTO statuses (object_id, name, color, sort_order, is_default) VALUES
|
|
151
|
+
((SELECT id FROM objects WHERE name = 'task'), 'In Queue', '#94a3b8', 0, true),
|
|
152
|
+
((SELECT id FROM objects WHERE name = 'task'), 'In Progress', '#3b82f6', 1, false),
|
|
153
|
+
((SELECT id FROM objects WHERE name = 'task'), 'Done', '#22c55e', 2, false)
|
|
154
|
+
ON CONFLICT (object_id, name) DO NOTHING;
|
|
155
|
+
|
|
156
|
+
CREATE OR REPLACE VIEW v_task AS
|
|
157
|
+
PIVOT (
|
|
158
|
+
SELECT e.id as entry_id, e.created_at, e.updated_at,
|
|
159
|
+
f.name as field_name, ef.value
|
|
160
|
+
FROM entries e
|
|
161
|
+
JOIN entry_fields ef ON ef.entry_id = e.id
|
|
162
|
+
JOIN fields f ON f.id = ef.field_id
|
|
163
|
+
WHERE e.object_id = (SELECT id FROM objects WHERE name = 'task')
|
|
164
|
+
AND f.type != 'action'
|
|
165
|
+
) ON field_name IN ('Title', 'Description', 'Status', 'Priority', 'Due Date', 'Assigned To', 'Notes') USING first(value);
|
|
166
|
+
|
|
167
|
+
COMMIT;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Step 2 — Filesystem (MANDATORY):**
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
mkdir -p {{WORKSPACE_PATH}}/task
|
|
174
|
+
OBJ_ID=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT id FROM objects WHERE name = 'task'")
|
|
175
|
+
|
|
176
|
+
cat > {{WORKSPACE_PATH}}/task/.object.yaml << EOF
|
|
177
|
+
id: "$OBJ_ID"
|
|
178
|
+
name: "task"
|
|
179
|
+
description: "Task tracking board"
|
|
180
|
+
icon: "check-square"
|
|
181
|
+
default_view: "kanban"
|
|
182
|
+
entry_count: 0
|
|
183
|
+
view_settings:
|
|
184
|
+
kanbanField: "Status"
|
|
185
|
+
fields:
|
|
186
|
+
- name: "Status"
|
|
187
|
+
type: enum
|
|
188
|
+
values: ["In Queue", "In Progress", "Done"]
|
|
189
|
+
- name: "Assigned To"
|
|
190
|
+
type: user
|
|
191
|
+
EOF
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Step 3 — Verify:** `duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_task"` and `cat {{WORKSPACE_PATH}}/task/.object.yaml`.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Proactive Relation Creation (IMPORTANT)
|
|
199
|
+
|
|
200
|
+
**When creating multiple objects, ALWAYS create relation fields to link them — even if the user did not explicitly ask for it.** Real-world data is interconnected. If two objects are obviously related, link them. The user expects this; not linking them is a missed opportunity that forces manual work later.
|
|
201
|
+
|
|
202
|
+
### When to create relations automatically
|
|
203
|
+
|
|
204
|
+
- **People + Company** → add "Company" relation on people (many_to_one → company)
|
|
205
|
+
- **Deal/Opportunity + Contact** → add "Primary Contact" relation on deal (many_to_one → people)
|
|
206
|
+
- **Deal + Company** → add "Company" relation on deal (many_to_one → company)
|
|
207
|
+
- **Task + Project** → add "Project" relation on task (many_to_one → project)
|
|
208
|
+
- **Task + Contact/Person** → add "Related Contact" relation on task (many_to_one → people)
|
|
209
|
+
- **Case + Client** → add "Client" relation on case (many_to_one → people or company)
|
|
210
|
+
- **Invoice + Company** → add "Company" relation on invoice (many_to_one → company)
|
|
211
|
+
- **Invoice + Deal** → add "Deal" relation on invoice (many_to_one → deal)
|
|
212
|
+
- **Property + Agent** → add "Agent" relation on property (many_to_one → people)
|
|
213
|
+
- **Any child object + parent object** → link child to parent
|
|
214
|
+
|
|
215
|
+
**General rule**: If you're creating object B and object A already exists (or is being created alongside), ask yourself: "Would an entry in B logically belong to or reference an entry in A?" If yes, add a relation field.
|
|
216
|
+
|
|
217
|
+
### Relation field SQL pattern
|
|
218
|
+
|
|
219
|
+
```sql
|
|
220
|
+
INSERT INTO fields (object_id, name, type, related_object_id, relationship_type, sort_order)
|
|
221
|
+
VALUES (
|
|
222
|
+
(SELECT id FROM objects WHERE name = 'people'),
|
|
223
|
+
'Company',
|
|
224
|
+
'relation',
|
|
225
|
+
(SELECT id FROM objects WHERE name = 'company'),
|
|
226
|
+
'many_to_one',
|
|
227
|
+
3
|
|
228
|
+
) ON CONFLICT (object_id, name) DO NOTHING;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Use `many_to_one` when each entry links to exactly one entry in the other object (most common). Use `many_to_many` when an entry can link to multiple entries (e.g., project → team members).
|
|
232
|
+
|
|
233
|
+
**Relation fields must be created via SQL** — the API does not support the `relation` type.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## CRM Patterns
|
|
238
|
+
|
|
239
|
+
### Contact/Customer
|
|
240
|
+
|
|
241
|
+
- Full Name (text, required), Email Address (email, required), Phone Number (phone), **Company (relation → company, many_to_one)**, Notes (richtext)
|
|
242
|
+
- Universal pattern for clients, customers, patients, members
|
|
243
|
+
- **Always link to company** if a company object exists or is being created
|
|
244
|
+
|
|
245
|
+
### Lead/Prospect
|
|
246
|
+
|
|
247
|
+
- Full Name (text, required), Email Address (email, required), Phone Number (phone), Status (enum: New/Contacted/Qualified/Converted), Source (enum: Website/Referral/Cold Call/Social), Score (number), **Company (relation → company, many_to_one)**, Assigned To (user), Notes (richtext)
|
|
248
|
+
- Sales, legal intake, real estate prospects
|
|
249
|
+
- **Link to company** when company object exists; **link to deal** if deal pipeline is also being set up
|
|
250
|
+
|
|
251
|
+
### Company/Organization
|
|
252
|
+
|
|
253
|
+
- Company Name (text, required), Industry (enum), Website (url), Type (enum: Client/Partner/Vendor), Relationship Status (enum), Notes (richtext)
|
|
254
|
+
- B2B relationships, vendor management
|
|
255
|
+
- Other objects typically link TO company (people, deals, invoices), not the other way around
|
|
256
|
+
|
|
257
|
+
### Deal/Opportunity
|
|
258
|
+
|
|
259
|
+
- Deal Name (text, required), Amount (number), Stage (enum: Discovery/Proposal/Negotiation/Closed Won/Closed Lost), Close Date (date), Probability (number), **Primary Contact (relation → people, many_to_one)**, **Company (relation → company, many_to_one)**, Assigned To (user), Notes (richtext)
|
|
260
|
+
- Sales pipeline, project bids
|
|
261
|
+
- **Always link to contact AND company** — a deal without a contact or company is incomplete
|
|
262
|
+
|
|
263
|
+
### Case/Project
|
|
264
|
+
|
|
265
|
+
- Case Number (text, required), Title (text, required), **Client (relation → people or company, many_to_one)**, Status (enum: Open/In Progress/Closed), Priority (enum: Low/Medium/High/Urgent), Due Date (date), Assigned To (user), Notes (richtext)
|
|
266
|
+
- Legal cases, client projects
|
|
267
|
+
- **Always link to client** (person or company depending on context)
|
|
268
|
+
|
|
269
|
+
### Property/Asset
|
|
270
|
+
|
|
271
|
+
- Address (text, required), Property Type (enum), Price (number), Status (enum: Available/Under Contract/Sold), Square Footage (number), Bedrooms (number), **Agent (relation → people, many_to_one)**, **Client (relation → people, many_to_one)**, Notes (richtext)
|
|
272
|
+
- Real estate listings, asset management
|
|
273
|
+
- **Link to agent and/or client** when people object exists
|
|
274
|
+
|
|
275
|
+
### Task/Activity (use kanban)
|
|
276
|
+
|
|
277
|
+
- Title (text, required), Description (text), Assigned To (user), Due Date (date), Status (enum: In Queue/In Progress/Done), Priority (enum: Low/Medium/High), **Related To (relation → contextual parent, many_to_one)**, Notes (richtext)
|
|
278
|
+
- Use `default_view = 'kanban'` — auto-creates Status and Assigned To fields
|
|
279
|
+
- **Link to parent object** (project, deal, case, etc.) whenever tasks are created alongside another object
|
|
280
|
+
|
|
281
|
+
### Invoice/Payment
|
|
282
|
+
|
|
283
|
+
- Invoice Number (text, required), Amount (number), Status (enum: Draft/Sent/Paid/Overdue), Due Date (date), **Company (relation → company, many_to_one)**, **Deal (relation → deal, many_to_one)**, Notes (richtext)
|
|
284
|
+
- Billing, payments
|
|
285
|
+
- **Always link to company and optionally to deal**
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Post-Mutation Checklist (MANDATORY)
|
|
290
|
+
|
|
291
|
+
You MUST complete ALL steps below after ANY schema mutation (create/update/delete object, field, or entry). Do NOT skip any step. Do NOT consider the operation complete until all steps are done.
|
|
292
|
+
|
|
293
|
+
### After creating or modifying an OBJECT or its FIELDS:
|
|
294
|
+
|
|
295
|
+
- [ ] `CREATE OR REPLACE VIEW v_{object_name}` — regenerate the PIVOT view
|
|
296
|
+
- [ ] `mkdir -p {{WORKSPACE_PATH}}/{object_name}/` — create the object directory
|
|
297
|
+
- [ ] Write `{{WORKSPACE_PATH}}/{object_name}/.object.yaml` — metadata projection with id, name, description, icon, default_view, entry_count, and full field list
|
|
298
|
+
- [ ] If object has a `parent_document_id`, place directory inside the parent document's directory
|
|
299
|
+
- [ ] Update `WORKSPACE.md` if it exists
|
|
300
|
+
|
|
301
|
+
### After adding or updating ENTRIES:
|
|
302
|
+
|
|
303
|
+
- [ ] Update `entry_count` in the corresponding `.object.yaml`
|
|
304
|
+
- [ ] Verify the view returns correct data: `SELECT * FROM v_{object} LIMIT 5`
|
|
305
|
+
|
|
306
|
+
### After deleting an OBJECT:
|
|
307
|
+
|
|
308
|
+
- [ ] `DROP VIEW IF EXISTS v_{object_name}` — remove the view
|
|
309
|
+
- [ ] `rm -rf {{WORKSPACE_PATH}}/{object_name}/` — remove the directory (unless it contains nested documents that need relocating)
|
|
310
|
+
- [ ] Update `WORKSPACE.md`
|
|
311
|
+
|
|
312
|
+
### After creating or modifying a DOCUMENT:
|
|
313
|
+
|
|
314
|
+
- [ ] Write the `.md` file to the correct path in `{{WORKSPACE_PATH}}/**`
|
|
315
|
+
- [ ] `INSERT INTO documents` — ensure metadata row exists with correct `file_path`, `parent_id`, or `parent_object_id`
|
|
316
|
+
|
|
317
|
+
### After adding ACTION FIELDS to an object:
|
|
318
|
+
|
|
319
|
+
- [ ] `mkdir -p {{WORKSPACE_PATH}}/{object_name}/.actions/` — create the actions directory
|
|
320
|
+
- [ ] **Write every script file** referenced by `scriptPath` in the action config (e.g. `.actions/send-email.js`)
|
|
321
|
+
- [ ] Regenerate PIVOT view (exclude action fields with `AND f.type != 'action'`)
|
|
322
|
+
- [ ] Update `.object.yaml` with the action field including `action_config`
|
|
323
|
+
- [ ] Verify script files exist: `ls {{WORKSPACE_PATH}}/{object_name}/.actions/`
|
|
324
|
+
|
|
325
|
+
See the **actions** child skill (`crm/actions/SKILL.md`) for the complete end-to-end action creation walkthrough.
|
|
326
|
+
|
|
327
|
+
These steps ensure the filesystem always mirrors DuckDB. The sidebar depends on `.object.yaml` files — if they are missing, objects will not appear.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Common Mistakes and Recovery
|
|
332
|
+
|
|
333
|
+
### Object exists in DuckDB but doesn't appear in the sidebar
|
|
334
|
+
The `.object.yaml` file is missing. Regenerate it:
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
OBJ_ID=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT id FROM objects WHERE name = 'lead'")
|
|
338
|
+
mkdir -p {{WORKSPACE_PATH}}/lead
|
|
339
|
+
# Then write .object.yaml with the correct id, name, fields, and entry_count
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### PIVOT view returns wrong columns or errors
|
|
343
|
+
The `IN (...)` field list is out of date. Regenerate the view by querying current fields:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
duckdb {{WORKSPACE_PATH}}/workspace.duckdb -json "SELECT name FROM fields WHERE object_id = (SELECT id FROM objects WHERE name = 'lead') AND type != 'action' ORDER BY sort_order"
|
|
347
|
+
# Use the output to rebuild the IN clause in the PIVOT view
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### `.object.yaml` is out of sync with DuckDB
|
|
351
|
+
Query the current state and rewrite the file:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
OBJ_ID=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT id FROM objects WHERE name = 'lead'")
|
|
355
|
+
ENTRY_COUNT=$(duckdb {{WORKSPACE_PATH}}/workspace.duckdb -noheader -list "SELECT COUNT(*) FROM entries WHERE object_id = '$OBJ_ID'")
|
|
356
|
+
duckdb {{WORKSPACE_PATH}}/workspace.duckdb -json "SELECT name, type, required, enum_values, default_value FROM fields WHERE object_id = '$OBJ_ID' ORDER BY sort_order"
|
|
357
|
+
# Use these values to rebuild .object.yaml
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### DuckDB name doesn't match directory name
|
|
361
|
+
All three must be identical: the DuckDB `objects.name`, the filesystem directory name, and `.object.yaml` `name`. If they diverge, rename them to match. See the "Renaming / Moving Objects" section in the parent CRM skill.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reports
|
|
3
|
+
description: Report generation with .report.json format, interactive chart types (bar, line, area, pie, donut, radar, scatter, funnel), panel sizes, filter types, inline chat reports, and post-report checklist.
|
|
4
|
+
metadata: { "openclaw": { "inject": true, "always": true, "emoji": "📈" } }
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# CRM Reports
|
|
8
|
+
|
|
9
|
+
This skill covers report generation and inline chat charts. For workspace fundamentals, see the parent **crm** skill (`crm/SKILL.md`). For DuckDB queries used in report SQL, see **duckdb-operations** (`crm/duckdb-operations/SKILL.md`).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Report Generation (Analytics / Charts)
|
|
14
|
+
|
|
15
|
+
Reports are JSON config files (`.report.json`) that the web app renders as live interactive dashboards using Recharts. The agent creates these files to give the user visual analytics over their CRM data.
|
|
16
|
+
|
|
17
|
+
### Report file format
|
|
18
|
+
|
|
19
|
+
Store reports as `.report.json` files in `{{WORKSPACE_PATH}}/**` (wherever appropriate / create directories if you need for better structure). The JSON schema:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"version": 1,
|
|
24
|
+
"title": "Report Title",
|
|
25
|
+
"description": "Brief description of what this report shows",
|
|
26
|
+
"panels": [
|
|
27
|
+
{
|
|
28
|
+
"id": "unique-panel-id",
|
|
29
|
+
"title": "Panel Title",
|
|
30
|
+
"type": "bar",
|
|
31
|
+
"sql": "SELECT ... FROM v_{object} ...",
|
|
32
|
+
"mapping": { "xAxis": "column_name", "yAxis": ["value_column"] },
|
|
33
|
+
"size": "half"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"filters": [
|
|
37
|
+
{
|
|
38
|
+
"id": "filter-id",
|
|
39
|
+
"type": "dateRange",
|
|
40
|
+
"label": "Date Range",
|
|
41
|
+
"column": "created_at"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Chart types
|
|
48
|
+
|
|
49
|
+
| Type | Best for | Required mapping |
|
|
50
|
+
| --------- | ---------------------------- | ------------------------------- |
|
|
51
|
+
| `bar` | Comparing categories | `xAxis`, `yAxis` |
|
|
52
|
+
| `line` | Trends over time | `xAxis`, `yAxis` |
|
|
53
|
+
| `area` | Volume trends | `xAxis`, `yAxis` |
|
|
54
|
+
| `pie` | Distribution/share | `nameKey`, `valueKey` |
|
|
55
|
+
| `donut` | Distribution (with center) | `nameKey`, `valueKey` |
|
|
56
|
+
| `radar` | Multi-dimensional comparison | `xAxis` (or `nameKey`), `yAxis` |
|
|
57
|
+
| `scatter` | Correlation | `xAxis`, `yAxis` |
|
|
58
|
+
| `funnel` | Pipeline/conversion | `nameKey`, `valueKey` |
|
|
59
|
+
|
|
60
|
+
### Panel sizes
|
|
61
|
+
|
|
62
|
+
- `"full"` — spans full width (6 columns)
|
|
63
|
+
- `"half"` — spans half width (3 columns) — **default**
|
|
64
|
+
- `"third"` — spans one third (2 columns)
|
|
65
|
+
|
|
66
|
+
### Filter types
|
|
67
|
+
|
|
68
|
+
- `dateRange` — date picker (from/to), filters on `column`
|
|
69
|
+
- `select` — single-select dropdown, needs `sql` to fetch options
|
|
70
|
+
- `multiSelect` — multi-select chips, needs `sql` to fetch options
|
|
71
|
+
- `number` — min/max numeric range
|
|
72
|
+
|
|
73
|
+
### SQL query rules for reports
|
|
74
|
+
|
|
75
|
+
- Always use the auto-generated `v_{object}` PIVOT views — never raw EAV queries
|
|
76
|
+
- SQL must be SELECT-only (no INSERT/UPDATE/DELETE)
|
|
77
|
+
- Cast numeric fields: `"Amount"::NUMERIC` or `CAST("Amount" AS NUMERIC)`
|
|
78
|
+
- Use `DATE_TRUNC('month', created_at)` for time-series grouping
|
|
79
|
+
- Always include `ORDER BY` for consistent chart rendering
|
|
80
|
+
- Use aggregate functions: `COUNT(*)`, `SUM(...)`, `AVG(...)`, `MIN(...)`, `MAX(...)`
|
|
81
|
+
- **Double-quote field names with spaces**: `"Full Name"`, `"Email Address"`, `"Assigned To"`
|
|
82
|
+
- **Verify the PIVOT view exists before writing report SQL**: run `SELECT COUNT(*) FROM v_{object}` first. If the view doesn't exist, create it (see **duckdb-operations** skill).
|
|
83
|
+
|
|
84
|
+
### Before writing a report
|
|
85
|
+
|
|
86
|
+
1. **Verify the PIVOT view exists**: `duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_{object}"` — if this fails, the view needs to be created first.
|
|
87
|
+
2. **Check the view columns**: `duckdb {{WORKSPACE_PATH}}/workspace.duckdb -json "SELECT * FROM v_{object} LIMIT 1"` — use the actual column names in your SQL (they are case-sensitive and may contain spaces).
|
|
88
|
+
3. **Test each panel's SQL individually**: Run each query to confirm it returns data before assembling the report JSON.
|
|
89
|
+
|
|
90
|
+
### Handling empty data
|
|
91
|
+
|
|
92
|
+
If a view exists but returns 0 rows, the chart will render but show nothing. This is fine — no special handling needed. However, if the user asks "why is the chart empty?", check:
|
|
93
|
+
- Are there entries in the object? `SELECT COUNT(*) FROM entries WHERE object_id = (SELECT id FROM objects WHERE name = '{object}')`
|
|
94
|
+
- Do entries have field values? `SELECT COUNT(*) FROM entry_fields WHERE entry_id IN (SELECT id FROM entries WHERE object_id = ...)`
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Example Reports
|
|
99
|
+
|
|
100
|
+
### Pipeline Funnel
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"version": 1,
|
|
105
|
+
"title": "Deal Pipeline",
|
|
106
|
+
"description": "Deal count and value by stage",
|
|
107
|
+
"panels": [
|
|
108
|
+
{
|
|
109
|
+
"id": "deals-by-stage",
|
|
110
|
+
"title": "Deals by Stage",
|
|
111
|
+
"type": "funnel",
|
|
112
|
+
"sql": "SELECT \"Stage\", COUNT(*) as count FROM v_deal GROUP BY \"Stage\" ORDER BY count DESC",
|
|
113
|
+
"mapping": { "nameKey": "Stage", "valueKey": "count" },
|
|
114
|
+
"size": "half"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "revenue-by-stage",
|
|
118
|
+
"title": "Revenue by Stage",
|
|
119
|
+
"type": "bar",
|
|
120
|
+
"sql": "SELECT \"Stage\", SUM(\"Amount\"::NUMERIC) as total FROM v_deal GROUP BY \"Stage\" ORDER BY total DESC",
|
|
121
|
+
"mapping": { "xAxis": "Stage", "yAxis": ["total"] },
|
|
122
|
+
"size": "half"
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
"filters": [
|
|
126
|
+
{ "id": "date", "type": "dateRange", "label": "Created", "column": "created_at" },
|
|
127
|
+
{
|
|
128
|
+
"id": "assignee",
|
|
129
|
+
"type": "select",
|
|
130
|
+
"label": "Assigned To",
|
|
131
|
+
"sql": "SELECT DISTINCT \"Assigned To\" as value FROM v_deal WHERE \"Assigned To\" IS NOT NULL",
|
|
132
|
+
"column": "Assigned To"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Contact Growth
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"version": 1,
|
|
143
|
+
"title": "Contact Growth",
|
|
144
|
+
"description": "New contacts over time",
|
|
145
|
+
"panels": [
|
|
146
|
+
{
|
|
147
|
+
"id": "growth-trend",
|
|
148
|
+
"title": "Contacts Over Time",
|
|
149
|
+
"type": "area",
|
|
150
|
+
"sql": "SELECT DATE_TRUNC('month', created_at) as month, COUNT(*) as count FROM v_people GROUP BY month ORDER BY month",
|
|
151
|
+
"mapping": { "xAxis": "month", "yAxis": ["count"] },
|
|
152
|
+
"size": "full"
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Inline Chat Reports
|
|
161
|
+
|
|
162
|
+
When a user asks for analytics in chat (without explicitly asking to save a report), emit the report JSON inside a fenced code block with language `report-json`. The web UI will render interactive charts inline:
|
|
163
|
+
|
|
164
|
+
````
|
|
165
|
+
Here's your pipeline analysis:
|
|
166
|
+
|
|
167
|
+
```report-json
|
|
168
|
+
{"version":1,"title":"Deals by Stage","panels":[{"id":"p1","title":"Deal Count","type":"bar","sql":"SELECT \"Stage\", COUNT(*) as count FROM v_deal GROUP BY \"Stage\" ORDER BY count DESC","mapping":{"xAxis":"Stage","yAxis":["count"]},"size":"full"}]}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Most deals are currently in the Discovery stage.
|
|
172
|
+
````
|
|
173
|
+
|
|
174
|
+
The user can then "Pin" the inline report to save it as a `.report.json` file.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Post-Report Checklist
|
|
179
|
+
|
|
180
|
+
After creating a `.report.json` file:
|
|
181
|
+
|
|
182
|
+
- [ ] **Verify the PIVOT view exists**: `duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_{object}"` — create the view if missing
|
|
183
|
+
- [ ] **Test each panel's SQL individually**: Run each query against the DB to confirm it returns valid data
|
|
184
|
+
- [ ] Verify the report JSON is valid (proper JSON syntax, no trailing commas)
|
|
185
|
+
- [ ] Choose which directory the report should be created in `{{WORKSPACE_PATH}}` based on the context of the conversation, if nothing very relevant, create/use the `{{WORKSPACE_PATH}}/reports/` directory.
|
|
186
|
+
- [ ] Write the file: `{{WORKSPACE_PATH}}/**/{slug}.report.json`
|
|
187
|
+
- [ ] Tell the user they can view it in the workspace sidebar under whichever directory it was rightfully placed in based on the context.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Choosing the Right Chart Type
|
|
192
|
+
|
|
193
|
+
- **Comparing categories** (status breakdown, source distribution): `bar` or `pie`
|
|
194
|
+
- **Time series** (growth, trends, revenue over time): `line` or `area`
|
|
195
|
+
- **Pipeline/conversion** (deal stages, lead funnel): `funnel`
|
|
196
|
+
- **Distribution/proportion** (market share, segment split): `pie` or `donut`
|
|
197
|
+
- **Multi-metric comparison** (performance scores): `radar`
|
|
198
|
+
- **Correlation** (price vs. size, score vs. revenue): `scatter`
|
|
199
|
+
- When in doubt, `bar` is the safest default
|