@notis_ai/cli 0.2.0-beta.191.1 → 0.2.0-beta.196.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 (106) hide show
  1. package/README.md +479 -80
  2. package/config/portal-route-roots.json +48 -0
  3. package/dist/agent-hooks/notis-agent-hook.mjs +29072 -2784
  4. package/dist/base-skills/notis-apps/SKILL.md +88 -67
  5. package/dist/base-skills/notis-apps/references/architecture.md +114 -167
  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 +104 -142
  10. package/dist/base-skills/notis-apps/references/sdk.md +113 -60
  11. package/dist/base-skills/notis-apps/references/troubleshooting.md +22 -21
  12. package/dist/base-skills/notis-apps/references/views.md +142 -0
  13. package/dist/base-skills/notis-cli/SKILL.md +4 -4
  14. package/dist/base-skills/notis-cli/references/app-delivery.md +12 -11
  15. package/dist/base-skills/notis-cli/references/native-databases.md +6 -6
  16. package/dist/base-skills/notis-cli/references/tool-examples.md +4 -4
  17. package/dist/base-skills/notis-query/SKILL.md +34 -60
  18. package/dist/base-skills/notis-query/references/database-discovery.md +59 -69
  19. package/dist/base-skills/notis-query/references/documents.md +63 -50
  20. package/dist/base-skills/notis-query/references/query.md +57 -524
  21. package/dist/sdk/src/bundleModule.ts +79 -0
  22. package/dist/sdk/src/components/DocumentEditor.tsx +6 -3
  23. package/dist/sdk/src/components/DocumentPage.tsx +141 -0
  24. package/dist/sdk/src/components/RecordComponents.tsx +33 -0
  25. package/dist/sdk/src/components/RenderChartData.tsx +19 -0
  26. package/dist/sdk/src/config.ts +4 -26
  27. package/dist/sdk/src/documents.ts +2 -0
  28. package/dist/sdk/src/hooks/useAction.ts +28 -0
  29. package/dist/sdk/src/hooks/useCloudComputer.ts +35 -4
  30. package/dist/sdk/src/hooks/useCloudComputerShell.ts +114 -0
  31. package/dist/sdk/src/hooks/useHandover.ts +5 -4
  32. package/dist/sdk/src/hooks/useNativeDocumentBody.ts +50 -0
  33. package/dist/sdk/src/hooks/useNativeDocuments.ts +83 -0
  34. package/dist/sdk/src/hooks/useNotis.ts +3 -0
  35. package/dist/sdk/src/hooks/useNotisNavigation.ts +26 -11
  36. package/dist/sdk/src/hooks/useQuery.ts +7 -4
  37. package/dist/sdk/src/hooks/useViewParams.ts +121 -0
  38. package/dist/sdk/src/hooks/useViewerReads.ts +129 -0
  39. package/dist/sdk/src/index.ts +36 -0
  40. package/dist/sdk/src/interactions/shortcuts.tsx +17 -3
  41. package/dist/sdk/src/nativeData.ts +39 -0
  42. package/dist/sdk/src/presentation.tsx +82 -0
  43. package/dist/sdk/src/provider.tsx +9 -4
  44. package/dist/sdk/src/queryCache.ts +5 -3
  45. package/dist/sdk/src/queryErrors.ts +51 -0
  46. package/dist/sdk/src/runtime.ts +146 -8
  47. package/dist/sdk/src/space.ts +425 -0
  48. package/dist/sdk/src/styles.css +96 -72
  49. package/dist/sdk/src/vite.ts +11 -1
  50. package/dist/skill-sync/index.js +458 -68
  51. package/dist/skill-sync/index.js.map +4 -4
  52. package/dist/skill-sync-worker.mjs +451 -77
  53. package/dist/space-harness/host.js +66 -0
  54. package/dist/view-renderer/dist/host.css +1 -0
  55. package/dist/view-renderer/dist/host.js +1042 -0
  56. package/dist/view-renderer/dist/theme.css +73 -0
  57. package/dist/view-renderer/src/dom.js +180 -0
  58. package/dist/view-renderer/src/errors.js +8 -0
  59. package/dist/view-renderer/src/host.tsx +173 -0
  60. package/dist/view-renderer/src/index.js +4 -0
  61. package/dist/view-renderer/src/pool.js +76 -0
  62. package/dist/view-renderer/src/remote-broker.js +59 -0
  63. package/dist/view-renderer/src/renderer.js +201 -0
  64. package/package.json +11 -5
  65. package/skills/notis-apps/cli.md +270 -163
  66. package/skills/notis-cli/AGENT_INSTRUCTIONS.md +2 -2
  67. package/skills/notis-onboarding/BRIEF.md +7 -3
  68. package/src/command-specs/apps.js +1 -8
  69. package/src/command-specs/files.js +29 -0
  70. package/src/command-specs/helpers.js +1 -0
  71. package/src/command-specs/index.js +10 -4
  72. package/src/command-specs/skills.js +229 -0
  73. package/src/command-specs/spaces.js +572 -0
  74. package/src/command-specs/views.js +69 -0
  75. package/src/runtime/agent-browser.js +30 -7
  76. package/src/runtime/app-boundary-validator.js +7 -4
  77. package/src/runtime/app-data-literals.js +82 -0
  78. package/src/runtime/app-platform.js +321 -253
  79. package/src/runtime/confined-space-build.js +74 -0
  80. package/src/runtime/confined-space-verify.js +49 -0
  81. package/src/runtime/native-record-files.js +47 -0
  82. package/src/runtime/retired-sdk-files.js +20 -0
  83. package/src/runtime/skill-sync/cloud-client.ts +26 -4
  84. package/src/runtime/skill-sync/index.ts +154 -35
  85. package/src/runtime/skill-sync/local-scanner.ts +125 -17
  86. package/src/runtime/skill-sync/native-identity.ts +102 -0
  87. package/src/runtime/skill-sync/native-plan.ts +59 -0
  88. package/src/runtime/skill-sync/sync-plan.ts +16 -9
  89. package/src/runtime/skill-sync/types.ts +32 -6
  90. package/src/runtime/source-root.js +32 -0
  91. package/src/runtime/space-collection-scaffold.js +66 -0
  92. package/src/runtime/space-database-structures.js +229 -0
  93. package/src/runtime/space-fixture-broker.js +50 -0
  94. package/src/runtime/space-lock.js +337 -0
  95. package/src/runtime/space-platform.js +105 -0
  96. package/src/runtime/space-source.js +281 -0
  97. package/src/runtime/space-test-server.js +327 -0
  98. package/src/runtime/space-verification.js +89 -0
  99. package/src/runtime/space-verify-browser-worker.js +51 -0
  100. package/src/runtime/space-view-manifest.js +254 -0
  101. package/src/runtime/sync-skills.js +1 -1
  102. package/src/runtime/transport.js +8 -1
  103. package/src/runtime/view-render.js +49 -0
  104. package/src/space-harness-host.ts +103 -0
  105. package/template/app/globals.css +1 -0
  106. package/src/command-specs/reports.js +0 -97
