@pikku/skills 0.12.52 → 0.12.55

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 (112) hide show
  1. package/README.md +1 -1
  2. package/dist/skills.gen.js +2 -2
  3. package/dist/snippets.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/pikku-a11y/SKILL.md +22 -15
  6. package/skills/pikku-addon/SKILL.md +5 -5
  7. package/skills/pikku-addon/references/addon-package-manifest.md +7 -0
  8. package/skills/pikku-addon/references/openapi.md +11 -0
  9. package/skills/pikku-agent/SKILL.md +6 -6
  10. package/skills/pikku-agent/references/agents.md +8 -1
  11. package/skills/pikku-agent/references/runner-vercel.md +2 -2
  12. package/skills/pikku-agent/references/voice.md +7 -1
  13. package/skills/pikku-architect/SKILL.md +2 -2
  14. package/skills/pikku-architect/references/plan-defects.md +9 -7
  15. package/skills/pikku-auth/SKILL.md +15 -36
  16. package/skills/pikku-auth/references/better-auth.md +106 -133
  17. package/skills/pikku-auth/references/jose.md +6 -0
  18. package/skills/pikku-auth/references/machine-auth.md +6 -0
  19. package/skills/pikku-auth/references/sessions.md +6 -0
  20. package/skills/pikku-build/SKILL.md +37 -34
  21. package/skills/pikku-build/references/app.md +113 -99
  22. package/skills/pikku-build/references/design.md +43 -31
  23. package/skills/pikku-build/references/feature.md +17 -3
  24. package/skills/pikku-build/references/mocks.md +29 -0
  25. package/skills/pikku-build/references/multi-app.md +25 -18
  26. package/skills/pikku-build/references/native-app.md +9 -0
  27. package/skills/pikku-build/references/openapi.md +41 -34
  28. package/skills/pikku-build/references/platform.md +23 -14
  29. package/skills/pikku-build/references/post-clone.md +1 -1
  30. package/skills/pikku-build/references/quick.md +76 -39
  31. package/skills/pikku-build/references/scenarios.md +28 -16
  32. package/skills/pikku-build/references/ship.md +19 -16
  33. package/skills/pikku-build/references/theming.md +76 -127
  34. package/skills/pikku-changes/SKILL.md +7 -10
  35. package/skills/pikku-concepts/SKILL.md +34 -44
  36. package/skills/pikku-concepts/references/concept-mapping.md +18 -0
  37. package/skills/pikku-concepts/references/language.md +6 -6
  38. package/skills/pikku-convert-screen/SKILL.md +45 -0
  39. package/skills/pikku-deploy/references/cloudflare.md +8 -0
  40. package/skills/pikku-deploy/references/lambda.md +8 -0
  41. package/skills/pikku-deploy/references/nextjs.md +1 -1
  42. package/skills/pikku-deploy/references/uws.md +1 -1
  43. package/skills/pikku-deploy/references/ws.md +3 -3
  44. package/skills/pikku-emails/SKILL.md +3 -9
  45. package/skills/pikku-guide/SKILL.md +28 -27
  46. package/skills/pikku-i18n/SKILL.md +7 -7
  47. package/skills/pikku-i18n/references/enum-labels.md +9 -0
  48. package/skills/pikku-i18n/references/messages.md +21 -9
  49. package/skills/pikku-i18n/references/rtl.md +18 -38
  50. package/skills/pikku-knowledge/SKILL.md +12 -13
  51. package/skills/pikku-kysely/SKILL.md +3 -21
  52. package/skills/pikku-list-query/SKILL.md +2 -2
  53. package/skills/pikku-meta/references/audit.md +10 -1
  54. package/skills/pikku-meta/references/meta.md +6 -0
  55. package/skills/pikku-meta/references/versioning.md +10 -0
  56. package/skills/pikku-middleware/SKILL.md +7 -16
  57. package/skills/pikku-n8n-import/SKILL.md +9 -1
  58. package/skills/pikku-n8n-import/references/addon-mapping.md +6 -0
  59. package/skills/pikku-n8n-import/references/code-translation.md +7 -0
  60. package/skills/pikku-permissions/SKILL.md +41 -10
  61. package/skills/pikku-permissions/references/scopes.md +59 -0
  62. package/skills/pikku-react/SKILL.md +20 -22
  63. package/skills/pikku-react/references/client.md +2 -70
  64. package/skills/pikku-react/references/react-query.md +11 -0
  65. package/skills/pikku-react/references/workflows.md +11 -0
  66. package/skills/pikku-realtime/SKILL.md +9 -3
  67. package/skills/pikku-report/SKILL.md +17 -16
  68. package/skills/pikku-scenario/SKILL.md +72 -81
  69. package/skills/pikku-scenario/references/browser.md +5 -5
  70. package/skills/pikku-scenario/references/coverage.md +4 -4
  71. package/skills/pikku-scenario/references/steps.md +31 -30
  72. package/skills/pikku-scenario/references/{persona-run.md → virtual-user-run.md} +47 -42
  73. package/skills/pikku-scenario/references/virtual-users.md +114 -0
  74. package/skills/pikku-seo/SKILL.md +12 -16
  75. package/skills/pikku-service-backends/SKILL.md +0 -10
  76. package/skills/pikku-service-backends/references/aws.md +6 -0
  77. package/skills/pikku-service-backends/references/mongodb.md +7 -0
  78. package/skills/pikku-service-backends/references/redis.md +6 -0
  79. package/skills/pikku-services/references/audit-wire-service.md +2 -2
  80. package/skills/pikku-services/references/audit.md +10 -1
  81. package/skills/pikku-services/references/config.md +6 -0
  82. package/skills/pikku-services/references/services.md +9 -2
  83. package/skills/pikku-software-archaeology/SKILL.md +21 -27
  84. package/skills/pikku-software-archaeology/references/blueprint.schema.json +16 -16
  85. package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
  86. package/skills/pikku-software-archaeology/references/second-opinion.md +13 -1
  87. package/skills/pikku-tailwind/SKILL.md +111 -0
  88. package/skills/pikku-theme/SKILL.md +187 -0
  89. package/skills/pikku-theme/references/from-a-reference.md +44 -0
  90. package/skills/pikku-theme/references/presets.md +40 -0
  91. package/skills/pikku-ui/SKILL.md +41 -0
  92. package/skills/pikku-wiring/SKILL.md +13 -12
  93. package/skills/pikku-wiring/references/channel.md +7 -1
  94. package/skills/pikku-wiring/references/cli.md +7 -1
  95. package/skills/pikku-wiring/references/gateway-slack.md +6 -0
  96. package/skills/pikku-wiring/references/http.md +10 -3
  97. package/skills/pikku-wiring/references/mcp.md +8 -0
  98. package/skills/pikku-wiring/references/queue.md +6 -0
  99. package/skills/pikku-wiring/references/realtime.md +34 -4
  100. package/skills/pikku-wiring/references/rpc.md +6 -0
  101. package/skills/pikku-wiring/references/scheduler.md +6 -0
  102. package/skills/pikku-wiring/references/trigger.md +8 -0
  103. package/skills/pikku-workflow/SKILL.md +9 -7
  104. package/skills/pikku-admin-to-fabric/SKILL.md +0 -212
  105. package/skills/pikku-auth/references/permissions.md +0 -261
  106. package/skills/pikku-blueprint-to-fabric/SKILL.md +0 -377
  107. package/skills/pikku-blueprint-to-fabric/scripts/inventory.mjs +0 -367
  108. package/skills/pikku-fabric/SKILL.md +0 -619
  109. package/skills/pikku-fabric/references/debugging.md +0 -110
  110. package/skills/pikku-mantine/SKILL.md +0 -80
  111. package/skills/pikku-scenario/references/personas.md +0 -117
  112. package/skills/pikku-wiring/references/realtime-other-routes.md +0 -23
