@notis_ai/cli 0.2.0-beta.159.1 → 0.2.0-beta.160.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 +94 -0
- package/dist/agent-hooks/notis-agent-hook.mjs +180 -56
- package/dist/base-skills/notis-apps/SKILL.md +21 -2
- package/dist/base-skills/notis-apps/references/context.md +81 -0
- package/dist/base-skills/notis-apps/references/reading.md +89 -0
- package/dist/base-skills/notis-apps/references/sdk.md +1 -0
- package/dist/skill-sync/index.js +25 -6
- package/dist/skill-sync/index.js.map +2 -2
- package/dist/skill-sync-worker.mjs +2 -1
- package/package.json +1 -1
- package/skills/notis-apps/cli.md +89 -0
- package/skills/notis-onboarding/BRIEF.md +6 -5
- package/src/command-specs/apps.js +1 -1
- package/src/command-specs/index.js +3 -0
- package/src/command-specs/onboarding.js +1 -1
- package/src/command-specs/reports.js +86 -0
- package/src/runtime/skill-sync/index.ts +31 -4
- package/template/packages/sdk/src/agentContext.ts +36 -0
- package/template/packages/sdk/src/components/NotisCommentBoundary.tsx +172 -0
- package/template/packages/sdk/src/components/NotisSelectionBoundary.tsx +9 -5
- package/template/packages/sdk/src/hooks/useAgentContext.ts +23 -0
- package/template/packages/sdk/src/index.ts +5 -0
- package/template/packages/sdk/src/runtime.ts +9 -2
- package/template/packages/sdk/src/tailwind.ts +56 -0
- package/template/packages/sdk/src/vite.ts +2 -0
- package/template/tailwind.config.ts +1 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentContextContent, AgentContextItem, AgentContextSource } from './agentContext';
|
|
1
2
|
/**
|
|
2
3
|
* NotisRuntime is the bridge between app code running in the browser and the
|
|
3
4
|
* Notis platform. The portal owns the runtime and injects it through
|
|
@@ -197,7 +198,8 @@ export type ContextAttributeValue = string | number | boolean | null;
|
|
|
197
198
|
* app/view provenance onto this value before it reaches chat, so apps only
|
|
198
199
|
* describe their own resource rather than impersonating another surface.
|
|
199
200
|
*/
|
|
200
|
-
export interface ContextResource {
|
|
201
|
+
export interface ContextResource extends AgentContextContent {
|
|
202
|
+
additionalContext?: Record<string, unknown>;
|
|
201
203
|
id: string;
|
|
202
204
|
kind: string;
|
|
203
205
|
label: string;
|
|
@@ -211,7 +213,8 @@ export interface ContextResource {
|
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
/** A quote copied from an app, kept separate from the user's prompt. */
|
|
214
|
-
export interface ContextSelection {
|
|
216
|
+
export interface ContextSelection extends AgentContextContent {
|
|
217
|
+
source?: AgentContextSource;
|
|
215
218
|
id: string;
|
|
216
219
|
text: string;
|
|
217
220
|
resource?: ContextResource | null;
|
|
@@ -371,10 +374,14 @@ export interface NotisRuntime {
|
|
|
371
374
|
ui?: NotisRuntimeUI;
|
|
372
375
|
|
|
373
376
|
/** Publish or clear the focused resource inside the current app view. */
|
|
377
|
+
contextSource?: AgentContextSource;
|
|
374
378
|
publishActiveResource?(resource: ContextResource | null): void;
|
|
375
379
|
|
|
376
380
|
/** Remember a copied quote so the host can recover it across iframe paste. */
|
|
377
381
|
captureContextSelection?(selection: ContextSelection): void;
|
|
382
|
+
addContext?(item: AgentContextItem): Promise<boolean>;
|
|
383
|
+
updateContext?(item: AgentContextItem): Promise<boolean>;
|
|
384
|
+
removeContext?(id: string): Promise<boolean>;
|
|
378
385
|
|
|
379
386
|
/**
|
|
380
387
|
* Subscribe to changes on an app-owned database. Returns an unsubscribe.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Build-only SDK content discovery. Author configuration and PostCSS plugins stay intact. */
|
|
2
|
+
import { existsSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
export function notisTailwindContent() {
|
|
8
|
+
let root = process.cwd();
|
|
9
|
+
let temporary: string | undefined;
|
|
10
|
+
const wrappers = new Map<string, string>();
|
|
11
|
+
const cleanup = () => {
|
|
12
|
+
if (temporary) rmSync(temporary, { recursive: true, force: true });
|
|
13
|
+
temporary = undefined;
|
|
14
|
+
wrappers.clear();
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
name: 'notis-sdk-tailwind-content',
|
|
18
|
+
enforce: 'pre' as const,
|
|
19
|
+
configResolved(config: { root: string }) { root = config.root; },
|
|
20
|
+
transform(source: string, id: string) {
|
|
21
|
+
if (!id.split('?')[0].endsWith('.css') || !/@tailwind\s/.test(source)) return null;
|
|
22
|
+
const explicit = source.match(/@config\s+(['"])(.*?)\1\s*;/);
|
|
23
|
+
const config = explicit
|
|
24
|
+
? resolve(dirname(id.split('?')[0]), explicit[2])
|
|
25
|
+
: ['ts', 'js', 'cjs', 'mjs'].map(ext => join(root, `tailwind.config.${ext}`)).find(existsSync);
|
|
26
|
+
if (!config) return null;
|
|
27
|
+
let wrapper = wrappers.get(config);
|
|
28
|
+
if (!wrapper) {
|
|
29
|
+
temporary ||= mkdtempSync(join(tmpdir(), 'notis-tailwind-'));
|
|
30
|
+
wrapper = join(temporary, `config-${wrappers.size}.ts`);
|
|
31
|
+
const sdkGlob = join(dirname(fileURLToPath(import.meta.url)), '**/*.{ts,tsx}').replaceAll('\\', '/');
|
|
32
|
+
writeFileSync(wrapper, `import config from ${JSON.stringify(config)};
|
|
33
|
+
import { resolve } from 'node:path';
|
|
34
|
+
const content = config.content || [];
|
|
35
|
+
const files = Array.isArray(content) ? content : (content.files || []);
|
|
36
|
+
const base = ${JSON.stringify(root)};
|
|
37
|
+
const relativeBase = ${JSON.stringify(dirname(config))};
|
|
38
|
+
export default { ...config, content: {
|
|
39
|
+
...(Array.isArray(content) ? {} : content),
|
|
40
|
+
relative: false,
|
|
41
|
+
files: [...files.map(file => typeof file !== 'string' ? file :
|
|
42
|
+
(file.startsWith('!') ? '!' : '') + resolve(content.relative ? relativeBase : base, file.replace(/^!/, ''))),
|
|
43
|
+
${JSON.stringify(sdkGlob)}],
|
|
44
|
+
} };
|
|
45
|
+
`);
|
|
46
|
+
wrappers.set(config, wrapper);
|
|
47
|
+
}
|
|
48
|
+
const directive = `@config ${JSON.stringify('./' + relative(dirname(id.split('?')[0]), wrapper).replaceAll('\\', '/'))};`;
|
|
49
|
+
// Imports must remain before @config. Vite resolves them before PostCSS.
|
|
50
|
+
const code = explicit ? source.replace(explicit[0], directive) : `${source}\n${directive}\n`;
|
|
51
|
+
return { code, map: null };
|
|
52
|
+
},
|
|
53
|
+
closeBundle: cleanup,
|
|
54
|
+
closeWatcher: cleanup,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import type { NotisAppConfig } from './config';
|
|
17
|
+
import { notisTailwindContent } from './tailwind';
|
|
17
18
|
|
|
18
19
|
export function notisViteConfig(appConfig: NotisAppConfig) {
|
|
19
20
|
return {
|
|
20
21
|
plugins: [
|
|
22
|
+
notisTailwindContent(),
|
|
21
23
|
// @vitejs/plugin-react is added by the consumer's vite.config.ts
|
|
22
24
|
// or auto-detected. We provide the config shape only.
|
|
23
25
|
],
|