@@ -1,145 +1,107 @@
1
- ## Delivery
2
-
3
- Workspace runs released versions only. Local and cloud agents use the same
4
- workflow. Run Notis commands through
5
- `npx --package @notis_ai/cli@latest -- notis ...`.
6
-
7
- A create/edit request normally authorizes updating that app after checks pass,
8
- **unless user or repository policy requires explicit deployment consent**.
9
- Preserve authorization already given. Read-only, preview-only, and no-deploy
10
- instructions stop at local source, build, and stub verification: no remote
11
- resource mutation, app activation, or live verification. Store publication always
12
- needs separate explicit approval. Do not deploy just to obtain visual proof when
13
- deployment is not authorized; report that the host check remains unverified.
14
-
15
- ## Update an app
16
-
17
- 1. **Check identity.** Inspect the effective CLI profile and `apps list --json`.
18
- Preserve local edits, then pull the exact editable app ID and intended
19
- personal/team scope. Keep its profile-scoped link, current version, and revision.
20
- Never silently advance a stale checkout or create a duplicate to avoid a conflict.
21
- 2. **Build and inspect.** Edit the source, increment `notisAppVersion`, and update
22
- `CHANGELOG.md`. Run `apps build` and automated `apps verify`, then do the
23
- [visual check](design.md#look-at-the-result). For a new app, complete these
24
- local checks before creating remote resources.
25
- 3. **Prepare only missing resources.** For an existing app, retain its identity.
26
- For a new app, reconcile the exact canonical name, edit permission, and scope
27
- against `apps list --json`; reuse one matching editable identity, stop on
28
- ambiguity, or create only when none exists. Use `apps create "<display title>"
29
- <dir>` (with a verified `--team-id` for team scope), and read back the same ID.
30
- Create only necessary missing databases against that app. Verify ownership
31
- and database IDs before changing schemas; read back changes. Breaking changes
32
- require separate coordination. Never mutate user data merely to test the UI.
33
- 4. **Update Workspace.** Run `apps deploy` against that linked app. It builds and
34
- verifies a frozen source/artifact snapshot before activation. `--skip-build`
35
- accepts only unchanged valid output and still verifies. Use the supported
36
- backend path; do not bypass checks or write directly to storage.
37
- 5. **Verify delivery.** Read back the app ID, integer version, and Portal URL with
38
- `apps list --json`. Run `apps verify --mode live`, then open the released app
39
- inside Notis and inspect the affected screen and main interaction. Confirm the
40
- intended bundle/version, not just the existence of an app with the same name.
41
- A successful live harness check alone is not visual proof inside Notis.
42
- 6. **Report accurately.** Give the app link and a brief description of what changed
43
- and what was verified. Distinguish local-only, deployed and verified, deployed
44
- but unverified, failed before activation, and outcome unknown. If create/deploy
45
- has an uncertain outcome, reconcile its exact identity/version before retrying.
1
+ # Delivery
2
+
3
+ Workspace runs released Space source. Use the same workflow locally and on the
4
+ cloud computer through `npx --package @notis_ai/cli@latest -- notis`.
5
+ A create/edit request authorizes the checked installed-Space update unless the
6
+ user or applicable policy says preview-only/no-deploy. Store publication is a
7
+ separate action. Preserve exact identity and prior authorization.
8
+
9
+ ## Update one Space
10
+
11
+ 1. **Read identity.** Check the active account/endpoint and `spaces get <space-id>`.
12
+ Pull the exact editable source with `spaces pull <space-id> <dir>`. Keep
13
+ `.notis/space-lock.json`, resources, source key and current revisions. Never
14
+ silently advance a stale checkout or create a duplicate to avoid a conflict.
15
+ 2. **Build.** Edit the selected definition, its view and linked Skill files.
16
+ Update `CHANGELOG.md`. Run `spaces build <dir> --space <key>`; it freezes source
17
+ and artifact bytes and validates the view contract and design.
18
+ 3. **Verify.** Run `spaces verify <dir> --space <key> --space-id <space-id>`.
19
+ This checks current action authorizations and renders explicit fictional
20
+ fixtures at 390px and 1440px with the shared read-only renderer. Provide exact
21
+ action/list/body/record fixtures. A denied read, write-on-load or failed width
22
+ is a failure, not a passing empty page. Inspect both locales and intended states.
23
+ 4. **Publish source.** Use `spaces deploy <dir> --space <key> --space-id <space-id>
24
+ --request-id <stable-id>`. Or `spaces preview` seals a candidate, and
25
+ `spaces promote <release-id> <dir>` publishes that exact candidate. Preview
26
+ authoring never silently gains live record-edit authority. Deployment updates
27
+ the selected Space, not siblings or the Store.
28
+ 5. **Read back.** Confirm published source revision and link with `spaces get` or
29
+ `views find --space-id`. Run `views render <view-link>` and inspect Markdown
30
+ plus the full-height screenshot. Check the affected interaction in the actual
31
+ Portal/required Desktop surface, in EN/FR at 390px and 1440px. Fixture success
32
+ does not prove data, access, collaboration or Site revocation.
33
+ 6. **Report.** Return the canonical view link and the exact completed boundary:
34
+ local-only, deployed/verified, deployed/unverified, failed-before-publication,
35
+ or outcome-unknown. After an uncertain response, read the same release/request
36
+ identity before retrying. Never bypass source checks with direct Storage writes.
37
+
38
+ ## Create without duplicates
39
+
40
+ Start locally with `spaces init`, then build. Discover/list existing Spaces before
41
+ creating the intended remote identity with `LOCAL_NOTIS_MANAGE_SPACE`. Use a stable
42
+ UUID and reconcile an uncertain creation. Read back its revision and resources,
43
+ then verify/deploy with `--space-id`. A source-created database is committed with
44
+ its main view in that publication; no separate provisional database is necessary.
46
45
 
47
46
  ## What the checks prove
48
47
 
49
- `build` validates the package, enforces design rules, and refreshes its embedded
50
- SDK. Automated `verify` checks every route at desktop (1280px) and phone (390px)
51
- widths, render errors, runtime calls, nested boxes, small text, lingering loading
52
- placeholders, and horizontal overflow. It uses a temporary server and browser;
53
- printed URLs or `--no-browser` are not passing verification. If tooling is missing,
54
- install it with `npm exec --yes --package agent-browser@latest -- agent-browser install`.
55
-
56
- Stub verification does not establish real account data, permissions, host layout,
57
- or visual quality. Live verification exercises the authenticated runtime but still
58
- uses the harness. The final installed-app check establishes the result inside Notis.
59
- If that surface cannot be inspected, say so rather than claim it passed. No extra
60
- approval round is needed for an already-authorized check.
61
-
62
- `apps screenshot` supports declared scenarios and stub fixtures, including
63
- `theme: 'dark'`; `--raw` gives uncomposited captures. Store listing screenshots are
64
- not required for an ordinary Workspace update.
65
-
66
- ## Special cases — read only when relevant
67
-
68
- ### Publication privacy and portability gate
69
-
70
- Before submitting or updating a Store listing:
71
-
72
- 1. Inventory the exact public source archive, listing text/media, database schemas,
73
- starter rows, bundled skills (including scripts/references), and automation
74
- prompts/configuration. Review their actual contents, not just filenames or
75
- a passing secret scan. Exclude personal records, transcripts, health/journal
76
- history, customer details, private repository/account identifiers, credentials,
77
- local paths, run logs, and private links. Do not merely replace a person's name
78
- in otherwise real data. Rebuild examples from wholly fictional scenarios.
79
- 2. Keep live owner databases structure-only (`seedDocuments` absent or false).
80
- Opting in seeds the database's live rows, including folders: it is not a
81
- fixture selector. Use fictional screenshot fixtures and an explicit, idempotent
82
- onboarding demo-data option. If starter rows are needed in the install snapshot,
83
- publish only from an isolated, verified fictional dataset; never replace or
84
- delete the owner's real data to prepare a submission. When the user asks for
85
- examples to come with the app, include them in that verified install snapshot:
86
- screenshot fixtures or an optional onboarding seed step do not satisfy this.
87
- 3. Bundle the full dependency closure of every app/automation skill, including
88
- referenced helpers and resources. Remove private account-specific defaults;
89
- resolve the installer's databases, connections, repository, timezone and
90
- delivery choices at runtime. Preserve existing owner's schedules and data.
91
- 4. Declare a source-owned onboarding skill. It must work through available MCP
92
- tools or the Notis CLI in any agent harness, without requiring Notis Manager,
93
- vendor-specific delegation tools, hidden local files, or publisher access.
94
- Discover tools and inspect schemas before calls; reconcile existing resources
95
- before creating them. Obtain installer choices before enabling automation or
96
- external actions. Installing examples must not activate external deliveries.
97
- 5. Test onboarding as an independent harness-native proof agent using an account
98
- isolated from the publisher, then rerun to prove no duplicates. Exercise each
99
- route and its interactions with fictional data, including empty/error states.
100
- Record exact identities, versions, results and run-created resource cleanup in
101
- a private Notis document owned by the app, never only in local files; never use
102
- owner records as writable test fixtures.
103
- For bundled starter-data claims, install the actual published listing into an
104
- empty test account and read back its rows before onboarding or any manual data
105
- writes. Confirm the installed listing version and remapped relations; do not
106
- substitute an editable-source deployment for this Store-install test.
107
- 6. Inspect the final submitted snapshot and media after packaging. Record the
108
- privacy audit and verification against that exact source version in the same
109
- private Notis document. Any unknown
110
- provenance, missing dependency, untested onboarding or suspected personal data
111
- blocks submission until resolved. Never equate submission with review approval
112
- or Store publication.
113
-
114
- ### Unreleased container or stale checkout
115
-
116
- An unreleased container has no source to pull. Recover its original local source,
117
- or scaffold only if it cannot be recovered; verify the exact ID and scope and use
118
- `apps link <app-id> <dir> --expected-version 0`. Reuse the container after a failed
119
- first release; do not duplicate or automatically delete it. If another release
120
- has appeared, pull it into a fresh directory and reapply the intended edits without
121
- replacing its deployment base. Link/deploy guards must reject races and conflicts.
122
-
123
- ### Restore an older source
124
-
125
- Pull the current release into a fresh checkout and the historical source into a
126
- separate folder (`apps pull <id> <dir> --source-version <n>`). Replace source without
127
- replacing the current `.notis` link/base, then check and deploy as a new release.
128
- Preserve app/database/skill IDs. Never decrement versions or imply that source
129
- restoration undoes user data or external actions.
130
-
131
- ### Release history and Store publication
132
-
133
- Keep all release history in root `CHANGELOG.md`, newest first, with headings
134
- `## [Release title] - YYYY-MM-DD` (or `{PR_MERGE_DATE}` while unpublished). Do not add
135
- `versionNotes` to the config. App Details reads deployed history; the Store reads
136
- its published snapshot. Local edits must not change the published listing.
137
-
138
- `apps deploy` updates Workspace only. Use `apps publish --confirm-ready` only after
139
- the user explicitly approves the current App Details and Store listing. Deploy the
140
- exact approved source first. Respect listing completeness, visibility, version,
141
- and pending-review guards. A public submission includes editable source, Store
142
- assets, source-declared database schemas, and only explicitly opted-in starter
143
- rows. Do not hand-edit `notis-listing.json` or strip files to pass review; fix the
144
- source, redeploy, and resubmit. To start from a Store app, use `apps init --from
145
- <slug>`; `apps pull` is for an accessible installed app, not a Store listing clone.
48
+ | Check | Proves | Does not prove |
49
+ | --- | --- | --- |
50
+ | Build | Current selected source/artifact and schema syntax | Runtime data or access |
51
+ | Verify | Frozen fixture rendering and current declarations/authorizations | Live record values, publication, sharing or visual quality |
52
+ | Live render | Read-only current view data, Markdown and full-height image | Mutation behavior or collaborative editing |
53
+ | Installed interaction | The specific checked host behavior and data readback | Store installation or production release |
54
+
55
+ `notis spaces screenshot <view-link> --width 390` captures an already deployed
56
+ view. `notis views render` saves Markdown and/or PNG with a new output path; read
57
+ the artifact, not only the command's success message. Missing output is not proof.
58
+
59
+ ## Skills, resources and concurrent edits
60
+
61
+ Pulled Skill folders, `resources.json` and source share one release transaction.
62
+ Only changed content is sent; unrelated remote edits stay intact. A conflict
63
+ publishes nothing: pull fresh source into a new directory, merge the intended
64
+ change and preserve the new lock. Stale source/record/binding revisions must not
65
+ be replaced with guessed current values merely to force a write.
66
+
67
+ To restore older source, pull current identity and the desired historical
68
+ revision separately. Reapply the old content against the current lock and publish
69
+ a new revision. Source restoration does not revert user data or provider effects.
70
+
71
+ ## Publication privacy and portability gate
72
+
73
+ Before an explicitly authorized Store publication:
74
+
75
+ 1. Review the complete snapshot: source, listing, media, schema, selected starter
76
+ rows, linked Skills/helpers and automations. Exclude personal data, account
77
+ identifiers, credentials, local paths and private run logs. Use wholly fictional
78
+ fixtures; redacting a name from real private content is insufficient.
79
+ 2. Keep databases structure-only unless the user requested packaged examples.
80
+ Store `--starter` is an explicit set of record keys per database, not a fixture
81
+ selector. Never populate it from private notes, leads, history or folders.
82
+ 3. Package the full dependency closure. Resolve the installer's own resources and
83
+ connections; never keep publisher defaults. Preserve existing schedules and
84
+ local customizations. Installation must not activate external deliveries.
85
+ 4. Link a Set up Skill when setup is needed. It must work through native tools or
86
+ the CLI in any harness, reconcile existing resources and be safe to rerun.
87
+ 5. Use an independent isolated installer proof: install the exact listing version,
88
+ verify remapped main views/relations and any claimed starter rows before setup,
89
+ run setup twice, exercise fictional views and clean only run-created resources.
90
+ Record exact identities, versions, results and cleanup in a private Notis
91
+ record owned by the Space, never only in local files.
92
+ 6. Run `spaces store publish <space-id> --dry-run` and review its diff. Execute
93
+ only the authorized channel/publication, then read back the listing version
94
+ and review state. Record the privacy audit and verification against that exact
95
+ source revision in the same private record. Submission is not review approval
96
+ or public availability.
97
+
98
+ `spaces store update <install-id> --dry-run` exposes a three-way update plan.
99
+ Resolve each explicit conflict with `keep_mine` or `take_theirs`; retain unrelated
100
+ local changes. Store publication and installed source deployment remain separate.
101
+
102
+ ## Release history
103
+
104
+ Keep `CHANGELOG.md` newest first, with `## [Release title] - YYYY-MM-DD` headings
105
+ (or `{PR_MERGE_DATE}` before the release date is known). Source history belongs to
106
+ that Space; changing its local changelog does not change an already published
107
+ Store snapshot. Use the verified source revision, not the changelog title, as proof.
@@ -1,63 +1,116 @@
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), `header`, `meta`, `properties`, `width`; `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
+ It has no upload, collaboration credential, authoring controls or sharing mutation.
48
+ Preview source does not gain live record editing. No app-owned credentials or
49
+ filesystem URLs belong in component props.
50
+
51
+ ## Navigation
52
+
53
+ `useNotisNavigation()` exposes `toSpace(spaceId, {recordKey?, params?})` and
54
+ `toNamedSpace(alias, {recordKey?, params?})`. Prefer declared portable navigation
55
+ aliases for sibling destinations; the host resolves them under current access.
56
+ Use declared params for view state, for example `{params: {project: key, period: 'week'}}`.
57
+ The destination drops unknown params and authorizes referenced records. Changing
58
+ a slug cannot change identity. Agents cite current server-returned links.
59
+
60
+ ## Viewer-only exploration
61
+
62
+ `viewerReads: ['databases', 'skills']` permits read-only inspection of what the
63
+ signed-in viewer already reaches. It creates no shared grant. Use
64
+ `useViewerReadAvailable(family)`, `useViewerDatabases`, `useViewerSkills`, or
65
+ `useViewerRead(operation, input)`. Anonymous Sites cannot use these families.
66
+ Explicit synthetic `viewerReads` fixtures stand in for the viewer's reads offline.
67
+
68
+ ## The viewer's cloud computer
69
+
70
+ `cloudComputer: 'shell'` (or `'read'` for facts only) lets a page run one command
71
+ or write one file on the signed-in viewer's own cloud computer, after that viewer
72
+ allows it in the Portal prompt. Use `useCloudComputerShell()`: check `level`, call
73
+ `requestApproval()` when `approved` is false (either level; the facts of
74
+ `useCloudComputer()` are read again once allowed), then, when `available` (`shell`),
75
+ `run(command, options)` or
76
+ `upload({ path, content, content_encoding: 'base64', mode: 0o600 })`. Never put
77
+ secrets in a command; send them as upload content. A run is never repeated for one
78
+ request key: pass `requestId` (run option, or `request_id` in the upload) when the
79
+ page retries a run itself; `cloud_computer_already_ran` means it already ran. The
80
+ approval covers only the exact code the viewer allowed, so every new release asks again. Keep a fallback (a Manager
81
+ draft) for Sites, previews offline and viewers who do not allow it. Declare it only
82
+ when the page's core controls run on the cloud computer.
83
+
84
+ ## Visual data and Markdown
85
+
86
+ `<RenderChartData title columns rows>` adds a semantic table for the chart without
87
+ a second visible table. Give it the same labels/values used by the chart. The
88
+ renderer never guesses exact numbers from SVG/canvas geometry: a chart without
89
+ `RenderChartData` contributes only its accessible name to the Markdown.
90
+
91
+ An optional `markdown` source module exports a pure function of `{params, shown}`.
92
+ It must describe the rendered selection and its actual data. Ordinary rendering
93
+ extracts tables, lists, controls and visible document/HTML content automatically.
94
+
95
+ ## Host interactions and context
96
+
97
+ - `useHandover()` exposes `{handover, available, pending, error}`. Call a declared
98
+ linked Skill with `handover({skill, prompt})`; fall back when no agent UI exists.
99
+ - `useTopBarSearch` registers a host-owned search field. Do not duplicate host chrome.
100
+ - `useActiveResource` publishes the current resource; `useAgentContext`,
101
+ `NotisSelectionBoundary`, `NotisCommentBoundary` and `NotisCommentBox` support
102
+ explicit reference context. [Context sharing](context.md) owns the contract.
103
+ - `useCollectionInteractions`, selection components and `MultiSelectActionBar`
104
+ support native collection interactions. `Dialog` supplies themed top-layer
105
+ dialogs, focus handling and shortcut isolation.
106
+ - `MarkdownEditor` is for a view-owned Markdown draft/persistence adapter. Native
107
+ documents use `DocumentEditor` so collaboration and file authority stay with Notis.
108
+
109
+ ## Offline fixtures
110
+
111
+ Declare a `verificationFixtures` JSON source with `actions` and optional `context`,
112
+ `shown`, `viewerReads`, `documentBodies`, `recordViews`. Cases match exact action
113
+ inputs/list params. Record views use `{operation: 'record'|'html'|'report', record_key,
114
+ result}`; native record snapshots require `writable: false` and no authoring target.
115
+ Keep every fixture fictional and include every load-time read. Failed or missing
116
+ 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.