@@ -1,5 +1,11 @@
1
1
  # Integration stub → Pikku addon
2
2
 
3
+ ## Contents
4
+
5
+ - Inputs
6
+ - Per entry, in order
7
+ - Never
8
+
3
9
  Translate n8n integration nodes (`gmailTool`, `slackTool`, `googleSheetsTool`, plain
4
10
  `gmail` / `slack` action nodes, etc.) that the importer left as throwing stubs into
5
11
  real `ref('<addonRpc>')` references pointing at functions in **installed**
@@ -1,5 +1,12 @@
1
1
  # n8n Code node → Pikku function
2
2
 
3
+ ## Contents
4
+
5
+ - Process
6
+ - Rubric
7
+ - Example
8
+ - Report
9
+
3
10
  Replace a Code-node stub's `throw new Error(...)` body with a faithful TypeScript
4
11
  reimplementation. The original JS is preserved verbatim in the JSDoc above the
5
12
  function. Keep the signature and JSDoc intact; only widen the Zod input/output if
@@ -1,14 +1,24 @@
1
1
  ---
2
2
  name: pikku-permissions
3
3
  description: >-
4
- Use when deciding WHO may call a function — resource ownership, role gates, admin-only actions, or any "only their own rows" rule. Covers the `permissions` field, `pikkuPermission`, `pikkuAuth`, scopes, and where ownership belongs versus where it does not.
5
- TRIGGER when: writing or reviewing any function that touches a row a user owns, gating an action on a role, building the permissions half of a contract in build PHASE 2, or about to write an `if` in a function body that decides whether the caller is allowed.
6
- DO NOT TRIGGER when: the question is how to sign someone in or seed a persona (that is pikku-auth), or how to shape a paginated list (that is pikku-list-query).
4
+ Use when deciding WHO may call a function: resource ownership, role gates, admin-only actions, or any "only their own rows" rule. Covers the `permissions` field, `pikkuPermission`, `pikkuAuth`, scopes and `defineScope`, `addGlobalPermission`, the three gates, `permissionsInBody`, and where ownership belongs versus where it does not.
5
+ TRIGGER when: writing or reviewing any function that touches a row a user owns, gating an action on a role, building the permissions half of a contract in build PHASE 2, about to write an `if` in a function body that decides whether the caller is allowed, or hitting `MissingScopeError`.
6
+ DO NOT TRIGGER when: the question is how a caller proves who they are, such as sign-in, sessions, tokens, API keys or seeding a virtual user (use pikku-auth), or how to shape a paginated list (use pikku-list-query).
7
7
  installGroups: [core]
