@notis_ai/cli 0.2.17 → 0.2.19
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 +542 -146
- package/bin/check-runtime.js +15 -0
- package/bin/notis.js +2 -0
- package/config/notis_app_design_rules.json +320 -0
- package/config/portal-route-roots.json +45 -0
- package/dist/agent-hooks/notis-agent-hook.mjs +42323 -18258
- package/dist/base-skills/notis-cli/.notis-base-skill.json +1 -0
- package/dist/base-skills/notis-cli/SKILL.md +51 -280
- package/dist/base-skills/notis-cli/references/app-delivery.md +17 -0
- package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
- package/dist/base-skills/notis-cli/references/native-databases.md +21 -0
- package/dist/base-skills/notis-cli/references/tool-examples.md +56 -0
- package/dist/base-skills/notis-cli/references/troubleshooting.md +67 -0
- package/dist/base-skills/notis-query/.notis-base-skill.json +1 -0
- package/dist/base-skills/notis-query/SKILL.md +35 -699
- package/dist/base-skills/notis-query/references/database-discovery.md +59 -0
- package/dist/base-skills/notis-query/references/documents.md +74 -0
- package/dist/base-skills/notis-query/references/query.md +76 -0
- package/dist/base-skills/notis-spaces/.notis-base-skill.json +1 -0
- package/dist/base-skills/notis-spaces/SKILL.md +218 -0
- package/dist/base-skills/notis-spaces/references/architecture.md +116 -0
- package/dist/base-skills/notis-spaces/references/context.md +81 -0
- package/dist/base-skills/notis-spaces/references/design.md +141 -0
- package/dist/base-skills/notis-spaces/references/fixtures.md +29 -0
- package/dist/base-skills/notis-spaces/references/memory.md +58 -0
- package/dist/base-skills/notis-spaces/references/reading.md +73 -0
- package/dist/base-skills/notis-spaces/references/release.md +120 -0
- package/dist/base-skills/notis-spaces/references/reports.md +77 -0
- package/dist/base-skills/notis-spaces/references/sdk.md +273 -0
- package/dist/base-skills/notis-spaces/references/store.md +118 -0
- package/dist/base-skills/notis-spaces/references/troubleshooting.md +28 -0
- package/dist/base-skills/notis-spaces/references/views.md +229 -0
- package/{template/packages → dist}/sdk/package.json +9 -10
- package/dist/sdk/src/agentContext.ts +36 -0
- package/dist/sdk/src/bundleModule.ts +175 -0
- package/dist/sdk/src/components/Dialog.tsx +103 -0
- package/dist/sdk/src/components/DocumentEditor.tsx +113 -0
- package/dist/sdk/src/components/DocumentPage.tsx +184 -0
- package/{template/packages → dist}/sdk/src/components/Markdown.tsx +9 -3
- package/{template/packages → dist}/sdk/src/components/MarkdownEditor.tsx +26 -5
- package/{template/packages → dist}/sdk/src/components/MultiSelectActionBar.tsx +95 -12
- package/{template/packages → dist}/sdk/src/components/MultiSelectCheckbox.tsx +4 -2
- package/dist/sdk/src/components/NotisCommentBoundary.tsx +172 -0
- package/{template/packages → dist}/sdk/src/components/NotisSelectionBoundary.tsx +9 -5
- package/dist/sdk/src/components/RecordComponents.tsx +111 -0
- package/dist/sdk/src/components/Skeleton.tsx +38 -0
- package/dist/sdk/src/config.ts +31 -0
- package/{template/packages → dist}/sdk/src/documents.ts +21 -6
- package/dist/sdk/src/hooks/useAction.ts +28 -0
- package/dist/sdk/src/hooks/useAgentContext.ts +23 -0
- package/{template/packages → dist}/sdk/src/hooks/useBackend.ts +3 -2
- package/dist/sdk/src/hooks/useCloudComputer.ts +94 -0
- package/dist/sdk/src/hooks/useCloudComputerShell.ts +114 -0
- package/{template/packages → dist}/sdk/src/hooks/useCollectionInteractions.ts +157 -147
- package/dist/sdk/src/hooks/useDatabaseSchema.ts +50 -0
- package/{template/packages → dist}/sdk/src/hooks/useDatabaseSubscription.ts +2 -2
- package/dist/sdk/src/hooks/useDocument.ts +51 -0
- package/{template/packages → dist}/sdk/src/hooks/useDocuments.ts +25 -59
- package/{template/packages → dist}/sdk/src/hooks/useHandover.ts +7 -7
- package/dist/sdk/src/hooks/useLongPressSelection.ts +79 -0
- package/dist/sdk/src/hooks/useMarqueeSelection.ts +194 -0
- package/{template/packages → dist}/sdk/src/hooks/useMultiSelect.ts +2 -8
- package/dist/sdk/src/hooks/useNativeDocumentBody.ts +50 -0
- package/dist/sdk/src/hooks/useNativeDocuments.ts +143 -0
- package/{template/packages → dist}/sdk/src/hooks/useNotis.ts +6 -1
- package/dist/sdk/src/hooks/useNotisNavigation.ts +70 -0
- package/dist/sdk/src/hooks/useQuery.ts +81 -0
- package/dist/sdk/src/hooks/useToolQuery.ts +12 -0
- package/dist/sdk/src/hooks/useTopBarSearch.ts +102 -0
- package/dist/sdk/src/hooks/useTopBarTitleLeaf.ts +75 -0
- package/{template/packages → dist}/sdk/src/hooks/useUpsertDocument.ts +1 -1
- package/dist/sdk/src/hooks/useViewParams.ts +195 -0
- package/dist/sdk/src/hooks/useViewerReads.ts +129 -0
- package/{template/packages → dist}/sdk/src/index.ts +64 -1
- package/{template/packages → dist}/sdk/src/interactions/actions.ts +14 -1
- package/{template/packages → dist}/sdk/src/interactions/shortcuts.tsx +129 -23
- package/dist/sdk/src/interactions/visibility.ts +13 -0
- package/{template/packages → dist}/sdk/src/interactions.ts +5 -1
- package/dist/sdk/src/nativeData.ts +39 -0
- package/{template/packages → dist}/sdk/src/provider.tsx +9 -4
- package/dist/sdk/src/queryCache.ts +292 -0
- package/dist/sdk/src/queryErrors.ts +51 -0
- package/dist/sdk/src/runtime.ts +675 -0
- package/dist/sdk/src/runtimeModules.ts +33 -0
- package/dist/sdk/src/space.ts +442 -0
- package/dist/sdk/src/standardViewParams.ts +36 -0
- package/{template/packages → dist}/sdk/src/styles.css +81 -16
- package/dist/sdk/src/tailwind.ts +66 -0
- package/dist/sdk/src/ui/charts/RenderChartData.tsx +25 -0
- package/dist/sdk/src/ui/engine/core.ts +392 -0
- package/dist/sdk/src/ui/engine/dom.ts +183 -0
- package/dist/sdk/src/ui/engine/hooks.ts +195 -0
- package/dist/sdk/src/ui/engine/instance.ts +63 -0
- package/dist/sdk/src/ui/engine/keycapContext.ts +2 -0
- package/dist/sdk/src/ui/engine/registry.ts +262 -0
- package/dist/sdk/src/ui/engine/types.ts +62 -0
- package/dist/sdk/src/ui/icons.tsx +91 -0
- package/dist/sdk/src/ui/util.ts +83 -0
- package/dist/sdk/src/viewPeriod.ts +26 -0
- package/dist/sdk/src/vite.ts +92 -0
- package/dist/sdk/src/words/actions.ts +295 -0
- package/dist/sdk/src/words/clashes.ts +158 -0
- package/dist/sdk/src/words/format.ts +136 -0
- package/dist/sdk/src/words/index.ts +13 -0
- package/dist/sdk/src/words/keymap.ts +72 -0
- package/dist/sdk/src/words/keys.ts +297 -0
- package/dist/sdk/src/words/shell.ts +46 -0
- package/dist/sdk/src/words/types.ts +65 -0
- package/dist/skill-sync/index.js +832 -151
- package/dist/skill-sync/index.js.map +4 -4
- package/dist/skill-sync-worker.mjs +3941 -0
- package/dist/space-harness/host.js +1460 -0
- package/dist/space-sdk/dist/chunk-ZSN57ATH.js +5 -0
- package/dist/space-sdk/dist/index.js +15 -0
- package/dist/space-sdk/dist/ui.js +18 -0
- package/dist/space-sdk/package.json +33 -0
- package/dist/space-sdk/src/agentContext.d.ts +36 -0
- package/dist/space-sdk/src/components/Dialog.d.ts +20 -0
- package/dist/space-sdk/src/components/DocumentEditor.d.ts +46 -0
- package/dist/space-sdk/src/components/DocumentPage.d.ts +53 -0
- package/dist/space-sdk/src/components/Markdown.d.ts +18 -0
- package/dist/space-sdk/src/components/MarkdownEditor.d.ts +11 -0
- package/dist/space-sdk/src/components/MultiSelectActionBar.d.ts +31 -0
- package/dist/space-sdk/src/components/MultiSelectCheckbox.d.ts +14 -0
- package/dist/space-sdk/src/components/MultiSelectDragOverlay.d.ts +8 -0
- package/dist/space-sdk/src/components/NotisCommentBoundary.d.ts +36 -0
- package/dist/space-sdk/src/components/NotisSelectionBoundary.d.ts +16 -0
- package/dist/space-sdk/src/components/RecordComponents.d.ts +64 -0
- package/dist/space-sdk/src/components/ShortcutHints.d.ts +12 -0
- package/dist/space-sdk/src/components/Skeleton.d.ts +23 -0
- package/dist/space-sdk/src/config.ts +31 -0
- package/dist/space-sdk/src/documents.d.ts +59 -0
- package/dist/space-sdk/src/hooks/useAction.d.ts +8 -0
- package/dist/space-sdk/src/hooks/useActiveResource.d.ts +3 -0
- package/dist/space-sdk/src/hooks/useAgentContext.d.ts +7 -0
- package/dist/space-sdk/src/hooks/useBackend.d.ts +23 -0
- package/dist/space-sdk/src/hooks/useCloudComputer.d.ts +45 -0
- package/dist/space-sdk/src/hooks/useCloudComputerShell.d.ts +49 -0
- package/dist/space-sdk/src/hooks/useCollectionInteractions.d.ts +118 -0
- package/dist/space-sdk/src/hooks/useDatabaseSchema.d.ts +14 -0
- package/dist/space-sdk/src/hooks/useDatabaseSubscription.d.ts +26 -0
- package/dist/space-sdk/src/hooks/useDocument.d.ts +22 -0
- package/dist/space-sdk/src/hooks/useDocuments.d.ts +31 -0
- package/dist/space-sdk/src/hooks/useHandover.d.ts +43 -0
- package/dist/space-sdk/src/hooks/useLongPressSelection.d.ts +9 -0
- package/dist/space-sdk/src/hooks/useMarqueeSelection.d.ts +57 -0
- package/dist/space-sdk/src/hooks/useMultiSelect.d.ts +51 -0
- package/dist/space-sdk/src/hooks/useNativeDocumentBody.d.ts +24 -0
- package/dist/space-sdk/src/hooks/useNativeDocuments.d.ts +55 -0
- package/dist/space-sdk/src/hooks/useNotis.d.ts +25 -0
- package/dist/space-sdk/src/hooks/useNotisNavigation.d.ts +33 -0
- package/dist/space-sdk/src/hooks/useQuery.d.ts +22 -0
- package/dist/space-sdk/src/hooks/useTool.d.ts +20 -0
- package/dist/space-sdk/src/hooks/useToolQuery.d.ts +3 -0
- package/dist/space-sdk/src/hooks/useTools.d.ts +15 -0
- package/dist/space-sdk/src/hooks/useTopBarSearch.d.ts +48 -0
- package/dist/space-sdk/src/hooks/useTopBarTitleLeaf.d.ts +24 -0
- package/dist/space-sdk/src/hooks/useUpsertDocument.d.ts +27 -0
- package/dist/space-sdk/src/hooks/useViewParams.d.ts +76 -0
- package/dist/space-sdk/src/hooks/useViewerReads.d.ts +38 -0
- package/dist/space-sdk/src/index.d.ts +98 -0
- package/dist/space-sdk/src/interactions/actions.d.ts +33 -0
- package/dist/space-sdk/src/interactions/shortcuts.d.ts +42 -0
- package/dist/space-sdk/src/interactions/visibility.d.ts +2 -0
- package/dist/space-sdk/src/nativeData.d.ts +66 -0
- package/dist/space-sdk/src/provider.d.ts +17 -0
- package/dist/space-sdk/src/queryCache.d.ts +45 -0
- package/dist/space-sdk/src/queryErrors.ts +51 -0
- package/dist/space-sdk/src/runtime.d.ts +615 -0
- package/dist/space-sdk/src/runtimeModules.ts +33 -0
- package/dist/space-sdk/src/space.ts +442 -0
- package/dist/space-sdk/src/standardViewParams.d.ts +15 -0
- package/dist/space-sdk/src/tailwind-candidates.d.ts +3418 -0
- package/dist/space-sdk/src/tailwind.ts +66 -0
- package/dist/space-sdk/src/ui/actions/ActionToast.d.ts +15 -0
- package/dist/space-sdk/src/ui/actions/actionWords.d.ts +16 -0
- package/dist/space-sdk/src/ui/actions/index.d.ts +7 -0
- package/dist/space-sdk/src/ui/actions/useActions.d.ts +69 -0
- package/dist/space-sdk/src/ui/actions/useToast.d.ts +41 -0
- package/dist/space-sdk/src/ui/blocks/Tabs.d.ts +139 -0
- package/dist/space-sdk/src/ui/blocks/blocks.d.ts +217 -0
- package/dist/space-sdk/src/ui/blocks/index.d.ts +4 -0
- package/dist/space-sdk/src/ui/board/BoardView.d.ts +36 -0
- package/dist/space-sdk/src/ui/board/boardModel.d.ts +46 -0
- package/dist/space-sdk/src/ui/board/boardWords.d.ts +9 -0
- package/dist/space-sdk/src/ui/board/index.d.ts +5 -0
- package/dist/space-sdk/src/ui/calendar/CalendarView.d.ts +49 -0
- package/dist/space-sdk/src/ui/calendar/DayPicker.d.ts +23 -0
- package/dist/space-sdk/src/ui/calendar/calendarMath.d.ts +81 -0
- package/dist/space-sdk/src/ui/charts/Chart.d.ts +203 -0
- package/dist/space-sdk/src/ui/charts/ChartTable.d.ts +37 -0
- package/dist/space-sdk/src/ui/charts/RenderChartData.d.ts +16 -0
- package/dist/space-sdk/src/ui/charts/StatRow.d.ts +59 -0
- package/dist/space-sdk/src/ui/charts/chartData.d.ts +84 -0
- package/dist/space-sdk/src/ui/comments/CommentPane.d.ts +58 -0
- package/dist/space-sdk/src/ui/comments/commentModel.d.ts +157 -0
- package/dist/space-sdk/src/ui/comments/commentWords.d.ts +60 -0
- package/dist/space-sdk/src/ui/comments/index.d.ts +4 -0
- package/dist/space-sdk/src/ui/comments/useComments.d.ts +146 -0
- package/dist/space-sdk/src/ui/engine/HelpSheet.d.ts +12 -0
- package/dist/space-sdk/src/ui/engine/KeyboardEngine.d.ts +27 -0
- package/dist/space-sdk/src/ui/engine/core.d.ts +73 -0
- package/dist/space-sdk/src/ui/engine/hooks.d.ts +64 -0
- package/dist/space-sdk/src/ui/engine/index.d.ts +14 -0
- package/dist/space-sdk/src/ui/engine/instance.d.ts +21 -0
- package/dist/space-sdk/src/ui/engine/keycapContext.d.ts +2 -0
- package/dist/space-sdk/src/ui/engine/registry.d.ts +77 -0
- package/dist/space-sdk/src/ui/engine/step.d.ts +11 -0
- package/dist/space-sdk/src/ui/engine/types.d.ts +54 -0
- package/dist/space-sdk/src/ui/fields/fieldWords.d.ts +56 -0
- package/dist/space-sdk/src/ui/fields/fields.d.ts +162 -0
- package/dist/space-sdk/src/ui/fields/index.d.ts +5 -0
- package/dist/space-sdk/src/ui/fields/useFieldDraft.d.ts +22 -0
- package/dist/space-sdk/src/ui/gallery/AttachmentGallery.d.ts +53 -0
- package/dist/space-sdk/src/ui/gallery/ImageViewer.d.ts +27 -0
- package/dist/space-sdk/src/ui/gallery/galleryWords.d.ts +95 -0
- package/dist/space-sdk/src/ui/gallery/index.d.ts +5 -0
- package/dist/space-sdk/src/ui/icons.d.ts +13 -0
- package/dist/space-sdk/src/ui/index.d.ts +54 -0
- package/dist/space-sdk/src/ui/keycap/Keycap.d.ts +22 -0
- package/dist/space-sdk/src/ui/keycap/index.d.ts +2 -0
- package/dist/space-sdk/src/ui/layout/Panels.d.ts +50 -0
- package/dist/space-sdk/src/ui/layout/chatPanelEdge.d.ts +77 -0
- package/dist/space-sdk/src/ui/layout/index.d.ts +5 -0
- package/dist/space-sdk/src/ui/layout/panelMath.d.ts +91 -0
- package/dist/space-sdk/src/ui/list/ListReader.d.ts +380 -0
- package/dist/space-sdk/src/ui/list/Row.d.ts +145 -0
- package/dist/space-sdk/src/ui/list/SelectionBar.d.ts +65 -0
- package/dist/space-sdk/src/ui/list/index.d.ts +14 -0
- package/dist/space-sdk/src/ui/list/rowState.d.ts +22 -0
- package/dist/space-sdk/src/ui/list/useListKeys.d.ts +89 -0
- package/dist/space-sdk/src/ui/list/useReorder.d.ts +86 -0
- package/dist/space-sdk/src/ui/list/useSelection.d.ts +90 -0
- package/dist/space-sdk/src/ui/open/OpenAsMenu.d.ts +15 -0
- package/dist/space-sdk/src/ui/open/index.d.ts +6 -0
- package/dist/space-sdk/src/ui/open/openModeStore.d.ts +39 -0
- package/dist/space-sdk/src/ui/open/useOpenMode.d.ts +17 -0
- package/dist/space-sdk/src/ui/overlay/Menu.d.ts +88 -0
- package/dist/space-sdk/src/ui/overlay/Popover.d.ts +28 -0
- package/dist/space-sdk/src/ui/overlay/Tooltip.d.ts +19 -0
- package/dist/space-sdk/src/ui/overlay/index.d.ts +9 -0
- package/dist/space-sdk/src/ui/overlay/layerRoot.d.ts +24 -0
- package/dist/space-sdk/src/ui/overlay/position.d.ts +31 -0
- package/dist/space-sdk/src/ui/period/PeriodPicker.d.ts +30 -0
- package/dist/space-sdk/src/ui/period/dateFormat.d.ts +50 -0
- package/dist/space-sdk/src/ui/period/dateWords.d.ts +88 -0
- package/dist/space-sdk/src/ui/period/periods.d.ts +70 -0
- package/dist/space-sdk/src/ui/period/usePeriod.d.ts +23 -0
- package/dist/space-sdk/src/ui/present/index.d.ts +3 -0
- package/dist/space-sdk/src/ui/present/presentWords.d.ts +27 -0
- package/dist/space-sdk/src/ui/present/screens.d.ts +36 -0
- package/dist/space-sdk/src/ui/present/useAudienceScreen.d.ts +38 -0
- package/dist/space-sdk/src/ui/styles.d.ts +21 -0
- package/dist/space-sdk/src/ui/timeline/TimelineView.d.ts +44 -0
- package/dist/space-sdk/src/ui/timeline/timelineMath.d.ts +123 -0
- package/dist/space-sdk/src/viewPeriod.d.ts +8 -0
- package/dist/space-sdk/src/vite.ts +92 -0
- package/dist/space-sdk/src/words/actions.ts +295 -0
- package/dist/space-sdk/src/words/clashes.ts +158 -0
- package/dist/space-sdk/src/words/format.ts +136 -0
- package/dist/space-sdk/src/words/index.ts +13 -0
- package/dist/space-sdk/src/words/keymap.ts +72 -0
- package/dist/space-sdk/src/words/keys.ts +297 -0
- package/dist/space-sdk/src/words/shell.ts +46 -0
- package/dist/space-sdk/src/words/types.ts +65 -0
- package/dist/view-renderer/dist/host.css +1 -0
- package/dist/view-renderer/dist/host.js +2374 -0
- package/dist/view-renderer/dist/theme.css +73 -0
- package/dist/view-renderer/src/dom.js +212 -0
- package/dist/view-renderer/src/errors.js +8 -0
- package/dist/view-renderer/src/host.tsx +250 -0
- package/dist/view-renderer/src/index.js +4 -0
- package/dist/view-renderer/src/png.js +213 -0
- package/dist/view-renderer/src/pool.js +110 -0
- package/dist/view-renderer/src/remote-broker.js +59 -0
- package/dist/view-renderer/src/renderer.js +271 -0
- package/package.json +21 -11
- package/skills/notis-cli/AGENT_INSTRUCTIONS.md +63 -12
- package/skills/notis-onboarding/BRIEF.md +14 -9
- package/skills/notis-query/cli.md +1 -1
- package/skills/notis-spaces/cli.md +540 -0
- package/src/cli.js +8 -8
- package/src/command-specs/agents.js +121 -8
- package/src/command-specs/auth.js +3 -3
- package/src/command-specs/diagnostics.js +97 -20
- package/src/command-specs/documents.js +158 -0
- package/src/command-specs/files.js +29 -0
- package/src/command-specs/handover.js +331 -79
- package/src/command-specs/helpers.js +50 -40
- package/src/command-specs/index.js +14 -5
- package/src/command-specs/meta.js +38 -9
- package/src/command-specs/onboarding.js +1 -1
- package/src/command-specs/profile.js +42 -1
- package/src/command-specs/skills.js +314 -9
- package/src/command-specs/smoke.js +16 -4
- package/src/command-specs/spaces.js +783 -0
- package/src/command-specs/tools.js +118 -21
- package/src/command-specs/version-history.js +20 -0
- package/src/command-specs/views.js +69 -0
- package/src/runtime/agent-browser.js +178 -267
- package/src/runtime/agent-setup.js +172 -13
- package/src/runtime/app-boundary-validator.js +338 -2
- package/src/runtime/app-data-literals.js +82 -0
- package/src/runtime/app-platform.js +750 -1568
- package/src/runtime/auth-recovery.js +17 -0
- package/src/runtime/base-skills.d.ts +11 -0
- package/src/runtime/base-skills.js +100 -3
- package/src/runtime/computer-identity.d.ts +30 -0
- package/src/runtime/computer-identity.js +151 -0
- package/src/runtime/config-lock.js +135 -0
- package/src/runtime/confined-space-build.js +74 -0
- package/src/runtime/confined-space-verify.js +49 -0
- package/src/runtime/delegated-context.js +5 -21
- package/src/runtime/native-record-files.js +47 -0
- package/src/runtime/oauth.js +342 -31
- package/src/runtime/profiles.js +19 -112
- package/src/runtime/retired-sdk-files.js +24 -0
- package/src/runtime/retry.js +150 -0
- package/src/runtime/skill-sync/cloud-client.ts +33 -8
- package/src/runtime/skill-sync/index.ts +443 -106
- package/src/runtime/skill-sync/local-scanner.ts +248 -32
- package/src/runtime/skill-sync/native-identity.ts +102 -0
- package/src/runtime/skill-sync/native-plan.ts +70 -0
- package/src/runtime/skill-sync/symlink-manager.ts +66 -16
- package/src/runtime/skill-sync/sync-plan.ts +34 -2
- package/src/runtime/skill-sync/types.ts +54 -0
- package/src/runtime/skill-sync/write-cloud-skill.ts +4 -4
- package/src/runtime/skill-sync-service.js +109 -0
- package/src/runtime/source-root.js +32 -0
- package/src/runtime/space-collection-scaffold.js +107 -0
- package/src/runtime/space-database-structures.js +229 -0
- package/src/runtime/space-fixture-broker.js +68 -0
- package/src/runtime/space-lock.js +337 -0
- package/src/runtime/space-platform.js +133 -0
- package/src/runtime/space-source.js +290 -0
- package/src/runtime/space-test-server.js +354 -0
- package/src/runtime/space-verification.js +94 -0
- package/src/runtime/space-verify-browser-worker.js +51 -0
- package/src/runtime/space-view-manifest.js +368 -0
- package/src/runtime/sync-skills.d.ts +5 -1
- package/src/runtime/sync-skills.js +11 -2
- package/src/runtime/tool-confirmation.js +138 -0
- package/src/runtime/transport.js +118 -24
- package/src/runtime/upsell.js +219 -0
- package/src/runtime/view-render.js +49 -0
- package/src/skill-sync-worker-entry.js +2 -0
- package/src/skill-sync-worker.js +114 -0
- package/src/space-harness-host.ts +122 -0
- package/template/.harness/index.html.tmpl +9 -352
- package/template/app/globals.css +29 -3
- package/template/app/layout.tsx +2 -6
- package/template/components/ui/badge.tsx +7 -4
- package/template/components/ui/button.tsx +1 -1
- package/template/components/ui/native-select.tsx +24 -0
- package/template/notis.config.ts +4 -36
- package/template/package-lock.json +1800 -1867
- package/template/package.json +16 -14
- package/template/postcss.config.mjs +1 -1
- package/template/tailwind.config.ts +1 -6
- package/template/tsconfig.json +1 -0
- package/template/vite.config.ts +2 -2
- package/dist/base-skills/notis-apps/SKILL.md +0 -613
- package/skills/notis-apps/cli.md +0 -285
- package/src/command-specs/apps.js +0 -3000
- package/src/runtime/app-changelog.js +0 -79
- package/src/runtime/app-dev-consumers.js +0 -154
- package/src/runtime/app-dev-host-lock.js +0 -80
- package/src/runtime/app-dev-process-identity.js +0 -111
- package/src/runtime/app-dev-roots.js +0 -284
- package/src/runtime/app-dev-server.js +0 -1140
- package/src/runtime/app-dev-sessions.js +0 -185
- package/src/runtime/app-registry-scaffolds.js +0 -367
- package/src/runtime/assets/store-screenshot-dark.png +0 -0
- package/src/runtime/cli-mode.generated.js +0 -5
- package/src/runtime/cli-mode.js +0 -34
- package/src/runtime/store-screenshot.js +0 -143
- package/template/CHANGELOG.md +0 -5
- package/template/app/page.tsx +0 -60
- package/template/components/ui/card.tsx +0 -56
- package/template/packages/sdk/src/components/DocumentEditor.tsx +0 -103
- package/template/packages/sdk/src/config.ts +0 -259
- package/template/packages/sdk/src/hooks/useCloudComputer.ts +0 -97
- package/template/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
- package/template/packages/sdk/src/hooks/useDocument.ts +0 -78
- package/template/packages/sdk/src/hooks/useNotisNavigation.ts +0 -52
- package/template/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
- package/template/packages/sdk/src/runtime.ts +0 -439
- package/template/packages/sdk/src/vite.ts +0 -56
- package/template/packages/sdk/tsconfig.json +0 -15
- /package/{template/packages → dist}/sdk/src/components/MultiSelectDragOverlay.tsx +0 -0
- /package/{template/packages → dist}/sdk/src/components/ShortcutHints.tsx +0 -0
- /package/{template/packages → dist}/sdk/src/hooks/useActiveResource.ts +0 -0
- /package/{template/packages → dist}/sdk/src/hooks/useTool.ts +0 -0
- /package/{template/packages → dist}/sdk/src/hooks/useTools.ts +0 -0
- /package/{template/packages → dist}/sdk/src/ui.ts +0 -0
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
* `notis handover` -- give the branch you are on to a Notis agent.
|
|
3
3
|
*
|
|
4
4
|
* The coding agent already sitting in the user's terminal is the caller here.
|
|
5
|
-
* It pushes the branch, then
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* It pushes the branch, then starts a Notis thread for the task. The caller
|
|
6
|
+
* names who runs it and how, from the user's words, so the choice is never left
|
|
7
|
+
* to the Manager: `--route notis|codex|claude` becomes a plain sentence at the
|
|
8
|
+
* end of the task ("Use Codex for this task."), so it wins like it does in a
|
|
9
|
+
* chat message, and `--intelligence` and `--speed` become the thread's
|
|
10
|
+
* settings. `auto` hands a choice back to Notis, only when the user asked.
|
|
11
|
+
*
|
|
12
|
+
* The thread is started with `LOCAL_NOTIS_CONTROL_THREADS` create, the same
|
|
13
|
+
* operation voice, the hosted MCP and the agents use to start work. It shows up
|
|
14
|
+
* in the Manager like any other conversation, and its request receipt is what
|
|
15
|
+
* `handover status` reads back.
|
|
8
16
|
*
|
|
9
17
|
* The CLI deliberately does not create the cloud workspace itself. Doing so
|
|
10
18
|
* would hard-code the Conductor app's database schema and script paths into the
|
|
@@ -15,6 +23,8 @@
|
|
|
15
23
|
* on and getting it to origin.
|
|
16
24
|
*/
|
|
17
25
|
|
|
26
|
+
import { randomUUID } from 'node:crypto';
|
|
27
|
+
|
|
18
28
|
import { CliError, EXIT_CODES, usageError } from '../runtime/errors.js';
|
|
19
29
|
import {
|
|
20
30
|
commitWorkingTree,
|
|
@@ -25,16 +35,40 @@ import {
|
|
|
25
35
|
import { assertNotDelegated } from '../runtime/delegated-context.js';
|
|
26
36
|
import { fetchToolSchema, nextIdempotencyKey, runToolCommand } from './helpers.js';
|
|
27
37
|
|
|
28
|
-
const
|
|
29
|
-
const SEARCH_THREADS_TOOL = 'LOCAL_NOTIS_SEARCH_CODING_AGENT_THREADS';
|
|
38
|
+
const THREADS_TOOL = 'LOCAL_NOTIS_CONTROL_THREADS';
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
// What --route accepts and advertises. `auto` lets Notis pick the agent.
|
|
41
|
+
const ROUTES = ['notis', 'codex', 'claude', 'auto'];
|
|
42
|
+
// Values from before Notis picked the agent itself, the retired Mac runtimes
|
|
43
|
+
// among them. Still accepted, so scripts and agents that learned them keep
|
|
44
|
+
// working, but never shown in help, examples or errors. Each one now means the
|
|
45
|
+
// agent it names.
|
|
46
|
+
const LEGACY_ROUTES = new Map([
|
|
47
|
+
['codex_cloud', 'codex'],
|
|
48
|
+
['codex_local', 'codex'],
|
|
49
|
+
['claude_cloud', 'claude'],
|
|
50
|
+
['claude_local', 'claude'],
|
|
51
|
+
]);
|
|
52
|
+
const ROUTE_LABELS = { notis: 'Notis', codex: 'Codex', claude: 'Claude' };
|
|
32
53
|
const BRANCH_MODES = ['new', 'same'];
|
|
54
|
+
// The thread's settings. `auto` lets Notis pick the intelligence.
|
|
55
|
+
const INTELLIGENCE = ['low', 'medium', 'high', 'auto'];
|
|
56
|
+
const SPEEDS = ['normal', 'priority', 'flex'];
|
|
57
|
+
// Who runs the hand-over and how. All three are required, so the caller turns
|
|
58
|
+
// the user's words into a choice rather than leaving it to the Manager.
|
|
59
|
+
const CHOICES = [
|
|
60
|
+
['route', '--route', ROUTES],
|
|
61
|
+
['intelligence', '--intelligence', INTELLIGENCE],
|
|
62
|
+
['speed', '--speed', SPEEDS],
|
|
63
|
+
];
|
|
33
64
|
|
|
34
|
-
// A cloud coding agent takes minutes to start, and the
|
|
35
|
-
//
|
|
65
|
+
// A cloud coding agent takes minutes to start, and creating the thread admits
|
|
66
|
+
// its first turn. 30s is the CLI default and is not enough headroom.
|
|
36
67
|
const HANDOVER_TIMEOUT_MS = 120_000;
|
|
37
68
|
|
|
69
|
+
const TITLE_LENGTH = 120;
|
|
70
|
+
const RECENT_THREADS = 20;
|
|
71
|
+
|
|
38
72
|
/**
|
|
39
73
|
* Preflight outcomes that mean "this account cannot hand over", as opposed to
|
|
40
74
|
* "something went wrong on the way to asking". A tool denied by surface policy
|
|
@@ -44,6 +78,27 @@ const HANDOVER_TIMEOUT_MS = 120_000;
|
|
|
44
78
|
*/
|
|
45
79
|
const HANDOVER_UNAVAILABLE_CODES = new Set(['usage_error', 'forbidden']);
|
|
46
80
|
|
|
81
|
+
/** A legacy route as the agent it now means; anything else unchanged. */
|
|
82
|
+
function normalizeRoute(route) {
|
|
83
|
+
return LEGACY_ROUTES.get(route) || route;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Who the hand-over went to, in words, for progress lines and the summary. */
|
|
87
|
+
function describeRoute(route) {
|
|
88
|
+
if (route === 'auto') return 'Notis, which picks the agent';
|
|
89
|
+
return ROUTE_LABELS[route] || route;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The task as the thread receives it. A named agent becomes a plain sentence at
|
|
94
|
+
* the end ("Use Codex for this task."), so the user's choice wins like it does
|
|
95
|
+
* in a chat message; `auto` adds nothing and Notis picks the agent.
|
|
96
|
+
*/
|
|
97
|
+
function routedInstruction(instruction, route) {
|
|
98
|
+
const name = ROUTE_LABELS[route];
|
|
99
|
+
return name ? `${instruction}\n\nUse ${name} for this task.` : instruction;
|
|
100
|
+
}
|
|
101
|
+
|
|
47
102
|
/**
|
|
48
103
|
* Quote a value for the command line the receiving agent is told to run.
|
|
49
104
|
*
|
|
@@ -106,6 +161,66 @@ function buildInstruction({ task, repository, branchMode, repoSlug }) {
|
|
|
106
161
|
].join('\n');
|
|
107
162
|
}
|
|
108
163
|
|
|
164
|
+
/** The task's first line, short enough to read in the Manager's thread list. */
|
|
165
|
+
function threadTitle(task) {
|
|
166
|
+
const line = task.split('\n').find((part) => part.trim()) || task;
|
|
167
|
+
const title = line.replace(/\s+/g, ' ').trim();
|
|
168
|
+
return title.length > TITLE_LENGTH ? `${title.slice(0, TITLE_LENGTH - 3)}...` : title;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** The intelligence and speed as the thread's settings. */
|
|
172
|
+
function threadSettings(intelligence, speed) {
|
|
173
|
+
return intelligence === 'auto' ? { auto: true, speed } : { mode: intelligence, speed };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** The intelligence and speed, in words, for progress lines and the summary. */
|
|
177
|
+
function describeSettings(intelligence, speed) {
|
|
178
|
+
const level = intelligence === 'auto' ? 'Notis picks the intelligence' : `${intelligence} intelligence`;
|
|
179
|
+
return `${level}, ${speed} speed`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The command that starts this hand-over again: with its key, the same
|
|
184
|
+
* request; without one, a new request.
|
|
185
|
+
*/
|
|
186
|
+
function startCommand({ task, branchMode, route, intelligence, speed, repoSlug }, idempotencyKey = null) {
|
|
187
|
+
return [
|
|
188
|
+
...(idempotencyKey ? ['notis --idempotency-key', shellSingleQuote(idempotencyKey)] : ['notis']),
|
|
189
|
+
'handover start', shellSingleQuote(task),
|
|
190
|
+
'--route', route, '--intelligence', intelligence, '--speed', speed,
|
|
191
|
+
...(branchMode === 'new' ? [] : ['--branch-mode', branchMode]),
|
|
192
|
+
...(repoSlug ? ['--repo', shellSingleQuote(repoSlug)] : []),
|
|
193
|
+
].join(' ');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* How to settle a start whose outcome is unknown. Asking again with the same
|
|
198
|
+
* key settles it only when the answer was lost on the way (a timeout, a dropped
|
|
199
|
+
* connection) or the first attempt is still running. Any other uncertain answer
|
|
200
|
+
* is kept under the key and replayed as it is, so check whether the work
|
|
201
|
+
* started, and hand it over afresh only if it did not. A refusal gets neither:
|
|
202
|
+
* asking again cannot change it.
|
|
203
|
+
*/
|
|
204
|
+
function recoveryHints(error, command, idempotencyKey, requestIds = []) {
|
|
205
|
+
const serverCode = error.details?.error?.code;
|
|
206
|
+
if (['network_timeout', 'network_error'].includes(error.code) || serverCode === 'idempotency_in_progress') {
|
|
207
|
+
return [{
|
|
208
|
+
command: startCommand(command, idempotencyKey),
|
|
209
|
+
reason: 'Ask again with the same key: it returns this hand-over\'s answer and never starts the work twice',
|
|
210
|
+
}];
|
|
211
|
+
}
|
|
212
|
+
if (['backend_error', 'handover_unconfirmed'].includes(error.code) || serverCode === 'idempotency_outcome_unknown') {
|
|
213
|
+
return [
|
|
214
|
+
{
|
|
215
|
+
command: requestIds[0] ? `notis handover status ${requestIds[0]}` : 'notis handover status',
|
|
216
|
+
reason: 'Check whether the hand-over started before anything else',
|
|
217
|
+
},
|
|
218
|
+
{ command: startCommand(command), reason: 'Only if it did not start: hand it over again as a new request' },
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
|
|
109
224
|
async function handoverStartHandler(ctx) {
|
|
110
225
|
// First statement on purpose. Everything below spends the user's credits and
|
|
111
226
|
// starts real work; the check that this is a person's terminal comes first.
|
|
@@ -121,23 +236,45 @@ async function handoverStartHandler(ctx) {
|
|
|
121
236
|
throw usageError(`--branch-mode must be one of: ${BRANCH_MODES.join(', ')}`, { branchMode });
|
|
122
237
|
}
|
|
123
238
|
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
239
|
+
const choice = {
|
|
240
|
+
route: ctx.options.route === undefined ? undefined : normalizeRoute(ctx.options.route),
|
|
241
|
+
intelligence: ctx.options.intelligence,
|
|
242
|
+
speed: ctx.options.speed,
|
|
243
|
+
};
|
|
244
|
+
for (const [name, flag, values] of CHOICES) {
|
|
245
|
+
if (choice[name] !== undefined && !values.includes(choice[name])) {
|
|
246
|
+
throw usageError(`${flag} must be one of: ${values.join(', ')}`, { [name]: ctx.options[name] });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// No defaults: a missing choice stops here, before git is touched, and the
|
|
250
|
+
// refusal names every one still to make.
|
|
251
|
+
const missing = CHOICES.filter(([name]) => choice[name] === undefined);
|
|
252
|
+
if (missing.length) {
|
|
253
|
+
throw usageError(
|
|
254
|
+
'Choose who runs the hand-over and how from the user\'s words, then pass '
|
|
255
|
+
+ `${missing.map(([, flag, values]) => `${flag} ${values.join('|')}`).join(', ')}.`,
|
|
256
|
+
{ missing: missing.map(([, flag]) => flag) },
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
const { route, intelligence, speed } = choice;
|
|
260
|
+
// Codex and Claude have no flex speed, and with auto Notis may pick either,
|
|
261
|
+
// which would then inherit it.
|
|
262
|
+
if (speed === 'flex' && route !== 'notis') {
|
|
263
|
+
throw usageError('--speed flex runs on Notis only; use --route notis, or --speed normal.', { route, speed });
|
|
127
264
|
}
|
|
128
265
|
|
|
129
266
|
const repository = inspectRepository(ctx.options.cwd || process.cwd());
|
|
130
267
|
|
|
131
268
|
// Ask whether the hand-over is even allowed before touching git. Everything
|
|
132
269
|
// below this line is irreversible from the user's point of view -- a commit
|
|
133
|
-
// and a push -- and
|
|
134
|
-
//
|
|
135
|
-
//
|
|
270
|
+
// and a push -- and a server that does not offer the tool here would
|
|
271
|
+
// otherwise leave a `wip:` commit on their remote for a hand-over that never
|
|
272
|
+
// happened.
|
|
136
273
|
//
|
|
137
274
|
// Only an explicit refusal blocks: a network or schema hiccup must not stop a
|
|
138
275
|
// hand-over that would have worked.
|
|
139
276
|
try {
|
|
140
|
-
await fetchToolSchema(ctx.runtime,
|
|
277
|
+
await fetchToolSchema(ctx.runtime, THREADS_TOOL);
|
|
141
278
|
} catch (error) {
|
|
142
279
|
if (error instanceof CliError && HANDOVER_UNAVAILABLE_CODES.has(error.code)) {
|
|
143
280
|
throw new CliError({
|
|
@@ -216,33 +353,71 @@ async function handoverStartHandler(ctx) {
|
|
|
216
353
|
throw error;
|
|
217
354
|
}
|
|
218
355
|
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
repository,
|
|
222
|
-
branchMode,
|
|
223
|
-
repoSlug: ctx.options.repo || null,
|
|
224
|
-
});
|
|
356
|
+
const repoSlug = ctx.options.repo || null;
|
|
357
|
+
const instruction = buildInstruction({ task, repository, branchMode, repoSlug });
|
|
225
358
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
mutating: true,
|
|
236
|
-
idempotencyKey: nextIdempotencyKey(ctx.globalOptions),
|
|
359
|
+
// One key names this hand-over end to end: the HTTP retry key and, prefixed,
|
|
360
|
+
// the thread request. Resending it returns the thread the first attempt made.
|
|
361
|
+
const idempotencyKey = nextIdempotencyKey(ctx.globalOptions);
|
|
362
|
+
const requestKey = `handover:${idempotencyKey}`;
|
|
363
|
+
const command = { task, branchMode, route, intelligence, speed, repoSlug };
|
|
364
|
+
|
|
365
|
+
ctx.output.emitProgress({
|
|
366
|
+
phase: 'handover',
|
|
367
|
+
message: `Handing over to ${describeRoute(route)} (${describeSettings(intelligence, speed)})`,
|
|
237
368
|
});
|
|
369
|
+
let result;
|
|
370
|
+
try {
|
|
371
|
+
result = await runToolCommand({
|
|
372
|
+
runtime: {
|
|
373
|
+
...ctx.runtime,
|
|
374
|
+
// Raise the floor, never pin: an explicit --timeout-ms must still win.
|
|
375
|
+
timeoutMs: Math.max(ctx.runtime.timeoutMs || 0, HANDOVER_TIMEOUT_MS),
|
|
376
|
+
},
|
|
377
|
+
toolName: THREADS_TOOL,
|
|
378
|
+
arguments_: {
|
|
379
|
+
action: 'create',
|
|
380
|
+
request_id: requestKey,
|
|
381
|
+
instructions: routedInstruction(instruction, route),
|
|
382
|
+
title: threadTitle(task),
|
|
383
|
+
settings: threadSettings(intelligence, speed),
|
|
384
|
+
},
|
|
385
|
+
mutating: true,
|
|
386
|
+
idempotencyKey,
|
|
387
|
+
});
|
|
388
|
+
} catch (error) {
|
|
389
|
+
// A failed call may still have started the thread. Say how to find out
|
|
390
|
+
// without starting the work twice.
|
|
391
|
+
if (error instanceof CliError) {
|
|
392
|
+
error.details = { ...error.details, request_key: requestKey };
|
|
393
|
+
error.hints = [...(error.hints || []), ...recoveryHints(error, command, idempotencyKey)];
|
|
394
|
+
}
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
238
397
|
|
|
239
398
|
const payload = result?.payload ?? {};
|
|
240
399
|
if (payload.status === 'error') {
|
|
241
400
|
throw new CliError({
|
|
242
401
|
code: payload.error_code || 'handover_failed',
|
|
243
|
-
message: payload.message ||
|
|
402
|
+
message: payload.message || `Notis could not start the hand-over (${payload.error_code || 'error'}).`,
|
|
244
403
|
exitCode: EXIT_CODES.backend,
|
|
245
|
-
details: payload.
|
|
404
|
+
details: { request_key: requestKey, http_status: payload.http_status ?? null },
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (payload.status !== 'accepted') {
|
|
408
|
+
const requestIds = payload.request_ids || [];
|
|
409
|
+
throw new CliError({
|
|
410
|
+
code: 'handover_unconfirmed',
|
|
411
|
+
message:
|
|
412
|
+
'Notis could not confirm that the hand-over started. It may be running already, '
|
|
413
|
+
+ 'so check its status before handing it over again.',
|
|
414
|
+
exitCode: EXIT_CODES.backend,
|
|
415
|
+
details: {
|
|
416
|
+
request_key: requestKey,
|
|
417
|
+
request_ids: requestIds,
|
|
418
|
+
cause: payload.error_code || null,
|
|
419
|
+
},
|
|
420
|
+
hints: recoveryHints({ code: 'handover_unconfirmed' }, command, idempotencyKey, requestIds),
|
|
246
421
|
});
|
|
247
422
|
}
|
|
248
423
|
|
|
@@ -255,21 +430,29 @@ async function handoverStartHandler(ctx) {
|
|
|
255
430
|
branch_mode: branchMode,
|
|
256
431
|
head: repository.head,
|
|
257
432
|
wip_commit: wipCommit,
|
|
258
|
-
agent_routing:
|
|
259
|
-
|
|
433
|
+
agent_routing: route,
|
|
434
|
+
intelligence,
|
|
435
|
+
speed,
|
|
436
|
+
request_id: payload.request_id || null,
|
|
437
|
+
request_key: payload.request_key || requestKey,
|
|
438
|
+
row_id: payload.row_id || null,
|
|
260
439
|
thread_id: payload.thread_id || null,
|
|
440
|
+
interaction_id: payload.interaction_id || null,
|
|
261
441
|
};
|
|
262
442
|
|
|
263
443
|
return ctx.output.emitSuccess({
|
|
264
444
|
command: 'handover start',
|
|
265
445
|
data,
|
|
266
446
|
humanSummary:
|
|
267
|
-
`Handed ${data.branch} over to ${data.agent_routing} `
|
|
268
|
-
`(${
|
|
447
|
+
`Handed ${data.branch} over to ${describeRoute(data.agent_routing)} `
|
|
448
|
+
+ `(${describeSettings(intelligence, speed)}; `
|
|
449
|
+
+ `${branchMode === 'same' ? 'continuing the branch' : 'new branch from it'}).`,
|
|
269
450
|
hints: [
|
|
270
|
-
|
|
451
|
+
...(data.request_id
|
|
452
|
+
? [{ command: `notis handover status ${data.request_id}`, reason: 'Follow the hand-over and read its result' }]
|
|
453
|
+
: []),
|
|
271
454
|
{
|
|
272
|
-
command: `git fetch origin ${repository.branch}`,
|
|
455
|
+
command: `git fetch origin ${shellSingleQuote(repository.branch)}`,
|
|
273
456
|
reason: 'Pull the agent\'s commits back down when it has pushed',
|
|
274
457
|
},
|
|
275
458
|
],
|
|
@@ -277,32 +460,83 @@ async function handoverStartHandler(ctx) {
|
|
|
277
460
|
});
|
|
278
461
|
}
|
|
279
462
|
|
|
463
|
+
function eventText(event) {
|
|
464
|
+
const body = event?.body || {};
|
|
465
|
+
const message = body.message || {};
|
|
466
|
+
const text = message.text || message.body || message.content || body.text || '';
|
|
467
|
+
return typeof text === 'string' ? text : JSON.stringify(text);
|
|
468
|
+
}
|
|
469
|
+
|
|
280
470
|
async function handoverStatusHandler(ctx) {
|
|
471
|
+
const requestId = (ctx.args.requestId || '').trim();
|
|
281
472
|
const result = await runToolCommand({
|
|
282
473
|
runtime: ctx.runtime,
|
|
283
|
-
toolName:
|
|
284
|
-
arguments_:
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
},
|
|
474
|
+
toolName: THREADS_TOOL,
|
|
475
|
+
arguments_: requestId
|
|
476
|
+
? { action: 'request', request_id: requestId }
|
|
477
|
+
: { action: 'list', filters: { activity: 'running' }, limit: RECENT_THREADS },
|
|
288
478
|
mutating: false,
|
|
479
|
+
// The tool also writes, so the server asks every call for a key. A fresh
|
|
480
|
+
// one, never --idempotency-key: a reused key would replay a cached, stale
|
|
481
|
+
// read instead of asking again.
|
|
482
|
+
idempotencyKey: randomUUID(),
|
|
483
|
+
sendIdempotencyKeyWhenReading: true,
|
|
289
484
|
});
|
|
290
485
|
|
|
291
486
|
const payload = result?.payload ?? {};
|
|
292
|
-
|
|
487
|
+
if (payload.status === 'error') {
|
|
488
|
+
throw new CliError({
|
|
489
|
+
code: payload.error_code || 'handover_status_failed',
|
|
490
|
+
message: payload.message || `Notis could not read the hand-over (${payload.error_code || 'error'}).`,
|
|
491
|
+
exitCode: EXIT_CODES.backend,
|
|
492
|
+
details: { request_id: requestId || null, http_status: payload.http_status ?? null },
|
|
493
|
+
});
|
|
494
|
+
}
|
|
293
495
|
|
|
496
|
+
if (!requestId) {
|
|
497
|
+
// The running filter applies to the most recent threads only, so say so
|
|
498
|
+
// rather than claiming nothing runs anywhere.
|
|
499
|
+
const threads = Array.isArray(payload.threads) ? payload.threads : [];
|
|
500
|
+
const summary = threads.length
|
|
501
|
+
? `${threads.length} of your ${RECENT_THREADS} most recent threads running.`
|
|
502
|
+
: `None of your ${RECENT_THREADS} most recent threads is running.`;
|
|
503
|
+
return ctx.output.emitSuccess({
|
|
504
|
+
command: 'handover status',
|
|
505
|
+
data: { threads },
|
|
506
|
+
humanSummary: summary,
|
|
507
|
+
hints: [
|
|
508
|
+
{ command: 'notis handover status <request-id>', reason: 'Read one hand-over\'s progress and result' },
|
|
509
|
+
],
|
|
510
|
+
renderHuman: () => [
|
|
511
|
+
summary,
|
|
512
|
+
...threads.map((thread) => ` ${thread.id} ${thread.title || '(untitled)'}`),
|
|
513
|
+
].join('\n'),
|
|
514
|
+
meta: { mutating: false },
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const events = Array.isArray(payload.events) ? payload.events : [];
|
|
519
|
+
const finished = events.find((event) => event?.terminal);
|
|
520
|
+
const summary = finished
|
|
521
|
+
? `The hand-over finished (${finished.kind}).`
|
|
522
|
+
: `The hand-over is still running (${events.length} update(s) so far).`;
|
|
294
523
|
return ctx.output.emitSuccess({
|
|
295
524
|
command: 'handover status',
|
|
296
525
|
data: payload,
|
|
297
|
-
humanSummary:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
526
|
+
humanSummary: summary,
|
|
527
|
+
hints: payload.has_more
|
|
528
|
+
? [{
|
|
529
|
+
command:
|
|
530
|
+
`notis tools exec ${THREADS_TOOL} --arguments '${JSON.stringify({
|
|
531
|
+
action: 'request', request_id: requestId, after: payload.next_cursor,
|
|
532
|
+
})}'`,
|
|
533
|
+
reason: 'Read the next page of updates',
|
|
534
|
+
}]
|
|
535
|
+
: [],
|
|
536
|
+
renderHuman: () => [
|
|
537
|
+
summary,
|
|
538
|
+
...events.map((event) => `\n[${event.kind}] ${eventText(event)}`.trimEnd()),
|
|
539
|
+
].join('\n'),
|
|
306
540
|
meta: { mutating: false },
|
|
307
541
|
});
|
|
308
542
|
}
|
|
@@ -312,22 +546,36 @@ export const handoverCommandSpecs = [
|
|
|
312
546
|
command_path: ['handover', 'start'],
|
|
313
547
|
summary: 'Hand the current branch to a Notis agent and keep working.',
|
|
314
548
|
when_to_use:
|
|
315
|
-
'Use this when you want Notis to continue work on the branch you are on -- long refactors, '
|
|
316
|
-
'test fixing, or anything that should keep running after you close the laptop.
|
|
317
|
-
'
|
|
549
|
+
'Use this when you want Notis to continue work on the branch you are on -- long refactors, '
|
|
550
|
+
+ 'test fixing, or anything that should keep running after you close the laptop. Choose the agent, '
|
|
551
|
+
+ 'intelligence and speed yourself from the user\'s words, even loose ones ("get Claude on it", '
|
|
552
|
+
+ '"this one is tricky", "no rush"), and pass all three; with no agent named, codex for code work. '
|
|
553
|
+
+ 'Use auto only when the user asks Notis to pick.',
|
|
318
554
|
args_schema: {
|
|
319
555
|
arguments: [{ token: '<task>', description: 'What the agent should do, in plain language.' }],
|
|
320
556
|
options: [
|
|
321
557
|
{
|
|
322
|
-
flags: '--
|
|
323
|
-
key: 'branchMode',
|
|
558
|
+
flags: '--route <agent>',
|
|
324
559
|
description:
|
|
325
|
-
'
|
|
560
|
+
'Required. Which agent runs it: notis, codex or claude, or auto only when the user asks Notis to pick.',
|
|
326
561
|
},
|
|
327
562
|
{
|
|
328
|
-
flags: '--
|
|
563
|
+
flags: '--intelligence <level>',
|
|
329
564
|
description:
|
|
330
|
-
'
|
|
565
|
+
'Required. low (quick, simple tasks), medium (most multi-step work and coding), high (hard '
|
|
566
|
+
+ 'reasoning, investigations, complex code), or auto only when the user asks Notis to pick.',
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
flags: '--speed <speed>',
|
|
570
|
+
description:
|
|
571
|
+
'Required. normal (the usual choice), priority (faster, costs more; for Codex or Claude only when '
|
|
572
|
+
+ 'the user asks for their fast mode) or flex (cheaper and slower, Notis only).',
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
flags: '--branch-mode <mode>',
|
|
576
|
+
key: 'branchMode',
|
|
577
|
+
description:
|
|
578
|
+
'same = the agent commits onto your branch. new = the agent cuts a new branch from it (default).',
|
|
331
579
|
},
|
|
332
580
|
{ flags: '--repo <slug>', description: 'Configured repository slug on the cloud computer, when you know it.' },
|
|
333
581
|
{
|
|
@@ -337,38 +585,42 @@ export const handoverCommandSpecs = [
|
|
|
337
585
|
],
|
|
338
586
|
},
|
|
339
587
|
examples: [
|
|
340
|
-
'notis handover start "fix the failing auth tests"',
|
|
341
|
-
'notis handover start "finish the migration" --branch-mode same --route
|
|
342
|
-
'notis handover start "add integration tests" --route
|
|
343
|
-
'notis handover start "review and clean up this branch" --route
|
|
588
|
+
'notis handover start "fix the failing auth tests" --route codex --intelligence medium --speed normal',
|
|
589
|
+
'notis handover start "finish the migration" --branch-mode same --route codex --intelligence high --speed normal',
|
|
590
|
+
'notis handover start "add integration tests" --route claude --intelligence medium --speed normal',
|
|
591
|
+
'notis handover start "review and clean up this branch" --route notis --intelligence low --speed flex',
|
|
344
592
|
],
|
|
345
593
|
output_schema:
|
|
346
|
-
'Returns the branch, the
|
|
594
|
+
'Returns the branch, the agent routing (notis, codex or claude, or auto when Notis picks), the '
|
|
595
|
+
+ 'intelligence and speed the thread runs at, and the started thread: its request_id (for '
|
|
596
|
+
+ '`handover status`), row and thread ids, and the interaction id of its first turn.',
|
|
347
597
|
mutates: true,
|
|
348
598
|
idempotent: false,
|
|
349
599
|
require_auth: true,
|
|
350
|
-
related_commands: ['notis handover status'],
|
|
351
|
-
backend_call: { type: 'tool', name:
|
|
600
|
+
related_commands: ['notis handover status <request-id>'],
|
|
601
|
+
backend_call: { type: 'tool', name: THREADS_TOOL },
|
|
352
602
|
handler: handoverStartHandler,
|
|
353
603
|
},
|
|
354
604
|
{
|
|
355
605
|
command_path: ['handover', 'status'],
|
|
356
|
-
summary: '
|
|
357
|
-
when_to_use:
|
|
606
|
+
summary: 'Follow a hand-over, or list the work Notis is running for you.',
|
|
607
|
+
when_to_use:
|
|
608
|
+
'Use this after a hand-over. Pass the request_id `handover start` returned to read its progress '
|
|
609
|
+
+ 'and result; with no id it lists the threads still running.',
|
|
358
610
|
args_schema: {
|
|
359
|
-
arguments: [
|
|
360
|
-
|
|
361
|
-
{ flags: '--provider <provider>', description: 'Filter to codex or claude_code.' },
|
|
362
|
-
{ flags: '--refresh', description: 'Force a live refresh instead of cached state.' },
|
|
611
|
+
arguments: [
|
|
612
|
+
{ token: '[request-id]', key: 'requestId', description: 'The request_id `handover start` returned.' },
|
|
363
613
|
],
|
|
614
|
+
options: [],
|
|
364
615
|
},
|
|
365
|
-
examples: ['notis handover status', 'notis handover status
|
|
366
|
-
output_schema:
|
|
616
|
+
examples: ['notis handover status', 'notis handover status 6f1c2e8a-4b7d-5c3e-9a1f-2d8b7e6c5a4f'],
|
|
617
|
+
output_schema:
|
|
618
|
+
'With a request id: the request state, its result and its updates. Without: the running threads.',
|
|
367
619
|
mutates: false,
|
|
368
620
|
idempotent: true,
|
|
369
621
|
require_auth: true,
|
|
370
622
|
related_commands: ['notis handover start <task>'],
|
|
371
|
-
backend_call: { type: 'tool', name:
|
|
623
|
+
backend_call: { type: 'tool', name: THREADS_TOOL },
|
|
372
624
|
handler: handoverStatusHandler,
|
|
373
625
|
},
|
|
374
626
|
];
|