@notis_ai/cli 0.2.0-beta.178.1 → 0.2.0-beta.1792022492092.1

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.
Files changed (124) hide show
  1. package/README.md +548 -98
  2. package/config/portal-route-roots.json +47 -0
  3. package/dist/agent-hooks/notis-agent-hook.mjs +32901 -5934
  4. package/dist/base-skills/notis-apps/SKILL.md +76 -51
  5. package/dist/base-skills/notis-apps/references/architecture.md +116 -164
  6. package/dist/base-skills/notis-apps/references/design.md +26 -107
  7. package/dist/base-skills/notis-apps/references/memory.md +58 -0
  8. package/dist/base-skills/notis-apps/references/reading.md +52 -74
  9. package/dist/base-skills/notis-apps/references/release.md +105 -96
  10. package/dist/base-skills/notis-apps/references/sdk.md +115 -60
  11. package/dist/base-skills/notis-apps/references/troubleshooting.md +22 -21
  12. package/dist/base-skills/notis-apps/references/views.md +145 -0
  13. package/dist/base-skills/notis-cli/SKILL.md +29 -12
  14. package/dist/base-skills/notis-cli/references/app-delivery.md +12 -11
  15. package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
  16. package/dist/base-skills/notis-cli/references/native-databases.md +6 -5
  17. package/dist/base-skills/notis-cli/references/tool-examples.md +4 -4
  18. package/dist/base-skills/notis-query/SKILL.md +34 -60
  19. package/dist/base-skills/notis-query/references/database-discovery.md +60 -59
  20. package/dist/base-skills/notis-query/references/documents.md +53 -39
  21. package/dist/base-skills/notis-query/references/query.md +57 -524
  22. package/dist/sdk/src/bundleModule.ts +79 -0
  23. package/dist/sdk/src/components/DocumentEditor.tsx +6 -3
  24. package/dist/sdk/src/components/DocumentPage.tsx +144 -0
  25. package/dist/sdk/src/components/RecordComponents.tsx +33 -0
  26. package/dist/sdk/src/components/RenderChartData.tsx +19 -0
  27. package/dist/sdk/src/config.ts +4 -26
  28. package/dist/sdk/src/documents.ts +2 -0
  29. package/dist/sdk/src/hooks/useAction.ts +28 -0
  30. package/dist/sdk/src/hooks/useBackend.ts +3 -2
  31. package/dist/sdk/src/hooks/useCloudComputer.ts +35 -4
  32. package/dist/sdk/src/hooks/useCloudComputerShell.ts +114 -0
  33. package/dist/sdk/src/hooks/useCollectionInteractions.ts +4 -2
  34. package/dist/sdk/src/hooks/useHandover.ts +7 -7
  35. package/dist/sdk/src/hooks/useNativeDocumentBody.ts +50 -0
  36. package/dist/sdk/src/hooks/useNativeDocuments.ts +83 -0
  37. package/dist/sdk/src/hooks/useNotis.ts +3 -0
  38. package/dist/sdk/src/hooks/useNotisNavigation.ts +26 -11
  39. package/dist/sdk/src/hooks/useQuery.ts +7 -4
  40. package/dist/sdk/src/hooks/useViewParams.ts +121 -0
  41. package/dist/sdk/src/hooks/useViewerReads.ts +129 -0
  42. package/dist/sdk/src/index.ts +36 -0
  43. package/dist/sdk/src/interactions/shortcuts.tsx +42 -5
  44. package/dist/sdk/src/nativeData.ts +39 -0
  45. package/dist/sdk/src/presentation.tsx +82 -0
  46. package/dist/sdk/src/provider.tsx +9 -4
  47. package/dist/sdk/src/queryCache.ts +5 -3
  48. package/dist/sdk/src/queryErrors.ts +51 -0
  49. package/dist/sdk/src/runtime.ts +163 -13
  50. package/dist/sdk/src/space.ts +425 -0
  51. package/dist/sdk/src/styles.css +96 -72
  52. package/dist/sdk/src/vite.ts +11 -1
  53. package/dist/skill-sync/index.js +571 -80
  54. package/dist/skill-sync/index.js.map +4 -4
  55. package/dist/skill-sync-worker.mjs +858 -233
  56. package/dist/space-harness/host.js +66 -0
  57. package/dist/view-renderer/dist/host.css +1 -0
  58. package/dist/view-renderer/dist/host.js +1028 -0
  59. package/dist/view-renderer/dist/theme.css +73 -0
  60. package/dist/view-renderer/src/dom.js +180 -0
  61. package/dist/view-renderer/src/errors.js +8 -0
  62. package/dist/view-renderer/src/host.tsx +175 -0
  63. package/dist/view-renderer/src/index.js +4 -0
  64. package/dist/view-renderer/src/pool.js +76 -0
  65. package/dist/view-renderer/src/remote-broker.js +59 -0
  66. package/dist/view-renderer/src/renderer.js +201 -0
  67. package/package.json +16 -5
  68. package/skills/notis-apps/cli.md +323 -163
  69. package/skills/notis-cli/AGENT_INSTRUCTIONS.md +3 -3
  70. package/skills/notis-onboarding/BRIEF.md +7 -3
  71. package/src/command-specs/apps.js +2 -1
  72. package/src/command-specs/auth.js +2 -2
  73. package/src/command-specs/files.js +29 -0
  74. package/src/command-specs/handover.js +331 -79
  75. package/src/command-specs/helpers.js +2 -0
  76. package/src/command-specs/index.js +11 -5
  77. package/src/command-specs/profile.js +42 -1
  78. package/src/command-specs/skills.js +242 -1
  79. package/src/command-specs/spaces.js +645 -0
  80. package/src/command-specs/tools.js +0 -6
  81. package/src/command-specs/views.js +69 -0
  82. package/src/runtime/agent-browser.js +92 -29
  83. package/src/runtime/app-boundary-validator.js +7 -4
  84. package/src/runtime/app-data-literals.js +82 -0
  85. package/src/runtime/app-platform.js +321 -253
  86. package/src/runtime/computer-identity.d.ts +30 -0
  87. package/src/runtime/computer-identity.js +151 -0
  88. package/src/runtime/config-lock.js +135 -0
  89. package/src/runtime/confined-space-build.js +74 -0
  90. package/src/runtime/confined-space-verify.js +49 -0
  91. package/src/runtime/delegated-context.js +5 -21
  92. package/src/runtime/native-record-files.js +47 -0
  93. package/src/runtime/oauth.js +18 -1
  94. package/src/runtime/profiles.js +5 -107
  95. package/src/runtime/retired-sdk-files.js +20 -0
  96. package/src/runtime/screenshot-framing.js +85 -0
  97. package/src/runtime/skill-sync/cloud-client.ts +26 -4
  98. package/src/runtime/skill-sync/index.ts +230 -35
  99. package/src/runtime/skill-sync/local-scanner.ts +188 -29
  100. package/src/runtime/skill-sync/native-identity.ts +102 -0
  101. package/src/runtime/skill-sync/native-plan.ts +70 -0
  102. package/src/runtime/skill-sync/sync-plan.ts +16 -9
  103. package/src/runtime/skill-sync/types.ts +32 -6
  104. package/src/runtime/source-root.js +32 -0
  105. package/src/runtime/space-collection-scaffold.js +66 -0
  106. package/src/runtime/space-database-structures.js +229 -0
  107. package/src/runtime/space-fixture-broker.js +50 -0
  108. package/src/runtime/space-lock.js +337 -0
  109. package/src/runtime/space-platform.js +105 -0
  110. package/src/runtime/space-source.js +281 -0
  111. package/src/runtime/space-test-server.js +327 -0
  112. package/src/runtime/space-verification.js +89 -0
  113. package/src/runtime/space-verify-browser-worker.js +51 -0
  114. package/src/runtime/space-view-manifest.js +254 -0
  115. package/src/runtime/store-screenshot.js +10 -7
  116. package/src/runtime/sync-skills.d.ts +3 -1
  117. package/src/runtime/sync-skills.js +10 -2
  118. package/src/runtime/transport.js +8 -6
  119. package/src/runtime/view-render.js +49 -0
  120. package/src/skill-sync-worker.js +14 -2
  121. package/src/space-harness-host.ts +103 -0
  122. package/template/.harness/index.html.tmpl +7 -10
  123. package/template/app/globals.css +1 -0
  124. package/src/command-specs/reports.js +0 -97