8
8
  ---
9
9
 
10
10
  # Pikku Permissions
11
11
 
12
+ ## First: is the caller a machine with a token?
13
+
14
+ Then this is NOT a permissions problem. Resolve the token in `addHTTPMiddleware('*')`
15
+ middleware that calls `setSession`, make the function a `pikkuFunc`, and gate it with
16
+ `scopes` (pikku-auth, `../pikku-auth/references/machine-auth.md`). A `permissions` check that verifies a
17
+ bearer token and returns `true` is authentication wearing an authorization hat, and it
18
+ leaves the function sessionless. The only exception is a bootstrap endpoint whose caller
19
+ has no identity yet (a shared-secret registration, a login): it is sessionless and
20
+ declares its gate here.
21
+
12
22
  ## The rule
13
23
 
14
24
  **Authorization goes in the `permissions` field. Never in the `func` body.**
@@ -107,11 +117,32 @@ gets straight through if the function itself is open.
107
117
  ## Scopes
108
118
 
109
119
  `scopes: ['admin:invoices:void']` is an AND gate checked BEFORE permissions and before
110
- input validation. Declare the tree once with `defineScope`; a function naming an
111
- undeclared scope fails codegen rather than gating on nothing. A grant satisfies a scope if
112
- it is that scope, an ancestor, or a wildcard — a session holding `admin` satisfies
113
- `admin:invoices:void`. Most apps need roles, not scopes; reach for these only when the
114
- plan asked for granular grants.
120
+ input validation. A function naming an undeclared scope fails codegen rather than gating on
121
+ nothing. A grant satisfies a scope if it is that scope, an ancestor, or a wildcard. Most
122
+ apps need roles, not scopes; reach for these only when the plan asked for granular grants.
123
+ The `defineScope` tree, grant matching and the sessionless restriction are in
124
+ [references/scopes.md](references/scopes.md).
125
+
126
+ ## Global permissions
127
+
128
+ `addGlobalPermission([isEmployee])` (from `#pikku/auth`) is an app-wide baseline every
129
+ function must additionally pass. It is an independent AND gate: it can only narrow access,
130
+ never grant what a function's own `permissions` would deny. Multiple calls accumulate and
131
+ are AND'd.
132
+
133
+ ## The three gates
134
+
135
+ All must pass, in this order:
136
+
137
+ 1. **Scopes** (`scopes`) — AND'd, checked before input validation, fails closed.
138
+ 2. **Global permissions** (`addGlobalPermission`) — AND'd together, a baseline that only narrows.
139
+ 3. **The function's own `permissions`** — OR'd groups of AND'd entries.
140
+
141
+ They are independent: a broad global (e.g. `isEmployee`) can never satisfy an admin-only
142
+ function's own requirement. Wire-, tag- and HTTP-route-level permissions
143
+ (`addHTTPPermission`, `addTagPermission`, a `permissions` field on a wiring) no longer
144
+ exist; tags are organizational only. Use tag/HTTP middleware for cross-cutting request
145
+ handling, not authorization.
115
146
 
