@pikku/cli 0.12.22 → 0.12.24
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/console-app/assets/{index-CAk106ji.js → index-BDOqBctb.js} +2 -2
- package/console-app/index.html +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +161 -269
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.json +1 -62
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -2
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -2
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +14 -20
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +5 -23
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/functions/commands/dev.js +17 -2
- package/dist/src/functions/db/local-db.js +1 -0
- package/dist/src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.js +1 -1
- package/dist/src/scaffold/rpc-remote.gen.js +1 -1
- package/dist/src/utils/serialize-schemas.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/skills/pikku-i18n/SKILL.md +15 -6
- package/skills/pikku-rtl/SKILL.md +38 -24
- package/dist/.pikku/schemas/schemas/GraphStarterInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/GraphStarterOutput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowRunStatus.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowRunnerInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowStarterInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowStarterOutput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowStatusCheckerInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowStatusStreamFullInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/WorkflowStatusStreamInput.schema.json +0 -1
- package/dist/src/scaffold/workflow-routes.gen.d.ts +0 -84
- package/dist/src/scaffold/workflow-routes.gen.js +0 -229
|
@@ -14,7 +14,7 @@ registered `satisfies typeof en`) plus the document being told it is `rtl`.
|
|
|
14
14
|
## The one idea
|
|
15
15
|
|
|
16
16
|
Set `dir` **once at the document root** from the active locale, then let the
|
|
17
|
-
browser and Mantine mirror everything —
|
|
17
|
+
browser and Mantine mirror everything — _provided_ every custom style is written
|
|
18
18
|
**flow-relative** (start/end), never **physical** (left/right). Get those two
|
|
19
19
|
things right and Arabic, Hebrew, Farsi and Urdu all work with zero per-component
|
|
20
20
|
RTL code.
|
|
@@ -46,22 +46,22 @@ RTL code.
|
|
|
46
46
|
|
|
47
47
|
Use the **inline-axis logical** property; never the physical one:
|
|
48
48
|
|
|
49
|
-
| Don't (physical)
|
|
50
|
-
|
|
|
51
|
-
| `margin-left` / `marginLeft
|
|
52
|
-
| `margin-right`
|
|
53
|
-
| `padding-left/right`
|
|
54
|
-
| `left: 0` / `right: 0`
|
|
55
|
-
| `text-align: left/right`
|
|
56
|
-
| `border-top-left-radius`
|
|
57
|
-
| `float: left/right`
|
|
49
|
+
| Don't (physical) | Do (flow-relative) |
|
|
50
|
+
| ---------------------------- | -------------------------------------------- |
|
|
51
|
+
| `margin-left` / `marginLeft` | `margin-inline-start` / `marginInlineStart` |
|
|
52
|
+
| `margin-right` | `margin-inline-end` / `marginInlineEnd` |
|
|
53
|
+
| `padding-left/right` | `padding-inline-start/end` |
|
|
54
|
+
| `left: 0` / `right: 0` | `inset-inline-start: 0` / `inset-inline-end` |
|
|
55
|
+
| `text-align: left/right` | `text-align: start / end` |
|
|
56
|
+
| `border-top-left-radius` | `border-start-start-radius` |
|
|
57
|
+
| `float: left/right` | `float: inline-start / inline-end` |
|
|
58
58
|
|
|
59
59
|
In **Mantine**, use the logical style props — they emit the logical CSS above:
|
|
60
60
|
|
|
61
|
-
| Don't
|
|
62
|
-
|
|
|
63
|
-
| `ml` / `mr`
|
|
64
|
-
| `pl` / `pr`
|
|
61
|
+
| Don't | Do |
|
|
62
|
+
| ----------- | ----------- |
|
|
63
|
+
| `ml` / `mr` | `ms` / `me` |
|
|
64
|
+
| `pl` / `pr` | `ps` / `pe` |
|
|
65
65
|
|
|
66
66
|
Mantine's own components already use logical properties internally, so once the
|
|
67
67
|
direction is set they mirror automatically — you only have to be disciplined in
|
|
@@ -76,6 +76,7 @@ logical order; let `dir` handle the visual order.
|
|
|
76
76
|
## Applying direction at the root
|
|
77
77
|
|
|
78
78
|
### Mantine app (e.g. environment-template)
|
|
79
|
+
|
|
79
80
|
Mantine ships first-class RTL: wrap the tree in `DirectionProvider` and set the
|
|
80
81
|
matching `dir` on `<html>`.
|
|
81
82
|
|
|
@@ -83,14 +84,13 @@ matching `dir` on `<html>`.
|
|
|
83
84
|
import { DirectionProvider, MantineProvider } from '@mantine/core'
|
|
84
85
|
import i18n, { detectLocale, localeDir } from './i18n/config'
|
|
85
86
|
|
|
86
|
-
const locale =
|
|
87
|
-
? detectLocale(window.location.pathname)
|
|
88
|
-
: 'en'
|
|
87
|
+
const locale =
|
|
88
|
+
typeof window !== 'undefined' ? detectLocale(window.location.pathname) : 'en'
|
|
89
89
|
const dir = localeDir(locale)
|
|
90
90
|
|
|
91
91
|
if (typeof document !== 'undefined') {
|
|
92
92
|
document.documentElement.lang = locale
|
|
93
|
-
document.documentElement.dir = dir
|
|
93
|
+
document.documentElement.dir = dir // Mantine + browser read this
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
root.render(
|
|
@@ -98,14 +98,16 @@ root.render(
|
|
|
98
98
|
<MantineProvider theme={theme} defaultColorScheme="dark">
|
|
99
99
|
{/* …app… */}
|
|
100
100
|
</MantineProvider>
|
|
101
|
-
</DirectionProvider
|
|
101
|
+
</DirectionProvider>
|
|
102
102
|
)
|
|
103
103
|
```
|
|
104
|
+
|
|
104
105
|
To flip direction live (a language switcher) call
|
|
105
106
|
`document.documentElement.setAttribute('dir', localeDir(next))` and Mantine's
|
|
106
107
|
`useDirection().setDirection(dir)`; both read the same value.
|
|
107
108
|
|
|
108
109
|
### Plain Vite SPA (kanban, test-harness vite-spa)
|
|
110
|
+
|
|
109
111
|
No Mantine — just put `dir`/`lang` on `<html>` at bootstrap, after the locale is
|
|
110
112
|
detected (the same `detectLocale` the i18n config uses):
|
|
111
113
|
|
|
@@ -116,9 +118,11 @@ const locale = detectLocale(window.location.pathname)
|
|
|
116
118
|
document.documentElement.lang = locale
|
|
117
119
|
document.documentElement.dir = localeDir(locale)
|
|
118
120
|
```
|
|
121
|
+
|
|
119
122
|
Everything below inherits `dir` from `<html>`; logical CSS does the mirroring.
|
|
120
123
|
|
|
121
124
|
### Vite SSR (test-harness vite-ssr)
|
|
125
|
+
|
|
122
126
|
The worker renders the full HTML, so set `lang`/`dir` on the server `<html>`
|
|
123
127
|
from the **URL** locale (the client inherits it on hydration — no flash):
|
|
124
128
|
|
|
@@ -132,17 +136,23 @@ const html = `<!doctype html>
|
|
|
132
136
|
…
|
|
133
137
|
</html>`
|
|
134
138
|
```
|
|
139
|
+
|
|
135
140
|
i18next's active language must match: call `i18n.changeLanguage(locale)` before
|
|
136
141
|
`renderToString` so the SSR'd text and `dir` agree.
|
|
137
142
|
|
|
138
143
|
### Next.js app-router (test-harness next-ssr / next-static)
|
|
144
|
+
|
|
139
145
|
Set it on the `<html>` in `app/layout.tsx`. With locale-prefixed routes the
|
|
140
146
|
segment gives the locale; for a single-locale build it's a constant:
|
|
141
147
|
|
|
142
148
|
```tsx
|
|
143
149
|
import { localeDir, defaultLocale } from './i18n/config'
|
|
144
150
|
|
|
145
|
-
export default function RootLayout({
|
|
151
|
+
export default function RootLayout({
|
|
152
|
+
children,
|
|
153
|
+
}: {
|
|
154
|
+
children: React.ReactNode
|
|
155
|
+
}) {
|
|
146
156
|
const locale = defaultLocale // or the [lang] route segment / params
|
|
147
157
|
return (
|
|
148
158
|
<html lang={locale} dir={localeDir(locale)}>
|
|
@@ -151,6 +161,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
151
161
|
)
|
|
152
162
|
}
|
|
153
163
|
```
|
|
164
|
+
|
|
154
165
|
For `output: 'export'` with `/ar` prefixes, derive `locale` from the route
|
|
155
166
|
segment so each statically-exported tree carries the right `dir`.
|
|
156
167
|
|
|
@@ -162,8 +173,11 @@ non-directional icon (search, settings, avatar) must **not**. Flip with the
|
|
|
162
173
|
`:dir()` selector — no JS, no per-locale branching:
|
|
163
174
|
|
|
164
175
|
```css
|
|
165
|
-
:dir(rtl) .icon-directional {
|
|
176
|
+
:dir(rtl) .icon-directional {
|
|
177
|
+
transform: scaleX(-1);
|
|
178
|
+
}
|
|
166
179
|
```
|
|
180
|
+
|
|
167
181
|
Or in CSS-in-JS / inline, gate on the resolved direction:
|
|
168
182
|
`transform: localeDir(locale) === 'rtl' ? 'scaleX(-1)' : undefined`.
|
|
169
183
|
Prefer logical icon components if your icon set ships them.
|
|
@@ -171,8 +185,8 @@ Prefer logical icon components if your icon set ships them.
|
|
|
171
185
|
## Arabic typography niceties
|
|
172
186
|
|
|
173
187
|
- **Font:** the default Latin stack renders Arabic with the system fallback,
|
|
174
|
-
which is inconsistent. Add an Arabic-capable family (e.g.
|
|
175
|
-
|
|
188
|
+
which is inconsistent. Add an Arabic-capable family (e.g. _Noto Sans Arabic_,
|
|
189
|
+
_IBM Plex Sans Arabic_) to `font-family` so both scripts look intentional.
|
|
176
190
|
- **Numerals:** don't hardcode digits. Format numbers/dates with
|
|
177
191
|
`Intl.NumberFormat`/`Intl.DateTimeFormat` (or i18next formatters) given the
|
|
178
192
|
active locale, so Western vs Arabic-Indic digits follow the locale choice.
|
|
@@ -187,7 +201,7 @@ Prefer logical icon components if your icon set ships them.
|
|
|
187
201
|
2. Confirm the `localeDir` helper includes `ar` (it does by default).
|
|
188
202
|
3. Confirm the root sets `dir` from the locale (recipe above).
|
|
189
203
|
4. Sweep the app's styles: replace every `left/right`, `ml/mr`, `text-align:
|
|
190
|
-
|
|
204
|
+
left` with the flow-relative equivalent; revert any manual `row-reverse`.
|
|
191
205
|
5. Flip directional icons.
|
|
192
206
|
6. `tsc`, then load the Arabic route and verify the whole layout mirrors —
|
|
193
207
|
sidebar on the right, text right-aligned, arrows pointing the other way.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "nodeId": { "type": "string" }, "data": {} }, "required": ["workflowName", "nodeId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "runId": { "type": "string" } }, "required": ["runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "id": { "type": "string" }, "status": { "$ref": "#/definitions/WorkflowStatus" }, "startedAt": { "type": "string", "format": "date-time" }, "completedAt": { "type": "string", "format": "date-time" }, "deterministic": { "type": "boolean" }, "plannedSteps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowPlannedStep" } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "status": { "$ref": "#/definitions/StepStatus" }, "duration": { "type": "number" } }, "required": ["name", "status"], "additionalProperties": false } }, "output": {}, "error": { "type": "object", "properties": { "message": { "type": "string" } }, "required": ["message"], "additionalProperties": false } }, "required": ["id", "status", "startedAt", "steps"], "additionalProperties": false, "definitions": { "WorkflowStatus": { "type": "string", "enum": ["running", "suspended", "completed", "failed", "cancelled"], "description": "Workflow run status" }, "WorkflowPlannedStep": { "type": "object", "properties": { "stepName": { "type": "string", "description": "Human-readable step label for UI timeline" } }, "required": ["stepName"], "additionalProperties": false }, "StepStatus": { "type": "string", "enum": ["pending", "running", "scheduled", "succeeded", "failed", "suspended"], "description": "Workflow step status" } } }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "data": {} }, "required": ["workflowName"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "data": {} }, "required": ["workflowName"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "runId": { "type": "string" } }, "required": ["runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "runId": { "type": "string" } }, "required": ["workflowName", "runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "runId": { "type": "string" } }, "required": ["workflowName", "runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "workflowName": { "type": "string" }, "runId": { "type": "string" } }, "required": ["workflowName", "runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { WorkflowRunStatus } from '@pikku/core/workflow';
|
|
2
|
-
export declare const workflowStarter: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
3
|
-
workflowName: string;
|
|
4
|
-
data?: unknown;
|
|
5
|
-
}, {
|
|
6
|
-
runId: string;
|
|
7
|
-
}, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
8
|
-
workflowName: string;
|
|
9
|
-
data?: unknown;
|
|
10
|
-
}, {
|
|
11
|
-
runId: string;
|
|
12
|
-
}, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
13
|
-
workflowName: string;
|
|
14
|
-
data?: unknown;
|
|
15
|
-
}, {
|
|
16
|
-
runId: string;
|
|
17
|
-
}, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
18
|
-
export declare const workflowRunner: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
19
|
-
workflowName: string;
|
|
20
|
-
data?: unknown;
|
|
21
|
-
}, unknown, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
22
|
-
workflowName: string;
|
|
23
|
-
data?: unknown;
|
|
24
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
25
|
-
workflowName: string;
|
|
26
|
-
data?: unknown;
|
|
27
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
28
|
-
export declare const workflowStatusChecker: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
29
|
-
workflowName: string;
|
|
30
|
-
runId: string;
|
|
31
|
-
}, WorkflowRunStatus, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
32
|
-
workflowName: string;
|
|
33
|
-
runId: string;
|
|
34
|
-
}, WorkflowRunStatus, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
35
|
-
workflowName: string;
|
|
36
|
-
runId: string;
|
|
37
|
-
}, WorkflowRunStatus, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
38
|
-
/**
|
|
39
|
-
* Minimal workflow status stream — sends step names and statuses only.
|
|
40
|
-
* Use this for user-facing frontends where internal details should not be exposed.
|
|
41
|
-
*/
|
|
42
|
-
export declare const workflowStatusStream: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
43
|
-
workflowName: string;
|
|
44
|
-
runId: string;
|
|
45
|
-
}, unknown, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
46
|
-
workflowName: string;
|
|
47
|
-
runId: string;
|
|
48
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
49
|
-
workflowName: string;
|
|
50
|
-
runId: string;
|
|
51
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
52
|
-
/**
|
|
53
|
-
* Full workflow status stream — includes output, error, and child run IDs.
|
|
54
|
-
* Use this for admin consoles and internal tooling.
|
|
55
|
-
*/
|
|
56
|
-
export declare const workflowStatusStreamFull: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
57
|
-
workflowName: string;
|
|
58
|
-
runId: string;
|
|
59
|
-
}, unknown, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
60
|
-
workflowName: string;
|
|
61
|
-
runId: string;
|
|
62
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
63
|
-
workflowName: string;
|
|
64
|
-
runId: string;
|
|
65
|
-
}, unknown, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
66
|
-
export declare const graphStarter: import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
|
|
67
|
-
workflowName: string;
|
|
68
|
-
nodeId: string;
|
|
69
|
-
data?: unknown;
|
|
70
|
-
}, {
|
|
71
|
-
runId: string;
|
|
72
|
-
}, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
73
|
-
workflowName: string;
|
|
74
|
-
nodeId: string;
|
|
75
|
-
data?: unknown;
|
|
76
|
-
}, {
|
|
77
|
-
runId: string;
|
|
78
|
-
}, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
79
|
-
workflowName: string;
|
|
80
|
-
nodeId: string;
|
|
81
|
-
data?: unknown;
|
|
82
|
-
}, {
|
|
83
|
-
runId: string;
|
|
84
|
-
}, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>;
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file was generated by @pikku/cli@0.12.21
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Workflow HTTP catch-all routes
|
|
6
|
-
* Do not edit manually - regenerate with 'npx pikku'
|
|
7
|
-
*/
|
|
8
|
-
import { pikkuSessionlessFunc, wireHTTPRoutes } from '../../.pikku/pikku-types.gen.js';
|
|
9
|
-
import { MissingServiceError } from '@pikku/core/errors';
|
|
10
|
-
function assertWorkflowService(workflowService) {
|
|
11
|
-
if (!workflowService)
|
|
12
|
-
throw new MissingServiceError('workflowService is required');
|
|
13
|
-
}
|
|
14
|
-
function assertWorkflowRunService(workflowRunService) {
|
|
15
|
-
if (!workflowRunService)
|
|
16
|
-
throw new MissingServiceError('workflowRunService is required');
|
|
17
|
-
}
|
|
18
|
-
export const workflowStarter = pikkuSessionlessFunc({
|
|
19
|
-
auth: false,
|
|
20
|
-
func: async (_services, { workflowName, data }, { rpc }) => {
|
|
21
|
-
return await rpc.startWorkflow(workflowName, (data ?? {}));
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
export const workflowRunner = pikkuSessionlessFunc({
|
|
25
|
-
auth: false,
|
|
26
|
-
func: async ({ workflowService }, { workflowName, data }, { rpc }) => {
|
|
27
|
-
assertWorkflowService(workflowService);
|
|
28
|
-
return await workflowService.runToCompletion(workflowName, (data ?? {}), rpc);
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
export const workflowStatusChecker = pikkuSessionlessFunc({
|
|
32
|
-
auth: false,
|
|
33
|
-
func: async ({ workflowService }, { runId }) => {
|
|
34
|
-
assertWorkflowService(workflowService);
|
|
35
|
-
const status = await workflowService.getRunStatus(runId);
|
|
36
|
-
if (!status)
|
|
37
|
-
throw new Error(`Run not found: ${runId}`);
|
|
38
|
-
return status;
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
/**
|
|
42
|
-
* Minimal workflow status stream — sends step names and statuses only.
|
|
43
|
-
* Use this for user-facing frontends where internal details should not be exposed.
|
|
44
|
-
*/
|
|
45
|
-
export const workflowStatusStream = pikkuSessionlessFunc({
|
|
46
|
-
auth: false,
|
|
47
|
-
func: async ({ workflowRunService }, { runId }, { channel }) => {
|
|
48
|
-
assertWorkflowRunService(workflowRunService);
|
|
49
|
-
if (!channel)
|
|
50
|
-
return;
|
|
51
|
-
const terminalStatuses = new Set(['completed', 'failed', 'cancelled']);
|
|
52
|
-
let lastHash = '';
|
|
53
|
-
let initSent = false;
|
|
54
|
-
const poll = async () => {
|
|
55
|
-
const run = await workflowRunService.getRun(runId);
|
|
56
|
-
if (!run) {
|
|
57
|
-
channel.close();
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
const steps = await workflowRunService.getRunSteps(runId);
|
|
61
|
-
if (!initSent && run.deterministic) {
|
|
62
|
-
const statusByStep = new Map(steps.map((s) => [
|
|
63
|
-
s.stepName,
|
|
64
|
-
s.status,
|
|
65
|
-
]));
|
|
66
|
-
channel.send({
|
|
67
|
-
type: 'init',
|
|
68
|
-
deterministic: true,
|
|
69
|
-
steps: (run.plannedSteps ?? []).map((s) => ({
|
|
70
|
-
stepName: s.stepName,
|
|
71
|
-
status: statusByStep.get(s.stepName) ?? 'pending',
|
|
72
|
-
})),
|
|
73
|
-
});
|
|
74
|
-
initSent = true;
|
|
75
|
-
}
|
|
76
|
-
const hash = JSON.stringify({
|
|
77
|
-
s: run.status,
|
|
78
|
-
steps: steps.map((s) => [s.stepName, s.status]),
|
|
79
|
-
});
|
|
80
|
-
if (hash !== lastHash) {
|
|
81
|
-
lastHash = hash;
|
|
82
|
-
channel.send({
|
|
83
|
-
type: 'update',
|
|
84
|
-
status: run.status,
|
|
85
|
-
steps: steps.map((s) => ({
|
|
86
|
-
stepName: s.stepName,
|
|
87
|
-
status: s.status,
|
|
88
|
-
})),
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (terminalStatuses.has(run.status)) {
|
|
92
|
-
channel.send({ type: 'done' });
|
|
93
|
-
channel.close();
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
return true;
|
|
97
|
-
};
|
|
98
|
-
const shouldContinue = await poll();
|
|
99
|
-
if (!shouldContinue)
|
|
100
|
-
return;
|
|
101
|
-
await new Promise((resolve) => {
|
|
102
|
-
const interval = setInterval(async () => {
|
|
103
|
-
const cont = await poll();
|
|
104
|
-
if (!cont) {
|
|
105
|
-
clearInterval(interval);
|
|
106
|
-
resolve();
|
|
107
|
-
}
|
|
108
|
-
}, 500);
|
|
109
|
-
});
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
/**
|
|
113
|
-
* Full workflow status stream — includes output, error, and child run IDs.
|
|
114
|
-
* Use this for admin consoles and internal tooling.
|
|
115
|
-
*/
|
|
116
|
-
export const workflowStatusStreamFull = pikkuSessionlessFunc({
|
|
117
|
-
auth: false,
|
|
118
|
-
func: async ({ workflowRunService }, { runId }, { channel }) => {
|
|
119
|
-
assertWorkflowRunService(workflowRunService);
|
|
120
|
-
if (!channel)
|
|
121
|
-
return;
|
|
122
|
-
const terminalStatuses = new Set(['completed', 'failed', 'cancelled']);
|
|
123
|
-
let lastHash = '';
|
|
124
|
-
let initSent = false;
|
|
125
|
-
const poll = async () => {
|
|
126
|
-
const run = await workflowRunService.getRun(runId);
|
|
127
|
-
if (!run) {
|
|
128
|
-
channel.close();
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
const steps = await workflowRunService.getRunSteps(runId);
|
|
132
|
-
if (!initSent && run.deterministic) {
|
|
133
|
-
const statusByStep = new Map(steps.map((s) => [
|
|
134
|
-
s.stepName,
|
|
135
|
-
s.status,
|
|
136
|
-
]));
|
|
137
|
-
channel.send({
|
|
138
|
-
type: 'init',
|
|
139
|
-
deterministic: true,
|
|
140
|
-
steps: (run.plannedSteps ?? []).map((s) => ({
|
|
141
|
-
stepName: s.stepName,
|
|
142
|
-
status: statusByStep.get(s.stepName) ?? 'pending',
|
|
143
|
-
})),
|
|
144
|
-
});
|
|
145
|
-
initSent = true;
|
|
146
|
-
}
|
|
147
|
-
const hash = JSON.stringify({
|
|
148
|
-
s: run.status,
|
|
149
|
-
o: run.output,
|
|
150
|
-
steps: steps.map((s) => [s.stepName, s.status]),
|
|
151
|
-
});
|
|
152
|
-
if (hash !== lastHash) {
|
|
153
|
-
lastHash = hash;
|
|
154
|
-
channel.send({
|
|
155
|
-
type: 'update',
|
|
156
|
-
status: run.status,
|
|
157
|
-
output: run.output,
|
|
158
|
-
error: run.error,
|
|
159
|
-
steps: steps.map((s) => ({
|
|
160
|
-
stepName: s.stepName,
|
|
161
|
-
status: s.status,
|
|
162
|
-
...(s.childRunId ? { childRunId: s.childRunId } : {}),
|
|
163
|
-
})),
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
if (terminalStatuses.has(run.status)) {
|
|
167
|
-
channel.send({ type: 'done' });
|
|
168
|
-
channel.close();
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
return true;
|
|
172
|
-
};
|
|
173
|
-
const shouldContinue = await poll();
|
|
174
|
-
if (!shouldContinue)
|
|
175
|
-
return;
|
|
176
|
-
await new Promise((resolve) => {
|
|
177
|
-
const interval = setInterval(async () => {
|
|
178
|
-
const cont = await poll();
|
|
179
|
-
if (!cont) {
|
|
180
|
-
clearInterval(interval);
|
|
181
|
-
resolve();
|
|
182
|
-
}
|
|
183
|
-
}, 500);
|
|
184
|
-
});
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
export const graphStarter = pikkuSessionlessFunc({
|
|
188
|
-
auth: false,
|
|
189
|
-
func: async (_services, { workflowName, nodeId, data }, { rpc }) => {
|
|
190
|
-
return await rpc.startWorkflow(workflowName, (data ?? {}), { startNode: nodeId });
|
|
191
|
-
},
|
|
192
|
-
});
|
|
193
|
-
wireHTTPRoutes({
|
|
194
|
-
auth: false,
|
|
195
|
-
routes: {
|
|
196
|
-
workflowStart: {
|
|
197
|
-
route: '/workflow/:workflowName/start',
|
|
198
|
-
method: 'post',
|
|
199
|
-
func: workflowStarter,
|
|
200
|
-
},
|
|
201
|
-
workflowRun: {
|
|
202
|
-
route: '/workflow/:workflowName/run',
|
|
203
|
-
method: 'post',
|
|
204
|
-
func: workflowRunner,
|
|
205
|
-
},
|
|
206
|
-
workflowStatus: {
|
|
207
|
-
route: '/workflow/:workflowName/status/:runId',
|
|
208
|
-
method: 'get',
|
|
209
|
-
func: workflowStatusChecker,
|
|
210
|
-
},
|
|
211
|
-
workflowStatusStream: {
|
|
212
|
-
route: '/workflow/:workflowName/status/:runId/stream',
|
|
213
|
-
method: 'get',
|
|
214
|
-
sse: true,
|
|
215
|
-
func: workflowStatusStream,
|
|
216
|
-
},
|
|
217
|
-
workflowStatusStreamFull: {
|
|
218
|
-
route: '/workflow/:workflowName/status/:runId/stream/full',
|
|
219
|
-
method: 'get',
|
|
220
|
-
sse: true,
|
|
221
|
-
func: workflowStatusStreamFull,
|
|
222
|
-
},
|
|
223
|
-
graphStart: {
|
|
224
|
-
route: '/workflow/:workflowName/graph/:nodeId',
|
|
225
|
-
method: 'post',
|
|
226
|
-
func: graphStarter,
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
});
|