@@ -1,63 +1,118 @@
1
- ## SDK Hook Reference
2
-
3
- All hooks and components below are imported from `@notis/sdk`. `NotisProvider`
4
- already installs `ShortcutProvider`; app code should not add a second provider.
5
-
6
- | API | Signature | Description |
7
- |-----|-----------|-------------|
8
- | `useNotis()` | `() => { app, route, databases, collectionItem, resourceId, ready }` | App metadata, current route, selected collection item, decoded exact-resource id, ready state |
9
- | `useTool<TArgs, TResult>(name)` | `(name: string) => { call, loading, error }` | Call a declared tool with app-defined argument/result types. Identified reads use `call(args, { readOnly: true, dedupe: true })`; never dedupe writes. See [cached-read ownership](design.md#instant-view-loading-contract-required). |
10
- | `useTools()` | `() => { tools, loading }` | List available tools |
11
- | `useDocuments(slug, opts?)` | `(slug: string, opts?) => { documents, loading, hasData, error, refetch }` | Query an app database. Bodies are included by default. For metadata-only lists, opt into `includeContent: false`; load the opened record with `useDocument` and defer any full-body search query until needed. Metadata and full-content query caches are separate. |
12
- | `useNotisNavigation()` | `() => { toRoute, toDocument, toApp }` | Navigate between routes (including `toRoute(path, { resourceId })`), documents, or the app root |
13
- | `useTopBarSearch(opts)` | `({ value, onChange, placeholder?, onSubmit? }) => { setLoading }` | Bind the current view to the Portal-owned top-bar search input |
14
- | `useBackend()` | `() => { request }` | Raw backend request proxy with JWT auth |
15
- | `useDatabaseSubscription(slug, opts?)` | `(slug: string, opts?) => { rows, documents, loading, error, refetch, live }` | Query a database and refetch it when its rows change. `live` is false on hosts without a change feed (temporary test harness, vite preview) -- keep a manual refresh for those |
16
- | `useHandover()` | `() => { handover, pending, error, available }` | Open manager chat with app/resource context plus an optional starter prompt or declared skill. Omit `prompt` for a context-only composer. `available` is false on hosts with no chat -- fall back to a copyable prompt |
17
- | `useCloudComputer()` | `() => { facts, loading, error, refresh }` | Read-only cloud computer facts: sandbox existence/status and whether the GitHub CLI is signed in. Requires `capabilities.cloudComputer: 'read'` plus the user's approval; `facts.available === false` means answer from the app's own fallback |
18
- | `useActiveResource(resource)` | `(ContextResource \| null) => void` | Publish the record currently open in the app so manager handover and context menus stay grounded |
19
- | `useCollectionInteractions(opts)` | `(opts) => CollectionInteractionController` | Keyboard navigation, active-row state, range/toggle selection, marquee selection, and action dispatch for collection UIs |
20
- | `useShortcuts(definitions, opts?)` | `(definitions, opts?) => void` | Register scoped keyboard shortcuts. Editable targets are ignored unless explicitly allowed; use `ShortcutHints` to display them |
21
- | `MarkdownEditor` | `(NotisMarkdownEditorProps) => ReactElement` | Use the host editor with app-owned persistence, stable `resourceKey`, revision-aware `onSave`, and optional `onUploadFile` returning a durable URL |
22
- | `useAgentContext()` / `NotisCommentBoundary` / `NotisCommentBox` | generic context API and optional UI | App-defined pills, icons, context, attachments and nearby comments; see [Context sharing](context.md) |
23
- | `NotisSelectionBoundary` | `(NotisSelectionBoundaryProps) => ReactElement` | Attach structured, explicitly untrusted app/resource/selection context to selected content and copy operations |
24
- | `SelectionCheckbox` / `SelectionMarquee` | components | Standard selection controls backed by `useCollectionInteractions` |
25
- | `MultiSelectActionBar` | component | Standard bulk actions with pending/disabled state and shortcut support |
26
- | `Dialog` | `{ open, onClose, title, description?, role?, children }` | Themed native modal with top-layer stacking, focus handling and background shortcut isolation. Use `role="alertdialog"` for destructive confirmation; put the safe action first. |
27
-
28
- Import headless collection action types and helpers from
29
- `@notis/sdk/interactions`. Keep an open detail view synchronized with
30
- `useActiveResource`, and wrap its selectable content in
31
- `NotisSelectionBoundary` so the manager receives both the active record and the
32
- user's exact selection. For `MarkdownEditor`, keep `resourceKey` stable per
33
- record, pass the latest revision back from `onSave`, reject revision conflicts
34
- instead of overwriting newer data, and implement `onUploadFile` whenever the
35
- editor should accept media or file blocks.
36
-
37
- ### App configuration additions
38
-
39
- - `toolBindings` is only for provider-generated public tool names whose upstream
40
- action cannot be reconstructed. Keep the exact final public `name` in
41
- `tools`, then bind it to `providerToolName`; the public name remains the
42
- permission boundary.
43
-
44
- ### Typed tool calls
45
-
46
- `useTool` accepts generic argument and result types. Query the database at dev time to discover actual property shapes, then keep those types in the app:
1
+ # SDK reference for Space views
2
+
3
+ Import hooks/components from `@notis/sdk`; configuration helpers are in
4
+ `@notis/sdk/config`. `NotisProvider` already installs shortcut support. Use the
5
+ scoped host runtime—source never owns an account credential or backend transport.
6
+
7
+ ## Records and declared reads
8
+
9
+ | API | Use |
10
+ | --- | --- |
11
+ | `useViewParams<typeof definition>()` | `{params, invalid, missing, declared, ready}` for declared typed URL params. Unknown names are dropped; invalid values use their declared default. |
12
+ | `useShown<Row>(name, options?)` | Execute the native list in `shows[name]` with current params. Options: `sorts`, `pageSize`, `offset`, `includeContent`; result includes `data`, `loading`, `hasData`, `error`, `refetch`. |
13
+ | `useShownAvailable(name)` | Check whether this host exposes the declared native list. A record Site can expose only its exact server-pinned row scope. |
14
+ | `useAction<Inputs, Result>(name)` / `useActionQuery<Result>(name, inputs)` | Call a declared action; identify read-only calls explicitly and retain request IDs/revisions for writes. Never call account-wide tools from a Space. |
15
+ | `useNativeDocumentBody(binding, recordKey, {readAction, writeAction?, enabled?})` | Markdown body adapter. Keep drafts in the view; save with the original content, record/schema revisions and stable request ID. Rich editing normally uses `DocumentEditor`. |
16
+ | `useNotis()` | Host resource, Space/app labels, route and ready state. Use `resource.id` for the current Space identity. |
47
17
 
48
18
  ```tsx
49
- type QueryTasksArgs = { database_id?: string; database_slug?: string; query: { page_size?: number } };
50
- interface TaskDoc {
51
- title: string;
52
- properties: {
53
- Status: string;
54
- Priority: string;
55
- Due: string;
56
- };
57
- };
58
- type QueryTasksResult = { documents: TaskDoc[] };
59
-
60
- const queryTasks = useTool<QueryTasksArgs, QueryTasksResult>('LOCAL_NOTIS_DATABASE_QUERY');
61
- const result = await queryTasks.call({ database_id: 'tasks-db-id', query: { page_size: 25 } });
62
- // result.documents[0].properties.Status is typed as string
19
+ const { resource } = useNotis();
20
+ const nav = useNotisNavigation();
21
+ const { params } = useViewParams<typeof definition>();
22
+ const rows = useShown<{ record_key: string; title: string | null }>('notes');
23
+ // In the row's click handler:
24
+ nav.toSpace(resource.id, { recordKey: row.record_key });
25
+ // In the record branch:
26
+ <DocumentPage recordKey={params.note} breadcrumb={[{ label: 'All notes', onSelect: () => nav.toSpace(resource.id) }]} />
63
27
  ```
28
+
29
+ Keep hooks unconditional. Preserve cached content during refresh; `loading` is
30
+ first-read state, not every fetch. Use [Design](design.md#instant-view-loading-contract-required)
31
+ for loading/error/empty states and explicit read caching.
32
+
33
+ ## First-party record components
34
+
35
+ | Component | Contract |
36
+ | --- | --- |
37
+ | `<DocumentPage recordKey>` | The full page of a record that is the view's main content (a note, a document): breadcrumb, Saving or Saved, '...' menu, cover, icon, title, meta strip, properties that save automatically, collaborative body. Slots `breadcrumb`, `actions`, `menuItems`, `aboveBody`, `belowBody`; toggles `share` (off by default, never offered for a report record; in its own Space's view the record's Site is a row of the view's top bar Share panel, not a toolbar Share), `header`, `meta`, `properties`, `width`; `viewer: 'html'` opens a record whose one stored `.html` file is the page (such as an HTML page saved in Notis Notes) full height under the toolbar, without header, meta, properties or body editor; `onSaved`; `layout` to rearrange its parts. Pair with `DocumentPageSkeleton` and `usePrefetchRecord()`. Until the Notis CLI you build with exports it (`spaces build` replaces the Space's `packages/sdk` with the CLI's own SDK, and older ones have no `DocumentPage`, so the import fails the build), reach the same host page through `useNotisRuntime().ui?.DocumentPage` and fall back to `DocumentEditor` when it is missing, as the Notes Spaces do in `lib/document-page.tsx`. |
38
+ | `<DocumentEditor recordKey>` | Native collaborative body, properties, images and attachments. With separate properties use `showProperties={false}`. |
39
+ | `<RecordProperties recordKey>` | Native revision-checked property editing. |
40
+ | `<HtmlFrame recordKey>` | Attached HTML under viewer CSP and an opaque-origin sandbox. Source cannot relax that boundary. |
41
+ | `<ReportFrame recordKey>` | A report row's saved independent implementation in its database's current view. |
42
+ | `<ShareControl recordKey>` | Private/shared record Site, copy link and revoke. |
43
+
44
+ The published Space declares the database binding; the server rechecks record
45
+ scope and binding revision. A Site exposes read-only body/property snapshots and
46
+ HTML for its pinned record, including a declared non-collection record param.
47
+ A report row (`<ReportFrame>`) cannot be shared as a Site; a report saved as an
48
+ HTML file can.
49
+ It has no upload, collaboration credential, authoring controls or sharing mutation.
50
+ Preview source does not gain live record editing. No app-owned credentials or
51
+ filesystem URLs belong in component props.
52
+
53
+ ## Navigation
54
+
55
+ `useNotisNavigation()` exposes `toSpace(spaceId, {recordKey?, params?})` and
56
+ `toNamedSpace(alias, {recordKey?, params?})`. Prefer declared portable navigation
57
+ aliases for sibling destinations; the host resolves them under current access.
58
+ Use declared params for view state, for example `{params: {project: key, period: 'week'}}`.
59
+ The destination drops unknown params and authorizes referenced records. Changing
60
+ a slug cannot change identity. Agents cite current server-returned links.
61
+
62
+ ## Viewer-only exploration
63
+
64
+ `viewerReads: ['databases', 'skills']` permits read-only inspection of what the
65
+ signed-in viewer already reaches. It creates no shared grant. Use
66
+ `useViewerReadAvailable(family)`, `useViewerDatabases`, `useViewerSkills`, or
67
+ `useViewerRead(operation, input)`. Anonymous Sites cannot use these families.
68
+ Explicit synthetic `viewerReads` fixtures stand in for the viewer's reads offline.
69
+
70
+ ## The viewer's cloud computer
71
+
72
+ `cloudComputer: 'shell'` (or `'read'` for facts only) lets a page run one command
73
+ or write one file on the signed-in viewer's own cloud computer, after that viewer
74
+ allows it in the Portal prompt. Use `useCloudComputerShell()`: check `level`, call
75
+ `requestApproval()` when `approved` is false (either level; the facts of
76
+ `useCloudComputer()` are read again once allowed), then, when `available` (`shell`),
77
+ `run(command, options)` or
78
+ `upload({ path, content, content_encoding: 'base64', mode: 0o600 })`. Never put
79
+ secrets in a command; send them as upload content. A run is never repeated for one
80
+ request key: pass `requestId` (run option, or `request_id` in the upload) when the
81
+ page retries a run itself; `cloud_computer_already_ran` means it already ran. The
82
+ approval covers only the exact code the viewer allowed, so every new release asks again. Keep a fallback (a Manager
83
+ draft) for Sites, previews offline and viewers who do not allow it. Declare it only
84
+ when the page's core controls run on the cloud computer.
85
+
86
+ ## Visual data and Markdown
87
+
88
+ `<RenderChartData title columns rows>` adds a semantic table for the chart without
89
+ a second visible table. Give it the same labels/values used by the chart. The
90
+ renderer never guesses exact numbers from SVG/canvas geometry: a chart without
91
+ `RenderChartData` contributes only its accessible name to the Markdown.
92
+
93
+ An optional `markdown` source module exports a pure function of `{params, shown}`.
94
+ It must describe the rendered selection and its actual data. Ordinary rendering
95
+ extracts tables, lists, controls and visible document/HTML content automatically.
96
+
97
+ ## Host interactions and context
98
+
99
+ - `useHandover()` exposes `{handover, available, pending, error}`. Call a declared
100
+ linked Skill with `handover({skill, prompt})`; fall back when no agent UI exists.
101
+ - `useTopBarSearch` registers a host-owned search field. Do not duplicate host chrome.
102
+ - `useActiveResource` publishes the current resource; `useAgentContext`,
103
+ `NotisSelectionBoundary`, `NotisCommentBoundary` and `NotisCommentBox` support
104
+ explicit reference context. [Context sharing](context.md) owns the contract.
105
+ - `useCollectionInteractions`, selection components and `MultiSelectActionBar`
106
+ support native collection interactions. `Dialog` supplies themed top-layer
107
+ dialogs, focus handling and shortcut isolation.
108
+ - `MarkdownEditor` is for a view-owned Markdown draft/persistence adapter. Native
109
+ documents use `DocumentEditor` so collaboration and file authority stay with Notis.
110
+
111
+ ## Offline fixtures
112
+
113
+ Declare a `verificationFixtures` JSON source with `actions` and optional `context`,
114
+ `shown`, `viewerReads`, `documentBodies`, `recordViews`. Cases match exact action
115
+ inputs/list params. Record views use `{operation: 'record'|'html'|'report', record_key,
116
+ result}`; native record snapshots require `writable: false` and no authoring target.
117
+ Keep every fixture fictional and include every load-time read. Failed or missing
118
+ fixtures fail verification; there is no fallback to the user's real account.
@@ -1,23 +1,24 @@
1
- ## Troubleshooting
1
+ # Troubleshooting
2
2
 
3
- Start with the failing screen or operation. Do not invent a second app workflow;
4
- use the [delivery guide](release.md) and supported Notis CLI commands.
3
+ Start with the actual failing operation and its exact Space, source/record
4
+ revision and current target. [Delivery](release.md) owns the release sequence.
5
5
 
6
- - **App looks wrong despite passing checks:** open it inside Notis and compare
7
- the affected region with the request. Check loading and loaded states, viewport
8
- sizing, scrolling, and theme. A standalone harness does not reproduce the host's
9
- parent layout or shadow boundary. Do not assume the cause from a screenshot alone.
10
- - **Build reports a design violation:** use the scaffold component or theme token
11
- suggested by the diagnostic. Fix the reported file/line rather than hiding the
12
- pattern elsewhere. Existing validator exceptions are for justified cases, not a
13
- shortcut around visual review.
14
- - **The configured sidebar is missing:** preserve `routes` and `collection.sidebar`;
15
- investigate the host mismatch instead of duplicating the sidebar in app code.
16
- - **The app shows old code or is missing from Workspace:** check the exact installed
17
- app/version and requested bundle first. Local source edits and Desktop restarts
18
- do not update a released app. Refresh after confirming the correct release exists.
19
- - **Deploy transport failure:** run `notis doctor` and read back the exact app/version.
20
- Reconcile the outcome before retrying; do not bypass the backend with storage writes.
21
- - **Database query is empty or properties are undefined:** inspect the actual schema,
22
- database ID, and returned property shape through the CLI. Keep types in the app,
23
- guard optional fields, and distinguish an error from a successful empty result.
6
+ | Failure | Check |
7
+ | --- | --- |
8
+ | Build rejects a view | Required `specVersion`, path, descriptions, params, executable shows and memory; use the file/line diagnostic. |
9
+ | Main-view conflict | Inspect current database links/main view. Move the existing claim explicitly or retain it; do not remove main just to publish. |
10
+ | Source creation fails | Check its canonical schema and same-view main record param. Verify creates no resource; promotion is atomic. |
11
+ | View-link warning after a successful write | Use `FIND_VIEWS` with the returned record key. The write is already committed; do not insert again. |
12
+ | Empty list or missing properties | Inspect the live schema, filter, authorized binding and returned projection. Distinguish a successful empty result from a denied/failed read. |
13
+ | Verification fails on a read | Add the exact fictional case to the selected fixture file. Never fill missing fixtures with live private data. |
14
+ | A caught write-on-load fails rendering | Remove the side effect from initial rendering. A read-only check cannot authorize writes. |
15
+ | Stale binding/schema/record | Read current state, preserve the original receipt/intent and merge the intended edit. Do not overwrite concurrent changes. |
16
+ | Old code in Workspace | Read the published revision and requested bundle; source edits or restarting Desktop do not deploy it. |
17
+ | Uncertain deployment | Run `notis doctor`, read the same Space and release/request identity, then reconcile before retrying. |
18
+ | Screenshot misses content | Inspect actual inner scrolling, lazy data and frame layout; keep full-height limits and treat a failed capture as unverified. |
19
+ | Site unexpectedly has editor controls | Recheck the anonymous scoped runtime. A Site cannot borrow an ambient signed-in session or another record's authority. |
20
+ | Memory hit looks current but access/freshness is unknown | Render its current link and verify the relevant value. Do not release historical content from an unverified read set. |
21
+
22
+ For visual defects, compare the installed page at 390px and 1440px in EN/FR,
23
+ including loading, empty and error states. A standalone harness cannot certify
24
+ the Portal parent layout, collaboration or public Site behavior.
@@ -0,0 +1,145 @@
1
+ # View authoring
2
+
3
+ A view is the presentation of a Space. A record opens in a view; its database has
4
+ one main view. Words in links describe the destination, while IDs choose it.
5
+ Get links from write results or `LOCAL_NOTIS_FIND_VIEWS`, not by joining labels.
6
+
7
+ ## Start from the collection scaffold
8
+
9
+ ```bash
10
+ notis spaces init "Notes" ./notes --database-key notes --path notes
11
+ notis spaces build ./notes --space collection
12
+ ```
13
+
14
+ `init` is local only. For an existing Space, pull its exact ID instead. Keep its
15
+ lock and local source key; one build/deploy changes that selected Space only.
16
+ A container has children but no page; page-only params/shows/memory belong on views.
17
+
18
+ ## A complete view declaration
19
+
20
+ The linked `notes` resource below must already resolve to this installation's
21
+ native database. Descriptions explain what a person or agent can do here.
22
+
23
+ ```ts
24
+ import { defineSpace } from '@notis/sdk/config';
25
+
26
+ export default defineSpace({
27
+ specVersion: 2,
28
+ name: 'Notes',
29
+ path: 'notes',
30
+ description: 'Browse notes and open one with its files.',
31
+ readableContext: 'The note parameter opens one note. The list shows all notes available through this Space.',
32
+ entry: './view.tsx',
33
+ resources: { notes: { kind: 'database', key: 'notes' } },
34
+ collection: { database: 'notes', titleProperty: 'title' },
35
+ params: {
36
+ note: { type: 'record', database: 'notes', main: true,
37
+ description: 'The note to open beside the list.' },
38
+ },
39
+ shows: { notes: { database: 'notes', where: {}, open: 'note' } },
40
+ memory: { markdown: true, attachments: true, screenshot: false, snapshots: [] },
41
+ actions: {
42
+ read: {
43
+ tool: 'LOCAL_NOTIS_DATABASE_QUERY',
44
+ inputs: { type: 'object', additionalProperties: false,
45
+ required: ['request'], properties: { request: {
46
+ type: 'object', additionalProperties: false,
47
+ required: ['filter', 'page_size', 'include_content'],
48
+ properties: {
49
+ filter: { type: 'object', additionalProperties: false,
50
+ required: ['field', 'op', 'value'], properties: {
51
+ field: { type: 'object', additionalProperties: false,
52
+ required: ['column'], properties: { column: { const: 'record_key' } } },
53
+ op: { const: 'equals' }, value: { type: 'string', format: 'uuid' },
54
+ } },
55
+ page_size: { const: 1 }, include_content: { const: true },
56
+ },
57
+ } } },
58
+ arguments: { database_id: { $asset: 'notes' }, request: { $input: 'request' } },
59
+ },
60
+ },
61
+ });
62
+ ```
63
+
64
+ Use `useViewParams<typeof definition>()`, `useShown('notes')`, and
65
+ `<DocumentPage recordKey={params.note}>` (the whole note page; use `DocumentEditor` only to embed a body
66
+ inside a layout of your own; if `spaces build` reports no `DocumentPage` export, your CLI predates it: use
67
+ `useNotisRuntime().ui?.DocumentPage` with a `DocumentEditor` fallback, see the SDK reference). Keep hooks unconditional; conditional
68
+ record/list branches can be separate components. The SDK reference covers the
69
+ components and exact navigation helpers. The saved `read` action is deliberately
70
+ constrained to one native record for body/Site reads; `shows.notes` owns the
71
+ Editor’s collection list. Keep both tied to the same declared resource.
72
+
73
+ ## Params and declared lists
74
+
75
+ - Param types: `record`, `enum`, `text`, `number`, `date`, `boolean`. Each needs a
76
+ description. Enum values and defaults are typed; a required param has no default.
77
+ - Record params name a declared database and have no default record. `main: true`
78
+ claims that database's main view. `slugProperty` is a title/number property used
79
+ for readable link text, not record identity.
80
+ - `path` is descriptive lowercase words, up to four slash-separated segments;
81
+ do not put IDs, credentials or reserved product routes in it.
82
+ - `shows` for native data is `{database, where, open?}`. `where` is the native filter
83
+ grammar and is what `useShown` executes, not commentary beside a different query.
84
+ `open` names a record param over the same database.
85
+ - A project-scoped task list can use
86
+ `{field: {property: 'Project'}, op: 'contains', value: '{project}'}` with a declared
87
+ project record param. `{project.Status}` reads a property of that authorized record.
88
+ - For connected-service content use `{about, services?}` and declared actions.
89
+ This descriptive form is not a native executable list; use `useAction` for reads.
90
+ - Preserve the application's real semantics and option names. For the existing
91
+ Tasks migration, Inbox is **Project empty OR Status equals Inbox**. Keep imported
92
+ rows, statuses and creation defaults; add the Inbox option only if absent. Its
93
+ native filter is `{or: [{field: {property: 'Project'}, op: 'is_empty'},
94
+ {field: {property: 'Status'}, op: 'equals', value: 'Inbox'}]}`. Other applications
95
+ must use their own inspected schema rather than copying these labels blindly.
96
+
97
+ ## Create a database in the same release
98
+
99
+ Replace an existing database reference with:
100
+
101
+ ```ts
102
+ resources: {
103
+ notes: { kind: 'database', create: {
104
+ name: 'Notes',
105
+ schema: {
106
+ schema_version: 1, value_encoding_version: 1, coercion_version: 1,
107
+ title_property_id: 'title', property_order: ['title'],
108
+ properties: { title: { id: 'title', name: 'Name', kind: 'title',
109
+ storage_family: 'textish', description: '', order: 0, config: {} } },
110
+ },
111
+ } },
112
+ },
113
+ ```
114
+
115
+ The same view declares a record param over `notes` with `main: true`. Promotion
116
+ creates the database, link, main view, optional fictional `starterRows` and source
117
+ atomically; a later failure leaves none of them behind. Verification does not create
118
+ it. `create` is creation-only: later schema edits use native database tools;
119
+ `spaces pull` refreshes the declaration from the live schema.
120
+
121
+ The separate native schema-tool creation route requires `links.add` and
122
+ `main_view: {space_id, param}` in that linked Space. Until the Space next deploys
123
+ that main param, record links open the Space and writes return `view_warning`.
124
+ Inspect current tools for exact argument shapes; do not repeatedly insert rows
125
+ because a pending main view cannot yet open one.
126
+
127
+ ## Rendering and memory
128
+
129
+ Choose [memory](memory.md) deliberately. `chrome: 'hidden'` is for full-screen
130
+ presentations; ordinary collection views keep Portal chrome.
131
+ A Space whose published view hides chrome starts hidden from each person's sidebar;
132
+ it stays reachable by link and search. Each person can turn on **Show hidden Spaces**
133
+ in the sidebar's Spaces menu, then choose **Show in sidebar** in that Space's menu.
134
+ Skill review Spaces stay out of the sidebar, even with **Show hidden Spaces** on:
135
+ people open them from the Skill page's **Changes** list. A review a person already
136
+ chose to show stays in their sidebar until they hide it.
137
+ Optional `markdown: './markdown.ts'` names a module exporting a pure function of
138
+ `{params, shown}`. Its output must represent this view, not make hidden writes.
139
+ Use `<RenderChartData>` with the chart's actual rows so rendered Markdown contains
140
+ precise labels and values as well as its image.
141
+
142
+ Add synthetic action/list/body/record fixtures, then build and verify. Verification
143
+ and live rendering share the read-only renderer; fixture success does not prove
144
+ live permissions or data. After an authorized deploy, render the returned view link
145
+ with `notis views render` and inspect both the Markdown and full-height screenshot.
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: notis-cli
3
- description: Use when agents should work through the Notis CLI, especially to develop Notis apps locally or to access Notis, Composio, or MCP tools they do not currently have loaded directly.
3
+ description: Use when agents should work through the Notis CLI, especially to develop Notis Spaces locally or to access Notis, Composio, or MCP tools they do not currently have loaded directly.
4
4
  mcp_resource: true
5
- mcp_tool_patterns: []
6
- mcp_references: ["references/app-delivery.md", "references/tool-examples.md", "references/native-databases.md", "references/troubleshooting.md"]
5
+ mcp_tool_patterns: ["LOCAL_NOTIS_GET_INTELLIGENCE_POLICY"]
6
+ mcp_references: ["references/app-delivery.md", "references/tool-examples.md", "references/native-databases.md", "references/troubleshooting.md", "references/intelligence.md"]
7
7
  ---
8
8
 
9
9
  # Notis CLI Skill
@@ -12,13 +12,13 @@ Use this skill when the user wants work done through the Notis CLI.
12
12
 
13
13
  This skill covers two main CLI workflows:
14
14
 
15
- 1. Developing Notis apps locally.
15
+ 1. Developing Notis Spaces (views, their source and linked Skills) locally.
16
16
  2. Accessing Notis, Composio, and MCP tools through the CLI.
17
17
  ## When to use this skill
18
18
 
19
19
  Activate this skill when:
20
20
 
21
- - the user wants to init, develop, build, verify, link, pull, or deploy a Notis app through the CLI
21
+ - the user wants to init, pull, build, verify, preview, deploy or promote a Notis Space through the CLI
22
22
  - the current agent does not have the tool it needs in its direct tool list
23
23
  - the user wants direct MCP access through Notis
24
24
  - the user wants to use an integration-backed capability through Notis rather than a first-class local tool
@@ -28,7 +28,7 @@ Use the registry-resolved published npm package everywhere:
28
28
 
29
29
  - `npx --package @notis_ai/cli@latest -- notis ...`
30
30
 
31
- Always use this NPX command form so the agent runs the current published CLI. In hosted shells, the CLI is pre-authenticated through `NOTIS_JWT`. On a local machine the CLI holds its own OAuth grant: `notis login` authorizes one in the browser, and signing in to the Notis desktop app authorizes one automatically for that account. Either way the grant belongs to the CLI, which refreshes it without the desktop app running.
31
+ Always use this NPX command form so the agent runs the current published CLI, with one exception: on the Notis Cloud Computer (home folder `/vercel/sandbox`) the CLI is preinstalled and kept current, so run `notis ...` there with the same arguments, and use the NPX form only if `notis` is not found. Parallel NPX runs reinstall the package and can break each other. In hosted shells, the CLI is pre-authenticated through `NOTIS_JWT`. On a local machine the CLI holds its own OAuth grant: `notis login` authorizes one in the browser, and signing in to the Notis desktop app authorizes one automatically for that account. Either way the grant belongs to the CLI, which refreshes it without the desktop app running.
32
32
 
33
33
  `@latest` is correct for every account, including beta ones. Each deployment reports which published build belongs to it, `notis login` pins that on the profile, and a later run that finds itself on the wrong build hands the invocation to the right one before doing anything. Never substitute a channel by hand: pinning `@beta` on a production profile is how a machine ends up running a build its API does not expect. `notis doctor` reports the active channel, and `NOTIS_CLI_AUTO_CHANNEL=0` turns the hand-off off for a run.
34
34
 
@@ -38,11 +38,13 @@ The CLI bundles this `notis-cli` base skill and refreshes its canonical copy und
38
38
 
39
39
  A profile is one account paired with one API endpoint. Profiles live side by side; switching between them never signs any of them out.
40
40
 
41
- - `npx --package @notis_ai/cli@latest -- notis profile list` — every profile on this machine, with its endpoint, user, and whether it is signed in. The active one is marked.
42
- - `npx --package @notis_ai/cli@latest -- notis profile use <name>` — change which account subsequent commands run as.
43
- - `npx --package @notis_ai/cli@latest -- notis --profile <name> <command>` — run a single command as another account without changing the active one.
44
- - `npx --package @notis_ai/cli@latest -- notis login --profile <name>` — add an account. The existing profiles keep their credentials.
45
- - `npx --package @notis_ai/cli@latest -- notis logout` — sign out of the active profile only; pass `--all-profiles` to clear every one.
41
+ Notis Desktop signs the CLI in for every account saved in the app, one profile each. `default` keeps its name; each added account gets a profile named after its email with `@` turned into `-` (for example `flo-mindtheflo.com`), and Beta Desktop adds `-beta`. Switching accounts in Desktop never changes the active profile. Only the active profile's skills are linked into Claude Code, Codex and Cursor; every other account's skills sync into their own folder. Signing an account out of Desktop signs it out of the CLI on this computer and removes the profile and skills Desktop made for it. If that was the active profile, the CLI switches to the account Desktop opens next; with no other signed-in Desktop account it stays signed out. Profiles made with `notis login` are never removed or picked automatically.
42
+
43
+ - `npx --package @notis_ai/cli@latest -- notis profile list`: every profile on this machine, with its endpoint, user, and whether it is signed in. The active one is marked.
44
+ - `npx --package @notis_ai/cli@latest -- notis profile use <name>`: change which account subsequent commands run as, and link that account's skills into the agent folders straight away.
45
+ - `npx --package @notis_ai/cli@latest -- notis --profile <name> <command>`: run a single command as another account without changing the active one.
46
+ - `npx --package @notis_ai/cli@latest -- notis login --profile <name>`: add an account. The existing profiles keep their credentials.
47
+ - `npx --package @notis_ai/cli@latest -- notis logout`: sign this computer out of the active profile only; the account stays signed in on other computers. Pass `--all-profiles` to clear every profile on this computer.
46
48
 
47
49
  Read the profile before acting on the user's data. `notis whoami` reports the account and endpoint a command will hit; if that is not the account the user meant, switch profiles rather than proceeding.
48
50
 
@@ -133,7 +135,22 @@ For hosted MCP, fetch the matching `notis://docs/notis-cli/references/<file>.md`
133
135
  with resources/read or the available Notis resource-fetch tool; the root resource
134
136
  also rewrites these links to their published URIs.
135
137
 
136
- - [App delivery](references/app-delivery.md)
138
+ - [Space delivery](references/app-delivery.md)
137
139
  - [Toolkit mental model](references/tool-examples.md)
138
140
  - [Native database access](references/native-databases.md)
139
141
  - [Supporting commands](references/troubleshooting.md)
142
+
143
+ ## Intelligence for skills and delegated work
144
+
145
+ Skills request `low`, `medium`, or `high`, never a fixed model name. Discover the
146
+ read-only `LOCAL_NOTIS_GET_INTELLIGENCE_POLICY` tool to obtain the shared `contract`
147
+ and current mapping
148
+ for `notis`, `codex`, or `claude_code` and the requested `level`. Resolve model and
149
+ reasoning effort together at the start of each job; validate the selected options
150
+ with the executing harness. Explicit invocation overrides win. A fixed-model
151
+ harness may inherit and disclose that the level was not applied; an automated
152
+ launcher needing an exact selection stops before side effects if policy is unavailable.
153
+ Repository and installed skills consume that same response; neither needs a
154
+ checkout-relative document. Record actual execution receipts, not the level name, as model provenance. Media
155
+ engines remain separate capabilities selected by their tools. See
156
+ [the intelligence contract](references/intelligence.md) for cross-environment details.
@@ -1,18 +1,19 @@
1
- # App delivery
1
+ # Space delivery
2
2
 
3
- Use the canonical `notis-apps` skill’s entrypoint and [release guide](../../notis-apps/references/release.md).
3
+ Use the canonical `notis-apps` skill's entrypoint and [release guide](../../notis-apps/references/release.md).
4
4
  For hosted MCP fetch `notis://docs/notis-apps` and `notis://docs/notis-apps/references/release.md`.
5
5
  User/repository no-deploy and explicit-consent policies take precedence over default delivery.
6
6
 
7
- ## IMPORTANT: When NOT to use tool access for app development
7
+ ## IMPORTANT: When NOT to use tool access for Space development
8
8
 
9
- When building or deploying a Notis app, do NOT use `npx --package @notis_ai/cli@latest -- notis tools exec` for app file operations:
9
+ When building or deploying a Space, do NOT use `npx --package @notis_ai/cli@latest -- notis tools exec` for source operations:
10
10
 
11
- - Loading or saving app files -- use `npx --package @notis_ai/cli@latest -- notis apps build` and `npx --package @notis_ai/cli@latest -- notis apps deploy`
12
- - Linting app files -- use `npx --package @notis_ai/cli@latest -- notis apps build` which validates automatically
13
- - Managing app routes -- write standard Vite + React pages in `app/`, not raw JS files
11
+ - Loading, building or publishing source -- use `notis spaces pull`, `spaces build`, `spaces verify`, `spaces preview`, `spaces deploy` and `spaces promote` as the release guide orders them
12
+ - Validating views -- `spaces build` and `spaces verify` check declarations, fixtures and renders
13
+ - Writing pages -- write standard Vite + React views with `@notis/sdk`, not raw JS files
14
14
 
15
- Database schemas are the exception: declaring a slug in `notis.config.ts` does
16
- not create it. Use the discovery-first native database tool workflow to
17
- create/update and read back each app-owned schema before deployment. Tool calls
18
- are also valid for testing runtime behavior after deployment.
15
+ Database schemas have two routes: the native database tool (create with `links.add`
16
+ and `main_view`), or a `create` declaration in Space source that the deploy applies
17
+ atomically. Tool calls are also valid for testing runtime behavior after deployment.
18
+ `notis apps` is the legacy App group for accounts not yet moved to Spaces; a legacy
19
+ App cannot declare Skills.
@@ -0,0 +1,94 @@
1
+ # Agent intelligence levels
2
+
3
+ This is one shared contract for repository skills and account-installed skills.
4
+ Read it from the `contract` field returned by `LOCAL_NOTIS_GET_INTELLIGENCE_POLICY`,
5
+ directly as a native tool or through the authenticated Notis CLI. The same response
6
+ contains current harness mappings and a `contract_revision` fingerprint. No local
7
+ repository document is a runtime prerequisite. This bundled guide is the source
8
+ served by that lookup, not a separate environment-specific contract.
9
+
10
+ Skills request **low**, **medium**, or **high**. They never maintain model names,
11
+ version pins, family aliases, effort tables, or price scorecards. The current
12
+ Notis runtime policy is the source of truth, on every operating system and host.
13
+
14
+ ## Choosing a level
15
+
16
+ | Level | Work |
17
+ | --- | --- |
18
+ | **low** | Bounded extraction, classification against a supplied rubric, formatting, and repetitive generation from complete inputs. |
19
+ | **medium** | Synthesis, writing and reviewing prose from supplied evidence, and moderately complex bounded work. |
20
+ | **high** | The skill default when unspecified: complex reasoning, investigation, coding, code review, and orchestration. |
21
+
22
+ These are skill defaults, not changes to account or product defaults. The user's
23
+ explicit instruction for this invocation wins: level, exact model, effort,
24
+ harness, or inheritance from the current session. Preserve the scope of that
25
+ override; never save a lasting preference unless asked. Maximum-depth requests
26
+ are invocation overrides, not a fourth Notis level.
27
+
28
+ ## Resolve at execution time
29
+
30
+ Discover **get current Notis intelligence policy for each harness** through the
31
+ Notis tool catalogue. The read-only tool is `LOCAL_NOTIS_GET_INTELLIGENCE_POLICY`:
32
+
33
+ ```bash
34
+ npx --package @notis_ai/cli@latest -- notis tools exec LOCAL_NOTIS_GET_INTELLIGENCE_POLICY \
35
+ --arguments '{"harness":"codex","level":"low"}'
36
+ ```
37
+
38
+ Omit arguments to read all levels. Harness keys are `notis`, `codex`, and
39
+ `claude_code`. A local Mac, Windows host, cloud sandbox, or CI runner uses the
40
+ same contract. Cursor or another host must identify its actual execution engine;
41
+ it must not pretend to be a supported harness based on installed binaries.
42
+
43
+ The projection is generated from the backend native intelligence configuration and external-harness policy. It contains no
44
+ second mapping. Weekly policy changes therefore require no skill edits.
45
+
46
+ - Resolve **both model and reasoning effort**. Level names are not effort names.
47
+ - Resolve once per delegated job; keep its `policy_revision` and selection stable
48
+ through claim, generation, retry and completion. A new job gets a fresh policy.
49
+ - Explicit user choices override the selection; validate them with the executing
50
+ harness. Never substitute another model, buy API capacity, or change accounts
51
+ because a selection is unavailable.
52
+ - Validate the request against advertised harness capabilities. Policy is not
53
+ evidence of entitlement, quota, installed support or successful execution.
54
+ - Use native `intelligence_mode` when the Notis delegation interface supports it.
55
+ External launchers translate the returned selection into their supported options.
56
+ - Do not downgrade or restart the main session to enforce a skill default.
57
+ - A single-model harness can inherit its current configuration and disclose that
58
+ the requested level was not applied. Unknown or unavailable mappings are not
59
+ permission to guess a model. Automated launchers that require an exact selection
60
+ stop before claiming jobs or producing side effects and explain the missing policy.
61
+ - Before this lookup is deployed, use a current runtime-injected policy if present;
62
+ otherwise use the transparent inheritance behavior above. Do not copy a temporary
63
+ model table into skills as a rollout workaround.
64
+
65
+ ## Modalities, product assertions and provenance
66
+
67
+ Image, speech, video, embedding and provider-research engines are capabilities,
68
+ not interchangeable text-reasoning levels. Skills discover the current native
69
+ capability and let its backend select the engine. External scripts requiring an
70
+ exact provider-specific identifier must resolve current supported configuration
71
+ or take an explicit invocation override; they must not pass `low` as an engine ID.
72
+
73
+ Test specs assert behavior against the current backend configuration, rather than
74
+ freezing last month's model names. Preserve exact comparisons: derive the expected
75
+ identifier from the owning policy or tool configuration, then compare the receipt.
76
+ Do not weaken a routing test to merely check that some model name exists.
77
+
78
+ Persist **the actual model that ran**, not an intelligence level. Resolve before
79
+ claiming jobs when the identifier participates in a prompt hash or lease contract.
80
+ Verify execution readback before certifying provenance; aliases and requested
81
+ settings are not actual-model receipts. Preserve historical evidence and existing
82
+ records. Do not rewrite an old receipt as today's policy.
83
+
84
+ ## Subscription execution
85
+
86
+ A level chooses intelligence, not payment authority. Use the current harness's
87
+ sub-agents or the user's subscription CLI. The existing direct-provider approval
88
+ boundary remains in the workspace/account provider-approval policy.
89
+
90
+ For subscription CLI subprocesses, remove provider API-key/base-URL variables
91
+ from the child environment. Preserve native subscription credentials; never log
92
+ out or rewrite account authentication to enforce a level. Check the harness's
93
+ execution/authentication readback. Resolve only once per job, batch bounded items
94
+ where appropriate, and keep existing concurrency and usage limits.