create-coline-app 2.3.0 → 2.5.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 (32) hide show
  1. package/AGENTS.md +26 -2
  2. package/README.md +51 -4
  3. package/assets/preview-host.ts +130 -0
  4. package/bin/_run.mjs +11 -2
  5. package/package.json +8 -4
  6. package/src/check.ts +46 -0
  7. package/src/cli.test.ts +112 -6
  8. package/src/cli.ts +12 -1
  9. package/src/client-build.ts +50 -0
  10. package/src/dev.ts +6 -5
  11. package/src/preview-capture.ts +101 -0
  12. package/src/preview.ts +189 -0
  13. package/src/push.ts +8 -47
  14. package/src/scaffold.ts +6 -0
  15. package/templates/backendless/.agents/skills/coline-app-development/SKILL.md +30 -64
  16. package/templates/backendless/.agents/skills/coline-app-development/references/live-records.md +53 -0
  17. package/templates/backendless/.agents/skills/coline-ui-design/SKILL.md +89 -0
  18. package/templates/backendless/.agents/skills/coline-ui-design/assets/board.png +0 -0
  19. package/templates/backendless/.agents/skills/coline-ui-design/assets/settings.png +0 -0
  20. package/templates/backendless/.agents/skills/coline-ui-design/assets/triage.png +0 -0
  21. package/templates/backendless/.agents/skills/coline-ui-review/SKILL.md +47 -0
  22. package/templates/backendless/AGENTS.md +70 -158
  23. package/templates/backendless/CLAUDE.md +1 -6
  24. package/templates/backendless/README.md +22 -29
  25. package/templates/backendless/app.config.ts +12 -8
  26. package/templates/backendless/app.css +84 -0
  27. package/templates/backendless/examples/board.tsx +168 -0
  28. package/templates/backendless/examples/settings.tsx +113 -0
  29. package/templates/backendless/examples/triage.tsx +243 -0
  30. package/templates/backendless/main.tsx +198 -66
  31. package/templates/backendless/package.json +10 -5
  32. package/templates/backendless/preview.seed.ts +26 -0
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: coline-ui-review
3
+ description: Review and finish a Coline App UI with local browser previews, screenshots, keyboard interaction, and light/dark/mobile states. Use after UI changes or when fixing clipping, generic layouts, broken styling, or inaccessible controls.
4
+ ---
5
+
6
+ # Coline UI review — experimental
7
+
8
+ 1. Run `npm test` and `npm run check`. Fix new failures before visual review.
9
+ 2. Run `npm run preview`. Exercise the main action, search/filter, open/close,
10
+ save/discard, and recovery. Tab through the UI; confirm visible focus and
11
+ labelled fields. A screenshot does not prove an action works.
12
+ 3. Install Chromium if needed: `npx playwright install chromium`. Then run
13
+ `npm run screenshots`. For a reference pattern append `-- --pattern triage`
14
+ (or board/settings). Read `.coline/screenshots/report.json`.
15
+ 4. View at least ready desktop light/dark and mobile, plus affected empty/error
16
+ states. Check title/action hierarchy, awkward wrapping, clipped content,
17
+ cramped controls, contrast, and whether repeated cards should be rows.
18
+ Compare against the selected example or the user's visual reference.
19
+ 5. Fix the largest concrete problem, recapture the affected view, and inspect
20
+ again. Keep local scrolling intentional. Long content must not push actions
21
+ off screen. Respect reduced motion; don't animate routine data refreshes.
22
+ 6. Report what was actually tested and any limitation. The screenshot command
23
+ catches browser errors, whole-page overflow, and unlabelled form fields;
24
+ it does not grade beauty, certify accessibility, or prove hosted behavior.
25
+
26
+ The preview's data resets on reload. Its state selector injects capability faults;
27
+ if your page bypasses capabilities or swallows errors, that state may expose a
28
+ bug rather than a useful screen. Example layouts handle state locally to make
29
+ reference states inspectable. Test permissions/persistence on the real host
30
+ separately when that work is in scope.
31
+
32
+ Do not claim visual review if you cannot view the images. Give the image paths
33
+ and explain what remains for someone with vision/browser tools to check.
34
+
35
+
36
+ Keep preview cleanup scoped. The screenshot command closes its own server. For
37
+ interactive QA, retain the terminal session or exact child-process PID you started
38
+ and stop only that process. Never use broad `pkill -f` or `killall` commands: other
39
+ apps may be running previews at the same time.
40
+
41
+ Check dialog buttons in both themes: page-scoped CSS variables do not inherit
42
+ into portals. Exercise form submission, Escape/close, tab keyboard navigation,
43
+ and filter menu selection. Capture every actual app view, not only the default
44
+ preview tab. Inspect motion and reduced-motion behavior as well as still images.
45
+ Keep the number of attached images within the model/provider's request limit;
46
+ review a small representative set, compact context before accumulating more,
47
+ and record provider failures separately from app failures.
@@ -1,169 +1,81 @@
1
- # AGENTS.md — building __APP_NAME__ (a Coline App)
1
+ # Building __APP_NAME__
2
2
 
