@notis_ai/cli 0.2.0-beta.35.1 → 0.2.0-beta.48.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 (84) hide show
  1. package/README.md +84 -83
  2. package/dist/scaffolds/notis-database/app/globals.css +44 -0
  3. package/dist/scaffolds/notis-database/app/page.tsx +1091 -0
  4. package/dist/scaffolds/notis-database/components/ui/table.tsx +120 -0
  5. package/dist/scaffolds/notis-database/index.html +12 -0
  6. package/dist/scaffolds/notis-database/lib/types.ts +134 -0
  7. package/dist/scaffolds/notis-database/metadata/cover.png +0 -0
  8. package/dist/scaffolds/notis-database/metadata/screenshot-1.png +0 -0
  9. package/dist/scaffolds/notis-database/metadata/screenshot-2.png +0 -0
  10. package/dist/scaffolds/notis-database/metadata/screenshot-3.png +0 -0
  11. package/dist/scaffolds/notis-database/notis.config.ts +27 -0
  12. package/dist/scaffolds/notis-database/package.json +31 -0
  13. package/dist/scaffolds/notis-database/src/dev-main.tsx +23 -0
  14. package/dist/scaffolds/notis-database/src/mock-runtime.ts +557 -0
  15. package/dist/scaffolds/notis-database/tailwind.config.ts +59 -0
  16. package/dist/scaffolds/{notes → notis-database}/tsconfig.json +2 -1
  17. package/dist/scaffolds/notis-database/vite.config.ts +22 -0
  18. package/dist/scaffolds/notis-notes/app/layout.tsx +6 -0
  19. package/dist/scaffolds/{notes → notis-notes}/app/page.tsx +783 -80
  20. package/dist/scaffolds/notis-notes/components/ui/badge.tsx +28 -0
  21. package/dist/scaffolds/notis-notes/components/ui/button.tsx +53 -0
  22. package/dist/scaffolds/notis-notes/components/ui/card.tsx +56 -0
  23. package/dist/scaffolds/notis-notes/components.json +20 -0
  24. package/dist/scaffolds/notis-notes/lib/utils.ts +6 -0
  25. package/dist/scaffolds/notis-notes/metadata/cover.png +0 -0
  26. package/dist/scaffolds/notis-notes/metadata/screenshot-1.png +0 -0
  27. package/dist/scaffolds/notis-notes/metadata/screenshot-2.png +0 -0
  28. package/dist/scaffolds/notis-notes/metadata/screenshot-3.png +0 -0
  29. package/dist/scaffolds/{notes → notis-notes}/notis.config.ts +12 -7
  30. package/dist/scaffolds/{notes → notis-notes}/package.json +3 -3
  31. package/dist/scaffolds/notis-notes/postcss.config.mjs +8 -0
  32. package/dist/scaffolds/notis-notes/tsconfig.json +23 -0
  33. package/dist/scaffolds/notis-random/README.md +33 -0
  34. package/dist/scaffolds/notis-random/app/globals.css +11 -0
  35. package/dist/scaffolds/notis-random/app/history/page.tsx +66 -0
  36. package/dist/scaffolds/notis-random/app/layout.tsx +7 -0
  37. package/dist/scaffolds/notis-random/app/page.tsx +222 -0
  38. package/dist/scaffolds/notis-random/index.html +12 -0
  39. package/dist/scaffolds/notis-random/lib/notis-tools.ts +109 -0
  40. package/dist/scaffolds/notis-random/lib/rng.ts +42 -0
  41. package/dist/scaffolds/notis-random/lib/roll-record.ts +102 -0
  42. package/dist/scaffolds/notis-random/lib/utils.ts +25 -0
  43. package/dist/scaffolds/notis-random/metadata/cover.png +0 -0
  44. package/dist/scaffolds/notis-random/metadata/screenshot-1.png +0 -0
  45. package/dist/scaffolds/notis-random/metadata/screenshot-2.png +0 -0
  46. package/dist/scaffolds/notis-random/metadata/screenshot-3.png +0 -0
  47. package/dist/scaffolds/notis-random/notis.config.ts +43 -0
  48. package/dist/scaffolds/notis-random/package.json +32 -0
  49. package/dist/scaffolds/notis-random/postcss.config.mjs +6 -0
  50. package/dist/scaffolds/notis-random/src/dev-main.tsx +70 -0
  51. package/dist/scaffolds/notis-random/src/mock-runtime.ts +128 -0
  52. package/dist/scaffolds/notis-random/tailwind.config.ts +43 -0
  53. package/dist/scaffolds/notis-random/tsconfig.json +23 -0
  54. package/dist/scaffolds/notis-random/vite.config.ts +11 -0
  55. package/dist/scaffolds.json +27 -4
  56. package/package.json +1 -1
  57. package/skills/notis-apps/SKILL.md +27 -33
  58. package/skills/notis-apps/cli.md +51 -51
  59. package/skills/notis-cli/SKILL.md +66 -71
  60. package/skills/notis-query/cli.md +11 -11
  61. package/src/cli.js +10 -1
  62. package/src/command-specs/apps.js +9 -9
  63. package/src/command-specs/helpers.js +69 -46
  64. package/src/command-specs/meta.js +6 -6
  65. package/src/command-specs/tools.js +159 -50
  66. package/src/runtime/app-dev-server.js +2 -2
  67. package/src/runtime/app-platform.js +28 -0
  68. package/src/runtime/transport.js +122 -37
  69. package/template/packages/sdk/package.json +6 -0
  70. package/template/packages/sdk/src/hooks/useDatabase.ts +76 -0
  71. package/template/packages/sdk/src/hooks/useNotis.ts +10 -6
  72. package/template/packages/sdk/src/hooks/useUpsertDocument.ts +50 -0
  73. package/template/packages/sdk/src/index.ts +9 -1
  74. package/template/packages/sdk/src/runtime.ts +83 -2
  75. /package/dist/scaffolds/{notes → notis-database}/app/layout.tsx +0 -0
  76. /package/dist/scaffolds/{notes → notis-database}/components/ui/badge.tsx +0 -0
  77. /package/dist/scaffolds/{notes → notis-database}/components/ui/button.tsx +0 -0
  78. /package/dist/scaffolds/{notes → notis-database}/components/ui/card.tsx +0 -0
  79. /package/dist/scaffolds/{notes → notis-database}/components.json +0 -0
  80. /package/dist/scaffolds/{notes → notis-database}/lib/utils.ts +0 -0
  81. /package/dist/scaffolds/{notes → notis-database}/postcss.config.mjs +0 -0
  82. /package/dist/scaffolds/{notes → notis-notes}/app/globals.css +0 -0
  83. /package/dist/scaffolds/{notes → notis-notes}/tailwind.config.ts +0 -0
  84. /package/dist/scaffolds/{notes → notis-notes}/vite.config.ts +0 -0
