@notis_ai/cli 0.2.0-beta.19.1 → 0.2.0-beta.191.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 (164) hide show
  1. package/README.md +421 -133
  2. package/bin/check-runtime.js +15 -0
  3. package/bin/notis.js +2 -0
  4. package/config/notis_app_boundary_rules.json +50 -0
  5. package/config/notis_app_design_rules.json +135 -0
  6. package/dist/agent-hooks/notis-agent-hook.mjs +19299 -0
  7. package/dist/base-skills/notis-apps/SKILL.md +72 -0
  8. package/dist/base-skills/notis-apps/references/architecture.md +167 -0
  9. package/dist/base-skills/notis-apps/references/context.md +81 -0
  10. package/dist/base-skills/notis-apps/references/design.md +178 -0
  11. package/dist/base-skills/notis-apps/references/reading.md +89 -0
  12. package/dist/base-skills/notis-apps/references/release.md +145 -0
  13. package/dist/base-skills/notis-apps/references/sdk.md +63 -0
  14. package/dist/base-skills/notis-apps/references/troubleshooting.md +23 -0
  15. package/dist/base-skills/notis-cli/SKILL.md +154 -0
  16. package/dist/base-skills/notis-cli/references/app-delivery.md +18 -0
  17. package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
  18. package/dist/base-skills/notis-cli/references/native-databases.md +21 -0
  19. package/dist/base-skills/notis-cli/references/tool-examples.md +56 -0
  20. package/dist/base-skills/notis-cli/references/troubleshooting.md +39 -0
  21. package/dist/base-skills/notis-query/SKILL.md +67 -0
  22. package/dist/base-skills/notis-query/references/database-discovery.md +70 -0
  23. package/dist/base-skills/notis-query/references/documents.md +50 -0
  24. package/dist/base-skills/notis-query/references/query.md +543 -0
  25. package/{template/packages/notis-sdk → dist/sdk}/package.json +14 -4
  26. package/dist/sdk/src/agentContext.ts +36 -0
  27. package/dist/sdk/src/components/Dialog.tsx +46 -0
  28. package/dist/sdk/src/components/DocumentEditor.tsx +103 -0
  29. package/dist/sdk/src/components/Markdown.tsx +60 -0
  30. package/dist/sdk/src/components/MarkdownEditor.tsx +121 -0
  31. package/dist/sdk/src/components/MultiSelectActionBar.tsx +285 -0
  32. package/dist/sdk/src/components/MultiSelectCheckbox.tsx +97 -0
  33. package/dist/sdk/src/components/MultiSelectDragOverlay.tsx +39 -0
  34. package/dist/sdk/src/components/NotisCommentBoundary.tsx +172 -0
  35. package/dist/sdk/src/components/NotisSelectionBoundary.tsx +59 -0
  36. package/dist/sdk/src/components/ShortcutHints.tsx +56 -0
  37. package/dist/sdk/src/components/Skeleton.tsx +24 -0
  38. package/dist/sdk/src/config.ts +261 -0
  39. package/dist/sdk/src/documents.ts +256 -0
  40. package/dist/sdk/src/hooks/useActiveResource.ts +19 -0
  41. package/dist/sdk/src/hooks/useAgentContext.ts +23 -0
  42. package/dist/sdk/src/hooks/useCloudComputer.ts +64 -0
  43. package/dist/sdk/src/hooks/useCollectionInteractions.ts +838 -0
  44. package/dist/sdk/src/hooks/useDatabaseSchema.ts +49 -0
  45. package/dist/sdk/src/hooks/useDatabaseSubscription.ts +76 -0
  46. package/dist/sdk/src/hooks/useDocument.ts +43 -0
  47. package/dist/sdk/src/hooks/useDocuments.ts +84 -0
  48. package/dist/sdk/src/hooks/useHandover.ts +77 -0
  49. package/dist/sdk/src/hooks/useLongPressSelection.ts +79 -0
  50. package/dist/sdk/src/hooks/useMultiSelect.ts +95 -0
  51. package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useNotis.ts +12 -4
  52. package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useNotisNavigation.ts +11 -8
  53. package/dist/sdk/src/hooks/useQuery.ts +71 -0
  54. package/dist/sdk/src/hooks/useTool.ts +65 -0
  55. package/dist/sdk/src/hooks/useToolQuery.ts +12 -0
  56. package/dist/sdk/src/hooks/useTopBarSearch.ts +81 -0
  57. package/dist/sdk/src/hooks/useUpsertDocument.ts +95 -0
  58. package/dist/sdk/src/index.ts +164 -0
  59. package/dist/sdk/src/interactions/actions.ts +59 -0
  60. package/dist/sdk/src/interactions/shortcuts.tsx +726 -0
  61. package/dist/sdk/src/interactions/visibility.ts +13 -0
  62. package/dist/sdk/src/interactions.ts +45 -0
  63. package/dist/sdk/src/provider.tsx +44 -0
  64. package/dist/sdk/src/queryCache.ts +170 -0
  65. package/dist/sdk/src/runtime.ts +465 -0
  66. package/dist/sdk/src/styles.css +266 -0
  67. package/dist/sdk/src/tailwind.ts +66 -0
  68. package/dist/sdk/src/vite.ts +73 -0
  69. package/dist/skill-sync/index.js +1753 -0
  70. package/dist/skill-sync/index.js.map +7 -0
  71. package/dist/skill-sync-worker.mjs +3113 -0
  72. package/package.json +18 -7
  73. package/skills/notis-apps/cli.md +299 -0
  74. package/skills/notis-cli/AGENT_INSTRUCTIONS.md +39 -0
  75. package/skills/notis-onboarding/BRIEF.md +129 -0
  76. package/skills/notis-query/cli.md +39 -0
  77. package/src/agent-hook-entry.js +5 -0
  78. package/src/cli.js +294 -25
  79. package/src/command-specs/agents.js +392 -0
  80. package/src/command-specs/apps.js +1483 -203
  81. package/src/command-specs/auth.js +114 -137
  82. package/src/command-specs/diagnostics.js +730 -0
  83. package/src/command-specs/handover.js +374 -0
  84. package/src/command-specs/helpers.js +85 -82
  85. package/src/command-specs/index.js +25 -6
  86. package/src/command-specs/meta.js +150 -18
  87. package/src/command-specs/onboarding.js +290 -0
  88. package/src/command-specs/profile.js +358 -0
  89. package/src/command-specs/reports.js +97 -0
  90. package/src/command-specs/skills.js +75 -0
  91. package/src/command-specs/smoke.js +386 -0
  92. package/src/command-specs/tools.js +455 -139
  93. package/src/runtime/agent-browser.js +677 -0
  94. package/src/runtime/agent-memory-state.js +126 -0
  95. package/src/runtime/agent-setup.js +383 -0
  96. package/src/runtime/app-boundary-validator.js +404 -0
  97. package/src/runtime/app-changelog.js +79 -0
  98. package/src/runtime/app-platform.js +2652 -205
  99. package/src/runtime/app-registry-scaffolds.js +367 -0
  100. package/src/runtime/app-test-server.js +293 -0
  101. package/src/runtime/assets/store-screenshot-dark.png +0 -0
  102. package/src/runtime/auth-recovery.js +110 -0
  103. package/src/runtime/base-skills.d.ts +20 -0
  104. package/src/runtime/base-skills.js +167 -0
  105. package/src/runtime/channel.js +133 -0
  106. package/src/runtime/delegated-context.js +68 -0
  107. package/src/runtime/errors.js +1 -0
  108. package/src/runtime/git.js +233 -0
  109. package/src/runtime/login-listener.js +15 -0
  110. package/src/runtime/oauth.js +2622 -0
  111. package/src/runtime/output.js +37 -5
  112. package/src/runtime/ports.js +31 -0
  113. package/src/runtime/profiles.js +906 -55
  114. package/src/runtime/screenshot-framing.js +85 -0
  115. package/src/runtime/skill-sync/cloud-client.ts +99 -0
  116. package/src/runtime/skill-sync/index.ts +786 -0
  117. package/src/runtime/skill-sync/local-scanner.ts +1151 -0
  118. package/src/runtime/skill-sync/symlink-manager.ts +433 -0
  119. package/src/runtime/skill-sync/sync-plan.ts +47 -0
  120. package/src/runtime/skill-sync/types.ts +131 -0
  121. package/src/runtime/skill-sync/write-cloud-skill.ts +50 -0
  122. package/src/runtime/skill-sync-service.js +109 -0
  123. package/src/runtime/store-screenshot.js +146 -0
  124. package/src/runtime/sync-skills.d.ts +37 -0
  125. package/src/runtime/sync-skills.js +231 -0
  126. package/src/runtime/telemetry.js +92 -0
  127. package/src/runtime/transport.js +324 -45
  128. package/src/skill-sync-worker-entry.js +2 -0
  129. package/src/skill-sync-worker.js +50 -0
  130. package/template/.harness/index.html.tmpl +435 -0
  131. package/template/CHANGELOG.md +5 -0
  132. package/template/app/globals.css +28 -3
  133. package/template/app/layout.tsx +6 -3
  134. package/template/app/page.tsx +49 -42
  135. package/template/components/page-heading.tsx +23 -0
  136. package/template/components/ui/badge.tsx +7 -4
  137. package/template/components/ui/button.tsx +1 -1
  138. package/template/components/ui/card.tsx +24 -11
  139. package/template/components/ui/native-select.tsx +24 -0
  140. package/template/notis.config.ts +24 -6
  141. package/template/package-lock.json +3642 -0
  142. package/template/package.json +19 -16
  143. package/template/postcss.config.mjs +1 -1
  144. package/template/tailwind.config.ts +1 -6
  145. package/template/tsconfig.json +1 -0
  146. package/src/command-specs/db.js +0 -163
  147. package/src/runtime/app-preview-server.js +0 -312
  148. package/template/packages/notis-sdk/src/config.ts +0 -48
  149. package/template/packages/notis-sdk/src/helpers.ts +0 -131
  150. package/template/packages/notis-sdk/src/hooks/useAppState.ts +0 -50
  151. package/template/packages/notis-sdk/src/hooks/useCollectionItem.ts +0 -58
  152. package/template/packages/notis-sdk/src/hooks/useDatabase.ts +0 -87
  153. package/template/packages/notis-sdk/src/hooks/useDocument.ts +0 -61
  154. package/template/packages/notis-sdk/src/hooks/useTool.ts +0 -49
  155. package/template/packages/notis-sdk/src/hooks/useUpsertDocument.ts +0 -57
  156. package/template/packages/notis-sdk/src/index.ts +0 -47
  157. package/template/packages/notis-sdk/src/provider.tsx +0 -44
  158. package/template/packages/notis-sdk/src/runtime.ts +0 -159
  159. package/template/packages/notis-sdk/src/styles.css +0 -123
  160. package/template/packages/notis-sdk/src/vite.ts +0 -54
  161. package/template/packages/notis-sdk/tsconfig.json +0 -15
  162. /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useBackend.ts +0 -0
  163. /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useTools.ts +0 -0
  164. /package/{template/packages/notis-sdk → dist/sdk}/src/ui.ts +0 -0