116
147
  ## The one sanctioned exception
117
148
 
@@ -122,5 +153,5 @@ the auditor the openness is deliberate. Anything expressible as a permission mus
122
153
 
123
154
  ## After changes
124
155
 
125
- `pikku all` — regenerates and typechecks the checkers. A permission whose signature is
126
- wrong fails here, not at runtime.
156
+ `pikku all --tsc` — regenerates, then verifies the checker types. A permission whose
157
+ signature is wrong fails here, not at runtime.
@@ -0,0 +1,59 @@
1
+ # Scopes
2
+
3
+ Scopes answer "what was this session granted?" before permissions ask "may this user do
4
+ this to this resource?". They are AND-ed: every scope listed must be held. Because they
5
+ are checked first and fail closed, a scope can only ever narrow access.
6
+
7
+ ## Declaring the tree
8
+
9
+ Declare the scope tree once with `defineScope`. The body is a no-op that tree-shakes
10
+ away; the CLI reads the call by AST and generates a `ScopeId` union, so a function naming
11
+ an undeclared scope fails the build.
12
+
13
+ ```typescript
14
+ // src/scopes.ts
15
+ import { defineScope } from '#pikku/scopes'
16
+
17
+ defineScope({
18
+ admin: {
19
+ displayName: 'Administration',
20
+ description: 'Administrative access',
21
+ scopes: {
22
+ invoices: {
23
+ description: 'Invoice management',
24
+ scopes: {
25
+ create: { description: 'Create invoices' },
26
+ void: { description: 'Void invoices' },
27
+ },
28
+ },
29
+ },
30
+ },
31
+ billing: {},
32
+ })
33
+ ```
34
+
35
+ Every node is grantable, keyed by segment: the above yields `admin`, `admin:invoices`,
36
+ `admin:invoices:create`, `admin:invoices:void` and `billing`. Scopes may be declared
37
+ across more than one file; the declarations merge.
38
+
39
+ ## Using them
40
+
41
+ ```typescript
42
+ export const voidInvoice = pikkuFunc({
43
+ scopes: ['admin:invoices:void'],
44
+ permissions: { owner: isInvoiceOwner },
45
+ func: async ({ kysely }, { invoiceId }) => { ... },
46
+ })
47
+ ```
48
+
49
+ A grant satisfies a required scope if it is the scope itself, an ancestor of it, or a
50
+ wildcard at any level: a session holding `admin` satisfies `admin:invoices:void`, and so
51
+ does `admin:*`. A missing scope throws `MissingScopeError` naming the first one that
52
+ failed.
53
+
54
+ ## Not on sessionless functions
55
+
56
+ `scopes` requires a session and is unavailable on `pikkuSessionlessFunc`: scopes fail
57
+ closed, an anonymous caller holds none, and a sessionless function with scopes would
58
+ reject every caller it exists to serve. Gate those with `permissions`, which receive the
59
+ optional session and may pass anonymous.
@@ -3,12 +3,10 @@ name: pikku-react
3
3
  description: >-
4
4
  Use when a React frontend talks to a Pikku backend — PikkuProvider and createPikku at the app
5
5
  root, the generated React Query hooks (usePikkuQuery, usePikkuMutation, usePikkuInfiniteQuery),
