@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.
- package/README.md +421 -133
- package/bin/check-runtime.js +15 -0
- package/bin/notis.js +2 -0
- package/config/notis_app_boundary_rules.json +50 -0
- package/config/notis_app_design_rules.json +135 -0
- package/dist/agent-hooks/notis-agent-hook.mjs +19299 -0
- package/dist/base-skills/notis-apps/SKILL.md +72 -0
- package/dist/base-skills/notis-apps/references/architecture.md +167 -0
- package/dist/base-skills/notis-apps/references/context.md +81 -0
- package/dist/base-skills/notis-apps/references/design.md +178 -0
- package/dist/base-skills/notis-apps/references/reading.md +89 -0
- package/dist/base-skills/notis-apps/references/release.md +145 -0
- package/dist/base-skills/notis-apps/references/sdk.md +63 -0
- package/dist/base-skills/notis-apps/references/troubleshooting.md +23 -0
- package/dist/base-skills/notis-cli/SKILL.md +154 -0
- package/dist/base-skills/notis-cli/references/app-delivery.md +18 -0
- package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
- package/dist/base-skills/notis-cli/references/native-databases.md +21 -0
- package/dist/base-skills/notis-cli/references/tool-examples.md +56 -0
- package/dist/base-skills/notis-cli/references/troubleshooting.md +39 -0
- package/dist/base-skills/notis-query/SKILL.md +67 -0
- package/dist/base-skills/notis-query/references/database-discovery.md +70 -0
- package/dist/base-skills/notis-query/references/documents.md +50 -0
- package/dist/base-skills/notis-query/references/query.md +543 -0
- package/{template/packages/notis-sdk → dist/sdk}/package.json +14 -4
- package/dist/sdk/src/agentContext.ts +36 -0
- package/dist/sdk/src/components/Dialog.tsx +46 -0
- package/dist/sdk/src/components/DocumentEditor.tsx +103 -0
- package/dist/sdk/src/components/Markdown.tsx +60 -0
- package/dist/sdk/src/components/MarkdownEditor.tsx +121 -0
- package/dist/sdk/src/components/MultiSelectActionBar.tsx +285 -0
- package/dist/sdk/src/components/MultiSelectCheckbox.tsx +97 -0
- package/dist/sdk/src/components/MultiSelectDragOverlay.tsx +39 -0
- package/dist/sdk/src/components/NotisCommentBoundary.tsx +172 -0
- package/dist/sdk/src/components/NotisSelectionBoundary.tsx +59 -0
- package/dist/sdk/src/components/ShortcutHints.tsx +56 -0
- package/dist/sdk/src/components/Skeleton.tsx +24 -0
- package/dist/sdk/src/config.ts +261 -0
- package/dist/sdk/src/documents.ts +256 -0
- package/dist/sdk/src/hooks/useActiveResource.ts +19 -0
- package/dist/sdk/src/hooks/useAgentContext.ts +23 -0
- package/dist/sdk/src/hooks/useCloudComputer.ts +64 -0
- package/dist/sdk/src/hooks/useCollectionInteractions.ts +838 -0
- package/dist/sdk/src/hooks/useDatabaseSchema.ts +49 -0
- package/dist/sdk/src/hooks/useDatabaseSubscription.ts +76 -0
- package/dist/sdk/src/hooks/useDocument.ts +43 -0
- package/dist/sdk/src/hooks/useDocuments.ts +84 -0
- package/dist/sdk/src/hooks/useHandover.ts +77 -0
- package/dist/sdk/src/hooks/useLongPressSelection.ts +79 -0
- package/dist/sdk/src/hooks/useMultiSelect.ts +95 -0
- package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useNotis.ts +12 -4
- package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useNotisNavigation.ts +11 -8
- package/dist/sdk/src/hooks/useQuery.ts +71 -0
- package/dist/sdk/src/hooks/useTool.ts +65 -0
- package/dist/sdk/src/hooks/useToolQuery.ts +12 -0
- package/dist/sdk/src/hooks/useTopBarSearch.ts +81 -0
- package/dist/sdk/src/hooks/useUpsertDocument.ts +95 -0
- package/dist/sdk/src/index.ts +164 -0
- package/dist/sdk/src/interactions/actions.ts +59 -0
- package/dist/sdk/src/interactions/shortcuts.tsx +726 -0
- package/dist/sdk/src/interactions/visibility.ts +13 -0
- package/dist/sdk/src/interactions.ts +45 -0
- package/dist/sdk/src/provider.tsx +44 -0
- package/dist/sdk/src/queryCache.ts +170 -0
- package/dist/sdk/src/runtime.ts +465 -0
- package/dist/sdk/src/styles.css +266 -0
- package/dist/sdk/src/tailwind.ts +66 -0
- package/dist/sdk/src/vite.ts +73 -0
- package/dist/skill-sync/index.js +1753 -0
- package/dist/skill-sync/index.js.map +7 -0
- package/dist/skill-sync-worker.mjs +3113 -0
- package/package.json +18 -7
- package/skills/notis-apps/cli.md +299 -0
- package/skills/notis-cli/AGENT_INSTRUCTIONS.md +39 -0
- package/skills/notis-onboarding/BRIEF.md +129 -0
- package/skills/notis-query/cli.md +39 -0
- package/src/agent-hook-entry.js +5 -0
- package/src/cli.js +294 -25
- package/src/command-specs/agents.js +392 -0
- package/src/command-specs/apps.js +1483 -203
- package/src/command-specs/auth.js +114 -137
- package/src/command-specs/diagnostics.js +730 -0
- package/src/command-specs/handover.js +374 -0
- package/src/command-specs/helpers.js +85 -82
- package/src/command-specs/index.js +25 -6
- package/src/command-specs/meta.js +150 -18
- package/src/command-specs/onboarding.js +290 -0
- package/src/command-specs/profile.js +358 -0
- package/src/command-specs/reports.js +97 -0
- package/src/command-specs/skills.js +75 -0
- package/src/command-specs/smoke.js +386 -0
- package/src/command-specs/tools.js +455 -139
- package/src/runtime/agent-browser.js +677 -0
- package/src/runtime/agent-memory-state.js +126 -0
- package/src/runtime/agent-setup.js +383 -0
- package/src/runtime/app-boundary-validator.js +404 -0
- package/src/runtime/app-changelog.js +79 -0
- package/src/runtime/app-platform.js +2652 -205
- package/src/runtime/app-registry-scaffolds.js +367 -0
- package/src/runtime/app-test-server.js +293 -0
- package/src/runtime/assets/store-screenshot-dark.png +0 -0
- package/src/runtime/auth-recovery.js +110 -0
- package/src/runtime/base-skills.d.ts +20 -0
- package/src/runtime/base-skills.js +167 -0
- package/src/runtime/channel.js +133 -0
- package/src/runtime/delegated-context.js +68 -0
- package/src/runtime/errors.js +1 -0
- package/src/runtime/git.js +233 -0
- package/src/runtime/login-listener.js +15 -0
- package/src/runtime/oauth.js +2622 -0
- package/src/runtime/output.js +37 -5
- package/src/runtime/ports.js +31 -0
- package/src/runtime/profiles.js +906 -55
- package/src/runtime/screenshot-framing.js +85 -0
- package/src/runtime/skill-sync/cloud-client.ts +99 -0
- package/src/runtime/skill-sync/index.ts +786 -0
- package/src/runtime/skill-sync/local-scanner.ts +1151 -0
- package/src/runtime/skill-sync/symlink-manager.ts +433 -0
- package/src/runtime/skill-sync/sync-plan.ts +47 -0
- package/src/runtime/skill-sync/types.ts +131 -0
- package/src/runtime/skill-sync/write-cloud-skill.ts +50 -0
- package/src/runtime/skill-sync-service.js +109 -0
- package/src/runtime/store-screenshot.js +146 -0
- package/src/runtime/sync-skills.d.ts +37 -0
- package/src/runtime/sync-skills.js +231 -0
- package/src/runtime/telemetry.js +92 -0
- package/src/runtime/transport.js +324 -45
- package/src/skill-sync-worker-entry.js +2 -0
- package/src/skill-sync-worker.js +50 -0
- package/template/.harness/index.html.tmpl +435 -0
- package/template/CHANGELOG.md +5 -0
- package/template/app/globals.css +28 -3
- package/template/app/layout.tsx +6 -3
- package/template/app/page.tsx +49 -42
- package/template/components/page-heading.tsx +23 -0
- package/template/components/ui/badge.tsx +7 -4
- package/template/components/ui/button.tsx +1 -1
- package/template/components/ui/card.tsx +24 -11
- package/template/components/ui/native-select.tsx +24 -0
- package/template/notis.config.ts +24 -6
- package/template/package-lock.json +3642 -0
- package/template/package.json +19 -16
- package/template/postcss.config.mjs +1 -1
- package/template/tailwind.config.ts +1 -6
- package/template/tsconfig.json +1 -0
- package/src/command-specs/db.js +0 -163
- package/src/runtime/app-preview-server.js +0 -312
- package/template/packages/notis-sdk/src/config.ts +0 -48
- package/template/packages/notis-sdk/src/helpers.ts +0 -131
- package/template/packages/notis-sdk/src/hooks/useAppState.ts +0 -50
- package/template/packages/notis-sdk/src/hooks/useCollectionItem.ts +0 -58
- package/template/packages/notis-sdk/src/hooks/useDatabase.ts +0 -87
- package/template/packages/notis-sdk/src/hooks/useDocument.ts +0 -61
- package/template/packages/notis-sdk/src/hooks/useTool.ts +0 -49
- package/template/packages/notis-sdk/src/hooks/useUpsertDocument.ts +0 -57
- package/template/packages/notis-sdk/src/index.ts +0 -47
- package/template/packages/notis-sdk/src/provider.tsx +0 -44
- package/template/packages/notis-sdk/src/runtime.ts +0 -159
- package/template/packages/notis-sdk/src/styles.css +0 -123
- package/template/packages/notis-sdk/src/vite.ts +0 -54
- package/template/packages/notis-sdk/tsconfig.json +0 -15
- /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useBackend.ts +0 -0
- /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useTools.ts +0 -0
- /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
|
+
}
|