3
- This is a self-contained Coline App project. Read this file before changing
4
- code. The public SDK, UI package, tests, and this guide are the contract; do
5
- not inspect the Coline product repository or private worktrees to discover how
6
- to build an app.
3
+ Use the installed public packages, this project, and its examples. Do not inspect
4
+ the private Coline product repository to discover app APIs. User instructions
5
+ and the product's existing design take precedence over starter preferences.
7
6
 
8
- ## Project model
7
+ ## Start here
9
8
 
10
- Coline hosts the app logic. There is no server, database, auth flow, or deploy
11
- step in this project:
9
+ - `app.config.ts`: hosted manifest, permissions, tools, file types, tree fallbacks.
10
+ - `main.tsx`: sandboxed React home/editor inside `ColineAppProvider`.
11
+ - `app.css`: app styling. Tailwind v4 and ordinary CSS compile automatically.
12
+ - `preview.seed.ts`: disposable local fixtures; never imported by production entries.
13
+ - `examples/`: working UI references with local state, not persistent business data.
14
+ - `app.test.ts`: logic tests using the public in-memory workspace.
12
15
 
13
- - `app.config.ts` is the hosted logic bundle: manifest, permissions, tools,
14
- file types, tree handlers, and capability calls.
15
- - `main.tsx` is the React client entry for the starter home surface. It runs in
16
- a locked sandbox iframe and uses `@colineapp/ui`.
17
- - `app.test.ts` runs the logic against `createTestWorkspace`, an in-memory
18
- capability fake. It does not need a Coline server.
19
- - `.agents/skills/coline-app-development/SKILL.md` is the detailed task
20
- workflow for agents that support skills.
16
+ For UI work, read `.agents/skills/coline-ui-design/SKILL.md`, choose the closest
17
+ example, then use `.agents/skills/coline-ui-review/SKILL.md` to finish. These
18
+ experimental skills are plain Markdown: follow them even if your agent has no
19
+ skill loader. Development details: `.agents/skills/coline-app-development/SKILL.md`.
21
20
 
22
- ## Commands
21
+ ## Working loop
23
22
 
