@notis_ai/cli 0.2.13 → 0.2.15
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 +125 -21
- package/dist/agent-hooks/notis-agent-hook.mjs +19750 -0
- package/{skills → dist/base-skills}/notis-apps/SKILL.md +93 -58
- package/{skills → dist/base-skills}/notis-cli/SKILL.md +9 -9
- package/dist/base-skills/notis-query/SKILL.md +705 -0
- package/dist/skill-sync/index.js +1528 -0
- package/dist/skill-sync/index.js.map +7 -0
- package/package.json +5 -2
- package/skills/notis-apps/cli.md +44 -18
- package/skills/notis-cli/AGENT_INSTRUCTIONS.md +39 -0
- package/skills/notis-onboarding/BRIEF.md +16 -0
- package/src/agent-hook-entry.js +5 -0
- package/src/cli.js +23 -14
- package/src/command-specs/agents.js +392 -0
- package/src/command-specs/apps.js +1090 -418
- package/src/command-specs/auth.js +63 -10
- package/src/command-specs/handover.js +374 -0
- package/src/command-specs/index.js +9 -0
- package/src/command-specs/onboarding.js +69 -5
- package/src/command-specs/skills.js +56 -0
- package/src/command-specs/tools.js +6 -0
- package/src/runtime/agent-memory-state.js +126 -0
- package/src/runtime/agent-setup.js +383 -0
- package/src/runtime/app-dev-consumers.js +154 -0
- package/src/runtime/app-dev-host-lock.js +80 -0
- package/src/runtime/app-dev-roots.js +284 -0
- package/src/runtime/app-dev-server.js +229 -30
- package/src/runtime/app-dev-sessions.js +105 -145
- package/src/runtime/app-platform.js +1499 -161
- package/src/runtime/app-registry-scaffolds.js +367 -0
- package/src/runtime/base-skills.d.ts +20 -0
- package/src/runtime/base-skills.js +167 -0
- package/src/runtime/delegated-context.js +68 -0
- package/src/runtime/git.js +233 -0
- package/src/runtime/login-listener.js +15 -0
- package/src/runtime/oauth.js +1506 -141
- package/src/runtime/output.js +7 -0
- package/src/runtime/ports.js +16 -0
- package/src/runtime/profiles.js +0 -5
- package/src/runtime/skill-sync/cloud-client.ts +96 -0
- package/src/runtime/skill-sync/index.ts +644 -0
- package/src/runtime/skill-sync/local-scanner.ts +1046 -0
- package/src/runtime/skill-sync/symlink-manager.ts +383 -0
- package/src/runtime/skill-sync/sync-plan.ts +22 -0
- package/src/runtime/skill-sync/types.ts +103 -0
- package/src/runtime/skill-sync/write-cloud-skill.ts +50 -0
- package/src/runtime/store-screenshot.js +6 -1
- package/src/runtime/sync-skills.d.ts +37 -0
- package/src/runtime/sync-skills.js +215 -0
- package/src/runtime/transport.js +19 -2
- package/template/.harness/index.html.tmpl +116 -47
- package/template/app/layout.tsx +5 -1
- package/template/notis.config.ts +1 -0
- package/template/packages/sdk/package.json +2 -1
- package/template/packages/sdk/src/components/DocumentEditor.tsx +13 -3
- package/template/packages/sdk/src/components/MarkdownEditor.tsx +121 -0
- package/template/packages/sdk/src/components/MultiSelectActionBar.tsx +37 -119
- package/template/packages/sdk/src/components/MultiSelectCheckbox.tsx +5 -1
- package/template/packages/sdk/src/components/MultiSelectDragOverlay.tsx +1 -1
- package/template/packages/sdk/src/components/NotisSelectionBoundary.tsx +55 -0
- package/template/packages/sdk/src/components/ShortcutHints.tsx +56 -0
- package/template/packages/sdk/src/config.ts +71 -0
- package/template/packages/sdk/src/documents.ts +28 -1
- package/template/packages/sdk/src/hooks/useActiveResource.ts +19 -0
- package/template/packages/sdk/src/hooks/useCloudComputer.ts +97 -0
- package/template/packages/sdk/src/hooks/useCollectionInteractions.ts +709 -0
- package/template/packages/sdk/src/hooks/useDatabaseSubscription.ts +76 -0
- package/template/packages/sdk/src/hooks/useHandover.ts +78 -0
- package/template/packages/sdk/src/hooks/useMultiSelect.ts +44 -482
- package/template/packages/sdk/src/hooks/useTool.ts +5 -4
- package/template/packages/sdk/src/index.ts +64 -2
- package/template/packages/sdk/src/interactions/actions.ts +46 -0
- package/template/packages/sdk/src/interactions/shortcuts.tsx +628 -0
- package/template/packages/sdk/src/interactions.ts +41 -0
- package/template/packages/sdk/src/provider.tsx +2 -1
- package/template/packages/sdk/src/runtime.ts +219 -3
- package/dist/scaffolds/notis-database/CHANGELOG.md +0 -5
- package/dist/scaffolds/notis-database/app/globals.css +0 -44
- package/dist/scaffolds/notis-database/app/layout.tsx +0 -6
- package/dist/scaffolds/notis-database/app/page.tsx +0 -1088
- package/dist/scaffolds/notis-database/components/ui/badge.tsx +0 -28
- package/dist/scaffolds/notis-database/components/ui/button.tsx +0 -53
- package/dist/scaffolds/notis-database/components/ui/card.tsx +0 -56
- package/dist/scaffolds/notis-database/components/ui/table.tsx +0 -120
- package/dist/scaffolds/notis-database/components.json +0 -20
- package/dist/scaffolds/notis-database/index.html +0 -12
- package/dist/scaffolds/notis-database/lib/types.ts +0 -132
- package/dist/scaffolds/notis-database/lib/utils.ts +0 -6
- package/dist/scaffolds/notis-database/metadata/screenshot-1.png +0 -0
- package/dist/scaffolds/notis-database/metadata/screenshot-2.png +0 -0
- package/dist/scaffolds/notis-database/metadata/screenshot-3.png +0 -0
- package/dist/scaffolds/notis-database/metadata/screenshot-4.png +0 -0
- package/dist/scaffolds/notis-database/metadata/screenshot-5.png +0 -0
- package/dist/scaffolds/notis-database/metadata/screenshot-fixtures.json +0 -1839
- package/dist/scaffolds/notis-database/notis.config.ts +0 -73
- package/dist/scaffolds/notis-database/package-lock.json +0 -3935
- package/dist/scaffolds/notis-database/package.json +0 -32
- package/dist/scaffolds/notis-database/packages/sdk/package.json +0 -36
- package/dist/scaffolds/notis-database/packages/sdk/src/components/DocumentEditor.tsx +0 -93
- package/dist/scaffolds/notis-database/packages/sdk/src/components/Markdown.tsx +0 -60
- package/dist/scaffolds/notis-database/packages/sdk/src/components/MultiSelectActionBar.tsx +0 -278
- package/dist/scaffolds/notis-database/packages/sdk/src/components/MultiSelectCheckbox.tsx +0 -91
- package/dist/scaffolds/notis-database/packages/sdk/src/components/MultiSelectDragOverlay.tsx +0 -39
- package/dist/scaffolds/notis-database/packages/sdk/src/config.ts +0 -196
- package/dist/scaffolds/notis-database/packages/sdk/src/documents.ts +0 -229
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useBackend.ts +0 -41
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useDocument.ts +0 -78
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useDocuments.ts +0 -121
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useMultiSelect.ts +0 -539
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useNotis.ts +0 -34
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useNotisNavigation.ts +0 -49
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useTool.ts +0 -64
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useTools.ts +0 -56
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
- package/dist/scaffolds/notis-database/packages/sdk/src/hooks/useUpsertDocument.ts +0 -95
- package/dist/scaffolds/notis-database/packages/sdk/src/index.ts +0 -83
- package/dist/scaffolds/notis-database/packages/sdk/src/provider.tsx +0 -43
- package/dist/scaffolds/notis-database/packages/sdk/src/runtime.ts +0 -220
- package/dist/scaffolds/notis-database/packages/sdk/src/styles.css +0 -186
- package/dist/scaffolds/notis-database/packages/sdk/src/ui.ts +0 -15
- package/dist/scaffolds/notis-database/packages/sdk/src/vite.ts +0 -56
- package/dist/scaffolds/notis-database/packages/sdk/tsconfig.json +0 -15
- package/dist/scaffolds/notis-database/postcss.config.mjs +0 -8
- package/dist/scaffolds/notis-database/src/dev-main.tsx +0 -23
- package/dist/scaffolds/notis-database/src/mock-runtime.ts +0 -561
- package/dist/scaffolds/notis-database/tailwind.config.ts +0 -59
- package/dist/scaffolds/notis-database/tsconfig.json +0 -23
- package/dist/scaffolds/notis-database/vite.config.ts +0 -22
- package/dist/scaffolds/notis-journal/CHANGELOG.md +0 -29
- package/dist/scaffolds/notis-journal/app/globals.css +0 -37
- package/dist/scaffolds/notis-journal/app/insights/page.tsx +0 -513
- package/dist/scaffolds/notis-journal/app/journal-core.tsx +0 -362
- package/dist/scaffolds/notis-journal/app/journal-ui.tsx +0 -337
- package/dist/scaffolds/notis-journal/app/layout.tsx +0 -6
- package/dist/scaffolds/notis-journal/app/page.tsx +0 -486
- package/dist/scaffolds/notis-journal/components/ui/badge.tsx +0 -28
- package/dist/scaffolds/notis-journal/components/ui/button.tsx +0 -53
- package/dist/scaffolds/notis-journal/components/ui/card.tsx +0 -56
- package/dist/scaffolds/notis-journal/components.json +0 -20
- package/dist/scaffolds/notis-journal/index.html +0 -12
- package/dist/scaffolds/notis-journal/lib/utils.ts +0 -6
- package/dist/scaffolds/notis-journal/metadata/screenshot-1.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-2.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-3.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-4.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-5.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-6.png +0 -0
- package/dist/scaffolds/notis-journal/metadata/screenshot-fixtures.json +0 -132
- package/dist/scaffolds/notis-journal/notis.config.ts +0 -93
- package/dist/scaffolds/notis-journal/package-lock.json +0 -4615
- package/dist/scaffolds/notis-journal/package.json +0 -34
- package/dist/scaffolds/notis-journal/packages/sdk/package.json +0 -36
- package/dist/scaffolds/notis-journal/packages/sdk/src/components/DocumentEditor.tsx +0 -93
- package/dist/scaffolds/notis-journal/packages/sdk/src/components/Markdown.tsx +0 -60
- package/dist/scaffolds/notis-journal/packages/sdk/src/components/MultiSelectActionBar.tsx +0 -278
- package/dist/scaffolds/notis-journal/packages/sdk/src/components/MultiSelectCheckbox.tsx +0 -91
- package/dist/scaffolds/notis-journal/packages/sdk/src/components/MultiSelectDragOverlay.tsx +0 -39
- package/dist/scaffolds/notis-journal/packages/sdk/src/config.ts +0 -196
- package/dist/scaffolds/notis-journal/packages/sdk/src/documents.ts +0 -229
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useBackend.ts +0 -41
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useDocument.ts +0 -78
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useDocuments.ts +0 -121
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useMultiSelect.ts +0 -539
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useNotis.ts +0 -34
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useNotisNavigation.ts +0 -49
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useTool.ts +0 -64
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useTools.ts +0 -56
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
- package/dist/scaffolds/notis-journal/packages/sdk/src/hooks/useUpsertDocument.ts +0 -95
- package/dist/scaffolds/notis-journal/packages/sdk/src/index.ts +0 -83
- package/dist/scaffolds/notis-journal/packages/sdk/src/provider.tsx +0 -43
- package/dist/scaffolds/notis-journal/packages/sdk/src/runtime.ts +0 -220
- package/dist/scaffolds/notis-journal/packages/sdk/src/styles.css +0 -186
- package/dist/scaffolds/notis-journal/packages/sdk/src/ui.ts +0 -15
- package/dist/scaffolds/notis-journal/packages/sdk/src/vite.ts +0 -56
- package/dist/scaffolds/notis-journal/packages/sdk/tsconfig.json +0 -15
- package/dist/scaffolds/notis-journal/postcss.config.mjs +0 -8
- package/dist/scaffolds/notis-journal/skills/journal-onboarding/SKILL.md +0 -120
- package/dist/scaffolds/notis-journal/src/dev-main.tsx +0 -58
- package/dist/scaffolds/notis-journal/src/mock-runtime.ts +0 -197
- package/dist/scaffolds/notis-journal/tailwind.config.ts +0 -58
- package/dist/scaffolds/notis-journal/tsconfig.json +0 -23
- package/dist/scaffolds/notis-journal/vite.config.ts +0 -10
- package/dist/scaffolds/notis-notes/CHANGELOG.md +0 -5
- package/dist/scaffolds/notis-notes/app/globals.css +0 -3
- package/dist/scaffolds/notis-notes/app/layout.tsx +0 -6
- package/dist/scaffolds/notis-notes/app/page.tsx +0 -1943
- package/dist/scaffolds/notis-notes/app/phosphor-icons.ts +0 -596
- package/dist/scaffolds/notis-notes/components/ui/badge.tsx +0 -28
- package/dist/scaffolds/notis-notes/components/ui/button.tsx +0 -53
- package/dist/scaffolds/notis-notes/components/ui/card.tsx +0 -56
- package/dist/scaffolds/notis-notes/components.json +0 -20
- package/dist/scaffolds/notis-notes/lib/utils.ts +0 -6
- package/dist/scaffolds/notis-notes/lib/visible-properties.ts +0 -144
- package/dist/scaffolds/notis-notes/metadata/screenshot-1.png +0 -0
- package/dist/scaffolds/notis-notes/metadata/screenshot-2.png +0 -0
- package/dist/scaffolds/notis-notes/metadata/screenshot-3.png +0 -0
- package/dist/scaffolds/notis-notes/metadata/screenshot-4.png +0 -0
- package/dist/scaffolds/notis-notes/metadata/screenshot-5.png +0 -0
- package/dist/scaffolds/notis-notes/metadata/screenshot-fixtures.json +0 -752
- package/dist/scaffolds/notis-notes/notis.config.ts +0 -80
- package/dist/scaffolds/notis-notes/package-lock.json +0 -4636
- package/dist/scaffolds/notis-notes/package.json +0 -35
- package/dist/scaffolds/notis-notes/packages/sdk/package.json +0 -36
- package/dist/scaffolds/notis-notes/packages/sdk/src/components/DocumentEditor.tsx +0 -93
- package/dist/scaffolds/notis-notes/packages/sdk/src/components/Markdown.tsx +0 -60
- package/dist/scaffolds/notis-notes/packages/sdk/src/components/MultiSelectActionBar.tsx +0 -278
- package/dist/scaffolds/notis-notes/packages/sdk/src/components/MultiSelectCheckbox.tsx +0 -91
- package/dist/scaffolds/notis-notes/packages/sdk/src/components/MultiSelectDragOverlay.tsx +0 -39
- package/dist/scaffolds/notis-notes/packages/sdk/src/config.ts +0 -196
- package/dist/scaffolds/notis-notes/packages/sdk/src/documents.ts +0 -229
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useBackend.ts +0 -41
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useDocument.ts +0 -78
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useDocuments.ts +0 -121
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useMultiSelect.ts +0 -539
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useNotis.ts +0 -34
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useNotisNavigation.ts +0 -49
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useTool.ts +0 -64
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useTools.ts +0 -56
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
- package/dist/scaffolds/notis-notes/packages/sdk/src/hooks/useUpsertDocument.ts +0 -95
- package/dist/scaffolds/notis-notes/packages/sdk/src/index.ts +0 -83
- package/dist/scaffolds/notis-notes/packages/sdk/src/provider.tsx +0 -43
- package/dist/scaffolds/notis-notes/packages/sdk/src/runtime.ts +0 -220
- package/dist/scaffolds/notis-notes/packages/sdk/src/styles.css +0 -186
- package/dist/scaffolds/notis-notes/packages/sdk/src/ui.ts +0 -15
- package/dist/scaffolds/notis-notes/packages/sdk/src/vite.ts +0 -56
- package/dist/scaffolds/notis-notes/packages/sdk/tsconfig.json +0 -15
- package/dist/scaffolds/notis-notes/postcss.config.mjs +0 -8
- package/dist/scaffolds/notis-notes/tailwind.config.ts +0 -58
- package/dist/scaffolds/notis-notes/tsconfig.json +0 -23
- package/dist/scaffolds/notis-notes/vite.config.ts +0 -10
- package/dist/scaffolds/notis-random/CHANGELOG.md +0 -15
- package/dist/scaffolds/notis-random/README.md +0 -33
- package/dist/scaffolds/notis-random/app/globals.css +0 -11
- package/dist/scaffolds/notis-random/app/history/page.tsx +0 -67
- package/dist/scaffolds/notis-random/app/layout.tsx +0 -7
- package/dist/scaffolds/notis-random/app/page.tsx +0 -289
- package/dist/scaffolds/notis-random/components/ui/button.tsx +0 -50
- package/dist/scaffolds/notis-random/components/ui/card.tsx +0 -16
- package/dist/scaffolds/notis-random/components/ui/input.tsx +0 -23
- package/dist/scaffolds/notis-random/components.json +0 -20
- package/dist/scaffolds/notis-random/index.html +0 -12
- package/dist/scaffolds/notis-random/lib/notis-tools.ts +0 -128
- package/dist/scaffolds/notis-random/lib/rng.ts +0 -202
- package/dist/scaffolds/notis-random/lib/roll-record.ts +0 -189
- package/dist/scaffolds/notis-random/lib/utils.ts +0 -25
- package/dist/scaffolds/notis-random/metadata/screenshot-1.png +0 -0
- package/dist/scaffolds/notis-random/metadata/screenshot-2.png +0 -0
- package/dist/scaffolds/notis-random/metadata/screenshot-3.png +0 -0
- package/dist/scaffolds/notis-random/metadata/screenshot-4.png +0 -0
- package/dist/scaffolds/notis-random/metadata/screenshot-5.png +0 -0
- package/dist/scaffolds/notis-random/metadata/screenshot-fixtures.json +0 -753
- package/dist/scaffolds/notis-random/notis.config.ts +0 -86
- package/dist/scaffolds/notis-random/package-lock.json +0 -4513
- package/dist/scaffolds/notis-random/package.json +0 -36
- package/dist/scaffolds/notis-random/packages/sdk/package.json +0 -36
- package/dist/scaffolds/notis-random/packages/sdk/src/components/DocumentEditor.tsx +0 -93
- package/dist/scaffolds/notis-random/packages/sdk/src/components/Markdown.tsx +0 -60
- package/dist/scaffolds/notis-random/packages/sdk/src/components/MultiSelectActionBar.tsx +0 -278
- package/dist/scaffolds/notis-random/packages/sdk/src/components/MultiSelectCheckbox.tsx +0 -91
- package/dist/scaffolds/notis-random/packages/sdk/src/components/MultiSelectDragOverlay.tsx +0 -39
- package/dist/scaffolds/notis-random/packages/sdk/src/config.ts +0 -196
- package/dist/scaffolds/notis-random/packages/sdk/src/documents.ts +0 -229
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useBackend.ts +0 -41
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useDocument.ts +0 -78
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useDocuments.ts +0 -121
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useMultiSelect.ts +0 -539
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useNotis.ts +0 -34
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useNotisNavigation.ts +0 -49
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useTool.ts +0 -64
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useTools.ts +0 -56
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
- package/dist/scaffolds/notis-random/packages/sdk/src/hooks/useUpsertDocument.ts +0 -95
- package/dist/scaffolds/notis-random/packages/sdk/src/index.ts +0 -83
- package/dist/scaffolds/notis-random/packages/sdk/src/provider.tsx +0 -43
- package/dist/scaffolds/notis-random/packages/sdk/src/runtime.ts +0 -220
- package/dist/scaffolds/notis-random/packages/sdk/src/styles.css +0 -186
- package/dist/scaffolds/notis-random/packages/sdk/src/ui.ts +0 -15
- package/dist/scaffolds/notis-random/packages/sdk/src/vite.ts +0 -56
- package/dist/scaffolds/notis-random/packages/sdk/tsconfig.json +0 -15
- package/dist/scaffolds/notis-random/postcss.config.mjs +0 -6
- package/dist/scaffolds/notis-random/src/dev-main.tsx +0 -70
- package/dist/scaffolds/notis-random/src/mock-runtime.ts +0 -129
- package/dist/scaffolds/notis-random/tailwind.config.ts +0 -50
- package/dist/scaffolds/notis-random/tsconfig.json +0 -23
- package/dist/scaffolds/notis-random/vite.config.ts +0 -11
- package/dist/scaffolds.json +0 -49
- package/template/metadata/screenshot-1.png +0 -0
- package/template/metadata/screenshot-2.png +0 -0
- package/template/metadata/screenshot-3.png +0 -0
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
} from '../runtime/profiles.js';
|
|
12
12
|
import { ensureFreshOAuthCredential, loginWithOAuth } from '../runtime/oauth.js';
|
|
13
13
|
import { runToolCommand } from './helpers.js';
|
|
14
|
+
import { loginAgentAuthorizationPresentation } from './auth.js';
|
|
15
|
+
import { installLocalAgentContext } from './agents.js';
|
|
14
16
|
|
|
15
17
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
16
18
|
const BUNDLED_BRIEF_PATH = join(HERE, '..', '..', 'skills', 'notis-onboarding', 'BRIEF.md');
|
|
@@ -86,6 +88,44 @@ function isAuthenticated(runtime) {
|
|
|
86
88
|
&& !credentialIsExpired(runtime, getProfile(loadConfig(), runtime.profileName));
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
function renderAgentSetup(results) {
|
|
92
|
+
const configured = (results || []).filter((result) => result?.agent && result?.instructions);
|
|
93
|
+
if (!configured.length) return '';
|
|
94
|
+
const lines = configured.map((result) => {
|
|
95
|
+
const label = result.agent === 'claude-code' ? 'Claude Code' : 'Codex';
|
|
96
|
+
const instructions = result.instructions?.status || 'skipped';
|
|
97
|
+
const memoryStatus = result.memory_hook?.status || 'skipped';
|
|
98
|
+
const memory = memoryStatus === 'preserved'
|
|
99
|
+
? 'memory hooks not changed'
|
|
100
|
+
: `memory recall and capture ${memoryStatus}`;
|
|
101
|
+
return `- ${label}: instructions ${instructions}; ${memory}`;
|
|
102
|
+
});
|
|
103
|
+
if (configured.some((result) => (
|
|
104
|
+
result.agent === 'codex'
|
|
105
|
+
&& ['installed', 'updated', 'unchanged'].includes(result.memory_hook?.status)
|
|
106
|
+
))) {
|
|
107
|
+
lines.push('- Codex: open /hooks once and trust the Notis hooks before they can run.');
|
|
108
|
+
}
|
|
109
|
+
return ['## Coding-agent setup', ...lines].join('\n');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function agentSetupHints(results) {
|
|
113
|
+
const hints = [];
|
|
114
|
+
if ((results || []).some((result) => (
|
|
115
|
+
result.agent === 'codex'
|
|
116
|
+
&& ['installed', 'updated', 'unchanged'].includes(result.memory_hook?.status)
|
|
117
|
+
))) {
|
|
118
|
+
hints.push({ message: 'In Codex, open /hooks once and trust the Notis hooks.' });
|
|
119
|
+
}
|
|
120
|
+
if ((results || []).some((result) => result.status === 'not_detected')) {
|
|
121
|
+
hints.push({ command: 'notis agents install', reason: 'Configure Codex and Claude Code later if they were not detected now' });
|
|
122
|
+
}
|
|
123
|
+
if ((results || []).some((result) => result.memory_hook?.status === 'preserved')) {
|
|
124
|
+
hints.push({ command: 'notis agents install', reason: 'Explicitly enable Notis memory recall and completed-turn capture' });
|
|
125
|
+
}
|
|
126
|
+
return hints;
|
|
127
|
+
}
|
|
128
|
+
|
|
89
129
|
/**
|
|
90
130
|
* What an authenticated `start` reports.
|
|
91
131
|
*
|
|
@@ -105,9 +145,20 @@ async function authenticatedResult(ctx) {
|
|
|
105
145
|
onboarding_complete: onboardingComplete,
|
|
106
146
|
...(state ? { known_settings: state.settings, missing_settings: state.missingSettings } : {}),
|
|
107
147
|
};
|
|
148
|
+
try {
|
|
149
|
+
base.agent_setup = installLocalAgentContext(ctx, {
|
|
150
|
+
onlyExisting: true,
|
|
151
|
+
memoryHooks: null,
|
|
152
|
+
});
|
|
153
|
+
} catch {
|
|
154
|
+
// Authentication and onboarding remain usable if a local vendor config is
|
|
155
|
+
// malformed or read-only. `notis agents install` reports the exact path.
|
|
156
|
+
base.agent_setup = [];
|
|
157
|
+
}
|
|
108
158
|
|
|
109
159
|
if (onboardingComplete) {
|
|
110
160
|
const name = state?.settings?.full_name;
|
|
161
|
+
const setupSummary = renderAgentSetup(base.agent_setup);
|
|
111
162
|
return ctx.output.emitSuccess({
|
|
112
163
|
command: 'start',
|
|
113
164
|
data: { ...base, brief: null, brief_source: null },
|
|
@@ -120,20 +171,27 @@ async function authenticatedResult(ctx) {
|
|
|
120
171
|
'',
|
|
121
172
|
'This account has already completed onboarding. Do not run an onboarding',
|
|
122
173
|
'flow and do not call LOCAL_NOTIS_COMPLETE_TUTORIAL.',
|
|
174
|
+
...(setupSummary ? ['', setupSummary] : []),
|
|
123
175
|
].join('\n'),
|
|
124
176
|
hints: [
|
|
125
177
|
{ command: 'notis whoami', reason: 'Show the account and its connected toolkits' },
|
|
126
178
|
{ command: 'notis tools search "<what you need>"', reason: 'Find a tool and get on with the task' },
|
|
179
|
+
...agentSetupHints(base.agent_setup),
|
|
127
180
|
],
|
|
128
181
|
});
|
|
129
182
|
}
|
|
130
183
|
|
|
131
184
|
const brief = await fetchBrief(ctx.runtime.apiBase, ctx.runtime.timeoutMs);
|
|
185
|
+
const setupSummary = renderAgentSetup(base.agent_setup);
|
|
132
186
|
return ctx.output.emitSuccess({
|
|
133
187
|
command: 'start',
|
|
134
188
|
data: { ...base, brief: brief.markdown, brief_source: brief.source },
|
|
135
189
|
humanSummary: `Notis CLI is authenticated for profile "${ctx.runtime.profileName}". Onboarding is not complete.`,
|
|
136
|
-
renderHuman: () =>
|
|
190
|
+
renderHuman: () => [
|
|
191
|
+
brief.markdown || 'Notis CLI is authenticated.',
|
|
192
|
+
setupSummary,
|
|
193
|
+
].filter(Boolean).join('\n\n'),
|
|
194
|
+
hints: agentSetupHints(base.agent_setup),
|
|
137
195
|
});
|
|
138
196
|
}
|
|
139
197
|
|
|
@@ -166,8 +224,13 @@ async function startHandler(ctx) {
|
|
|
166
224
|
// Browser authorization is the whole signup path: it creates the account when
|
|
167
225
|
// the address is new and authorizes this machine either way. There is nothing
|
|
168
226
|
// for the CLI to collect up front, and nothing to wait on afterwards.
|
|
169
|
-
const authorization = await loginWithOAuth(
|
|
227
|
+
const authorization = await loginWithOAuth(
|
|
228
|
+
runtime,
|
|
229
|
+
{ browser: true, mode: options.mode, reusePersistedCredential: true },
|
|
230
|
+
output,
|
|
231
|
+
);
|
|
170
232
|
if (authorization?.agentAuthorization) {
|
|
233
|
+
const presentation = loginAgentAuthorizationPresentation(authorization.agentAuthorization);
|
|
171
234
|
return output.emitSuccess({
|
|
172
235
|
command: 'start',
|
|
173
236
|
data: {
|
|
@@ -175,8 +238,7 @@ async function startHandler(ctx) {
|
|
|
175
238
|
profile: runtime.profileName,
|
|
176
239
|
...authorization.agentAuthorization,
|
|
177
240
|
},
|
|
178
|
-
|
|
179
|
-
renderHuman: () => `Authorize Notis CLI: ${authorization.agentAuthorization.authorize_url}`,
|
|
241
|
+
...presentation,
|
|
180
242
|
});
|
|
181
243
|
}
|
|
182
244
|
|
|
@@ -205,16 +267,18 @@ export const onboardingCommandSpecs = [
|
|
|
205
267
|
arguments: [],
|
|
206
268
|
options: [
|
|
207
269
|
{ flags: '--brief-only', description: 'Print the onboarding brief for an already-signed-in profile.' },
|
|
270
|
+
{ flags: '--mode <mode>', description: 'auto (default) hands the browser callback to a background listener when this command cannot wait; browser waits in-process; code shows a one-time code to copy.' },
|
|
208
271
|
],
|
|
209
272
|
},
|
|
210
273
|
examples: [
|
|
211
274
|
'notis start',
|
|
212
275
|
'notis start --profile work',
|
|
276
|
+
'notis start --mode browser',
|
|
213
277
|
'notis start --brief-only',
|
|
214
278
|
'notis start --json',
|
|
215
279
|
],
|
|
216
280
|
output_schema:
|
|
217
|
-
'Returns {authenticated, profile, api_base, onboarding_complete, known_settings, missing_settings, brief, brief_source} once signed in — brief is null when onboarding_complete is true — or {authorize_url, expires_in,
|
|
281
|
+
'Returns {authenticated, profile, api_base, onboarding_complete, known_settings, missing_settings, agent_setup, brief, brief_source} once signed in — brief is null when onboarding_complete is true — or {authorize_url, expires_in, hand_off, ...} while waiting for browser authorization. hand_off is "browser_callback" when signing in finishes the login by itself (re-run confirm_command to see it land) or "code" when the user must be asked for the code the page shows and it redeemed with redeem_command.',
|
|
218
282
|
mutates: true,
|
|
219
283
|
idempotent: true,
|
|
220
284
|
require_auth: false,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getJwtSubject } from '../runtime/profiles.js';
|
|
2
|
+
import { reconcileAllSkills } from '../runtime/sync-skills.js';
|
|
3
|
+
|
|
4
|
+
async function loadSkillSyncEngine() {
|
|
5
|
+
return import('../../dist/skill-sync/index.js');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async function syncSkillsHandler(ctx) {
|
|
9
|
+
const userId = ctx.runtime.oauthUserId || getJwtSubject(ctx.runtime.jwt);
|
|
10
|
+
const { runSkillSync } = await loadSkillSyncEngine();
|
|
11
|
+
const result = await reconcileAllSkills({
|
|
12
|
+
serverUrl: ctx.runtime.apiBase,
|
|
13
|
+
jwt: ctx.runtime.jwt,
|
|
14
|
+
userId,
|
|
15
|
+
honorSyncEnabled: Boolean(ctx.options.electronRepeat),
|
|
16
|
+
runAccountSync: runSkillSync,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return ctx.output.emitSuccess({
|
|
20
|
+
command: 'skills sync',
|
|
21
|
+
data: result,
|
|
22
|
+
humanSummary: result.syncEnabled
|
|
23
|
+
? `Synced account skills and kept ${result.baseSkills.length} base skills current.`
|
|
24
|
+
: `Automatic Desktop sync is off; kept ${result.baseSkills.length} base skills current.`,
|
|
25
|
+
renderHuman: () => result.syncEnabled
|
|
26
|
+
? `Skills synced. Base skills current: ${result.baseSkills.join(', ')}.`
|
|
27
|
+
: `Automatic Desktop sync is off. Base skills remain current: ${result.baseSkills.join(', ')}.`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const skillsCommandSpecs = [
|
|
32
|
+
{
|
|
33
|
+
command_path: ['skills', 'sync'],
|
|
34
|
+
summary: 'Synchronize account skills and keep the three Notis base skills current.',
|
|
35
|
+
when_to_use:
|
|
36
|
+
'Run manually whenever local agent skills should be reconciled. Manual runs ignore the Desktop automatic-sync preference.',
|
|
37
|
+
args_schema: {
|
|
38
|
+
arguments: [],
|
|
39
|
+
options: [
|
|
40
|
+
{
|
|
41
|
+
flags: '--electron-repeat',
|
|
42
|
+
description: 'Honor the automatic Desktop sync preference (used by Notis Desktop).',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
examples: ['notis skills sync', 'notis skills sync --json'],
|
|
47
|
+
output_schema:
|
|
48
|
+
'Returns account sync counts plus baseSkills, baseInstalled, baseLinked, and baseBackups.',
|
|
49
|
+
mutates: true,
|
|
50
|
+
idempotent: true,
|
|
51
|
+
require_auth: true,
|
|
52
|
+
related_commands: ['notis login', 'notis start', 'notis doctor'],
|
|
53
|
+
backend_call: { type: 'local', name: 'skill_sync' },
|
|
54
|
+
handler: syncSkillsHandler,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
@@ -2,6 +2,7 @@ import { accessSync, constants as fsConstants, createReadStream, existsSync, rea
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { basename } from 'node:path';
|
|
4
4
|
import { usageError } from '../runtime/errors.js';
|
|
5
|
+
import { assertToolNotDelegated } from '../runtime/delegated-context.js';
|
|
5
6
|
import {
|
|
6
7
|
COMPOSIO_GET_TOOL_SCHEMAS,
|
|
7
8
|
COMPOSIO_MULTI_EXECUTE_TOOL,
|
|
@@ -380,6 +381,9 @@ async function toolsDescribeHandler(ctx) {
|
|
|
380
381
|
|
|
381
382
|
async function toolsExecHandler(ctx) {
|
|
382
383
|
const requestedToolName = localNotisToolSlug(ctx.args.toolName);
|
|
384
|
+
// `tools exec` is the escape hatch around every first-class command, so the
|
|
385
|
+
// hand-over guard has to live here too or it guards nothing.
|
|
386
|
+
assertToolNotDelegated(requestedToolName);
|
|
383
387
|
let targetMutating = classifyToolMutation(requestedToolName);
|
|
384
388
|
ensureLongRunningToolTimeout(ctx, requestedToolName);
|
|
385
389
|
ctx.output.emitProgress({
|
|
@@ -495,6 +499,8 @@ async function toolsExecParallelHandler(ctx) {
|
|
|
495
499
|
if (!call.tool_name || typeof call.tool_name !== 'string') {
|
|
496
500
|
throw usageError(`calls[${i}] missing required "tool_name" string`);
|
|
497
501
|
}
|
|
502
|
+
// A batch is just as good an escape hatch as a single exec.
|
|
503
|
+
assertToolNotDelegated(localNotisToolSlug(call.tool_name));
|
|
498
504
|
}
|
|
499
505
|
ensureLongRunningToolTimeout(ctx, calls.map((call) => localNotisToolSlug(call.tool_name)));
|
|
500
506
|
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import {
|
|
3
|
+
existsSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
renameSync,
|
|
7
|
+
writeFileSync,
|
|
8
|
+
} from 'node:fs';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
|
|
12
|
+
const MAX_SEEN_HASHES = 500;
|
|
13
|
+
const MAX_PROMPT_CHARS = 12_000;
|
|
14
|
+
|
|
15
|
+
function hash(value) {
|
|
16
|
+
return createHash('sha256').update(String(value || '')).digest('hex').slice(0, 24);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function statePath(sessionId, home = homedir()) {
|
|
20
|
+
if (!sessionId) return null;
|
|
21
|
+
return join(home, '.notis', 'agent-memory-hooks', `${hash(sessionId)}.json`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readState(sessionId, home) {
|
|
25
|
+
const filePath = statePath(sessionId, home);
|
|
26
|
+
if (!filePath || !existsSync(filePath)) return { seen: [], pending: null };
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
29
|
+
return parsed && typeof parsed === 'object'
|
|
30
|
+
? {
|
|
31
|
+
seen: Array.isArray(parsed.seen) ? parsed.seen.filter((item) => typeof item === 'string') : [],
|
|
32
|
+
pending: parsed.pending && typeof parsed.pending === 'object' ? parsed.pending : null,
|
|
33
|
+
identity: parsed.identity && typeof parsed.identity === 'object' ? parsed.identity : null,
|
|
34
|
+
}
|
|
35
|
+
: { seen: [], pending: null };
|
|
36
|
+
} catch {
|
|
37
|
+
return { seen: [], pending: null };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function inputIdentity(input) {
|
|
42
|
+
const profile = typeof input?.profile_name === 'string' ? input.profile_name : '';
|
|
43
|
+
const account = typeof input?.account_id === 'string' ? input.account_id : '';
|
|
44
|
+
const apiBase = typeof input?.api_base === 'string' ? input.api_base : '';
|
|
45
|
+
return profile && account && apiBase ? { profile, account, apiBase } : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function identityMatches(left, right) {
|
|
49
|
+
return (!left && !right) || Boolean(
|
|
50
|
+
left && right
|
|
51
|
+
&& left.profile === right.profile
|
|
52
|
+
&& left.account === right.account
|
|
53
|
+
&& left.apiBase === right.apiBase,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function stateForInput(sessionId, input, home) {
|
|
58
|
+
const state = readState(sessionId, home);
|
|
59
|
+
const identity = inputIdentity(input);
|
|
60
|
+
if (identityMatches(state.identity, identity)) return state;
|
|
61
|
+
return { seen: [], pending: null, identity };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function writeState(sessionId, state, home) {
|
|
65
|
+
const filePath = statePath(sessionId, home);
|
|
66
|
+
if (!filePath) return;
|
|
67
|
+
mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });
|
|
68
|
+
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
69
|
+
writeFileSync(temporaryPath, `${JSON.stringify(state)}\n`, { mode: 0o600 });
|
|
70
|
+
renameSync(temporaryPath, filePath);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function rememberPendingTurn(input, home = homedir()) {
|
|
74
|
+
const sessionId = input?.session_id;
|
|
75
|
+
const prompt = typeof input?.prompt === 'string' ? input.prompt.trim() : '';
|
|
76
|
+
if (!sessionId || !prompt || ['/', '!', '#'].includes(prompt[0])) return;
|
|
77
|
+
const state = stateForInput(sessionId, input, home);
|
|
78
|
+
state.pending = {
|
|
79
|
+
prompt: prompt.slice(0, MAX_PROMPT_CHARS),
|
|
80
|
+
turn_id: typeof input?.turn_id === 'string' ? input.turn_id : null,
|
|
81
|
+
cwd: typeof input?.cwd === 'string' ? input.cwd : null,
|
|
82
|
+
recorded_at: new Date().toISOString(),
|
|
83
|
+
};
|
|
84
|
+
writeState(sessionId, state, home);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function pendingTurn(input, home = homedir()) {
|
|
88
|
+
const sessionId = input?.session_id;
|
|
89
|
+
const state = readState(sessionId, home);
|
|
90
|
+
const identity = inputIdentity(input);
|
|
91
|
+
if (!identityMatches(state.identity, identity)) {
|
|
92
|
+
if (sessionId) writeState(sessionId, { seen: [], pending: null, identity }, home);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!state.pending) return null;
|
|
96
|
+
if (state.pending.turn_id && input?.turn_id && state.pending.turn_id !== input.turn_id) return null;
|
|
97
|
+
return state.pending;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function completePendingTurn(input, home = homedir()) {
|
|
101
|
+
const sessionId = input?.session_id;
|
|
102
|
+
if (!sessionId) return;
|
|
103
|
+
const filePath = statePath(sessionId, home);
|
|
104
|
+
if (!filePath || !existsSync(filePath)) return;
|
|
105
|
+
const state = readState(sessionId, home);
|
|
106
|
+
if (!state.pending) return;
|
|
107
|
+
state.pending = null;
|
|
108
|
+
writeState(sessionId, state, home);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function freshRecallItems(input, items, home = homedir()) {
|
|
112
|
+
const sessionId = input?.session_id;
|
|
113
|
+
if (!sessionId) return items;
|
|
114
|
+
const state = stateForInput(sessionId, input, home);
|
|
115
|
+
const seen = new Set(state.seen);
|
|
116
|
+
const fresh = [];
|
|
117
|
+
for (const item of items) {
|
|
118
|
+
const fingerprint = hash(item);
|
|
119
|
+
if (seen.has(fingerprint)) continue;
|
|
120
|
+
seen.add(fingerprint);
|
|
121
|
+
fresh.push(item);
|
|
122
|
+
}
|
|
123
|
+
state.seen = [...seen].slice(-MAX_SEEN_HASHES);
|
|
124
|
+
writeState(sessionId, state, home);
|
|
125
|
+
return fresh;
|
|
126
|
+
}
|