@@ -0,0 +1,76 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useState } from 'react';
4
+ import { useNotisRuntime } from '../provider';
5
+ import type { DocumentRecord, QueryFilter } from '../runtime';
6
+
7
+ interface UseDatabaseOptions {
8
+ filter?: QueryFilter;
9
+ pageSize?: number;
10
+ offset?: number;
11
+ enabled?: boolean;
12
+ }
13
+
14
+ interface UseDatabaseResult {
15
+ documents: DocumentRecord[];
16
+ loading: boolean;
17
+ error: Error | null;
18
+ refetch: () => void;
19
+ }
20
+
21
+ export function useDatabase(
22
+ databaseSlug: string,
23
+ options: UseDatabaseOptions = {},
24
+ ): UseDatabaseResult {
25
+ const runtime = useNotisRuntime();
26
+ const [documents, setDocuments] = useState<DocumentRecord[]>([]);
27
+ const [loading, setLoading] = useState(true);
28
+ const [error, setError] = useState<Error | null>(null);
29
+ const [fetchKey, setFetchKey] = useState(0);
30
+
31
+ const enabled = options.enabled !== false;
32
+ const filterKey = JSON.stringify(options.filter ?? null);
33
+
34
+ const refetch = useCallback(() => {
35
+ setFetchKey((key) => key + 1);
36
+ }, []);
37
+
38
+ useEffect(() => {
39
+ if (!runtime || !enabled) {
40
+ setLoading(false);
41
+ return;
42
+ }
43
+
44
+ let cancelled = false;
45
+ setLoading(true);
46
+ setError(null);
47
+
48
+ runtime
49
+ .queryDatabase({
50
+ databaseSlug,
51
+ query: {
52
+ ...options.filter,
53
+ page_size: options.pageSize,
54
+ },
55
+ offset: options.offset,
56
+ })
57
+ .then((result) => {
58
+ if (!cancelled) {
59
+ setDocuments(result.documents);
60
+ setLoading(false);
61
+ }
62
+ })
63
+ .catch((err) => {
64
+ if (!cancelled) {
65
+ setError(err instanceof Error ? err : new Error(String(err)));
66
+ setLoading(false);
67
+ }
68
+ });
69
+
70
+ return () => {
71
+ cancelled = true;
72
+ };
73
+ }, [runtime, databaseSlug, fetchKey, enabled, filterKey, options.offset, options.pageSize]);
74
+
75
+ return { documents, loading, error, refetch };
76
+ }
@@ -1,22 +1,25 @@
1
1
  'use client';