24
23
  ```sh
25
24
  npm install
26
- npm run typecheck
27
25
  npm test
28
-
29
- # after local checks pass and the user has supplied these variables:
30
- npx coline-app dev --internal
31
- npx coline-app push --internal
32
- ```
33
-
34
- `COLINE_BASE_URL` selects the Coline instance and `COLINE_API_KEY` must be a
35
- workspace API key with `apps.write`. The CLI uploads `app.config.ts` as a
36
- logic bundle and submits `main.tsx` plus app `.ts`, `.tsx`, and `.css` source
37
- when the manifest declares a React surface. It never uploads `node_modules`.
38
-
39
- ## Public package contract
40
-
41
- Use only these app-facing entry points:
42
-
43
- ```ts
44
- import { z } from "zod/v4";
45
- import { defineApp, defineFileType, defineTool, ui } from "@colineapp/sdk/v2";
46
- import { createTestWorkspace } from "@colineapp/sdk/testing";
47
- ```
48
-
49
- For React:
50
-
51
- ```tsx
52
- import { createRoot } from "react-dom/client";
53
- import { ColineAppProvider, useColine, useColineQuery } from "@colineapp/ui";
54
- import "@colineapp/ui/styles.css";
55
- ```
56
-
57
- The scaffold installs the SDK, UI, React, ReactDOM, and their type packages.
58
- Do not replace them with private workspace paths or a second bridge.
59
-
60
- ## Manifest and permissions
61
-
62
- Keep permissions minimal. Common permissions include:
63
-
64
- | Permission | Use |
65
- | --- | --- |
66
- | `storage.app` | App-private key/value and typed record collections |
67
- | `files.read` / `files.write` | Read or create workspace files |
68
- | `ai.tools` | Expose app tools to Kairo |
69
- | `members.read` | Read workspace member summaries |
70
- | `search.index` / `search.query` | Index or query workspace search |
71
- | `network.external` | Use `coline.net.fetch` for allowlisted hosts |
72
-
73
- Tool effects are enforced ceilings, not labels:
74
-
75
- - `read` for reads only
76
- - `write` for ordinary mutations
77
- - `destructive` for irreversible or deletion-like actions
78
- - `external` for outbound side effects
79
-
80
- Every tool input is a Zod schema and every tool name is prefixed with the app
81
- key (`__APP_KEY__.operation`).
82
-
83
- ## Capability patterns
84
-
85
- ```ts
86
- interface Decision {
87
- title: string;
88
- status: "proposed" | "decided";
89
- }
90
-
91
- const decisions = context.coline.storage.collection<Decision>("decisions");
92
- const created = await decisions.insert({ title: "Use Postgres", status: "decided" });
93
- const page = await decisions.query({
94
- where: { status: "decided" },
95
- orderBy: "title",
96
- order: "asc",
97
- limit: 50,
98
- });
99
- ```
100
-
101
- Collection `where` is exact-match on top-level fields. Records are envelopes
102
- with the user data under `.data`. Keep pages bounded and filter contains,
103
- search, or range conditions in app code.
104
-
105
- File capabilities include `list`, `get`, `create`, `update`, `trash`,
106
- `getDocument`, and `updateDocument`. Navigation includes `openFile`,
107
- `openAppHome`, `navigate`, and `openReference`.
108
-
109
- ## UI tiers
110
-
111
- Tree UI is native and works in previews, inline surfaces, mobile, and Kairo
112
- cards:
113
-
114
- ```ts
115
- return ui.stack([
116
- ui.heading("Decisions", { level: 1 }),
117
- ui.text("No decisions yet.", { tone: "muted" }),
118
- ]);
119
- ```
120
-
121
- The starter home is React with a tree fallback for mobile:
122
-
123
- ```ts
124
- surfaces: {
125
- home: {
126
- tier: "react",
127
- entry: "main.tsx",
128
- mobile: { tier: "tree" },
129
- },
130
- }
26
+ npm run check
27
+ npm run preview
28
+ # Other working screen references:
29
+ npm run preview -- --pattern triage
30
+ npm run preview -- --pattern board
31
+ npm run preview -- --pattern settings
32
+ # Install Chromium once for captures:
33
+ npx playwright install chromium
34
+ npm run screenshots
131
35
  ```
132
36
 