6
- direct usePikkuRPC / usePikkuFetch calls, realtime subscriptions, agent and workflow hooks, and
7
- the dev actor switcher. TRIGGER when: writing a React component that fetches or mutates backend
8
- data, wiring PikkuProvider, paginating, running or tracking a workflow from the client, or
9
- asking about useDevActors / DevActorSwitcher / quick login. DO NOT TRIGGER when: working on the
10
- backend (use pikku-wiring), defining the workflow itself (use pikku-workflow), or writing
11
- user-facing copy (use pikku-i18n).
6
+ direct usePikkuRPC / usePikkuFetch calls, realtime subscriptions, and agent and workflow hooks. TRIGGER when: writing a React component that fetches or mutates backend
7
+ data, wiring PikkuProvider, paginating, running or tracking a workflow from the client. DO NOT TRIGGER when: working on the
8
+ backend (use pikku-wiring), defining the workflow itself (use pikku-workflow), rendering fetched values such as
9
+ dates (use pikku-tailwind), or writing user-facing copy (use pikku-i18n).
12
10
  installGroups: [client]
13
11
  ---
14
12
 
@@ -21,25 +19,25 @@ stops.
21
19
 
22
20
  ## Pick the reference
23
21
 
24
- | You are… | Read |
25
- | --- | --- |
26
- | Wiring the app root, resolving the server URL, authenticating, or subscribing to realtime | `references/client.md` |
27
- | Fetching, mutating or paginating data | `references/react-query.md` |
28
- | Starting a workflow and showing its progress | `references/workflows.md` |
22
+ | You are… | Read |
23
+ | ----------------------------------------------------------------------------------------- | --------------------------- |
24
+ | Wiring the app root, resolving the server URL, authenticating, or subscribing to realtime | `references/client.md` |
25
+ | Fetching, mutating or paginating data | `references/react-query.md` |
26
+ | Starting a workflow and showing its progress | `references/workflows.md` |
29
27
 
30
28
  ## Reach for what
31
29
 
32
- | Need | Use |
33
- | --- | --- |
34
- | Render data, dedupe and cache | `usePikkuQuery` |
35
- | Trigger a write and wait for the result | `usePikkuMutation` |
36
- | Paginate | `usePikkuInfiniteQuery` |
37
- | One-off call from an event handler | `usePikkuRPC()` |
38
- | Hit a REST endpoint rather than an RPC | `usePikkuFetch()` |
39
- | Talk to one named AI agent | `usePikkuAgent(name)` → `.run` / `.stream` / `.approve` |
40
- | Run one named workflow | `usePikkuWorkflow(name)` → `.start` / `.run` / `.status` |
41
- | A workflow long enough to need progress UI | `references/workflows.md` |
42
- | Subscribe to events, SSE or a channel | `usePikkuRealtime()` |
30
+ | Need | Use |
31
+ | ------------------------------------------ | -------------------------------------------------------- |
32
+ | Render data, dedupe and cache | `usePikkuQuery` |
33
+ | Trigger a write and wait for the result | `usePikkuMutation` |
34
+ | Paginate | `usePikkuInfiniteQuery` |
35
+ | One-off call from an event handler | `usePikkuRPC()` |
36
+ | Hit a REST endpoint rather than an RPC | `usePikkuFetch()` |
37
+ | Talk to one named AI agent | `usePikkuAgent(name)` → `.run` / `.stream` / `.approve` |
38
+ | Run one named workflow | `usePikkuWorkflow(name)` → `.start` / `.run` / `.status` |
39
+ | A workflow long enough to need progress UI | `references/workflows.md` |
40
+ | Subscribe to events, SSE or a channel | `usePikkuRealtime()` |
43
41
 
44
42
  A workflow that finishes in a moment can be awaited; one that does not needs
45
43
  start-plus-observe, or the component holds a pending state with nothing to show.
@@ -1,6 +1,5 @@
1
1
  # Pikku React
2
2
 
3
-
4
3
  What is here:
5
4
 