2
2
 
3
3
  import { useNotisRuntime } from '../provider';
4
- import type { AppDescriptor, NotisRuntimeContext, RouteDescriptor } from '../runtime';
4
+ import type { AppDescriptor, CollectionItemDetail, DatabaseDescriptor, RouteDescriptor } from '../runtime';
5
5
 
6
6
  interface NotisContext {
7
7
  /** App metadata (id, name, icon, description). Null before runtime loads. */
8
8
  app: AppDescriptor | null;
9
9
  /** Current route descriptor. Null before runtime loads. */
10
10
  route: RouteDescriptor | null;
11
- /** Generic route/app context supplied by the portal. */
12
- context: NotisRuntimeContext;
11
+ /** Databases declared by this app. Empty before runtime loads. */
12
+ databases: DatabaseDescriptor[];
13
+ /** Selected collection item for the current route, when applicable. */
14
+ collectionItem: CollectionItemDetail | null;
13
15
  /** Whether the runtime is loaded and available. */
14
16
  ready: boolean;
15
17
  }
16
18
 
17
19
  /**
18
- * Access app-level metadata, the current route, and generic portal context.
19
- * Returns safe defaults when the portal runtime is not available.
20
+ * Access app-level metadata, the current route, declared databases, and the
21
+ * selected collection item. Returns safe defaults when the portal runtime is
22
+ * not available.
20
23
  */
21
24
  export function useNotis(): NotisContext {
22
25
  const runtime = useNotisRuntime();
@@ -24,7 +27,8 @@ export function useNotis(): NotisContext {
24
27
  return {
25
28
  app: runtime?.app ?? null,
26
29
  route: runtime?.route ?? null,
27
- context: runtime?.context ?? {},
30
+ databases: runtime?.databases ?? [],
31
+ collectionItem: runtime?.context?.collectionItem ?? null,
28
32
  ready: runtime !== null,
29
33
  };
30
34
  }
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useState } from 'react';
4
+ import { useNotisRuntime } from '../provider';
5
+ import type { DocumentRecord } from '../runtime';
6
+
7
+ interface UpsertArgs {
8
+ databaseSlug: string;
9
+ documentId?: string;
10
+ title?: string;
11
+ properties?: Record<string, unknown>;
12
+ contentBlocknote?: Array<Record<string, unknown>> | null;
13
+ }
14
+
15
+ interface UseUpsertDocumentResult {
16
+ upsert: (args: UpsertArgs) => Promise<DocumentRecord>;
17
+ loading: boolean;
18
+ error: Error | null;
19
+ }
20
+
21
+ export function useUpsertDocument(): UseUpsertDocumentResult {
22
+ const runtime = useNotisRuntime();
23
+ const [loading, setLoading] = useState(false);
24
+ const [error, setError] = useState<Error | null>(null);
25
+
26
+ const upsert = useCallback(
27
+ async (args: UpsertArgs): Promise<DocumentRecord> => {
28
+ if (!runtime) {
29
+ throw new Error('Notis runtime not available. Ensure NotisProvider is mounted.');
30
+ }
31
+
32
+ setLoading(true);
33
+ setError(null);
34
+
35
+ try {
36
+ const result = await runtime.upsertDocument(args);
37
+ return result.document;
38
+ } catch (err) {
39
+ const e = err instanceof Error ? err : new Error(String(err));
40
+ setError(e);
41
+ throw e;
42
+ } finally {
43
+ setLoading(false);
44
+ }
45
+ },
46
+ [runtime],
47
+ );
48
+
49
+ return { upsert, loading, error };
50
+ }
@@ -7,10 +7,12 @@
7
7
  */
8
8
 
9
9
  // Provider
10
- export { NotisProvider } from './provider';
10
+ export { NotisProvider, useNotisRuntime } from './provider';
11
11
 
12
12
  // Hooks
13
13
  export { useNotis } from './hooks/useNotis';
14
+ export { useDatabase } from './hooks/useDatabase';
15
+ export { useUpsertDocument } from './hooks/useUpsertDocument';
14
16
  export { useTool } from './hooks/useTool';
15
17
  export type { ToolCallState, UseToolResult } from './hooks/useTool';
16
18
  export { useTools } from './hooks/useTools';
@@ -38,8 +40,14 @@ export type { MultiSelectDragOverlayProps } from './components/MultiSelectDragOv
38
40
  // Types (re-exported for convenience)