133
- In `main.tsx`, put the app under `ColineAppProvider`. Call capabilities only
134
- through `useColine()`, and use `useColineQuery(loader, deps)` for bounded
135
- loading/error/refetch state. The host supplies theme tokens and dark mode.
136
- Use classes such as `bg-background`, `text-foreground`,
137
- `text-muted-foreground`, and the exported UI components.
138
-
139
- Sandbox restrictions are real: no `fetch`, localStorage, cookies, credentials,
140
- or direct Coline API routes. External access goes through `coline.net.fetch`
141
- and a manifest allowlist.
142
-
143
- ## Testing workflow
144
-
145
- ```ts
146
- const workspace = createTestWorkspace(app);
147
- const result = await workspace.invokeTool("__APP_KEY__.create_note", {
148
- title: "Hello",
149
- });
150
- expect(result.card).not.toBeNull();
151
- expect(workspace.files.byType("__APP_KEY__.note")).toHaveLength(1);
152
- const tree = await workspace.renderHome();
153
- ```
154
-
155
- Test tools and tree handlers without a server. React client behavior is
156
- covered by the typecheck and the hosted dev loop after the logic tests pass.
157
- Keep explicit loading, empty, and error states in every async React view.
158
-
159
- ## Agent boundaries
160
-
161
- - Do not read `/Users/radin/coline-app`, any `*.worktrees` directory, or
162
- first-party app code to understand this public API.
163
- - Do not add dependencies until checking whether the installed SDK/UI already
164
- provides the capability or component.
165
- - Do not invent signatures from a README snippet: use the installed package
166
- declarations when a detail is unclear, then update this guide if the public
167
- contract is missing.
168
- - Keep changes inside this generated app. Ask the user before changing the
169
- platform or publishing packages.
37
+ Preview uses simulated data, requires no credentials, resets on reload, and
38
+ reloads when source changes. Theme and state selectors expose ready, empty,
39
+ error, loading, and permission-denied states. Screenshots and a mechanical
40
+ browser report go in `.coline/screenshots`. Inspect the pictures and exercise
41
+ controls: passing checks cannot prove that a UI looks good.
42
+ Stop only the preview terminal session/PID you started; never kill processes by
43
+ a shared name. The screenshot command cleans up its own server.
44
+
45
+ `npm run dev -- --internal` and `npm run push -- --internal` upload to Coline.
46
+ They need `COLINE_API_KEY` with `apps.write`; `COLINE_BASE_URL` selects the host.
47
+ Use these when publishing is in the user's scope. Local preview is not proof of
48
+ hosted authorization, persistence, multiplayer, delivery, or performance.
49
+
50
+ ## Build with the public contract
51
+
52
+ Use `@colineapp/sdk/v2`, `@colineapp/sdk/testing`, and `@colineapp/ui`.
53
+ Import UI styles, then `./app.css`. Use complete utility class strings;
54
+ `bg-${tone}` cannot be discovered by Tailwind. Use a fixed class map instead.
55
+ The CLI bundles installed browser-compatible dependencies, CSS, and inline
56
+ assets; there is no separate CSS command. Do not import preview fixtures into
57
+ `main.tsx` or `app.config.ts`.
58
+
59
+ Use `useColine()` for capabilities. `useColineQuery(loader, deps)` provides
60
+ bounded loading/error/refetch for files and other reads. For collaborative
61
+ records use `useLiveCollection`; it owns optimistic updates, version checks,
62
+ reconciliation, and subscriptions. Catch mutation rejections, show recovery,
63
+ and never retry a conflicting write blindly. Check installed declarations for
64
+ query operators and method arguments; do not guess APIs.
65
+
66
+ Store documents as files and structured app data in install-private collections.
67
+ Use `expectedVersion` when saving a document. Record access policies enforce
68
+ workspace/readers/writers on the server; hiding a button is not authorization.
69
+ Native tasks/calendar/messages/references and shared files require explicit
70
+ permissions and retain the invoking user's access. Render handlers/previews are
71
+ read-only; interactive home/editor capabilities can write within grants.
72
+
73
+ Prefix tools with the app key, validate input with `zod/v4`, and declare honest
74
+ effects. UI can call `coline.tools.invoke` to share a tool with Kairo. Tree
75
+ handlers use `ui.*`; chat cards use the restricted chat subset. Use tree mobile
76
+ fallbacks where declared; a narrow browser preview does not prove native mobile.
77
+
78
+ No direct API routes, credentials, cookies, or localStorage in the sandbox.
79
+ External calls use `coline.net.fetch` and declared allowlists. Keep React state
80
+ for transient UI, not as a substitute for saved records. Do not imply CRDT text
81
+ editing, durable offline queues, presence, or public hosting from live records.
@@ -1,6 +1 @@
1
- # Claude Instructions
2
-
3
- Read and follow [`AGENTS.md`](./AGENTS.md) — it contains the complete
4
- Coline App contract: capabilities, tools, storage, UI builders, sandbox
5
- rules, limits, and testing patterns. For app-authoring tasks, also read
6
- [`.agents/skills/coline-app-development/SKILL.md`](.agents/skills/coline-app-development/SKILL.md).
1
+ Read AGENTS.md before working. It contains the public SDK contract, local preview commands, and links to the bundled experimental UI skills.
@@ -1,40 +1,33 @@
1
1
  # __APP_NAME__
2
2
 