6
5
  - [What ships](#what-ships)
@@ -174,8 +173,8 @@ helpers live in **pikku-wiring**.
174
173
  | Hit a REST endpoint (not RPC) | `usePikkuFetch()` |
175
174
  | Run one named workflow | `usePikkuWorkflow('name')` → `.start/.run/.status` |
176
175
  | Talk to one named AI agent | `usePikkuAgent('name')` → `.run/.stream/.approve` |
177
- | Longer-running workflow UX | `references/workflows.md` |
178
- | Subscribe to events / SSE / channel | `usePikkuRealtime()` (see **pikku-wiring**) |
176
+ | Longer-running workflow UX | `references/workflows.md` |
177
+ | Subscribe to events / SSE / channel | `usePikkuRealtime()` (see **pikku-wiring**) |
179
178
 
180
179
  The first three live in your generated `api.gen.ts` (see the
181
180
  `references/react-query.md`). This reference covers the rest.
@@ -240,73 +239,6 @@ pikku.fetch.setHeader('x-tenant', tenantId)
240
239
  `authHeaders.jwt` becomes `Authorization: Bearer …` and `authHeaders.apiKey`
241
240
  becomes `X-API-KEY`; setting a JWT takes precedence over an API key.
242
241
 
243
- ### Dev actor sign-in (`useDevActors`)
244
-
245
- The dev-only "Sign in as …" control: one click signs in as a declared scenario
246
- persona with no password, so the app can be reviewed as each kind of user.
247
- `pikku fabric validate` **requires** any frontend with a login screen to ship one
248
- (`app-missing-actor-quick-login-<app>`) — without it a reviewer is locked out of
249
- their own sandbox.
250
-
251
- ```tsx
252
- import { useDevActors } from '@pikku/react'
253
-
254
- const { actors, signInAs, pendingId, isPending, error } = useDevActors({
255
- apiUrl: apiUrl(),
256
- app: appSlug,
257
- onSignedIn: () => navigate({ to: '/' }),
258
- })
259
- ```
260
-
261
- - **It is UI-free**, so render it however you like. For the default rendering use
262
- `<DevActorSwitcher />` from `@pikku/mantine/dev` — a separate entry point from
263
- `@pikku/mantine/core`, whose contract is "drop-in alias for `@mantine/core`"
264
- and so must not export components Mantine has no counterpart for.
265
- - **No credential reaches the bundle.** It lists from `/auth/sign-in/personas`
266
- and `signInAs(id)` posts only the persona id to `/auth/sign-in/persona`. The
267
- server decides who is offered and who may sign in, and offers nobody in
268
- production — see **pikku-scenario** for `personaSignIn`.
269
- - **It takes `onSignedIn` rather than a router**, since every app lands
270
- somewhere different.
271
- - `listDevActors()` and `signInAsPersona()` are exported too, for a non-React
272
- caller. The endpoint only
273
- signs in rows flagged `actor: true`, so it can never impersonate a real user —
274
- see **pikku-auth**.
275
-
276
- Do not hand-write the list-and-sign-in pair per app; that copy-paste is exactly
277
- what this replaced.
278
-
279
- ### Linking from a Mantine element: `renderRoot`, not `component`
280
-
281
- Handing TanStack's `Link` to a Mantine element as `component={Link}` compiles,
282
- renders, and navigates — and silently unties the type. Mantine's polymorphic
283
- `component` prop widens the router generic to `AnyRouter`, so `to` and
284
- `params` stop being checked against your actual routes. Renaming a route then
285
- breaks the running app instead of the build, which is the one thing the typed
286
- router exists to prevent.
287
-
288
- Wrap the typed `Link` once and reach it through `renderRoot`, which passes the
289
- props through without re-typing the element:
290
-
291
- ```tsx
292
- // components/links.tsx — one wrapper the whole app links through
293
- import { Link } from '@tanstack/react-router'
294
-
295
- export const AssessmentLink = (props: { assessmentId: string; children: React.ReactNode }) => (
296
- <Link to="/assessments/$assessmentId" params={{ assessmentId: props.assessmentId }}>
297
- {props.children}
298
- </Link>
299
- )
300
- ```
301
-
302
- ```tsx
303
- <Button renderRoot={(p) => <AssessmentLink assessmentId={id} {...p} />}>
304
- Open
305
- </Button>
306
- ```
307
-
308
- The wrapper is where `to` and `params` are checked, and it is checked once.
309
-
310
242
  ## What NOT to do
311
243
 
312
244
  - Don't instantiate `PikkuFetch`/`PikkuRPC` inside a component — `createPikku`
@@ -1,5 +1,16 @@
1
1
  # Pikku React Query Hooks
2
2
 
3
+ ## Contents
4
+
5
+ - [Discover what's available on the client](#discover-whats-available-on-the-client)
6
+ - [Setup (once per app)](#setup-once-per-app)
7
+ - [TanStack Start (SSR)](#tanstack-start-ssr)
8
+ - [The hooks](#the-hooks)
9
+ - [Workflow hooks](#workflow-hooks)
10
+ - [Calling RPCs without React Query](#calling-rpcs-without-react-query)
11
+ - [Common patterns](#common-patterns)
12
+ - [What NOT to do](#what-not-to-do)
13
+
3
14
 
4
15
  ## Discover what's available on the client
5
16
 
@@ -1,5 +1,16 @@
1
1
  # Pikku Workflows — Client Hooks
2
2
 
3
+ ## Contents
4
+
5
+ - [Discover what workflows exist](#discover-what-workflows-exist)
6
+ - [Setup](#setup)
7
+ - [useRunWorkflow(name, options?) — run and wait](#userunworkflowname-options--run-and-wait)
8
+ - [useStartWorkflow(name, options?) — fire-and-poll](#usestartworkflowname-options--fire-and-poll)
9
+ - [useWorkflowStatus(workflowName, runId, options?) — observe](#useworkflowstatusworkflowname-runid-options--observe)
10
+ - [Putting it together — start + observe](#putting-it-together--start--observe)
11
+ - [Backend: streaming richer progress](#backend-streaming-richer-progress)
12
+ - [What NOT to do](#what-not-to-do)
13
+
3
14
 
4
15
  ## Discover what workflows exist
5
16
 
@@ -1,9 +1,15 @@
1
1
  ---
2
2
  name: pikku-realtime
3
3
  description: >-
4
- Use when making ANY view live/realtime in a Pikku app — a board, shared list, dashboard, ticker, bidding room, live count — or when adding two-way chat/presence. Covers the DEFAULT event-hub SSE path and the two-way WebSocket channel.
5
- TRIGGER when: the user wants live updates, realtime, "update without refresh", a live board/feed/ticker/room, presence, or chat; or when data that MORE THAN ONE signed-in user can change should reflect others
6
- DO NOT TRIGGER when: a plain one-shot query/refetch is fine (data only one user changes, or a manual refresh is acceptable), or for background jobs (see `pikku-wiring`'s scheduler and queue references, or `pikku-workflow`).
4
+ Use when making a view live in a Pikku app — a board, shared list, dashboard, ticker, bidding
5
+ room, live count — or when adding two-way chat or presence. Covers the default event-hub SSE path
6
+ (`eventHub.publish` on the backend, `PikkuRealtime.subscribeToTopic` on the client) and the
7
+ two-way WebSocket channel. TRIGGER when: the user wants live updates, realtime, "update without
8
+ refresh", a live board/feed/ticker/room, presence or chat, or data that more than one signed-in
9
+ user can change should reflect to others. DO NOT TRIGGER when: a one-shot query/refetch is enough
10
+ (data only one user changes, or a manual refresh is acceptable), for background jobs (use
11
+ pikku-workflow, or pikku-wiring's queue and scheduler references), or for the full wiring
12
+ reference of channels, SSE routes and the `/events` scaffold (use pikku-wiring).
7
13
  installGroups: [core, client]
8
14
  ---
9
15
 
@@ -1,18 +1,19 @@
1
1
  ---
2
2
  name: pikku-report
3
3
  description: >-
4
- Use when pikku itself cost you time — wrong generated types, a check that passes when it
5
- should not, output that is quietly wrong, a skill that misled you — or when the user asks you
6
- to report a framework bug or file a finding. Owns `pikku fabric report` (a finding is about
7
- pikku, not the app), the product-vs-harness kinds, the workaround-first ladder, and asking the
8
- user at hand-over whether to send what was filed. TRIGGER when: the framework fought you,
9
- codegen produced something broken, a skill told you to run something that does not exist, the
10
- user says "report this to pikku" / "file a finding", or you are handing over a build. DO NOT TRIGGER when: the bug is in the app you are building (fix it
11
- there), or you are tempted to patch pikku's source (never do that from an app).
4
+ Use when pikku itself cost you time — wrong generated types, a check that passes when it should
5
+ not, output that is quietly wrong, a skill that misled you — or when the user asks you to report
6
+ a framework bug or file a finding. Owns `pikku cloud report` (a finding is about pikku, not the
7
+ app), the product-vs-harness kinds, the workaround-first ladder, and asking the user at hand-over
8
+ whether to send what was filed. TRIGGER when: the framework fought you, codegen produced
9
+ something broken, a skill told you to run something that does not exist, the user says "report
10
+ this to pikku" / "file a finding", or you are handing over a build. DO NOT TRIGGER when: the bug
11
+ is in the app you are building (fix it there), you are debugging a deployed stage,
12
+ or you are tempted to patch pikku's source (never do that from an app).
12
13
  installGroups: [core]
13
14
  ---
14
15
 
15
- # Report a finding to Fabric
16
+ # Report a finding to Pikku Studio Cloud
16
17
 
17
18
  A finding is about **pikku**, not about the app you are building. It is how the
18
19
  framework learns what cost its users time — the bug, the misleading skill, the
@@ -20,7 +21,7 @@ silence where a check should have complained.
20
21
 
21
22
  File each one the moment it happens. Nothing leaves the machine until the user
22
23
  says so at hand-over, and nothing is written to the repository. The command is
23
- spelled `pikku fabric report` — there is no top-level report command.
24
+ spelled `pikku cloud report` — there is no top-level report command.
24
25
 
25
26
  ## Report at the moment it happens
26
27
 
@@ -61,7 +62,7 @@ baseline noise that was already failing before you started.
61
62
  - `--kind harness` — a skill misled you: it told you to run something that does
62
63
  not exist, described a flag that is spelled differently, or contradicted what
63
64
  the CLI actually did. Pass `--skill <name>` and `--passage "<the line or
64
- section>"`. This is the most useful kind to file, because it is fixable
65
+ section>"`. This is the most useful kind to file, because it is fixable
65
66
  immediately — so file it even when the cost was small.
66
67
 
67
68
  ## The command
@@ -74,7 +75,7 @@ follows it. Quote the heredoc delimiter (`<<'EOF'`, never `<<EOF`) so the shell
74
75
  leaves the body alone.
75
76
 
76
77
  ```bash
77
- pikku fabric report --stdin <<'EOF'
78
+ pikku cloud report --stdin <<'EOF'
78
79
  {
79
80
  "title": "<one-line title>",
80
81
  "kind": "product",
@@ -87,7 +88,7 @@ pikku fabric report --stdin <<'EOF'
87
88
  EOF
88
89
  ```
89
90
 
90
- The same fields exist as flags for a finding short enough to type; `pikku fabric
91
+ The same fields exist as flags for a finding short enough to type; `pikku cloud
91
92
  report --help` lists them. Whichever path you use, the rules below are checked
92
93
  before anything is sent:
93
94
 
@@ -115,7 +116,7 @@ The last thing in the hand-over — after the app runs, and is deployed if they
115
116
  chose to — is:
116
117
 
117
118
  ```bash
118
- pikku fabric report
119
+ pikku cloud report
119
120
  ```
120
121
 
121
122
  With no finding, it lists what this build filed. What happens next depends on
@@ -129,12 +130,12 @@ what the user said before, which the CLI keeps on their machine:
129
130
  **Never**. Then run it again with their answer:
130
131
 
131
132
  ```bash
132
- pikku fabric report --consent yes|no|always|never
133
+ pikku cloud report --consent yes|no|always|never
133
134
  ```
134
135
 
135
136
  Yes sends and No discards what is held now; Always and Never are saved and the
136
137
  question is not asked again. If nobody answers, leave them held and say that
137
- `pikku fabric report` sends them later.
138
+ `pikku cloud report` sends them later.
138
139
 
139
140
  Findings are anonymous: no account, no project. The receipt printed when you
140
141
  filed each one is exactly what leaves the machine. A send that fails keeps what