@nex-ai/nex 0.1.65 → 0.2.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 +236 -231
- package/bin/nex-mcp.js +50 -0
- package/bin/nex.js +53 -0
- package/package.json +9 -36
- package/dist/agent/adoption.d.ts +0 -23
- package/dist/agent/adoption.js +0 -87
- package/dist/agent/adoption.js.map +0 -1
- package/dist/agent/gossip.d.ts +0 -17
- package/dist/agent/gossip.js +0 -48
- package/dist/agent/gossip.js.map +0 -1
- package/dist/agent/loop.d.ts +0 -59
- package/dist/agent/loop.js +0 -389
- package/dist/agent/loop.js.map +0 -1
- package/dist/agent/queues.d.ts +0 -16
- package/dist/agent/queues.js +0 -44
- package/dist/agent/queues.js.map +0 -1
- package/dist/agent/session-store.d.ts +0 -21
- package/dist/agent/session-store.js +0 -96
- package/dist/agent/session-store.js.map +0 -1
- package/dist/agent/templates.d.ts +0 -5
- package/dist/agent/templates.js +0 -55
- package/dist/agent/templates.js.map +0 -1
- package/dist/agent/tools.d.ts +0 -25
- package/dist/agent/tools.js +0 -238
- package/dist/agent/tools.js.map +0 -1
- package/dist/agent/types.d.ts +0 -59
- package/dist/agent/types.js +0 -5
- package/dist/agent/types.js.map +0 -1
- package/dist/calendar/scheduler.d.ts +0 -32
- package/dist/calendar/scheduler.js +0 -178
- package/dist/calendar/scheduler.js.map +0 -1
- package/dist/calendar/store.d.ts +0 -15
- package/dist/calendar/store.js +0 -50
- package/dist/calendar/store.js.map +0 -1
- package/dist/calendar/types.d.ts +0 -17
- package/dist/calendar/types.js +0 -5
- package/dist/calendar/types.js.map +0 -1
- package/dist/chat/channel.d.ts +0 -20
- package/dist/chat/channel.js +0 -84
- package/dist/chat/channel.js.map +0 -1
- package/dist/chat/message-store.d.ts +0 -18
- package/dist/chat/message-store.js +0 -82
- package/dist/chat/message-store.js.map +0 -1
- package/dist/chat/router.d.ts +0 -17
- package/dist/chat/router.js +0 -65
- package/dist/chat/router.js.map +0 -1
- package/dist/chat/suggested-responses.d.ts +0 -6
- package/dist/chat/suggested-responses.js +0 -99
- package/dist/chat/suggested-responses.js.map +0 -1
- package/dist/chat/types.d.ts +0 -28
- package/dist/chat/types.js +0 -5
- package/dist/chat/types.js.map +0 -1
- package/dist/cli.d.ts +0 -5
- package/dist/cli.js +0 -20
- package/dist/cli.js.map +0 -1
- package/dist/commands/attribute.d.ts +0 -4
- package/dist/commands/attribute.js +0 -75
- package/dist/commands/attribute.js.map +0 -1
- package/dist/commands/config-cmd.d.ts +0 -4
- package/dist/commands/config-cmd.js +0 -53
- package/dist/commands/config-cmd.js.map +0 -1
- package/dist/commands/context.d.ts +0 -4
- package/dist/commands/context.js +0 -167
- package/dist/commands/context.js.map +0 -1
- package/dist/commands/dispatch.d.ts +0 -44
- package/dist/commands/dispatch.js +0 -1544
- package/dist/commands/dispatch.js.map +0 -1
- package/dist/commands/graph.d.ts +0 -5
- package/dist/commands/graph.js +0 -77
- package/dist/commands/graph.js.map +0 -1
- package/dist/commands/init.d.ts +0 -49
- package/dist/commands/init.js +0 -319
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/insight.d.ts +0 -4
- package/dist/commands/insight.js +0 -39
- package/dist/commands/insight.js.map +0 -1
- package/dist/commands/integrate.d.ts +0 -4
- package/dist/commands/integrate.js +0 -361
- package/dist/commands/integrate.js.map +0 -1
- package/dist/commands/list-job.d.ts +0 -4
- package/dist/commands/list-job.js +0 -41
- package/dist/commands/list-job.js.map +0 -1
- package/dist/commands/list.d.ts +0 -4
- package/dist/commands/list.js +0 -148
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/note.d.ts +0 -4
- package/dist/commands/note.js +0 -77
- package/dist/commands/note.js.map +0 -1
- package/dist/commands/object.d.ts +0 -4
- package/dist/commands/object.js +0 -78
- package/dist/commands/object.js.map +0 -1
- package/dist/commands/parse-input.d.ts +0 -5
- package/dist/commands/parse-input.js +0 -37
- package/dist/commands/parse-input.js.map +0 -1
- package/dist/commands/record.d.ts +0 -4
- package/dist/commands/record.js +0 -126
- package/dist/commands/record.js.map +0 -1
- package/dist/commands/register.d.ts +0 -4
- package/dist/commands/register.js +0 -23
- package/dist/commands/register.js.map +0 -1
- package/dist/commands/relationship.d.ts +0 -4
- package/dist/commands/relationship.js +0 -80
- package/dist/commands/relationship.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -4
- package/dist/commands/scan.js +0 -111
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/search.d.ts +0 -4
- package/dist/commands/search.js +0 -62
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/session.d.ts +0 -4
- package/dist/commands/session.js +0 -31
- package/dist/commands/session.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -25
- package/dist/commands/setup.js +0 -584
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/task.d.ts +0 -4
- package/dist/commands/task.js +0 -140
- package/dist/commands/task.js.map +0 -1
- package/dist/commands/workspace.d.ts +0 -8
- package/dist/commands/workspace.js +0 -251
- package/dist/commands/workspace.js.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -142
- package/dist/index.js.map +0 -1
- package/dist/lib/capture-filter.d.ts +0 -9
- package/dist/lib/capture-filter.js +0 -14
- package/dist/lib/capture-filter.js.map +0 -1
- package/dist/lib/client.d.ts +0 -20
- package/dist/lib/client.js +0 -160
- package/dist/lib/client.js.map +0 -1
- package/dist/lib/compounding-worker.d.ts +0 -2
- package/dist/lib/compounding-worker.js +0 -21
- package/dist/lib/compounding-worker.js.map +0 -1
- package/dist/lib/compounding.d.ts +0 -20
- package/dist/lib/compounding.js +0 -45
- package/dist/lib/compounding.js.map +0 -1
- package/dist/lib/config.d.ts +0 -35
- package/dist/lib/config.js +0 -96
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/context-format.d.ts +0 -7
- package/dist/lib/context-format.js +0 -21
- package/dist/lib/context-format.js.map +0 -1
- package/dist/lib/errors.d.ts +0 -18
- package/dist/lib/errors.js +0 -30
- package/dist/lib/errors.js.map +0 -1
- package/dist/lib/file-scanner.d.ts +0 -38
- package/dist/lib/file-scanner.js +0 -188
- package/dist/lib/file-scanner.js.map +0 -1
- package/dist/lib/graph-html.d.ts +0 -59
- package/dist/lib/graph-html.js +0 -859
- package/dist/lib/graph-html.js.map +0 -1
- package/dist/lib/installers.d.ts +0 -80
- package/dist/lib/installers.js +0 -602
- package/dist/lib/installers.js.map +0 -1
- package/dist/lib/integrations.d.ts +0 -23
- package/dist/lib/integrations.js +0 -25
- package/dist/lib/integrations.js.map +0 -1
- package/dist/lib/output.d.ts +0 -7
- package/dist/lib/output.js +0 -70
- package/dist/lib/output.js.map +0 -1
- package/dist/lib/platform-detect.d.ts +0 -23
- package/dist/lib/platform-detect.js +0 -359
- package/dist/lib/platform-detect.js.map +0 -1
- package/dist/lib/project-config.d.ts +0 -53
- package/dist/lib/project-config.js +0 -151
- package/dist/lib/project-config.js.map +0 -1
- package/dist/lib/prompt.d.ts +0 -15
- package/dist/lib/prompt.js +0 -213
- package/dist/lib/prompt.js.map +0 -1
- package/dist/lib/rate-limiter.d.ts +0 -13
- package/dist/lib/rate-limiter.js +0 -49
- package/dist/lib/rate-limiter.js.map +0 -1
- package/dist/lib/recall-filter.d.ts +0 -5
- package/dist/lib/recall-filter.js +0 -24
- package/dist/lib/recall-filter.js.map +0 -1
- package/dist/lib/session-store.d.ts +0 -15
- package/dist/lib/session-store.js +0 -62
- package/dist/lib/session-store.js.map +0 -1
- package/dist/lib/tui.d.ts +0 -57
- package/dist/lib/tui.js +0 -247
- package/dist/lib/tui.js.map +0 -1
- package/dist/lib/workspace-registry.d.ts +0 -47
- package/dist/lib/workspace-registry.js +0 -240
- package/dist/lib/workspace-registry.js.map +0 -1
- package/dist/mcp/channel.d.ts +0 -24
- package/dist/mcp/channel.js +0 -198
- package/dist/mcp/channel.js.map +0 -1
- package/dist/mcp/client.d.ts +0 -20
- package/dist/mcp/client.js +0 -131
- package/dist/mcp/client.js.map +0 -1
- package/dist/mcp/config.d.ts +0 -19
- package/dist/mcp/config.js +0 -48
- package/dist/mcp/config.js.map +0 -1
- package/dist/mcp/context-files.d.ts +0 -9
- package/dist/mcp/context-files.js +0 -90
- package/dist/mcp/context-files.js.map +0 -1
- package/dist/mcp/file-manifest.d.ts +0 -27
- package/dist/mcp/file-manifest.js +0 -68
- package/dist/mcp/file-manifest.js.map +0 -1
- package/dist/mcp/file-scanner.d.ts +0 -17
- package/dist/mcp/file-scanner.js +0 -77
- package/dist/mcp/file-scanner.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -2
- package/dist/mcp/index.js +0 -51
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/rate-limiter.d.ts +0 -14
- package/dist/mcp/rate-limiter.js +0 -60
- package/dist/mcp/rate-limiter.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -6
- package/dist/mcp/server.js +0 -44
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/session-store.d.ts +0 -16
- package/dist/mcp/session-store.js +0 -70
- package/dist/mcp/session-store.js.map +0 -1
- package/dist/mcp/tools/context.d.ts +0 -3
- package/dist/mcp/tools/context.js +0 -65
- package/dist/mcp/tools/context.js.map +0 -1
- package/dist/mcp/tools/insights.d.ts +0 -3
- package/dist/mcp/tools/insights.js +0 -24
- package/dist/mcp/tools/insights.js.map +0 -1
- package/dist/mcp/tools/integrations.d.ts +0 -3
- package/dist/mcp/tools/integrations.js +0 -27
- package/dist/mcp/tools/integrations.js.map +0 -1
- package/dist/mcp/tools/lists.d.ts +0 -3
- package/dist/mcp/tools/lists.js +0 -101
- package/dist/mcp/tools/lists.js.map +0 -1
- package/dist/mcp/tools/notes.d.ts +0 -3
- package/dist/mcp/tools/notes.js +0 -52
- package/dist/mcp/tools/notes.js.map +0 -1
- package/dist/mcp/tools/notifications.d.ts +0 -3
- package/dist/mcp/tools/notifications.js +0 -53
- package/dist/mcp/tools/notifications.js.map +0 -1
- package/dist/mcp/tools/records.d.ts +0 -3
- package/dist/mcp/tools/records.js +0 -74
- package/dist/mcp/tools/records.js.map +0 -1
- package/dist/mcp/tools/register.d.ts +0 -3
- package/dist/mcp/tools/register.js +0 -41
- package/dist/mcp/tools/register.js.map +0 -1
- package/dist/mcp/tools/relationships.d.ts +0 -3
- package/dist/mcp/tools/relationships.js +0 -47
- package/dist/mcp/tools/relationships.js.map +0 -1
- package/dist/mcp/tools/scan.d.ts +0 -3
- package/dist/mcp/tools/scan.js +0 -37
- package/dist/mcp/tools/scan.js.map +0 -1
- package/dist/mcp/tools/schema.d.ts +0 -3
- package/dist/mcp/tools/schema.js +0 -108
- package/dist/mcp/tools/schema.js.map +0 -1
- package/dist/mcp/tools/search.d.ts +0 -3
- package/dist/mcp/tools/search.js +0 -8
- package/dist/mcp/tools/search.js.map +0 -1
- package/dist/mcp/tools/tasks.d.ts +0 -3
- package/dist/mcp/tools/tasks.js +0 -88
- package/dist/mcp/tools/tasks.js.map +0 -1
- package/dist/mcp/workspace-data-dir.d.ts +0 -2
- package/dist/mcp/workspace-data-dir.js +0 -28
- package/dist/mcp/workspace-data-dir.js.map +0 -1
- package/dist/orchestration/budget.d.ts +0 -32
- package/dist/orchestration/budget.js +0 -72
- package/dist/orchestration/budget.js.map +0 -1
- package/dist/orchestration/executor.d.ts +0 -59
- package/dist/orchestration/executor.js +0 -197
- package/dist/orchestration/executor.js.map +0 -1
- package/dist/orchestration/router.d.ts +0 -30
- package/dist/orchestration/router.js +0 -98
- package/dist/orchestration/router.js.map +0 -1
- package/dist/orchestration/templates.d.ts +0 -11
- package/dist/orchestration/templates.js +0 -99
- package/dist/orchestration/templates.js.map +0 -1
- package/dist/orchestration/types.d.ts +0 -58
- package/dist/orchestration/types.js +0 -7
- package/dist/orchestration/types.js.map +0 -1
- package/dist/plugin/auto-capture.d.ts +0 -11
- package/dist/plugin/auto-capture.js +0 -135
- package/dist/plugin/auto-capture.js.map +0 -1
- package/dist/plugin/auto-recall-worker.d.ts +0 -2
- package/dist/plugin/auto-recall-worker.js +0 -74
- package/dist/plugin/auto-recall-worker.js.map +0 -1
- package/dist/plugin/auto-recall.d.ts +0 -11
- package/dist/plugin/auto-recall.js +0 -186
- package/dist/plugin/auto-recall.js.map +0 -1
- package/dist/plugin/auto-register.d.ts +0 -10
- package/dist/plugin/auto-register.js +0 -81
- package/dist/plugin/auto-register.js.map +0 -1
- package/dist/plugin/auto-scan.d.ts +0 -10
- package/dist/plugin/auto-scan.js +0 -54
- package/dist/plugin/auto-scan.js.map +0 -1
- package/dist/plugin/auto-session-start.d.ts +0 -14
- package/dist/plugin/auto-session-start.js +0 -156
- package/dist/plugin/auto-session-start.js.map +0 -1
- package/dist/plugin/capture-filter.d.ts +0 -21
- package/dist/plugin/capture-filter.js +0 -32
- package/dist/plugin/capture-filter.js.map +0 -1
- package/dist/plugin/config.d.ts +0 -61
- package/dist/plugin/config.js +0 -182
- package/dist/plugin/config.js.map +0 -1
- package/dist/plugin/context-files.d.ts +0 -23
- package/dist/plugin/context-files.js +0 -103
- package/dist/plugin/context-files.js.map +0 -1
- package/dist/plugin/context-format.d.ts +0 -18
- package/dist/plugin/context-format.js +0 -34
- package/dist/plugin/context-format.js.map +0 -1
- package/dist/plugin/file-manifest.d.ts +0 -27
- package/dist/plugin/file-manifest.js +0 -68
- package/dist/plugin/file-manifest.js.map +0 -1
- package/dist/plugin/file-scanner.d.ts +0 -19
- package/dist/plugin/file-scanner.js +0 -90
- package/dist/plugin/file-scanner.js.map +0 -1
- package/dist/plugin/nex-client.d.ts +0 -50
- package/dist/plugin/nex-client.js +0 -129
- package/dist/plugin/nex-client.js.map +0 -1
- package/dist/plugin/rate-limiter.d.ts +0 -26
- package/dist/plugin/rate-limiter.js +0 -65
- package/dist/plugin/rate-limiter.js.map +0 -1
- package/dist/plugin/recall-cache.d.ts +0 -41
- package/dist/plugin/recall-cache.js +0 -195
- package/dist/plugin/recall-cache.js.map +0 -1
- package/dist/plugin/recall-filter.d.ts +0 -13
- package/dist/plugin/recall-filter.js +0 -39
- package/dist/plugin/recall-filter.js.map +0 -1
- package/dist/plugin/session-store.d.ts +0 -23
- package/dist/plugin/session-store.js +0 -73
- package/dist/plugin/session-store.js.map +0 -1
- package/dist/plugin/workspace-data-dir.d.ts +0 -2
- package/dist/plugin/workspace-data-dir.js +0 -31
- package/dist/plugin/workspace-data-dir.js.map +0 -1
- package/dist/tui/agent-colors.d.ts +0 -19
- package/dist/tui/agent-colors.js +0 -34
- package/dist/tui/agent-colors.js.map +0 -1
- package/dist/tui/app.d.ts +0 -14
- package/dist/tui/app.js +0 -181
- package/dist/tui/app.js.map +0 -1
- package/dist/tui/channel-colors.d.ts +0 -16
- package/dist/tui/channel-colors.js +0 -43
- package/dist/tui/channel-colors.js.map +0 -1
- package/dist/tui/components/agent-card.d.ts +0 -11
- package/dist/tui/components/agent-card.js +0 -40
- package/dist/tui/components/agent-card.js.map +0 -1
- package/dist/tui/components/banner.d.ts +0 -44
- package/dist/tui/components/banner.js +0 -130
- package/dist/tui/components/banner.js.map +0 -1
- package/dist/tui/components/channel-colors.d.ts +0 -21
- package/dist/tui/components/channel-colors.js +0 -53
- package/dist/tui/components/channel-colors.js.map +0 -1
- package/dist/tui/components/channel-message.d.ts +0 -53
- package/dist/tui/components/channel-message.js +0 -66
- package/dist/tui/components/channel-message.js.map +0 -1
- package/dist/tui/components/chat-input.d.ts +0 -11
- package/dist/tui/components/chat-input.js +0 -19
- package/dist/tui/components/chat-input.js.map +0 -1
- package/dist/tui/components/data-table.d.ts +0 -11
- package/dist/tui/components/data-table.js +0 -47
- package/dist/tui/components/data-table.js.map +0 -1
- package/dist/tui/components/error-box.d.ts +0 -11
- package/dist/tui/components/error-box.js +0 -59
- package/dist/tui/components/error-box.js.map +0 -1
- package/dist/tui/components/help-screen.d.ts +0 -3
- package/dist/tui/components/help-screen.js +0 -63
- package/dist/tui/components/help-screen.js.map +0 -1
- package/dist/tui/components/index.d.ts +0 -17
- package/dist/tui/components/index.js +0 -10
- package/dist/tui/components/index.js.map +0 -1
- package/dist/tui/components/inline-confirm.d.ts +0 -14
- package/dist/tui/components/inline-confirm.js +0 -13
- package/dist/tui/components/inline-confirm.js.map +0 -1
- package/dist/tui/components/inline-select.d.ts +0 -21
- package/dist/tui/components/inline-select.js +0 -20
- package/dist/tui/components/inline-select.js.map +0 -1
- package/dist/tui/components/markdown.d.ts +0 -6
- package/dist/tui/components/markdown.js +0 -179
- package/dist/tui/components/markdown.js.map +0 -1
- package/dist/tui/components/mention-autocomplete.d.ts +0 -79
- package/dist/tui/components/mention-autocomplete.js +0 -250
- package/dist/tui/components/mention-autocomplete.js.map +0 -1
- package/dist/tui/components/message-list.d.ts +0 -18
- package/dist/tui/components/message-list.js +0 -29
- package/dist/tui/components/message-list.js.map +0 -1
- package/dist/tui/components/picker.d.ts +0 -16
- package/dist/tui/components/picker.js +0 -32
- package/dist/tui/components/picker.js.map +0 -1
- package/dist/tui/components/progress-steps.d.ts +0 -13
- package/dist/tui/components/progress-steps.js +0 -21
- package/dist/tui/components/progress-steps.js.map +0 -1
- package/dist/tui/components/slack/compose.d.ts +0 -27
- package/dist/tui/components/slack/compose.js +0 -147
- package/dist/tui/components/slack/compose.js.map +0 -1
- package/dist/tui/components/slack/layout.d.ts +0 -36
- package/dist/tui/components/slack/layout.js +0 -96
- package/dist/tui/components/slack/layout.js.map +0 -1
- package/dist/tui/components/slack/messages.d.ts +0 -72
- package/dist/tui/components/slack/messages.js +0 -177
- package/dist/tui/components/slack/messages.js.map +0 -1
- package/dist/tui/components/slack/quick-switcher.d.ts +0 -33
- package/dist/tui/components/slack/quick-switcher.js +0 -98
- package/dist/tui/components/slack/quick-switcher.js.map +0 -1
- package/dist/tui/components/slack/sidebar-types.d.ts +0 -65
- package/dist/tui/components/slack/sidebar-types.js +0 -7
- package/dist/tui/components/slack/sidebar-types.js.map +0 -1
- package/dist/tui/components/slack/sidebar.d.ts +0 -46
- package/dist/tui/components/slack/sidebar.js +0 -52
- package/dist/tui/components/slack/sidebar.js.map +0 -1
- package/dist/tui/components/slack/thread-panel.d.ts +0 -45
- package/dist/tui/components/slack/thread-panel.js +0 -47
- package/dist/tui/components/slack/thread-panel.js.map +0 -1
- package/dist/tui/components/slash-autocomplete.d.ts +0 -83
- package/dist/tui/components/slash-autocomplete.js +0 -233
- package/dist/tui/components/slash-autocomplete.js.map +0 -1
- package/dist/tui/components/spinner.d.ts +0 -17
- package/dist/tui/components/spinner.js +0 -30
- package/dist/tui/components/spinner.js.map +0 -1
- package/dist/tui/components/status-bar.d.ts +0 -23
- package/dist/tui/components/status-bar.js +0 -55
- package/dist/tui/components/status-bar.js.map +0 -1
- package/dist/tui/components/success-box.d.ts +0 -7
- package/dist/tui/components/success-box.js +0 -10
- package/dist/tui/components/success-box.js.map +0 -1
- package/dist/tui/components/tool-indicator.d.ts +0 -12
- package/dist/tui/components/tool-indicator.js +0 -18
- package/dist/tui/components/tool-indicator.js.map +0 -1
- package/dist/tui/components/viewport.d.ts +0 -9
- package/dist/tui/components/viewport.js +0 -24
- package/dist/tui/components/viewport.js.map +0 -1
- package/dist/tui/generative/bindings.d.ts +0 -27
- package/dist/tui/generative/bindings.js +0 -152
- package/dist/tui/generative/bindings.js.map +0 -1
- package/dist/tui/generative/registry.d.ts +0 -19
- package/dist/tui/generative/registry.js +0 -31
- package/dist/tui/generative/registry.js.map +0 -1
- package/dist/tui/generative/renderer.d.ts +0 -24
- package/dist/tui/generative/renderer.js +0 -160
- package/dist/tui/generative/renderer.js.map +0 -1
- package/dist/tui/generative/types.d.ts +0 -68
- package/dist/tui/generative/types.js +0 -7
- package/dist/tui/generative/types.js.map +0 -1
- package/dist/tui/hooks/use-cancellable.d.ts +0 -28
- package/dist/tui/hooks/use-cancellable.js +0 -51
- package/dist/tui/hooks/use-cancellable.js.map +0 -1
- package/dist/tui/hooks/use-streaming.d.ts +0 -44
- package/dist/tui/hooks/use-streaming.js +0 -105
- package/dist/tui/hooks/use-streaming.js.map +0 -1
- package/dist/tui/index.d.ts +0 -4
- package/dist/tui/index.js +0 -7
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/keybindings.d.ts +0 -25
- package/dist/tui/keybindings.js +0 -277
- package/dist/tui/keybindings.js.map +0 -1
- package/dist/tui/register-views.d.ts +0 -8
- package/dist/tui/register-views.js +0 -122
- package/dist/tui/register-views.js.map +0 -1
- package/dist/tui/router.d.ts +0 -29
- package/dist/tui/router.js +0 -87
- package/dist/tui/router.js.map +0 -1
- package/dist/tui/services/agent-service.d.ts +0 -58
- package/dist/tui/services/agent-service.js +0 -197
- package/dist/tui/services/agent-service.js.map +0 -1
- package/dist/tui/services/calendar-service.d.ts +0 -31
- package/dist/tui/services/calendar-service.js +0 -133
- package/dist/tui/services/calendar-service.js.map +0 -1
- package/dist/tui/services/chat-service.d.ts +0 -28
- package/dist/tui/services/chat-service.js +0 -91
- package/dist/tui/services/chat-service.js.map +0 -1
- package/dist/tui/services/orchestration-service.d.ts +0 -42
- package/dist/tui/services/orchestration-service.js +0 -153
- package/dist/tui/services/orchestration-service.js.map +0 -1
- package/dist/tui/slash-commands.d.ts +0 -106
- package/dist/tui/slash-commands.js +0 -1421
- package/dist/tui/slash-commands.js.map +0 -1
- package/dist/tui/store.d.ts +0 -96
- package/dist/tui/store.js +0 -120
- package/dist/tui/store.js.map +0 -1
- package/dist/tui/theme.d.ts +0 -40
- package/dist/tui/theme.js +0 -39
- package/dist/tui/theme.js.map +0 -1
- package/dist/tui/tui-context.d.ts +0 -22
- package/dist/tui/tui-context.js +0 -17
- package/dist/tui/tui-context.js.map +0 -1
- package/dist/tui/views/agent-list.d.ts +0 -8
- package/dist/tui/views/agent-list.js +0 -11
- package/dist/tui/views/agent-list.js.map +0 -1
- package/dist/tui/views/ask-chat.d.ts +0 -9
- package/dist/tui/views/ask-chat.js +0 -40
- package/dist/tui/views/ask-chat.js.map +0 -1
- package/dist/tui/views/calendar.d.ts +0 -15
- package/dist/tui/views/calendar.js +0 -29
- package/dist/tui/views/calendar.js.map +0 -1
- package/dist/tui/views/chat.d.ts +0 -18
- package/dist/tui/views/chat.js +0 -28
- package/dist/tui/views/chat.js.map +0 -1
- package/dist/tui/views/generative.d.ts +0 -14
- package/dist/tui/views/generative.js +0 -37
- package/dist/tui/views/generative.js.map +0 -1
- package/dist/tui/views/help.d.ts +0 -6
- package/dist/tui/views/help.js +0 -9
- package/dist/tui/views/help.js.map +0 -1
- package/dist/tui/views/home-screen.d.ts +0 -67
- package/dist/tui/views/home-screen.js +0 -192
- package/dist/tui/views/home-screen.js.map +0 -1
- package/dist/tui/views/home.d.ts +0 -33
- package/dist/tui/views/home.js +0 -60
- package/dist/tui/views/home.js.map +0 -1
- package/dist/tui/views/index.d.ts +0 -20
- package/dist/tui/views/index.js +0 -11
- package/dist/tui/views/index.js.map +0 -1
- package/dist/tui/views/insights.d.ts +0 -19
- package/dist/tui/views/insights.js +0 -46
- package/dist/tui/views/insights.js.map +0 -1
- package/dist/tui/views/orchestration.d.ts +0 -18
- package/dist/tui/views/orchestration.js +0 -73
- package/dist/tui/views/orchestration.js.map +0 -1
- package/dist/tui/views/record-detail.d.ts +0 -10
- package/dist/tui/views/record-detail.js +0 -22
- package/dist/tui/views/record-detail.js.map +0 -1
- package/dist/tui/views/record-list.d.ts +0 -15
- package/dist/tui/views/record-list.js +0 -22
- package/dist/tui/views/record-list.js.map +0 -1
- package/dist/tui/views/slack-channel-header.d.ts +0 -15
- package/dist/tui/views/slack-channel-header.js +0 -16
- package/dist/tui/views/slack-channel-header.js.map +0 -1
- package/dist/tui/views/slack-home.d.ts +0 -21
- package/dist/tui/views/slack-home.js +0 -572
- package/dist/tui/views/slack-home.js.map +0 -1
- package/dist/tui/views/stream.d.ts +0 -16
- package/dist/tui/views/stream.js +0 -210
- package/dist/tui/views/stream.js.map +0 -1
- package/dist/tui/views/task-board.d.ts +0 -21
- package/dist/tui/views/task-board.js +0 -33
- package/dist/tui/views/task-board.js.map +0 -1
- package/dist/tui/views/timeline.d.ts +0 -17
- package/dist/tui/views/timeline.js +0 -24
- package/dist/tui/views/timeline.js.map +0 -1
|
@@ -1,1544 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command dispatch layer — executes CLI commands and returns structured results.
|
|
3
|
-
*
|
|
4
|
-
* This is a bridge that lets both the Commander CLI and the Ink TUI execute
|
|
5
|
-
* the same command logic. Instead of printing to stdout, each command returns
|
|
6
|
-
* a CommandResult with formatted output and raw data.
|
|
7
|
-
*/
|
|
8
|
-
import { NexClient } from "../lib/client.js";
|
|
9
|
-
import { resolveApiKey, resolveTimeout, loadConfig, saveConfig, CONFIG_PATH, BASE_URL } from "../lib/config.js";
|
|
10
|
-
import { formatOutput } from "../lib/output.js";
|
|
11
|
-
import { AuthError, RateLimitError, ServerError } from "../lib/errors.js";
|
|
12
|
-
import { launchBackgroundCompounding, shouldTriggerCompounding } from "../lib/compounding.js";
|
|
13
|
-
import { parseInput } from "./parse-input.js";
|
|
14
|
-
import { getAgentService } from "../tui/services/agent-service.js";
|
|
15
|
-
import { runInit, detectPlatforms } from "./init.js";
|
|
16
|
-
// ── Helpers ──
|
|
17
|
-
function makeClient(ctx) {
|
|
18
|
-
return new NexClient(ctx.apiKey ?? resolveApiKey(), ctx.timeout ?? resolveTimeout());
|
|
19
|
-
}
|
|
20
|
-
function fmt(data, ctx) {
|
|
21
|
-
const format = ctx.format ?? "text";
|
|
22
|
-
return formatOutput(data, format) ?? "";
|
|
23
|
-
}
|
|
24
|
-
function ok(data, ctx, extra) {
|
|
25
|
-
return { output: fmt(data, ctx), data, exitCode: 0, ...extra };
|
|
26
|
-
}
|
|
27
|
-
function fail(error, exitCode = 1) {
|
|
28
|
-
return { output: "", exitCode, error };
|
|
29
|
-
}
|
|
30
|
-
function wrapError(err) {
|
|
31
|
-
if (err instanceof AuthError)
|
|
32
|
-
return fail(err.message, 2);
|
|
33
|
-
if (err instanceof RateLimitError)
|
|
34
|
-
return fail(err.message, 1);
|
|
35
|
-
if (err instanceof ServerError)
|
|
36
|
-
return fail(err.message, 1);
|
|
37
|
-
if (err instanceof Error)
|
|
38
|
-
return fail(err.message, 1);
|
|
39
|
-
return fail(String(err), 1);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Extract named options from an args array.
|
|
43
|
-
* Returns the remaining positional args and an options map.
|
|
44
|
-
* Supports --key value and --flag (boolean).
|
|
45
|
-
*/
|
|
46
|
-
function extractOpts(args) {
|
|
47
|
-
const positional = [];
|
|
48
|
-
const opts = {};
|
|
49
|
-
for (let i = 0; i < args.length; i++) {
|
|
50
|
-
const arg = args[i];
|
|
51
|
-
if (arg.startsWith("--")) {
|
|
52
|
-
const key = arg.slice(2);
|
|
53
|
-
const next = args[i + 1];
|
|
54
|
-
if (next !== undefined && !next.startsWith("--")) {
|
|
55
|
-
opts[key] = next;
|
|
56
|
-
i++;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
opts[key] = true;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
positional.push(arg);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return { positional, opts };
|
|
67
|
-
}
|
|
68
|
-
// ── Command executors ──
|
|
69
|
-
// -- AI commands --
|
|
70
|
-
async function executeAsk(args, ctx) {
|
|
71
|
-
const query = args.join(" ");
|
|
72
|
-
if (!query)
|
|
73
|
-
return fail("No query provided. Pass a question as argument.");
|
|
74
|
-
try {
|
|
75
|
-
const client = makeClient(ctx);
|
|
76
|
-
const body = { query };
|
|
77
|
-
if (ctx.sessionId)
|
|
78
|
-
body.session_id = ctx.sessionId;
|
|
79
|
-
const result = await client.post("/v1/context/ask", body);
|
|
80
|
-
return ok(result, ctx, { sessionId: result.sessionId });
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
return wrapError(err);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async function executeRemember(args, ctx) {
|
|
87
|
-
const { positional, opts } = extractOpts(args);
|
|
88
|
-
const content = positional.join(" ");
|
|
89
|
-
if (!content)
|
|
90
|
-
return fail("No content provided. Pass content as argument.");
|
|
91
|
-
try {
|
|
92
|
-
const client = makeClient(ctx);
|
|
93
|
-
const body = { content };
|
|
94
|
-
if (typeof opts.context === "string")
|
|
95
|
-
body.context = opts.context;
|
|
96
|
-
const result = await client.post("/v1/context/text", body);
|
|
97
|
-
return ok(result, ctx);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
return wrapError(err);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
async function executeRecall(args, ctx) {
|
|
104
|
-
const query = args.join(" ");
|
|
105
|
-
if (!query)
|
|
106
|
-
return fail("No query provided. Pass a question as argument.");
|
|
107
|
-
try {
|
|
108
|
-
const client = makeClient(ctx);
|
|
109
|
-
const body = { query };
|
|
110
|
-
if (ctx.sessionId)
|
|
111
|
-
body.session_id = ctx.sessionId;
|
|
112
|
-
const result = await client.post("/v1/context/ask", body);
|
|
113
|
-
return ok(result, ctx, { sessionId: result.sessionId });
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
return wrapError(err);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
async function executeArtifact(args, ctx) {
|
|
120
|
-
const id = args[0];
|
|
121
|
-
if (!id)
|
|
122
|
-
return fail("No artifact ID provided.");
|
|
123
|
-
try {
|
|
124
|
-
const client = makeClient(ctx);
|
|
125
|
-
const result = await client.get(`/v1/context/artifacts/${encodeURIComponent(id)}`);
|
|
126
|
-
return ok(result, ctx);
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
return wrapError(err);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
async function executeCapture(args, ctx) {
|
|
133
|
-
const content = args.join(" ");
|
|
134
|
-
if (!content)
|
|
135
|
-
return fail("No content provided.");
|
|
136
|
-
try {
|
|
137
|
-
const client = makeClient(ctx);
|
|
138
|
-
const body = { content };
|
|
139
|
-
if (ctx.sessionId)
|
|
140
|
-
body.session_id = ctx.sessionId;
|
|
141
|
-
const result = await client.post("/v1/context/text", body, 60_000);
|
|
142
|
-
return ok(result, ctx);
|
|
143
|
-
}
|
|
144
|
-
catch (err) {
|
|
145
|
-
return wrapError(err);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// -- Query commands --
|
|
149
|
-
async function executeSearch(args, ctx) {
|
|
150
|
-
const query = args.join(" ");
|
|
151
|
-
if (!query)
|
|
152
|
-
return fail("No search query provided.");
|
|
153
|
-
try {
|
|
154
|
-
const client = makeClient(ctx);
|
|
155
|
-
const result = await client.post("/v1/search", { query });
|
|
156
|
-
return ok(result, ctx);
|
|
157
|
-
}
|
|
158
|
-
catch (err) {
|
|
159
|
-
return wrapError(err);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
async function executeObjectList(args, ctx) {
|
|
163
|
-
const { opts } = extractOpts(args);
|
|
164
|
-
try {
|
|
165
|
-
const client = makeClient(ctx);
|
|
166
|
-
const params = opts["include-attributes"] ? "?include_attributes=true" : "";
|
|
167
|
-
const result = await client.get(`/v1/objects${params}`);
|
|
168
|
-
return ok(result, ctx);
|
|
169
|
-
}
|
|
170
|
-
catch (err) {
|
|
171
|
-
return wrapError(err);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
async function executeObjectGet(args, ctx) {
|
|
175
|
-
const slug = args[0];
|
|
176
|
-
if (!slug)
|
|
177
|
-
return fail("No object slug provided.");
|
|
178
|
-
try {
|
|
179
|
-
const client = makeClient(ctx);
|
|
180
|
-
const result = await client.get(`/v1/objects/${encodeURIComponent(slug)}`);
|
|
181
|
-
return ok(result, ctx, { nav: { objectSlug: slug } });
|
|
182
|
-
}
|
|
183
|
-
catch (err) {
|
|
184
|
-
return wrapError(err);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
async function executeObjectCreate(args, ctx) {
|
|
188
|
-
const { opts } = extractOpts(args);
|
|
189
|
-
const name = opts.name;
|
|
190
|
-
const slug = opts.slug;
|
|
191
|
-
if (typeof name !== "string" || typeof slug !== "string") {
|
|
192
|
-
return fail("Required: --name <name> --slug <slug>");
|
|
193
|
-
}
|
|
194
|
-
try {
|
|
195
|
-
const client = makeClient(ctx);
|
|
196
|
-
const body = { name, slug };
|
|
197
|
-
if (typeof opts.type === "string")
|
|
198
|
-
body.type = opts.type;
|
|
199
|
-
if (typeof opts.description === "string")
|
|
200
|
-
body.description = opts.description;
|
|
201
|
-
const result = await client.post("/v1/objects", body);
|
|
202
|
-
return ok(result, ctx, { nav: { objectSlug: slug } });
|
|
203
|
-
}
|
|
204
|
-
catch (err) {
|
|
205
|
-
return wrapError(err);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
async function executeObjectUpdate(args, ctx) {
|
|
209
|
-
const { positional, opts } = extractOpts(args);
|
|
210
|
-
const slug = positional[0];
|
|
211
|
-
if (!slug)
|
|
212
|
-
return fail("No object slug provided.");
|
|
213
|
-
try {
|
|
214
|
-
const client = makeClient(ctx);
|
|
215
|
-
const body = {};
|
|
216
|
-
if (typeof opts.name === "string")
|
|
217
|
-
body.name = opts.name;
|
|
218
|
-
if (typeof opts.description === "string")
|
|
219
|
-
body.description = opts.description;
|
|
220
|
-
if (typeof opts["name-plural"] === "string")
|
|
221
|
-
body.name_plural = opts["name-plural"];
|
|
222
|
-
const result = await client.patch(`/v1/objects/${encodeURIComponent(slug)}`, body);
|
|
223
|
-
return ok(result, ctx, { nav: { objectSlug: slug } });
|
|
224
|
-
}
|
|
225
|
-
catch (err) {
|
|
226
|
-
return wrapError(err);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async function executeObjectDelete(args, ctx) {
|
|
230
|
-
const slug = args[0];
|
|
231
|
-
if (!slug)
|
|
232
|
-
return fail("No object slug provided.");
|
|
233
|
-
try {
|
|
234
|
-
const client = makeClient(ctx);
|
|
235
|
-
const result = await client.delete(`/v1/objects/${encodeURIComponent(slug)}`);
|
|
236
|
-
return ok(result, ctx);
|
|
237
|
-
}
|
|
238
|
-
catch (err) {
|
|
239
|
-
return wrapError(err);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
async function executeRecordList(args, ctx) {
|
|
243
|
-
const { positional, opts } = extractOpts(args);
|
|
244
|
-
const objectSlug = positional[0];
|
|
245
|
-
if (!objectSlug)
|
|
246
|
-
return fail("No object slug provided.");
|
|
247
|
-
try {
|
|
248
|
-
const client = makeClient(ctx);
|
|
249
|
-
const body = { attributes: opts.attributes ?? "primary" };
|
|
250
|
-
if (typeof opts.limit === "string")
|
|
251
|
-
body.limit = parseInt(opts.limit, 10);
|
|
252
|
-
if (typeof opts.offset === "string")
|
|
253
|
-
body.offset = parseInt(opts.offset, 10);
|
|
254
|
-
if (typeof opts.sort === "string") {
|
|
255
|
-
const [attribute, direction] = opts.sort.split(":");
|
|
256
|
-
body.sort = { attribute, direction };
|
|
257
|
-
}
|
|
258
|
-
const result = await client.post(`/v1/objects/${encodeURIComponent(objectSlug)}/records`, body);
|
|
259
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
260
|
-
}
|
|
261
|
-
catch (err) {
|
|
262
|
-
return wrapError(err);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
async function executeRecordGet(args, ctx) {
|
|
266
|
-
const id = args[0];
|
|
267
|
-
if (!id)
|
|
268
|
-
return fail("No record ID provided.");
|
|
269
|
-
try {
|
|
270
|
-
const client = makeClient(ctx);
|
|
271
|
-
const result = await client.get(`/v1/records/${encodeURIComponent(id)}`);
|
|
272
|
-
return ok(result, ctx, { nav: { recordId: id } });
|
|
273
|
-
}
|
|
274
|
-
catch (err) {
|
|
275
|
-
return wrapError(err);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
async function executeRecordCreate(args, ctx) {
|
|
279
|
-
const { positional, opts } = extractOpts(args);
|
|
280
|
-
const objectSlug = positional[0];
|
|
281
|
-
if (!objectSlug)
|
|
282
|
-
return fail("No object slug provided.");
|
|
283
|
-
if (typeof opts.data !== "string")
|
|
284
|
-
return fail("Required: --data <json>");
|
|
285
|
-
let attributes;
|
|
286
|
-
try {
|
|
287
|
-
attributes = JSON.parse(opts.data);
|
|
288
|
-
}
|
|
289
|
-
catch {
|
|
290
|
-
return fail(`Invalid JSON for --data: ${opts.data}`);
|
|
291
|
-
}
|
|
292
|
-
try {
|
|
293
|
-
const client = makeClient(ctx);
|
|
294
|
-
const result = await client.post(`/v1/objects/${encodeURIComponent(objectSlug)}`, { attributes });
|
|
295
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
296
|
-
}
|
|
297
|
-
catch (err) {
|
|
298
|
-
return wrapError(err);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
async function executeRecordUpsert(args, ctx) {
|
|
302
|
-
const { positional, opts } = extractOpts(args);
|
|
303
|
-
const objectSlug = positional[0];
|
|
304
|
-
if (!objectSlug)
|
|
305
|
-
return fail("No object slug provided.");
|
|
306
|
-
if (typeof opts.match !== "string")
|
|
307
|
-
return fail("Required: --match <attr>");
|
|
308
|
-
if (typeof opts.data !== "string")
|
|
309
|
-
return fail("Required: --data <json>");
|
|
310
|
-
let attributes;
|
|
311
|
-
try {
|
|
312
|
-
attributes = JSON.parse(opts.data);
|
|
313
|
-
}
|
|
314
|
-
catch {
|
|
315
|
-
return fail(`Invalid JSON for --data: ${opts.data}`);
|
|
316
|
-
}
|
|
317
|
-
try {
|
|
318
|
-
const client = makeClient(ctx);
|
|
319
|
-
const result = await client.put(`/v1/objects/${encodeURIComponent(objectSlug)}`, {
|
|
320
|
-
matching_attribute: opts.match,
|
|
321
|
-
attributes,
|
|
322
|
-
});
|
|
323
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
324
|
-
}
|
|
325
|
-
catch (err) {
|
|
326
|
-
return wrapError(err);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
async function executeRecordUpdate(args, ctx) {
|
|
330
|
-
const { positional, opts } = extractOpts(args);
|
|
331
|
-
const id = positional[0];
|
|
332
|
-
if (!id)
|
|
333
|
-
return fail("No record ID provided.");
|
|
334
|
-
if (typeof opts.data !== "string")
|
|
335
|
-
return fail("Required: --data <json>");
|
|
336
|
-
let attributes;
|
|
337
|
-
try {
|
|
338
|
-
attributes = JSON.parse(opts.data);
|
|
339
|
-
}
|
|
340
|
-
catch {
|
|
341
|
-
return fail(`Invalid JSON for --data: ${opts.data}`);
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
const client = makeClient(ctx);
|
|
345
|
-
const result = await client.patch(`/v1/records/${encodeURIComponent(id)}`, { attributes });
|
|
346
|
-
return ok(result, ctx, { nav: { recordId: id } });
|
|
347
|
-
}
|
|
348
|
-
catch (err) {
|
|
349
|
-
return wrapError(err);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
async function executeRecordDelete(args, ctx) {
|
|
353
|
-
const id = args[0];
|
|
354
|
-
if (!id)
|
|
355
|
-
return fail("No record ID provided.");
|
|
356
|
-
try {
|
|
357
|
-
const client = makeClient(ctx);
|
|
358
|
-
const result = await client.delete(`/v1/records/${encodeURIComponent(id)}`);
|
|
359
|
-
return ok(result, ctx);
|
|
360
|
-
}
|
|
361
|
-
catch (err) {
|
|
362
|
-
return wrapError(err);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
async function executeRecordTimeline(args, ctx) {
|
|
366
|
-
const { positional, opts } = extractOpts(args);
|
|
367
|
-
const id = positional[0];
|
|
368
|
-
if (!id)
|
|
369
|
-
return fail("No record ID provided.");
|
|
370
|
-
try {
|
|
371
|
-
const client = makeClient(ctx);
|
|
372
|
-
const params = new URLSearchParams();
|
|
373
|
-
if (typeof opts.limit === "string")
|
|
374
|
-
params.set("limit", opts.limit);
|
|
375
|
-
if (typeof opts.cursor === "string")
|
|
376
|
-
params.set("cursor", opts.cursor);
|
|
377
|
-
const qs = params.toString();
|
|
378
|
-
const result = await client.get(`/v1/records/${encodeURIComponent(id)}/timeline${qs ? `?${qs}` : ""}`);
|
|
379
|
-
return ok(result, ctx, { nav: { recordId: id } });
|
|
380
|
-
}
|
|
381
|
-
catch (err) {
|
|
382
|
-
return wrapError(err);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
// -- Insight commands --
|
|
386
|
-
async function executeInsightList(args, ctx) {
|
|
387
|
-
const { opts } = extractOpts(args);
|
|
388
|
-
try {
|
|
389
|
-
const client = makeClient(ctx);
|
|
390
|
-
const params = new URLSearchParams();
|
|
391
|
-
if (typeof opts.last === "string")
|
|
392
|
-
params.set("last", opts.last);
|
|
393
|
-
if (typeof opts.from === "string")
|
|
394
|
-
params.set("from", opts.from);
|
|
395
|
-
if (typeof opts.to === "string")
|
|
396
|
-
params.set("to", opts.to);
|
|
397
|
-
if (typeof opts.limit === "string")
|
|
398
|
-
params.set("limit", opts.limit);
|
|
399
|
-
const qs = params.toString();
|
|
400
|
-
const result = await client.get(`/v1/insights${qs ? `?${qs}` : ""}`);
|
|
401
|
-
return ok(result, ctx);
|
|
402
|
-
}
|
|
403
|
-
catch (err) {
|
|
404
|
-
return wrapError(err);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
// -- Note commands --
|
|
408
|
-
async function executeNoteList(args, ctx) {
|
|
409
|
-
const { opts } = extractOpts(args);
|
|
410
|
-
try {
|
|
411
|
-
const client = makeClient(ctx);
|
|
412
|
-
const params = opts.entity ? `?entity_id=${encodeURIComponent(opts.entity)}` : "";
|
|
413
|
-
const result = await client.get(`/v1/notes${params}`);
|
|
414
|
-
return ok(result, ctx);
|
|
415
|
-
}
|
|
416
|
-
catch (err) {
|
|
417
|
-
return wrapError(err);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
async function executeNoteGet(args, ctx) {
|
|
421
|
-
const id = args[0];
|
|
422
|
-
if (!id)
|
|
423
|
-
return fail("No note ID provided.");
|
|
424
|
-
try {
|
|
425
|
-
const client = makeClient(ctx);
|
|
426
|
-
const result = await client.get(`/v1/notes/${encodeURIComponent(id)}`);
|
|
427
|
-
return ok(result, ctx);
|
|
428
|
-
}
|
|
429
|
-
catch (err) {
|
|
430
|
-
return wrapError(err);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
async function executeNoteCreate(args, ctx) {
|
|
434
|
-
const { opts } = extractOpts(args);
|
|
435
|
-
if (typeof opts.title !== "string")
|
|
436
|
-
return fail("Required: --title <title>");
|
|
437
|
-
try {
|
|
438
|
-
const client = makeClient(ctx);
|
|
439
|
-
const body = { title: opts.title };
|
|
440
|
-
if (typeof opts.content === "string")
|
|
441
|
-
body.content = opts.content;
|
|
442
|
-
if (typeof opts.entity === "string")
|
|
443
|
-
body.entity_id = opts.entity;
|
|
444
|
-
const result = await client.post("/v1/notes", body);
|
|
445
|
-
return ok(result, ctx);
|
|
446
|
-
}
|
|
447
|
-
catch (err) {
|
|
448
|
-
return wrapError(err);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
async function executeNoteUpdate(args, ctx) {
|
|
452
|
-
const { positional, opts } = extractOpts(args);
|
|
453
|
-
const id = positional[0];
|
|
454
|
-
if (!id)
|
|
455
|
-
return fail("No note ID provided.");
|
|
456
|
-
try {
|
|
457
|
-
const client = makeClient(ctx);
|
|
458
|
-
const body = {};
|
|
459
|
-
if (typeof opts.title === "string")
|
|
460
|
-
body.title = opts.title;
|
|
461
|
-
if (typeof opts.content === "string")
|
|
462
|
-
body.content = opts.content;
|
|
463
|
-
if (typeof opts.entity === "string")
|
|
464
|
-
body.entity_id = opts.entity;
|
|
465
|
-
const result = await client.patch(`/v1/notes/${encodeURIComponent(id)}`, body);
|
|
466
|
-
return ok(result, ctx);
|
|
467
|
-
}
|
|
468
|
-
catch (err) {
|
|
469
|
-
return wrapError(err);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
async function executeNoteDelete(args, ctx) {
|
|
473
|
-
const id = args[0];
|
|
474
|
-
if (!id)
|
|
475
|
-
return fail("No note ID provided.");
|
|
476
|
-
try {
|
|
477
|
-
const client = makeClient(ctx);
|
|
478
|
-
const result = await client.delete(`/v1/notes/${encodeURIComponent(id)}`);
|
|
479
|
-
return ok(result, ctx);
|
|
480
|
-
}
|
|
481
|
-
catch (err) {
|
|
482
|
-
return wrapError(err);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
// -- Task commands --
|
|
486
|
-
async function executeTaskList(args, ctx) {
|
|
487
|
-
const { opts } = extractOpts(args);
|
|
488
|
-
try {
|
|
489
|
-
const client = makeClient(ctx);
|
|
490
|
-
const params = new URLSearchParams();
|
|
491
|
-
if (typeof opts.entity === "string")
|
|
492
|
-
params.set("entity_id", opts.entity);
|
|
493
|
-
if (typeof opts.assignee === "string")
|
|
494
|
-
params.set("assignee_id", opts.assignee);
|
|
495
|
-
if (typeof opts.search === "string")
|
|
496
|
-
params.set("search", opts.search);
|
|
497
|
-
if (opts.completed === true)
|
|
498
|
-
params.set("is_completed", "true");
|
|
499
|
-
if (typeof opts.limit === "string")
|
|
500
|
-
params.set("limit", opts.limit);
|
|
501
|
-
const qs = params.toString();
|
|
502
|
-
const result = await client.get(`/v1/tasks${qs ? `?${qs}` : ""}`);
|
|
503
|
-
return ok(result, ctx);
|
|
504
|
-
}
|
|
505
|
-
catch (err) {
|
|
506
|
-
return wrapError(err);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
async function executeTaskGet(args, ctx) {
|
|
510
|
-
const id = args[0];
|
|
511
|
-
if (!id)
|
|
512
|
-
return fail("No task ID provided.");
|
|
513
|
-
try {
|
|
514
|
-
const client = makeClient(ctx);
|
|
515
|
-
const result = await client.get(`/v1/tasks/${encodeURIComponent(id)}`);
|
|
516
|
-
return ok(result, ctx);
|
|
517
|
-
}
|
|
518
|
-
catch (err) {
|
|
519
|
-
return wrapError(err);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
async function executeTaskCreate(args, ctx) {
|
|
523
|
-
const { opts } = extractOpts(args);
|
|
524
|
-
if (typeof opts.title !== "string")
|
|
525
|
-
return fail("Required: --title <title>");
|
|
526
|
-
try {
|
|
527
|
-
const client = makeClient(ctx);
|
|
528
|
-
const body = { title: opts.title };
|
|
529
|
-
if (typeof opts.description === "string")
|
|
530
|
-
body.description = opts.description;
|
|
531
|
-
if (typeof opts.priority === "string")
|
|
532
|
-
body.priority = opts.priority;
|
|
533
|
-
if (typeof opts.due === "string")
|
|
534
|
-
body.due_date = opts.due;
|
|
535
|
-
if (typeof opts.entities === "string")
|
|
536
|
-
body.entity_ids = opts.entities.split(",");
|
|
537
|
-
if (typeof opts.assignees === "string")
|
|
538
|
-
body.assignee_ids = opts.assignees.split(",");
|
|
539
|
-
const result = await client.post("/v1/tasks", body);
|
|
540
|
-
return ok(result, ctx);
|
|
541
|
-
}
|
|
542
|
-
catch (err) {
|
|
543
|
-
return wrapError(err);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
async function executeTaskUpdate(args, ctx) {
|
|
547
|
-
const { positional, opts } = extractOpts(args);
|
|
548
|
-
const id = positional[0];
|
|
549
|
-
if (!id)
|
|
550
|
-
return fail("No task ID provided.");
|
|
551
|
-
try {
|
|
552
|
-
const client = makeClient(ctx);
|
|
553
|
-
const body = {};
|
|
554
|
-
if (typeof opts.title === "string")
|
|
555
|
-
body.title = opts.title;
|
|
556
|
-
if (typeof opts.description === "string")
|
|
557
|
-
body.description = opts.description;
|
|
558
|
-
if (opts.completed === true)
|
|
559
|
-
body.is_completed = true;
|
|
560
|
-
if (typeof opts.priority === "string")
|
|
561
|
-
body.priority = opts.priority;
|
|
562
|
-
if (typeof opts.due === "string")
|
|
563
|
-
body.due_date = opts.due;
|
|
564
|
-
if (typeof opts.entities === "string")
|
|
565
|
-
body.entity_ids = opts.entities.split(",");
|
|
566
|
-
if (typeof opts.assignees === "string")
|
|
567
|
-
body.assignee_ids = opts.assignees.split(",");
|
|
568
|
-
const result = await client.patch(`/v1/tasks/${encodeURIComponent(id)}`, body);
|
|
569
|
-
return ok(result, ctx);
|
|
570
|
-
}
|
|
571
|
-
catch (err) {
|
|
572
|
-
return wrapError(err);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
async function executeTaskDelete(args, ctx) {
|
|
576
|
-
const id = args[0];
|
|
577
|
-
if (!id)
|
|
578
|
-
return fail("No task ID provided.");
|
|
579
|
-
try {
|
|
580
|
-
const client = makeClient(ctx);
|
|
581
|
-
const result = await client.delete(`/v1/tasks/${encodeURIComponent(id)}`);
|
|
582
|
-
return ok(result, ctx);
|
|
583
|
-
}
|
|
584
|
-
catch (err) {
|
|
585
|
-
return wrapError(err);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
// -- Relationship commands --
|
|
589
|
-
async function executeRelListDefs(_args, ctx) {
|
|
590
|
-
try {
|
|
591
|
-
const client = makeClient(ctx);
|
|
592
|
-
const result = await client.get("/v1/relationships");
|
|
593
|
-
return ok(result, ctx);
|
|
594
|
-
}
|
|
595
|
-
catch (err) {
|
|
596
|
-
return wrapError(err);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
async function executeRelCreateDef(args, ctx) {
|
|
600
|
-
const { opts } = extractOpts(args);
|
|
601
|
-
if (typeof opts.type !== "string")
|
|
602
|
-
return fail("Required: --type <type>");
|
|
603
|
-
if (typeof opts.entity1 !== "string")
|
|
604
|
-
return fail("Required: --entity1 <id>");
|
|
605
|
-
if (typeof opts.entity2 !== "string")
|
|
606
|
-
return fail("Required: --entity2 <id>");
|
|
607
|
-
try {
|
|
608
|
-
const client = makeClient(ctx);
|
|
609
|
-
const body = {
|
|
610
|
-
type: opts.type,
|
|
611
|
-
entity_definition_1_id: opts.entity1,
|
|
612
|
-
entity_definition_2_id: opts.entity2,
|
|
613
|
-
};
|
|
614
|
-
if (typeof opts.pred12 === "string")
|
|
615
|
-
body.entity_1_to_2_predicate = opts.pred12;
|
|
616
|
-
if (typeof opts.pred21 === "string")
|
|
617
|
-
body.entity_2_to_1_predicate = opts.pred21;
|
|
618
|
-
const result = await client.post("/v1/relationships", body);
|
|
619
|
-
return ok(result, ctx);
|
|
620
|
-
}
|
|
621
|
-
catch (err) {
|
|
622
|
-
return wrapError(err);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
async function executeRelDeleteDef(args, ctx) {
|
|
626
|
-
const id = args[0];
|
|
627
|
-
if (!id)
|
|
628
|
-
return fail("No relationship definition ID provided.");
|
|
629
|
-
try {
|
|
630
|
-
const client = makeClient(ctx);
|
|
631
|
-
const result = await client.delete(`/v1/relationships/${encodeURIComponent(id)}`);
|
|
632
|
-
return ok(result, ctx);
|
|
633
|
-
}
|
|
634
|
-
catch (err) {
|
|
635
|
-
return wrapError(err);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
async function executeRelCreate(args, ctx) {
|
|
639
|
-
const { positional, opts } = extractOpts(args);
|
|
640
|
-
const recordId = positional[0];
|
|
641
|
-
if (!recordId)
|
|
642
|
-
return fail("No record ID provided.");
|
|
643
|
-
if (typeof opts.def !== "string")
|
|
644
|
-
return fail("Required: --def <id>");
|
|
645
|
-
if (typeof opts.entity1 !== "string")
|
|
646
|
-
return fail("Required: --entity1 <id>");
|
|
647
|
-
if (typeof opts.entity2 !== "string")
|
|
648
|
-
return fail("Required: --entity2 <id>");
|
|
649
|
-
try {
|
|
650
|
-
const client = makeClient(ctx);
|
|
651
|
-
const body = {
|
|
652
|
-
definition_id: opts.def,
|
|
653
|
-
entity_1_id: opts.entity1,
|
|
654
|
-
entity_2_id: opts.entity2,
|
|
655
|
-
};
|
|
656
|
-
const result = await client.post(`/v1/records/${encodeURIComponent(recordId)}/relationships`, body);
|
|
657
|
-
return ok(result, ctx);
|
|
658
|
-
}
|
|
659
|
-
catch (err) {
|
|
660
|
-
return wrapError(err);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
async function executeRelDelete(args, ctx) {
|
|
664
|
-
const recordId = args[0];
|
|
665
|
-
const relId = args[1];
|
|
666
|
-
if (!recordId)
|
|
667
|
-
return fail("No record ID provided.");
|
|
668
|
-
if (!relId)
|
|
669
|
-
return fail("No relationship ID provided.");
|
|
670
|
-
try {
|
|
671
|
-
const client = makeClient(ctx);
|
|
672
|
-
const result = await client.delete(`/v1/records/${encodeURIComponent(recordId)}/relationships/${encodeURIComponent(relId)}`);
|
|
673
|
-
return ok(result, ctx);
|
|
674
|
-
}
|
|
675
|
-
catch (err) {
|
|
676
|
-
return wrapError(err);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
// -- Attribute commands --
|
|
680
|
-
async function executeAttrCreate(args, ctx) {
|
|
681
|
-
const { positional, opts } = extractOpts(args);
|
|
682
|
-
const objectSlug = positional[0];
|
|
683
|
-
if (!objectSlug)
|
|
684
|
-
return fail("No object slug provided.");
|
|
685
|
-
if (typeof opts.name !== "string")
|
|
686
|
-
return fail("Required: --name <name>");
|
|
687
|
-
if (typeof opts.slug !== "string")
|
|
688
|
-
return fail("Required: --slug <slug>");
|
|
689
|
-
if (typeof opts.type !== "string")
|
|
690
|
-
return fail("Required: --type <type>");
|
|
691
|
-
const body = { name: opts.name, slug: opts.slug, type: opts.type };
|
|
692
|
-
if (typeof opts.description === "string")
|
|
693
|
-
body.description = opts.description;
|
|
694
|
-
if (typeof opts.options === "string") {
|
|
695
|
-
try {
|
|
696
|
-
body.options = JSON.parse(opts.options);
|
|
697
|
-
}
|
|
698
|
-
catch {
|
|
699
|
-
return fail(`Invalid JSON for --options: ${opts.options}`);
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
try {
|
|
703
|
-
const client = makeClient(ctx);
|
|
704
|
-
const result = await client.post(`/v1/objects/${encodeURIComponent(objectSlug)}/attributes`, body);
|
|
705
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
706
|
-
}
|
|
707
|
-
catch (err) {
|
|
708
|
-
return wrapError(err);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
async function executeAttrUpdate(args, ctx) {
|
|
712
|
-
const { positional, opts } = extractOpts(args);
|
|
713
|
-
const objectSlug = positional[0];
|
|
714
|
-
const attrId = positional[1];
|
|
715
|
-
if (!objectSlug)
|
|
716
|
-
return fail("No object slug provided.");
|
|
717
|
-
if (!attrId)
|
|
718
|
-
return fail("No attribute ID provided.");
|
|
719
|
-
const body = {};
|
|
720
|
-
if (typeof opts.name === "string")
|
|
721
|
-
body.name = opts.name;
|
|
722
|
-
if (typeof opts.description === "string")
|
|
723
|
-
body.description = opts.description;
|
|
724
|
-
if (typeof opts.options === "string") {
|
|
725
|
-
try {
|
|
726
|
-
body.options = JSON.parse(opts.options);
|
|
727
|
-
}
|
|
728
|
-
catch {
|
|
729
|
-
return fail(`Invalid JSON for --options: ${opts.options}`);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
try {
|
|
733
|
-
const client = makeClient(ctx);
|
|
734
|
-
const result = await client.patch(`/v1/objects/${encodeURIComponent(objectSlug)}/attributes/${encodeURIComponent(attrId)}`, body);
|
|
735
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
736
|
-
}
|
|
737
|
-
catch (err) {
|
|
738
|
-
return wrapError(err);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
async function executeAttrDelete(args, ctx) {
|
|
742
|
-
const objectSlug = args[0];
|
|
743
|
-
const attrId = args[1];
|
|
744
|
-
if (!objectSlug)
|
|
745
|
-
return fail("No object slug provided.");
|
|
746
|
-
if (!attrId)
|
|
747
|
-
return fail("No attribute ID provided.");
|
|
748
|
-
try {
|
|
749
|
-
const client = makeClient(ctx);
|
|
750
|
-
const result = await client.delete(`/v1/objects/${encodeURIComponent(objectSlug)}/attributes/${encodeURIComponent(attrId)}`);
|
|
751
|
-
return ok(result, ctx);
|
|
752
|
-
}
|
|
753
|
-
catch (err) {
|
|
754
|
-
return wrapError(err);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
// -- List commands --
|
|
758
|
-
async function executeListList(args, ctx) {
|
|
759
|
-
const { positional, opts } = extractOpts(args);
|
|
760
|
-
const objectSlug = positional[0];
|
|
761
|
-
if (!objectSlug)
|
|
762
|
-
return fail("No object slug provided.");
|
|
763
|
-
try {
|
|
764
|
-
const client = makeClient(ctx);
|
|
765
|
-
const params = opts["include-attributes"] ? "?include_attributes=true" : "";
|
|
766
|
-
const result = await client.get(`/v1/objects/${encodeURIComponent(objectSlug)}/lists${params}`);
|
|
767
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
768
|
-
}
|
|
769
|
-
catch (err) {
|
|
770
|
-
return wrapError(err);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
async function executeListGet(args, ctx) {
|
|
774
|
-
const id = args[0];
|
|
775
|
-
if (!id)
|
|
776
|
-
return fail("No list ID provided.");
|
|
777
|
-
try {
|
|
778
|
-
const client = makeClient(ctx);
|
|
779
|
-
const result = await client.get(`/v1/lists/${encodeURIComponent(id)}`);
|
|
780
|
-
return ok(result, ctx);
|
|
781
|
-
}
|
|
782
|
-
catch (err) {
|
|
783
|
-
return wrapError(err);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
async function executeListCreate(args, ctx) {
|
|
787
|
-
const { positional, opts } = extractOpts(args);
|
|
788
|
-
const objectSlug = positional[0];
|
|
789
|
-
if (!objectSlug)
|
|
790
|
-
return fail("No object slug provided.");
|
|
791
|
-
if (typeof opts.name !== "string")
|
|
792
|
-
return fail("Required: --name <name>");
|
|
793
|
-
if (typeof opts.slug !== "string")
|
|
794
|
-
return fail("Required: --slug <slug>");
|
|
795
|
-
try {
|
|
796
|
-
const client = makeClient(ctx);
|
|
797
|
-
const body = { name: opts.name, slug: opts.slug };
|
|
798
|
-
if (typeof opts.description === "string")
|
|
799
|
-
body.description = opts.description;
|
|
800
|
-
const result = await client.post(`/v1/objects/${encodeURIComponent(objectSlug)}/lists`, body);
|
|
801
|
-
return ok(result, ctx, { nav: { objectSlug } });
|
|
802
|
-
}
|
|
803
|
-
catch (err) {
|
|
804
|
-
return wrapError(err);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
async function executeListDelete(args, ctx) {
|
|
808
|
-
const id = args[0];
|
|
809
|
-
if (!id)
|
|
810
|
-
return fail("No list ID provided.");
|
|
811
|
-
try {
|
|
812
|
-
const client = makeClient(ctx);
|
|
813
|
-
const result = await client.delete(`/v1/lists/${encodeURIComponent(id)}`);
|
|
814
|
-
return ok(result, ctx);
|
|
815
|
-
}
|
|
816
|
-
catch (err) {
|
|
817
|
-
return wrapError(err);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
async function executeListRecords(args, ctx) {
|
|
821
|
-
const { positional, opts } = extractOpts(args);
|
|
822
|
-
const listId = positional[0];
|
|
823
|
-
if (!listId)
|
|
824
|
-
return fail("No list ID provided.");
|
|
825
|
-
try {
|
|
826
|
-
const client = makeClient(ctx);
|
|
827
|
-
const body = { attributes: opts.attributes ?? "primary" };
|
|
828
|
-
if (typeof opts.limit === "string")
|
|
829
|
-
body.limit = parseInt(opts.limit, 10);
|
|
830
|
-
if (typeof opts.offset === "string")
|
|
831
|
-
body.offset = parseInt(opts.offset, 10);
|
|
832
|
-
if (typeof opts.sort === "string") {
|
|
833
|
-
const [attribute, direction] = opts.sort.split(":");
|
|
834
|
-
body.sort = { attribute, direction };
|
|
835
|
-
}
|
|
836
|
-
const result = await client.post(`/v1/lists/${encodeURIComponent(listId)}/records`, body);
|
|
837
|
-
return ok(result, ctx);
|
|
838
|
-
}
|
|
839
|
-
catch (err) {
|
|
840
|
-
return wrapError(err);
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
// -- List job commands --
|
|
844
|
-
async function executeListJobCreate(args, ctx) {
|
|
845
|
-
const { positional, opts } = extractOpts(args);
|
|
846
|
-
const query = positional.join(" ");
|
|
847
|
-
if (!query)
|
|
848
|
-
return fail("No query provided.");
|
|
849
|
-
try {
|
|
850
|
-
const client = makeClient(ctx);
|
|
851
|
-
const body = { query };
|
|
852
|
-
if (typeof opts.type === "string")
|
|
853
|
-
body.object_type = opts.type;
|
|
854
|
-
if (typeof opts.limit === "string")
|
|
855
|
-
body.limit = parseInt(opts.limit, 10);
|
|
856
|
-
const result = await client.post("/v1/context/list/jobs", body);
|
|
857
|
-
return ok(result, ctx);
|
|
858
|
-
}
|
|
859
|
-
catch (err) {
|
|
860
|
-
return wrapError(err);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
async function executeListJobStatus(args, ctx) {
|
|
864
|
-
const { positional, opts } = extractOpts(args);
|
|
865
|
-
const id = positional[0];
|
|
866
|
-
if (!id)
|
|
867
|
-
return fail("No job ID provided.");
|
|
868
|
-
try {
|
|
869
|
-
const client = makeClient(ctx);
|
|
870
|
-
const params = opts["include-attributes"] ? "?include_attributes=true" : "";
|
|
871
|
-
const result = await client.get(`/v1/context/list/jobs/${encodeURIComponent(id)}${params}`);
|
|
872
|
-
return ok(result, ctx);
|
|
873
|
-
}
|
|
874
|
-
catch (err) {
|
|
875
|
-
return wrapError(err);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
// -- Config commands --
|
|
879
|
-
function executeConfigShow(_args, ctx) {
|
|
880
|
-
const config = loadConfig();
|
|
881
|
-
const apiKey = ctx.apiKey ?? resolveApiKey();
|
|
882
|
-
const display = {
|
|
883
|
-
...config,
|
|
884
|
-
api_key: apiKey ? maskKey(apiKey) : undefined,
|
|
885
|
-
base_url: BASE_URL,
|
|
886
|
-
config_path: CONFIG_PATH,
|
|
887
|
-
};
|
|
888
|
-
return Promise.resolve(ok(display, ctx));
|
|
889
|
-
}
|
|
890
|
-
function maskKey(key) {
|
|
891
|
-
if (key.length <= 4)
|
|
892
|
-
return key;
|
|
893
|
-
return "****" + key.slice(-4);
|
|
894
|
-
}
|
|
895
|
-
function executeConfigSet(args, ctx) {
|
|
896
|
-
const key = args[0];
|
|
897
|
-
const value = args[1];
|
|
898
|
-
if (!key || value === undefined)
|
|
899
|
-
return Promise.resolve(fail("Usage: config set <key> <value>"));
|
|
900
|
-
const config = loadConfig();
|
|
901
|
-
config[key] = value;
|
|
902
|
-
saveConfig(config);
|
|
903
|
-
return Promise.resolve(ok({ [key]: value }, ctx));
|
|
904
|
-
}
|
|
905
|
-
function executeConfigPath(_args, ctx) {
|
|
906
|
-
return Promise.resolve(ok({ path: CONFIG_PATH }, ctx));
|
|
907
|
-
}
|
|
908
|
-
// -- Integrate commands --
|
|
909
|
-
async function executeIntegrateList(_args, ctx) {
|
|
910
|
-
try {
|
|
911
|
-
const client = makeClient(ctx);
|
|
912
|
-
const result = await client.get("/v1/integrations/");
|
|
913
|
-
return ok(result, ctx);
|
|
914
|
-
}
|
|
915
|
-
catch (err) {
|
|
916
|
-
return wrapError(err);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
async function executeIntegrateConnect(args, ctx) {
|
|
920
|
-
const name = args[0];
|
|
921
|
-
if (!name)
|
|
922
|
-
return fail("No integration name provided.");
|
|
923
|
-
const INTEGRATIONS = {
|
|
924
|
-
gmail: { type: "email", provider: "google" },
|
|
925
|
-
"google-calendar": { type: "calendar", provider: "google" },
|
|
926
|
-
outlook: { type: "email", provider: "microsoft" },
|
|
927
|
-
"outlook-calendar": { type: "calendar", provider: "microsoft" },
|
|
928
|
-
slack: { type: "messaging", provider: "slack" },
|
|
929
|
-
salesforce: { type: "crm", provider: "salesforce" },
|
|
930
|
-
hubspot: { type: "crm", provider: "hubspot" },
|
|
931
|
-
attio: { type: "crm", provider: "attio" },
|
|
932
|
-
};
|
|
933
|
-
const integration = INTEGRATIONS[name.toLowerCase()];
|
|
934
|
-
if (!integration) {
|
|
935
|
-
return fail(`Unknown integration "${name}". Available: ${Object.keys(INTEGRATIONS).join(", ")}`);
|
|
936
|
-
}
|
|
937
|
-
try {
|
|
938
|
-
const client = makeClient(ctx);
|
|
939
|
-
const result = await client.post(`/v1/integrations/${encodeURIComponent(integration.type)}/${encodeURIComponent(integration.provider)}/connect`);
|
|
940
|
-
// Return the auth URL in data for the TUI to handle browser opening
|
|
941
|
-
return ok(result, ctx);
|
|
942
|
-
}
|
|
943
|
-
catch (err) {
|
|
944
|
-
return wrapError(err);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
async function executeIntegrateDisconnect(args, ctx) {
|
|
948
|
-
const connectionId = args[0];
|
|
949
|
-
if (!connectionId)
|
|
950
|
-
return fail("No connection ID provided.");
|
|
951
|
-
try {
|
|
952
|
-
const client = makeClient(ctx);
|
|
953
|
-
const result = await client.delete(`/v1/integrations/connections/${encodeURIComponent(connectionId)}`);
|
|
954
|
-
return ok(result, ctx);
|
|
955
|
-
}
|
|
956
|
-
catch (err) {
|
|
957
|
-
return wrapError(err);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
// -- Notification commands --
|
|
961
|
-
async function executeNotifyList(args, ctx) {
|
|
962
|
-
const { opts } = extractOpts(args);
|
|
963
|
-
try {
|
|
964
|
-
const client = makeClient(ctx);
|
|
965
|
-
const params = new URLSearchParams();
|
|
966
|
-
if (typeof opts.limit === "string")
|
|
967
|
-
params.set("limit", opts.limit);
|
|
968
|
-
if (typeof opts.since === "string")
|
|
969
|
-
params.set("since", opts.since);
|
|
970
|
-
const qs = params.toString();
|
|
971
|
-
const result = await client.get(`/v1/notifications/feed${qs ? `?${qs}` : ""}`);
|
|
972
|
-
return ok(result, ctx);
|
|
973
|
-
}
|
|
974
|
-
catch (err) {
|
|
975
|
-
return wrapError(err);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
async function executeNotifyPreferences(_args, ctx) {
|
|
979
|
-
try {
|
|
980
|
-
const client = makeClient(ctx);
|
|
981
|
-
const result = await client.get("/v1/notifications/preferences");
|
|
982
|
-
return ok(result, ctx);
|
|
983
|
-
}
|
|
984
|
-
catch (err) {
|
|
985
|
-
return wrapError(err);
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
async function executeNotifySetFrequency(args, ctx) {
|
|
989
|
-
const minutes = parseInt(args[0], 10);
|
|
990
|
-
if (!args[0] || isNaN(minutes) || minutes < 1)
|
|
991
|
-
return fail("Usage: notify set-frequency <minutes> (must be >= 1)");
|
|
992
|
-
try {
|
|
993
|
-
const client = makeClient(ctx);
|
|
994
|
-
const result = await client.patch("/v1/notifications/preferences", { frequency_minutes: minutes });
|
|
995
|
-
return ok(result, ctx);
|
|
996
|
-
}
|
|
997
|
-
catch (err) {
|
|
998
|
-
return wrapError(err);
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
const VALID_NOTIFY_TYPES = ["daily_digest", "meeting_summary", "task_reminder", "task_assigned", "context_alert"];
|
|
1002
|
-
async function executeNotifyEnable(args, ctx) {
|
|
1003
|
-
const typeName = args[0];
|
|
1004
|
-
if (!typeName || !VALID_NOTIFY_TYPES.includes(typeName)) {
|
|
1005
|
-
return fail(`Usage: notify enable <type>\nValid types: ${VALID_NOTIFY_TYPES.join(", ")}`);
|
|
1006
|
-
}
|
|
1007
|
-
try {
|
|
1008
|
-
const client = makeClient(ctx);
|
|
1009
|
-
const prefs = (await client.get("/v1/notifications/preferences"));
|
|
1010
|
-
const current = new Set(prefs.enabled_types ?? []);
|
|
1011
|
-
current.add(typeName);
|
|
1012
|
-
const result = await client.patch("/v1/notifications/preferences", { enabled_types: [...current] });
|
|
1013
|
-
return ok(result, ctx);
|
|
1014
|
-
}
|
|
1015
|
-
catch (err) {
|
|
1016
|
-
return wrapError(err);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
async function executeNotifyDisable(args, ctx) {
|
|
1020
|
-
const typeName = args[0];
|
|
1021
|
-
if (!typeName || !VALID_NOTIFY_TYPES.includes(typeName)) {
|
|
1022
|
-
return fail(`Usage: notify disable <type>\nValid types: ${VALID_NOTIFY_TYPES.join(", ")}`);
|
|
1023
|
-
}
|
|
1024
|
-
try {
|
|
1025
|
-
const client = makeClient(ctx);
|
|
1026
|
-
const prefs = (await client.get("/v1/notifications/preferences"));
|
|
1027
|
-
const current = new Set(prefs.enabled_types ?? []);
|
|
1028
|
-
current.delete(typeName);
|
|
1029
|
-
const result = await client.patch("/v1/notifications/preferences", { enabled_types: [...current] });
|
|
1030
|
-
return ok(result, ctx);
|
|
1031
|
-
}
|
|
1032
|
-
catch (err) {
|
|
1033
|
-
return wrapError(err);
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
async function executeNotifyRuleCreate(args, ctx) {
|
|
1037
|
-
const description = args.join(" ");
|
|
1038
|
-
if (!description)
|
|
1039
|
-
return fail('Usage: notify rule-create "<description>"');
|
|
1040
|
-
try {
|
|
1041
|
-
const client = makeClient(ctx);
|
|
1042
|
-
const result = await client.post("/v1/notifications/custom", { description });
|
|
1043
|
-
return ok(result, ctx);
|
|
1044
|
-
}
|
|
1045
|
-
catch (err) {
|
|
1046
|
-
return wrapError(err);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
async function executeNotifyRuleList(_args, ctx) {
|
|
1050
|
-
try {
|
|
1051
|
-
const client = makeClient(ctx);
|
|
1052
|
-
const result = await client.get("/v1/notifications/custom");
|
|
1053
|
-
return ok(result, ctx);
|
|
1054
|
-
}
|
|
1055
|
-
catch (err) {
|
|
1056
|
-
return wrapError(err);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
async function executeNotifyRuleDelete(args, ctx) {
|
|
1060
|
-
const id = args[0];
|
|
1061
|
-
if (!id)
|
|
1062
|
-
return fail("Usage: notify rule-delete <id>");
|
|
1063
|
-
try {
|
|
1064
|
-
const client = makeClient(ctx);
|
|
1065
|
-
const result = await client.delete(`/v1/notifications/custom/${encodeURIComponent(id)}`);
|
|
1066
|
-
return ok(result, ctx);
|
|
1067
|
-
}
|
|
1068
|
-
catch (err) {
|
|
1069
|
-
return wrapError(err);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
// -- Graph command --
|
|
1073
|
-
async function executeGraph(args, ctx) {
|
|
1074
|
-
const { opts } = extractOpts(args);
|
|
1075
|
-
const limit = typeof opts.limit === "string" ? parseInt(opts.limit, 10) : 1000;
|
|
1076
|
-
const outPath = typeof opts.out === "string" ? opts.out : undefined;
|
|
1077
|
-
const noOpen = opts["no-open"] === true || opts["no-open"] === "true";
|
|
1078
|
-
try {
|
|
1079
|
-
const client = makeClient(ctx);
|
|
1080
|
-
const html = await client.getRaw(`/v1/graph?limit=${limit}&format=html`);
|
|
1081
|
-
const { writeFileSync } = await import("node:fs");
|
|
1082
|
-
const { join } = await import("node:path");
|
|
1083
|
-
const { tmpdir } = await import("node:os");
|
|
1084
|
-
const filePath = outPath ?? join(tmpdir(), `nex-graph-${Date.now()}.html`);
|
|
1085
|
-
writeFileSync(filePath, html, "utf-8");
|
|
1086
|
-
if (!noOpen) {
|
|
1087
|
-
const { spawn } = await import("node:child_process");
|
|
1088
|
-
const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : "cmd";
|
|
1089
|
-
const cmdArgs = process.platform === "win32" ? ["/c", "start", "", filePath] : [filePath];
|
|
1090
|
-
try {
|
|
1091
|
-
spawn(cmd, cmdArgs, { stdio: "ignore", detached: true }).unref();
|
|
1092
|
-
}
|
|
1093
|
-
catch { /* ignore */ }
|
|
1094
|
-
}
|
|
1095
|
-
return ok({ path: filePath, message: noOpen ? `Graph saved to ${filePath}` : "Graph opened in browser" }, ctx);
|
|
1096
|
-
}
|
|
1097
|
-
catch (err) {
|
|
1098
|
-
return wrapError(err);
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
// ── Agent command executors ──
|
|
1102
|
-
async function executeAgentList(_args, ctx) {
|
|
1103
|
-
try {
|
|
1104
|
-
const service = getAgentService();
|
|
1105
|
-
const agents = service.list().map(m => ({
|
|
1106
|
-
slug: m.config.slug,
|
|
1107
|
-
name: m.config.name,
|
|
1108
|
-
phase: m.state.phase,
|
|
1109
|
-
expertise: m.config.expertise,
|
|
1110
|
-
tokensUsed: m.state.tokensUsed,
|
|
1111
|
-
costUsd: m.state.costUsd,
|
|
1112
|
-
}));
|
|
1113
|
-
return ok(agents, ctx);
|
|
1114
|
-
}
|
|
1115
|
-
catch (err) {
|
|
1116
|
-
return wrapError(err);
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
async function executeAgentCreate(args, _ctx) {
|
|
1120
|
-
try {
|
|
1121
|
-
const { positional, opts } = extractOpts(args);
|
|
1122
|
-
const slug = positional[0];
|
|
1123
|
-
if (!slug)
|
|
1124
|
-
return fail("Usage: agent create <slug> --template <name> | --name <name> --expertise <skills>");
|
|
1125
|
-
const service = getAgentService();
|
|
1126
|
-
if (opts.template && typeof opts.template === "string") {
|
|
1127
|
-
const managed = service.createFromTemplate(slug, opts.template);
|
|
1128
|
-
return { output: `Created agent "${managed.config.name}" (${slug}) from template "${opts.template}".`, data: managed.config, exitCode: 0 };
|
|
1129
|
-
}
|
|
1130
|
-
const name = typeof opts.name === "string" ? opts.name : slug;
|
|
1131
|
-
const expertiseRaw = typeof opts.expertise === "string" ? opts.expertise : "";
|
|
1132
|
-
const expertise = expertiseRaw ? expertiseRaw.split(",").map(s => s.trim()) : [];
|
|
1133
|
-
const personality = typeof opts.personality === "string" ? opts.personality : undefined;
|
|
1134
|
-
const managed = service.create({ slug, name, expertise, personality });
|
|
1135
|
-
return { output: `Created agent "${managed.config.name}" (${slug}).`, data: managed.config, exitCode: 0 };
|
|
1136
|
-
}
|
|
1137
|
-
catch (err) {
|
|
1138
|
-
return wrapError(err);
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
async function executeAgentStart(args, _ctx) {
|
|
1142
|
-
try {
|
|
1143
|
-
const slug = args[0];
|
|
1144
|
-
if (!slug)
|
|
1145
|
-
return fail("Usage: agent start <slug>");
|
|
1146
|
-
const service = getAgentService();
|
|
1147
|
-
await service.start(slug);
|
|
1148
|
-
const state = service.getState(slug);
|
|
1149
|
-
return { output: `Agent "${slug}" started (phase: ${state?.phase ?? "unknown"}).`, data: state, exitCode: 0 };
|
|
1150
|
-
}
|
|
1151
|
-
catch (err) {
|
|
1152
|
-
return wrapError(err);
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
async function executeAgentStop(args, _ctx) {
|
|
1156
|
-
try {
|
|
1157
|
-
const slug = args[0];
|
|
1158
|
-
if (!slug)
|
|
1159
|
-
return fail("Usage: agent stop <slug>");
|
|
1160
|
-
const service = getAgentService();
|
|
1161
|
-
service.stop(slug);
|
|
1162
|
-
return { output: `Agent "${slug}" stopped.`, exitCode: 0 };
|
|
1163
|
-
}
|
|
1164
|
-
catch (err) {
|
|
1165
|
-
return wrapError(err);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
async function executeAgentSteer(args, _ctx) {
|
|
1169
|
-
try {
|
|
1170
|
-
const slug = args[0];
|
|
1171
|
-
const message = args.slice(1).join(" ");
|
|
1172
|
-
if (!slug || !message)
|
|
1173
|
-
return fail("Usage: agent steer <slug> <message>");
|
|
1174
|
-
const service = getAgentService();
|
|
1175
|
-
service.steer(slug, message);
|
|
1176
|
-
return { output: `Steer message sent to "${slug}".`, exitCode: 0 };
|
|
1177
|
-
}
|
|
1178
|
-
catch (err) {
|
|
1179
|
-
return wrapError(err);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
async function executeAgentInspect(args, ctx) {
|
|
1183
|
-
try {
|
|
1184
|
-
const slug = args[0];
|
|
1185
|
-
if (!slug)
|
|
1186
|
-
return fail("Usage: agent inspect <slug>");
|
|
1187
|
-
const service = getAgentService();
|
|
1188
|
-
const managed = service.get(slug);
|
|
1189
|
-
if (!managed)
|
|
1190
|
-
return fail(`Agent "${slug}" not found.`);
|
|
1191
|
-
const data = {
|
|
1192
|
-
config: managed.config,
|
|
1193
|
-
state: managed.state,
|
|
1194
|
-
};
|
|
1195
|
-
return ok(data, ctx);
|
|
1196
|
-
}
|
|
1197
|
-
catch (err) {
|
|
1198
|
-
return wrapError(err);
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
async function executeAgentTemplates(_args, ctx) {
|
|
1202
|
-
try {
|
|
1203
|
-
const service = getAgentService();
|
|
1204
|
-
const names = service.getTemplateNames();
|
|
1205
|
-
const data = names.map(name => {
|
|
1206
|
-
const tmpl = service.getTemplate(name);
|
|
1207
|
-
return { name, ...(tmpl ?? {}) };
|
|
1208
|
-
});
|
|
1209
|
-
return ok(data, ctx);
|
|
1210
|
-
}
|
|
1211
|
-
catch (err) {
|
|
1212
|
-
return wrapError(err);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
// -- Init / Setup --
|
|
1216
|
-
async function executeInit(args, ctx) {
|
|
1217
|
-
const { positional, opts } = extractOpts(args);
|
|
1218
|
-
const email = typeof opts.email === "string" ? opts.email : positional[0];
|
|
1219
|
-
const existingKey = ctx.apiKey ?? resolveApiKey();
|
|
1220
|
-
const logs = [];
|
|
1221
|
-
try {
|
|
1222
|
-
await runInit((progress) => {
|
|
1223
|
-
const prefix = progress.error ? "[ERROR]" : "[OK]";
|
|
1224
|
-
const line = progress.detail ?? progress.step;
|
|
1225
|
-
logs.push(`${prefix} ${line}`);
|
|
1226
|
-
}, {
|
|
1227
|
-
email: email || undefined,
|
|
1228
|
-
apiKey: existingKey || undefined,
|
|
1229
|
-
});
|
|
1230
|
-
const output = logs.join("\n");
|
|
1231
|
-
return {
|
|
1232
|
-
output,
|
|
1233
|
-
data: { logs, success: true },
|
|
1234
|
-
exitCode: 0,
|
|
1235
|
-
};
|
|
1236
|
-
}
|
|
1237
|
-
catch (err) {
|
|
1238
|
-
const output = logs.join("\n");
|
|
1239
|
-
return {
|
|
1240
|
-
output,
|
|
1241
|
-
data: { logs, success: false },
|
|
1242
|
-
exitCode: 1,
|
|
1243
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
async function executeDetectPlatforms(_args, ctx) {
|
|
1248
|
-
const platforms = detectPlatforms();
|
|
1249
|
-
const detected = platforms.filter((p) => p.detected);
|
|
1250
|
-
return ok(detected, ctx);
|
|
1251
|
-
}
|
|
1252
|
-
// ── Command registry ──
|
|
1253
|
-
const commands = new Map();
|
|
1254
|
-
function register(name, entry) {
|
|
1255
|
-
commands.set(name, entry);
|
|
1256
|
-
}
|
|
1257
|
-
// -- AI commands --
|
|
1258
|
-
register("ask", { execute: executeAsk, description: "Query your context graph with AI", category: "ai", usage: "ask <query>" });
|
|
1259
|
-
register("remember", { execute: executeRemember, description: "Store a note, fact, or observation", category: "ai", usage: "remember <content> [--context <ctx>]" });
|
|
1260
|
-
register("recall", { execute: executeRecall, description: "Recall context for LLM prompt injection", category: "ai", usage: "recall <query>" });
|
|
1261
|
-
register("artifact", { execute: executeArtifact, description: "Retrieve a context artifact by ID", category: "ai", usage: "artifact <id>" });
|
|
1262
|
-
register("capture", { execute: executeCapture, description: "Auto-capture content with filtering", category: "ai", usage: "capture <content>" });
|
|
1263
|
-
// -- Query: objects --
|
|
1264
|
-
register("object list", { execute: executeObjectList, description: "List all objects", category: "query", usage: "object list [--include-attributes]" });
|
|
1265
|
-
register("object get", { execute: executeObjectGet, description: "Get an object by slug", category: "query", usage: "object get <slug>" });
|
|
1266
|
-
register("object create", { execute: executeObjectCreate, description: "Create a new object", category: "write", usage: "object create --name <n> --slug <s> [--type <t>]" });
|
|
1267
|
-
register("object update", { execute: executeObjectUpdate, description: "Update an object", category: "write", usage: "object update <slug> [--name <n>] [--description <d>]" });
|
|
1268
|
-
register("object delete", { execute: executeObjectDelete, description: "Delete an object", category: "write", usage: "object delete <slug>" });
|
|
1269
|
-
// -- Query/Write: records --
|
|
1270
|
-
register("record list", { execute: executeRecordList, description: "List records for an object", category: "query", usage: "record list <object-slug> [--limit <n>]" });
|
|
1271
|
-
register("record get", { execute: executeRecordGet, description: "Get a record by ID", category: "query", usage: "record get <id>" });
|
|
1272
|
-
register("record create", { execute: executeRecordCreate, description: "Create a record", category: "write", usage: "record create <object-slug> --data <json>" });
|
|
1273
|
-
register("record upsert", { execute: executeRecordUpsert, description: "Upsert a record", category: "write", usage: "record upsert <object-slug> --match <attr> --data <json>" });
|
|
1274
|
-
register("record update", { execute: executeRecordUpdate, description: "Update a record", category: "write", usage: "record update <id> --data <json>" });
|
|
1275
|
-
register("record delete", { execute: executeRecordDelete, description: "Delete a record", category: "write", usage: "record delete <id>" });
|
|
1276
|
-
register("record timeline", { execute: executeRecordTimeline, description: "Get record timeline", category: "query", usage: "record timeline <id> [--limit <n>]" });
|
|
1277
|
-
// -- Query: search --
|
|
1278
|
-
register("search", { execute: executeSearch, description: "Fuzzy keyword search across CRM records", category: "query", usage: "search <query>" });
|
|
1279
|
-
// -- Query: insights --
|
|
1280
|
-
register("insight list", { execute: executeInsightList, description: "List insights", category: "query", usage: "insight list [--last <dur>] [--from <date>] [--to <date>]" });
|
|
1281
|
-
// -- Write: notes --
|
|
1282
|
-
register("note list", { execute: executeNoteList, description: "List notes", category: "query", usage: "note list [--entity <id>]" });
|
|
1283
|
-
register("note get", { execute: executeNoteGet, description: "Get a note by ID", category: "query", usage: "note get <id>" });
|
|
1284
|
-
register("note create", { execute: executeNoteCreate, description: "Create a note", category: "write", usage: "note create --title <t> [--content <c>] [--entity <id>]" });
|
|
1285
|
-
register("note update", { execute: executeNoteUpdate, description: "Update a note", category: "write", usage: "note update <id> [--title <t>] [--content <c>]" });
|
|
1286
|
-
register("note delete", { execute: executeNoteDelete, description: "Delete a note", category: "write", usage: "note delete <id>" });
|
|
1287
|
-
// -- Write: tasks --
|
|
1288
|
-
register("task list", { execute: executeTaskList, description: "List tasks", category: "query", usage: "task list [--entity <id>] [--assignee <id>]" });
|
|
1289
|
-
register("task get", { execute: executeTaskGet, description: "Get a task by ID", category: "query", usage: "task get <id>" });
|
|
1290
|
-
register("task create", { execute: executeTaskCreate, description: "Create a task", category: "write", usage: "task create --title <t> [--priority <p>] [--due <d>]" });
|
|
1291
|
-
register("task update", { execute: executeTaskUpdate, description: "Update a task", category: "write", usage: "task update <id> [--title <t>] [--completed]" });
|
|
1292
|
-
register("task delete", { execute: executeTaskDelete, description: "Delete a task", category: "write", usage: "task delete <id>" });
|
|
1293
|
-
// -- Relationships --
|
|
1294
|
-
register("rel list-defs", { execute: executeRelListDefs, description: "List relationship definitions", category: "query", usage: "rel list-defs" });
|
|
1295
|
-
register("rel create-def", { execute: executeRelCreateDef, description: "Create a relationship definition", category: "write", usage: "rel create-def --type <t> --entity1 <id> --entity2 <id>" });
|
|
1296
|
-
register("rel delete-def", { execute: executeRelDeleteDef, description: "Delete a relationship definition", category: "write", usage: "rel delete-def <id>" });
|
|
1297
|
-
register("rel create", { execute: executeRelCreate, description: "Create a relationship between records", category: "write", usage: "rel create <record-id> --def <id> --entity1 <id> --entity2 <id>" });
|
|
1298
|
-
register("rel delete", { execute: executeRelDelete, description: "Delete a relationship", category: "write", usage: "rel delete <record-id> <rel-id>" });
|
|
1299
|
-
// -- Attributes --
|
|
1300
|
-
register("attribute create", { execute: executeAttrCreate, description: "Create an attribute on an object", category: "write", usage: "attribute create <slug> --name <n> --slug <s> --type <t>" });
|
|
1301
|
-
register("attribute update", { execute: executeAttrUpdate, description: "Update an attribute", category: "write", usage: "attribute update <object-slug> <attr-id> [--name <n>]" });
|
|
1302
|
-
register("attribute delete", { execute: executeAttrDelete, description: "Delete an attribute", category: "write", usage: "attribute delete <object-slug> <attr-id>" });
|
|
1303
|
-
// -- Lists --
|
|
1304
|
-
register("list list", { execute: executeListList, description: "List all lists for an object", category: "query", usage: "list list <object-slug>" });
|
|
1305
|
-
register("list get", { execute: executeListGet, description: "Get a list by ID", category: "query", usage: "list get <id>" });
|
|
1306
|
-
register("list create", { execute: executeListCreate, description: "Create a new list", category: "write", usage: "list create <object-slug> --name <n> --slug <s>" });
|
|
1307
|
-
register("list delete", { execute: executeListDelete, description: "Delete a list", category: "write", usage: "list delete <id>" });
|
|
1308
|
-
register("list records", { execute: executeListRecords, description: "List records in a list", category: "query", usage: "list records <list-id> [--limit <n>]" });
|
|
1309
|
-
// -- List jobs --
|
|
1310
|
-
register("list-job create", { execute: executeListJobCreate, description: "Create a list generation job", category: "ai", usage: "list-job create <query> [--type <t>]" });
|
|
1311
|
-
register("list-job status", { execute: executeListJobStatus, description: "Get list generation job status", category: "query", usage: "list-job status <id>" });
|
|
1312
|
-
// -- Config --
|
|
1313
|
-
register("config show", { execute: executeConfigShow, description: "Show resolved configuration", category: "config" });
|
|
1314
|
-
register("config set", { execute: executeConfigSet, description: "Set a configuration value", category: "config", usage: "config set <key> <value>" });
|
|
1315
|
-
register("config path", { execute: executeConfigPath, description: "Print the config file path", category: "config" });
|
|
1316
|
-
// -- Init / Setup --
|
|
1317
|
-
register("init", { execute: executeInit, description: "Set up Nex for all detected AI platforms", category: "config", usage: "init [email] [--email <email>]" });
|
|
1318
|
-
register("detect", { execute: executeDetectPlatforms, description: "Detect installed AI coding platforms", category: "config" });
|
|
1319
|
-
// -- Integrations --
|
|
1320
|
-
register("integrate list", { execute: executeIntegrateList, description: "List all integrations and connection status", category: "config" });
|
|
1321
|
-
register("integrate connect", { execute: executeIntegrateConnect, description: "Connect an integration", category: "config", usage: "integrate connect <name>" });
|
|
1322
|
-
register("integrate disconnect", { execute: executeIntegrateDisconnect, description: "Disconnect an integration", category: "config", usage: "integrate disconnect <connection-id>" });
|
|
1323
|
-
// -- Notifications --
|
|
1324
|
-
register("notify list", { execute: executeNotifyList, description: "List recent notifications", category: "query", usage: "notify list [--limit <n>] [--since <date>]" });
|
|
1325
|
-
register("notify preferences", { execute: executeNotifyPreferences, description: "Show notification preferences", category: "query" });
|
|
1326
|
-
register("notify set-frequency", { execute: executeNotifySetFrequency, description: "Set notification polling frequency", category: "config", usage: "notify set-frequency <minutes>" });
|
|
1327
|
-
register("notify enable", { execute: executeNotifyEnable, description: "Enable a notification type", category: "config", usage: "notify enable <type>" });
|
|
1328
|
-
register("notify disable", { execute: executeNotifyDisable, description: "Disable a notification type", category: "config", usage: "notify disable <type>" });
|
|
1329
|
-
register("notify rule-create", { execute: executeNotifyRuleCreate, description: "Create a custom notification rule", category: "write", usage: 'notify rule-create "<description>"' });
|
|
1330
|
-
register("notify rule-list", { execute: executeNotifyRuleList, description: "List custom notification rules", category: "query" });
|
|
1331
|
-
register("notify rule-delete", { execute: executeNotifyRuleDelete, description: "Delete a custom notification rule", category: "write", usage: "notify rule-delete <id>" });
|
|
1332
|
-
// -- Graph --
|
|
1333
|
-
register("graph", { execute: executeGraph, description: "Fetch workspace entity graph data", category: "graph", usage: "graph [--limit <n>]" });
|
|
1334
|
-
// -- Agents --
|
|
1335
|
-
register("agent list", { execute: executeAgentList, description: "List all managed agents", category: "agent", usage: "agent list" });
|
|
1336
|
-
register("agent create", { execute: executeAgentCreate, description: "Create an agent from template or config", category: "agent", usage: "agent create <slug> --template <name> | --name <n> --expertise <skills>" });
|
|
1337
|
-
register("agent start", { execute: executeAgentStart, description: "Start an agent loop", category: "agent", usage: "agent start <slug>" });
|
|
1338
|
-
register("agent stop", { execute: executeAgentStop, description: "Stop an agent loop", category: "agent", usage: "agent stop <slug>" });
|
|
1339
|
-
register("agent steer", { execute: executeAgentSteer, description: "Send a steer message to an agent", category: "agent", usage: "agent steer <slug> <message>" });
|
|
1340
|
-
register("agent inspect", { execute: executeAgentInspect, description: "Inspect agent config and state", category: "agent", usage: "agent inspect <slug>" });
|
|
1341
|
-
register("agent templates", { execute: executeAgentTemplates, description: "List available agent templates", category: "agent", usage: "agent templates" });
|
|
1342
|
-
// -- Scan --
|
|
1343
|
-
async function executeScan(args, ctx) {
|
|
1344
|
-
const { positional, opts } = extractOpts(args);
|
|
1345
|
-
const dir = positional[0] || ".";
|
|
1346
|
-
const maxFiles = typeof opts["max-files"] === "string" ? parseInt(opts["max-files"], 10) : undefined;
|
|
1347
|
-
if (maxFiles !== undefined && (!Number.isInteger(maxFiles) || maxFiles <= 0)) {
|
|
1348
|
-
return fail("Invalid --max-files. Expected a positive integer.");
|
|
1349
|
-
}
|
|
1350
|
-
const depth = typeof opts.depth === "string" ? parseInt(opts.depth, 10) : undefined;
|
|
1351
|
-
if (depth !== undefined && (!Number.isInteger(depth) || depth < 0)) {
|
|
1352
|
-
return fail("Invalid --depth. Expected a non-negative integer.");
|
|
1353
|
-
}
|
|
1354
|
-
const extensions = typeof opts.extensions === "string" ? opts.extensions : undefined;
|
|
1355
|
-
const force = opts.force === true;
|
|
1356
|
-
const dryRun = opts["dry-run"] === true;
|
|
1357
|
-
try {
|
|
1358
|
-
const { scanFiles, loadScanConfig } = await import("../lib/file-scanner.js");
|
|
1359
|
-
const scanOpts = loadScanConfig({
|
|
1360
|
-
extensions: extensions?.split(",").map((e) => e.trim()),
|
|
1361
|
-
maxFiles,
|
|
1362
|
-
depth,
|
|
1363
|
-
force,
|
|
1364
|
-
dryRun,
|
|
1365
|
-
});
|
|
1366
|
-
const client = makeClient(ctx);
|
|
1367
|
-
const result = await scanFiles(dir, scanOpts, async (content, context) => {
|
|
1368
|
-
return client.post("/v1/context/text", { content, context });
|
|
1369
|
-
});
|
|
1370
|
-
// Trigger compounding intelligence after successful ingestion
|
|
1371
|
-
const apiKey = ctx.apiKey ?? resolveApiKey();
|
|
1372
|
-
if (apiKey && shouldTriggerCompounding(result.scanned, dryRun)) {
|
|
1373
|
-
launchBackgroundCompounding(apiKey);
|
|
1374
|
-
}
|
|
1375
|
-
return ok({ scanned: result.scanned, skipped: result.skipped, errors: result.errors }, ctx);
|
|
1376
|
-
}
|
|
1377
|
-
catch (err) {
|
|
1378
|
-
return wrapError(err);
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
register("scan", { execute: executeScan, description: "Scan directory and ingest files", category: "config", usage: "scan [dir] [--max-files <n>] [--force] [--dry-run]" });
|
|
1382
|
-
// -- Register --
|
|
1383
|
-
async function executeRegister(args, ctx) {
|
|
1384
|
-
const { opts } = extractOpts(args);
|
|
1385
|
-
const email = typeof opts.email === "string" ? opts.email : undefined;
|
|
1386
|
-
if (!email)
|
|
1387
|
-
return fail("Usage: register --email <email>");
|
|
1388
|
-
try {
|
|
1389
|
-
const { persistRegistration } = await import("../lib/config.js");
|
|
1390
|
-
const client = new NexClient(undefined, ctx.timeout ?? resolveTimeout());
|
|
1391
|
-
const data = await client.register(email, typeof opts.name === "string" ? opts.name : undefined, typeof opts.company === "string" ? opts.company : undefined);
|
|
1392
|
-
persistRegistration(data);
|
|
1393
|
-
return ok(data, ctx);
|
|
1394
|
-
}
|
|
1395
|
-
catch (err) {
|
|
1396
|
-
return wrapError(err);
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
register("register", { execute: executeRegister, description: "Register a new Nex workspace", category: "config", usage: "register --email <email> [--name <name>] [--company <company>]" });
|
|
1400
|
-
// -- Session --
|
|
1401
|
-
async function executeSessionList(_args, ctx) {
|
|
1402
|
-
try {
|
|
1403
|
-
const { SessionStore } = await import("../lib/session-store.js");
|
|
1404
|
-
const store = new SessionStore();
|
|
1405
|
-
return ok(store.list(), ctx);
|
|
1406
|
-
}
|
|
1407
|
-
catch (err) {
|
|
1408
|
-
return wrapError(err);
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
async function executeSessionClear(_args, ctx) {
|
|
1412
|
-
try {
|
|
1413
|
-
const { SessionStore } = await import("../lib/session-store.js");
|
|
1414
|
-
const store = new SessionStore();
|
|
1415
|
-
store.clear();
|
|
1416
|
-
return ok({ message: "All sessions cleared." }, ctx);
|
|
1417
|
-
}
|
|
1418
|
-
catch (err) {
|
|
1419
|
-
return wrapError(err);
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
register("session list", { execute: executeSessionList, description: "List stored session mappings", category: "config" });
|
|
1423
|
-
register("session clear", { execute: executeSessionClear, description: "Clear all session mappings", category: "config" });
|
|
1424
|
-
// -- List member operations --
|
|
1425
|
-
function makeListRecordCommand(method, usage, pathFn, bodyFn) {
|
|
1426
|
-
return async (args, ctx) => {
|
|
1427
|
-
const { positional, opts } = extractOpts(args);
|
|
1428
|
-
const [listId, recordId] = positional;
|
|
1429
|
-
if (!listId || !recordId)
|
|
1430
|
-
return fail(`Usage: ${usage}`);
|
|
1431
|
-
try {
|
|
1432
|
-
const client = makeClient(ctx);
|
|
1433
|
-
const path = pathFn(encodeURIComponent(listId), encodeURIComponent(recordId));
|
|
1434
|
-
const body = bodyFn?.(recordId, opts);
|
|
1435
|
-
const data = method === "delete" ? await client.delete(path) : await client[method](path, body);
|
|
1436
|
-
return ok(data, ctx);
|
|
1437
|
-
}
|
|
1438
|
-
catch (err) {
|
|
1439
|
-
return wrapError(err);
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
register("list add-member", { execute: makeListRecordCommand("post", "list add-member <list-id> <record-id>", (lid) => `/v1/lists/${lid}/records`, (rid) => ({ record_id: rid })), description: "Add a record to a list", category: "write", usage: "list add-member <list-id> <record-id>" });
|
|
1444
|
-
register("list upsert-member", { execute: makeListRecordCommand("put", "list upsert-member <list-id> <record-id>", (lid, rid) => `/v1/lists/${lid}/records/${rid}`, (_rid, opts) => opts), description: "Upsert a record in a list", category: "write", usage: "list upsert-member <list-id> <record-id>" });
|
|
1445
|
-
register("list update-record", { execute: makeListRecordCommand("patch", "list update-record <list-id> <record-id>", (lid, rid) => `/v1/lists/${lid}/records/${rid}`, (_rid, opts) => opts), description: "Update a list record", category: "write", usage: "list update-record <list-id> <record-id>" });
|
|
1446
|
-
register("list remove-record", { execute: makeListRecordCommand("delete", "list remove-record <list-id> <record-id>", (lid, rid) => `/v1/lists/${lid}/records/${rid}`), description: "Remove a record from a list", category: "write", usage: "list remove-record <list-id> <record-id>" });
|
|
1447
|
-
// -- TUI view hints (so aliases resolve and dispatch does not return "unknown command") --
|
|
1448
|
-
register("chat", {
|
|
1449
|
-
execute: async () => ({ output: "Use the 'c' keybinding to open the chat view.", exitCode: 0 }),
|
|
1450
|
-
description: "Open the chat view (use 'c' keybinding in TUI)",
|
|
1451
|
-
category: "config",
|
|
1452
|
-
});
|
|
1453
|
-
register("calendar", {
|
|
1454
|
-
execute: async () => ({ output: "Use the 'C' keybinding to open the calendar view.", exitCode: 0 }),
|
|
1455
|
-
description: "Open the calendar view (use 'C' keybinding in TUI)",
|
|
1456
|
-
category: "config",
|
|
1457
|
-
});
|
|
1458
|
-
register("orchestration", {
|
|
1459
|
-
execute: async () => ({ output: "Use the 'o' keybinding to open the orchestration view.", exitCode: 0 }),
|
|
1460
|
-
description: "Open the orchestration view (use 'o' keybinding in TUI)",
|
|
1461
|
-
category: "config",
|
|
1462
|
-
});
|
|
1463
|
-
// ── Public API ──
|
|
1464
|
-
// ── Command aliases ──
|
|
1465
|
-
// Maps short-hand aliases to canonical command names so users can type less.
|
|
1466
|
-
const COMMAND_ALIASES = {
|
|
1467
|
-
agents: "agent list",
|
|
1468
|
-
objects: "object list",
|
|
1469
|
-
orch: "orchestration",
|
|
1470
|
-
setup: "init",
|
|
1471
|
-
sessions: "session list",
|
|
1472
|
-
};
|
|
1473
|
-
/**
|
|
1474
|
-
* Resolve alias tokens into their canonical form.
|
|
1475
|
-
* Single-word aliases are checked first, then multi-word aliases via join.
|
|
1476
|
-
*/
|
|
1477
|
-
function resolveAlias(tokens) {
|
|
1478
|
-
if (tokens.length === 0)
|
|
1479
|
-
return tokens;
|
|
1480
|
-
// Check single-word alias
|
|
1481
|
-
const oneWord = tokens[0].toLowerCase();
|
|
1482
|
-
if (COMMAND_ALIASES[oneWord]) {
|
|
1483
|
-
const canonical = COMMAND_ALIASES[oneWord].split(" ");
|
|
1484
|
-
return [...canonical, ...tokens.slice(1)];
|
|
1485
|
-
}
|
|
1486
|
-
return tokens;
|
|
1487
|
-
}
|
|
1488
|
-
/**
|
|
1489
|
-
* Resolve a token stream into a registered command name.
|
|
1490
|
-
* Tries alias resolution first, then two-word match (e.g. "record list"), then single-word.
|
|
1491
|
-
*/
|
|
1492
|
-
function resolveCommand(tokens) {
|
|
1493
|
-
if (tokens.length === 0)
|
|
1494
|
-
return undefined;
|
|
1495
|
-
// Apply alias resolution
|
|
1496
|
-
const resolved = resolveAlias(tokens);
|
|
1497
|
-
// Try two-word match first
|
|
1498
|
-
if (resolved.length >= 2) {
|
|
1499
|
-
const twoWord = `${resolved[0]} ${resolved[1]}`;
|
|
1500
|
-
if (commands.has(twoWord)) {
|
|
1501
|
-
return { name: twoWord, args: resolved.slice(2) };
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
// Single-word match
|
|
1505
|
-
if (commands.has(resolved[0])) {
|
|
1506
|
-
return { name: resolved[0], args: resolved.slice(1) };
|
|
1507
|
-
}
|
|
1508
|
-
return undefined;
|
|
1509
|
-
}
|
|
1510
|
-
/**
|
|
1511
|
-
* Dispatch a command string, returning a structured result.
|
|
1512
|
-
* The TUI and CLI can both call this to execute commands without stdout side effects.
|
|
1513
|
-
*/
|
|
1514
|
-
export async function dispatch(input, ctx) {
|
|
1515
|
-
const tokens = parseInput(input);
|
|
1516
|
-
return dispatchTokens(tokens, ctx);
|
|
1517
|
-
}
|
|
1518
|
-
/**
|
|
1519
|
-
* Dispatch from pre-tokenized args (e.g. process.argv).
|
|
1520
|
-
* Use this when the shell has already handled quoting/splitting.
|
|
1521
|
-
*/
|
|
1522
|
-
export async function dispatchTokens(tokens, ctx) {
|
|
1523
|
-
if (tokens.length === 0) {
|
|
1524
|
-
return fail("No command provided.");
|
|
1525
|
-
}
|
|
1526
|
-
const resolved = resolveCommand(tokens);
|
|
1527
|
-
if (!resolved) {
|
|
1528
|
-
return fail(`Unknown command: ${tokens[0]}${tokens.length > 1 ? " " + tokens[1] : ""}`);
|
|
1529
|
-
}
|
|
1530
|
-
const entry = commands.get(resolved.name);
|
|
1531
|
-
return entry.execute(resolved.args, ctx ?? {});
|
|
1532
|
-
}
|
|
1533
|
-
/** All registered command names, for autocomplete. */
|
|
1534
|
-
export const commandNames = Array.from(commands.keys()).sort();
|
|
1535
|
-
/** Help entries for each command, with category and description. */
|
|
1536
|
-
export const commandHelp = Array.from(commands.entries())
|
|
1537
|
-
.map(([name, entry]) => ({
|
|
1538
|
-
command: name,
|
|
1539
|
-
description: entry.description,
|
|
1540
|
-
category: entry.category,
|
|
1541
|
-
usage: entry.usage,
|
|
1542
|
-
}))
|
|
1543
|
-
.sort((a, b) => a.category.localeCompare(b.category) || a.command.localeCompare(b.command));
|
|
1544
|
-
//# sourceMappingURL=dispatch.js.map
|