3
- A hosted, backendless Coline App. The logic in `app.config.ts` runs on
4
- Coline's hosted runtime — no servers to deploy. The starter also includes a
5
- working React home in `main.tsx` using `@colineapp/ui`.
6
-
7
- ## Develop
3
+ A Coline App with a working notes home, editor, tool, and tree fallback.
8
4
 
9
5
  ```sh
10
6
  npm install
11
- npm test # runs against the in-memory test workspace
12
- npm run typecheck # checks app.config.ts and main.tsx
7
+ npm test
8
+ npm run check
9
+ npm run preview
13
10
  ```
14
11
 
15
- ## Push to Coline
16
-
17
- Create a workspace API key with the `apps.write` scope in
18
- **Workspace Settings → API**, then:
12
+ Preview runs locally with disposable fixtures, no account or API key. Try its
13
+ light/dark themes and ready/empty/error/loading/permission states. Source edits
14
+ reload the preview. `preview.seed.ts` defines local fixtures.
19
15
 
20
- ```sh
21
- export COLINE_API_KEY=col_ws_...
22
- npm run push
23
- ```
16
+ For other layouts, run `npm run preview -- --pattern triage`, `board`, or
17
+ `settings`. Copy and adapt the examples to your product, then connect their local
18
+ state to SDK data. `app.css` supports ordinary CSS and automatically compiled
19
+ Tailwind utilities.
24
20
 
25
- Versions land in your developer console in draft state. Use
26
- `npm run dev` to watch the project and push on every change.
21
+ For browser captures, install Chromium once with `npx playwright install chromium`,
22
+ then run `npm run screenshots`. Inspect `.coline/screenshots` and its report.
23
+ This catches browser errors, overflow, and missing form labels; visual quality
24
+ and interactions still need review.
27
25
 
28
- ## Grow the app
26
+ Read [AGENTS.md](AGENTS.md) for the SDK contract and bundled experimental design,
27
+ development, and review skills. They work as plain instructions with any agent;
28
+ models with limited visual or tool abilities may need human review.
29
29
 