@@ -0,0 +1,85 @@
1
+ /** Runs only in the capture harness, never in an installed app. */
2
+ export function measureScreenshotContent() {
3
+ const root = document.getElementById('root');
4
+ if (!root) return null;
5
+ const viewportWidth = document.documentElement.clientWidth;
6
+ const visible = (element) => {
7
+ const rect = element.getBoundingClientRect();
8
+ const style = getComputedStyle(element);
9
+ return rect.width > 0 && rect.height > 0
10
+ && style.display !== 'none' && style.visibility !== 'hidden';
11
+ };
12
+
13
+ // Follow layout wrappers only while they contain the entire visible app.
14
+ // Never select one column, card, or control out of a multi-pane layout.
15
+ let node = root;
16
+ let content = null;
17
+ while (node) {
18
+ const hasOwnText = Array.from(node.childNodes).some(
19
+ (child) => child.nodeType === 3 && child.textContent.trim(),
20
+ );
21
+ const children = Array.from(node.children).filter(visible);
22
+ if (hasOwnText || children.length !== 1) break;
23
+ node = children[0];
24
+ const rect = node.getBoundingClientRect();
25
+ if (['DIV', 'MAIN', 'SECTION', 'ARTICLE', 'FORM'].includes(node.tagName)
26
+ && rect.width >= 320 && rect.height >= 160
27
+ && rect.width < viewportWidth * 0.9) {
28
+ content = node;
29
+ }
30
+ }
31
+ if (!content) return null;
32
+ content.setAttribute('data-notis-screenshot-content', '');
33
+ const rect = content.getBoundingClientRect();
34
+ return {
35
+ selector: '[data-notis-screenshot-content]',
36
+ width: rect.width,
37
+ height: rect.height,
38
+ viewport_width: viewportWidth,
39
+ };
40
+ }
41
+
42
+ export const MEASURE_SCREENSHOT_CONTENT_SCRIPT = `(${measureScreenshotContent.toString()})()`;
43
+
44
+ /** Keep long pages readable, and rasterize bounded views at their final width. */
45
+ export function contentCapturePlan(bounds, viewport, outputWidth, outputHeight) {
46
+ const aspect = outputWidth / outputHeight;
47
+ if (bounds.width / bounds.height < aspect * 0.75) {
48
+ const width = Math.max(768, Math.ceil((bounds.width + 32) / 8) * 8);
49
+ return { focus: false, width, height: Math.round(width / aspect), scale: outputWidth / width };
50
+ }
51
+ return {
52
+ focus: true,
53
+ width: viewport.width,
54
+ height: viewport.height,
55
+ scale: Math.min(4, outputWidth / bounds.width),
56
+ };
57
+ }
58
+
59
+ export function safeViewportHeight(rectangles, height) {
60
+ const crossing = rectangles.filter((rect) => rect.top < height && rect.bottom > height
61
+ && rect.top >= height * 0.85);
62
+ return crossing.length
63
+ ? Math.max(Math.ceil(height * 0.85), Math.floor(Math.min(...crossing.map((rect) => rect.top)) - 8))
64
+ : height;
65
+ }
66
+
67
+ // End a long-page viewport in whitespace rather than through a text line or
68
+ // control. Only geometry leaves the browser; no page text is returned.
69
+ export const SAFE_VIEWPORT_HEIGHT_SCRIPT = `(() => {
70
+ const root = document.getElementById('root');
71
+ if (!root) return innerHeight;
72
+ const rects = [];
73
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
74
+ let node;
75
+ while ((node = walker.nextNode())) {
76
+ if (!node.textContent.trim() || getComputedStyle(node.parentElement).visibility !== 'visible') continue;
77
+ const range = document.createRange(); range.selectNodeContents(node);
78
+ for (const rect of range.getClientRects()) rects.push({ top: rect.top, bottom: rect.bottom });
79
+ }
80
+ for (const control of root.querySelectorAll('button,input,select,textarea')) {
81
+ const rect = control.getBoundingClientRect();
82
+ rects.push({ top: rect.top, bottom: rect.bottom });
83
+ }
84
+ return (${safeViewportHeight.toString()})(rects, innerHeight);
85
+ })()`;
@@ -0,0 +1,99 @@
1
+ import { createSkillBundleBase64 } from './local-scanner';
2
+ import type { AgentTargets, LocalSkill, SyncPullResponse, SyncPushResponse, SyncSettings } from './types';
3
+
4
+ type JsonBody = Record<string, unknown> | undefined;
5
+
6
+ async function requestJson<T>(
7
+ url: string,
8
+ jwt: string,
9
+ options: { method?: string; body?: JsonBody } = {},
10
+ ): Promise<T> {
11
+ const response = await fetch(url, {
12
+ signal: AbortSignal.timeout(90_000),
13
+ method: options.method || 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ Authorization: `Bearer ${jwt}`,
17
+ },
18
+ body: options.body ? JSON.stringify(options.body) : undefined,
19
+ });
20
+
21
+ if (!response.ok) {
22
+ const text = await response.text();
23
+ throw new Error(`${options.method || 'POST'} ${url} → ${response.status}: ${text}`);
24
+ }
25
+
26
+ return response.json() as Promise<T>;
27
+ }
28
+
29
+ export async function fetchSyncSettings(serverUrl: string, jwt: string): Promise<SyncSettings> {
30
+ return requestJson<SyncSettings>(`${serverUrl}/portal_skills/sync-settings`, jwt, {
31
+ body: {},
32
+ });
33
+ }
34
+
35
+ export async function pullSkills(serverUrl: string, jwt: string): Promise<SyncPullResponse> {
36
+ return requestJson<SyncPullResponse>(`${serverUrl}/portal_skills/sync-pull`, jwt, {
37
+ body: {},
38
+ });
39
+ }
40
+
41
+ export async function pushChangedSkills(
42
+ serverUrl: string,
43
+ jwt: string,
44
+ changedSkills: LocalSkill[],
45
+ ): Promise<SyncPushResponse> {
46
+ const payloadSkills = await Promise.all(changedSkills.map(async (skill) => ({
47
+ name: skill.name,
48
+ description: skill.description,
49
+ skill_md: skill.skillMd,
50
+ source_url: skill.sourceUrl,
51
+ folder_hash: skill.folderHash,
52
+ bundle_base64: await createSkillBundleBase64(skill),
53
+ })));
54
+
55
+ return requestJson<SyncPushResponse>(`${serverUrl}/portal_skills/sync-push`, jwt, {
56
+ body: {
57
+ skills: payloadSkills,
58
+ },
59
+ });
60
+ }
61
+
62
+ export async function downloadSkillBundle(bundleUrl: string): Promise<Buffer> {
63
+ const response = await fetch(bundleUrl, { signal: AbortSignal.timeout(90_000) });
64
+ if (!response.ok) {
65
+ const text = await response.text();
66
+ throw new Error(`GET ${bundleUrl} → ${response.status}: ${text}`);
67
+ }
68
+
69
+ return Buffer.from(await response.arrayBuffer());
70
+ }
71
+
72
+ export async function updateAgentTargets(
73
+ serverUrl: string,
74
+ jwt: string,
75
+ skillId: string,
76
+ targets: Partial<AgentTargets>,
77
+ expectedUpdatedAt?: string,
78
+ ): Promise<{ success: boolean; agent_targets: AgentTargets; updated_at?: string }> {
79
+ return requestJson<{ success: boolean; agent_targets: AgentTargets; updated_at?: string }>(`${serverUrl}/portal_skills/agent-targets`, jwt, {
80
+ method: 'PATCH',
81
+ body: {
82
+ skill_id: skillId,
83
+ agent_targets: targets,
84
+ ...(expectedUpdatedAt ? { expected_updated_at: expectedUpdatedAt } : {}),
85
+ },
86
+ });
87
+ }
88
+
89
+ // Install (enabled=true) or uninstall (enabled=false) the curated computer-use
90
+ // skill for the user, matching the desktop app's "Desktop Use" toggle.
91
+ export async function setComputerUseSkill(
92
+ serverUrl: string,
93
+ jwt: string,
94
+ enabled: boolean,
95
+ ): Promise<{ installed: boolean }> {
96
+ return requestJson<{ installed: boolean }>(`${serverUrl}/portal_skills/desktop-use`, jwt, {
97
+ body: { enabled, name: 'notis-desktop-use' },
98
+ });
99
+ }