39
41
  export type {
40
42
  AppDescriptor,
43
+ CollectionItem,
44
+ CollectionItemDetail,
45
+ DatabaseDescriptor,
46
+ DatabaseProperty,
47
+ DocumentRecord,
41
48
  NotisRuntime,
42
49
  NotisRuntimeContext,
50
+ QueryFilter,
43
51
  RouteDescriptor,
44
52
  ToolDescriptor,
45
53
  ToolInputSchema,
@@ -7,6 +7,39 @@
7
7
  * (useTool, useNotis, etc.) which read from the NotisProvider context.
8
8
  */
9
9
 
10
+ // ---------------------------------------------------------------------------
11
+ // Database types
12
+ // ---------------------------------------------------------------------------
13
+
14
+ export interface DatabaseProperty {
15
+ name: string;
16
+ type: 'title' | 'rich_text' | 'number' | 'checkbox' | 'date' | 'select' | 'multi_select' | 'status' | 'relation' | 'formula' | 'files';
17
+ description?: string;
18
+ options?: Array<{ name: string; id?: string }>;
19
+ }
20
+
21
+ export interface DatabaseDescriptor {
22
+ slug: string;
23
+ title: string;
24
+ description?: string | null;
25
+ icon?: string | null;
26
+ properties: DatabaseProperty[];
27
+ }
28
+
29
+ export interface DocumentRecord {
30
+ id: string;
31
+ title: string;
32
+ properties: Record<string, unknown>;
33
+ icon?: string | null;
34
+ cover?: string | null;
35
+ databaseSlug?: string;
36
+ contentBlocknote?: Array<Record<string, unknown>> | null;
37
+ contentMarkdown?: string | null;
38
+ plainText?: string | null;
39
+ createdAt?: string | null;
40
+ lastEditedTime?: string | null;
41
+ }
42
+
10
43
  // ---------------------------------------------------------------------------
11
44
  // Tool types
12
45
  // ---------------------------------------------------------------------------
@@ -30,7 +63,25 @@ export interface RouteDescriptor {
30
63
  icon?: string | null;
31
64
  parentSlug?: string | null;
32
65
  default?: boolean;
33
- collection?: Record<string, unknown> | null;
66
+ collection?: {
67
+ database: string;
68
+ titleProperty: string;
69
+ parentProperty?: string | null;
70
+ sidebar?: {
71
+ mode: 'flat-list' | 'tree';
72
+ allowCreate: boolean;
73
+ } | null;
74
+ } | null;
75
+ }
76
+
77
+ export interface CollectionItem {
78
+ id: string;
79
+ title: string;
80
+ icon?: string | null;
81
+ }
82
+
83
+ export interface CollectionItemDetail extends CollectionItem {
84
+ properties: Record<string, unknown>;
34
85
  }
35
86
 
36
87
  // ---------------------------------------------------------------------------
@@ -44,7 +95,22 @@ export interface AppDescriptor {
44
95
  description?: string | null;
45
96
  }
46
97
 
47
- export type NotisRuntimeContext = Record<string, unknown>;
98
+ export interface QueryFilter {
99
+ filters?: Array<{
100
+ property: string;
101
+ operator: string;
102
+ value: unknown;
103
+ }>;
104
+ sorts?: Array<{
105
+ property: string;
106
+ direction: 'asc' | 'desc';
107
+ }>;
108
+ page_size?: number;
109
+ }
110
+
111
+ export interface NotisRuntimeContext {
112
+ collectionItem?: CollectionItemDetail | null;
113
+ }
48
114
 
49
115
  // ---------------------------------------------------------------------------
50
116
  // NotisRuntime
@@ -53,6 +119,7 @@ export type NotisRuntimeContext = Record<string, unknown>;
53
119
  export interface NotisRuntime {
54
120
  app: AppDescriptor;
55
121
  route: RouteDescriptor;
122
+ databases: DatabaseDescriptor[];
56
123
  context: NotisRuntimeContext;
57
124
 
58
125
  navigate?: (payload: { kind: string; [key: string]: unknown }) => void;
@@ -72,6 +139,20 @@ export interface NotisRuntime {
72
139
  listTools(): Promise<ToolDescriptor[]>;
73
140
  callTool<TResult = unknown>(name: string, args?: Record<string, unknown>): Promise<TResult>;
74
141
 
142
+ queryDatabase(args: {
143
+ databaseSlug: string;
144
+ query?: QueryFilter;
145
+ offset?: number;
146
+ }): Promise<{ documents: DocumentRecord[] }>;
147
+
148
+ upsertDocument(args: {
149
+ databaseSlug: string;
150
+ documentId?: string;
151
+ title?: string;
152
+ properties?: Record<string, unknown>;
153
+ contentBlocknote?: Array<Record<string, unknown>> | null;
154
+ }): Promise<{ status: string; document: DocumentRecord }>;
155
+
75
156
  request(path: string, options?: {
76
157
  method?: string;
77
158
  headers?: Record<string, string>;