30
- - Add Kairo tools with `defineTool` declare the honest `effect`
31
- (`read` / `write` / `destructive` / `external`); the runtime enforces
32
- it as a capability ceiling.
33
- - Add file types with `defineFileType` — tree previews render everywhere
34
- Coline shows files, including mobile and Kairo chat.
35
- - The starter home is already a React surface. Keep `main.tsx` as the single
36
- client entry and use `@colineapp/ui` for components, provider, and hooks.
37
- - Store app-private data with `coline.storage.kv` and
38
- `coline.storage.collection(name)`.
39
- - Call external APIs with `coline.net.fetch` after declaring
40
- `network.external` hosts in the manifest.
30
+ To upload, set `COLINE_API_KEY` (workspace key with `apps.write`) and optionally
31
+ `COLINE_BASE_URL`, then run `npm run push -- --internal`. `npm run dev -- --internal`
32
+ watches and updates a development version. Local preview does not test production
33
+ persistence, authorization, multiplayer, or deployment.
@@ -11,16 +11,14 @@ const noteFileType = defineFileType({
11
11
  name: "__APP_NAME__ Note",
12
12
  indexable: true,
13
13
  surfaces: {
14
+ editor: { tier: "react", entry: "main.tsx" },
14
15
  preview: { tier: "tree" },
15
16
  inline: { tier: "tree" },
16
17
  },
17
18
  },
18
19
  runtime: {
19
20
  renderPreview: (context) =>
20
- ui.stack([
21
- ui.heading(context.file.name),
22
- ui.text(String(context.document.body ?? "")),
23
- ]),
21
+ ui.stack([ui.heading(context.file.name), ui.text(String(context.document.body ?? ""))]),
24
22
  renderInline: (context) => ui.text(context.file.name),
25
23
  index: {
26
24
  title: (document) => String(document.title ?? "Untitled note"),
@@ -41,7 +39,7 @@ const createNote = defineTool({
41
39
  const file = await context.coline.files.create({
42
40
  typeKey: "__APP_KEY__.note",
43
41
  name: input.title,
44
- document: { body: input.body },
42
+ document: { title: input.title, body: input.body },
45
43
  });
46
44
  return {
47
45
  output: { fileId: file.fileId },
@@ -57,7 +55,7 @@ export default defineApp({
57
55
  key: "__APP_KEY__",
58
56
  name: "__APP_NAME__",
59
57
  description: "A starter Coline App.",
60
- permissions: ["files.read", "files.write", "storage.app", "ai.tools"],
58
+ permissions: ["files.read", "files.write", "storage.app", "ai.tools", "drives.app"],
61
59
  hosting: { default: "coline" },
62
60
  surfaces: {
63
61
  home: {
@@ -77,9 +75,15 @@ export default defineApp({
77
75
  return ui.stack(
78
76
  [
79
77
  ui.heading("__APP_NAME__ is running", { level: 1 }),
80
- ui.text("Edit app.config.ts and save — dev mode hot-swaps this screen instantly.", {
81
- tone: "muted",
78
+ ui.button("New note", {
79
+ action: actions.invokeTool("__APP_KEY__.create_note", { title: "Untitled note" }),
82
80
  }),
81
+ ui.text(
82
+ "Edit app.config.ts and save — dev mode updates this app; reload to see changes.",
83
+ {
84
+ tone: "muted",
85
+ },
86
+ ),
83
87
  ui.card({
84
88
  title: "Try the example tool",
85
89
  description:
@@ -0,0 +1,84 @@
1
+ /* Compiled automatically by check, preview, dev, and push. Use complete class names. */
2
+ @import "tailwindcss";
3
+ @custom-variant dark (&:is(.dark *));
4
+
5
+ @theme inline {
6
+ --color-background: var(--background);
7
+ --color-foreground: var(--foreground);
8
+ --color-card: var(--card);
9
+ --color-card-foreground: var(--card-foreground);
10
+ --color-popover: var(--popover);
11
+ --color-popover-foreground: var(--popover-foreground);
12
+ --color-primary: var(--primary);
13
+ --color-primary-foreground: var(--primary-foreground);
14
+ --color-secondary: var(--secondary);
15
+ --color-secondary-foreground: var(--secondary-foreground);
16
+ --color-muted: var(--muted);
17
+ --color-muted-foreground: var(--muted-foreground);
18
+ --color-accent: var(--accent);
19
+ --color-accent-foreground: var(--accent-foreground);
20
+ --color-destructive: var(--destructive);
21
+ --color-border: var(--border);
22
+ --color-input: var(--input);
23
+ --color-ring: var(--ring);
24
+ --radius-sm: calc(var(--radius) - 4px);
25
+ --radius-md: calc(var(--radius) - 2px);
26
+ --radius-lg: var(--radius);
27
+ --radius-xl: calc(var(--radius) + 4px);
28
+ --radius-2xl: calc(var(--radius) + 8px);
29
+ --radius-3xl: calc(var(--radius) + 12px);
30
+ --radius-4xl: calc(var(--radius) + 16px);
31
+ }
32
+
33
+ body {
34
+ margin: 0;
35
+ }
36
+ .note-editor {
37
+ display: grid;
38
+ gap: 24px;
39
+ }
40
+ .note-editor label {
41
+ display: grid;
42
+ gap: 8px;
43
+ font-size: 13px;
44
+ font-weight: 500;
45
+ }
46
+ .note-editor textarea {
47
+ min-height: 340px;
48
+ line-height: 1.7;
49
+ }
50
+ .example-meta {
51
+ display: flex;
52
+ align-items: center;
53
+ gap: 8px;
54
+ color: var(--muted-foreground);
55
+ font-size: 12px;
56
+ }
57
+ .example-select {
58
+ border: 1px solid var(--border);
59
+ background: var(--background);
60
+ color: var(--foreground);
61
+ border-radius: 6px;
62
+ padding: 7px 9px;
63
+ font: inherit;
64
+ max-width: 100%;
65
+ }
66
+ .example-field {
67
+ display: grid;
68
+ gap: 8px;
69
+ font-size: 13px;
70
+ }
71
+ .example-description {
72
+ font-size: 13px;
73
+ line-height: 1.7;
74
+ color: var(--muted-foreground);
75
+ }
76
+
77
+ .coline-settings-fields .example-toggle {
78
+ display: flex;
79
+ align-items: center;
80
+ gap: 10px;
81
+ }
82
+ .example-description {
83
+ margin: 12px 0 18px;
84
+ }