@pikku/cli 0.12.81 → 0.12.83
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/cli.schema.json +1 -1
- package/console-app/assets/{index-NmNeixvK.js → index-CN_U0k_D.js} +154 -144
- package/console-app/assets/{index-DwyRdRuZ.css → index-CpHRlBt-.css} +1 -1
- package/console-app/index.html +2 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +3 -2
- 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 +21 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.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-meta.gen.json +60 -3
- 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 +6 -12
- package/dist/.pikku/function/pikku-function-types.gen.js +3 -12
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +190 -12
- package/dist/.pikku/function/pikku-functions.gen.js +15 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +2 -24
- package/dist/.pikku/http/pikku-http-types.gen.js +2 -24
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- 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 +4 -1
- package/dist/.pikku/pikku-services.gen.js +3 -0
- package/dist/.pikku/pikku-types.gen.d.ts +2 -1
- package/dist/.pikku/pikku-types.gen.js +3 -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 +9 -0
- 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 +13 -1
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuGraphWiringsOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuImportN8nInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuScopesInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuWebhookOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/ScopesAuditInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/ScopesPruneInput.schema.json +1 -0
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +5 -0
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +4 -0
- package/dist/.pikku/scopes/pikku-scopes-meta.gen.json +1 -0
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +35 -0
- package/dist/.pikku/scopes/pikku-scopes.gen.js +27 -0
- 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-meta.gen.json +1 -0
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +11 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +11 -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-meta.gen.json +1 -0
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +11 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +13 -3
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +48 -6
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +4 -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/cli.wiring.js +47 -4
- package/dist/src/deploy/analyzer/analyzer.js +6 -0
- package/dist/src/fabric/fabric-commands.d.ts +3 -3
- package/dist/src/fabric/functions/llm-key.function.d.ts +4 -4
- package/dist/src/fabric/functions/validate.function.js +42 -2
- package/dist/src/functions/commands/bootstrap.js +3 -0
- package/dist/src/functions/commands/dev.js +14 -3
- package/dist/src/functions/commands/enable.d.ts +1 -0
- package/dist/src/functions/commands/enable.js +10 -5
- package/dist/src/functions/commands/import-n8n.d.ts +10 -0
- package/dist/src/functions/commands/import-n8n.js +130 -0
- package/dist/src/functions/commands/info.js +0 -13
- package/dist/src/functions/commands/new-addon.js +33 -35
- package/dist/src/functions/commands/pikku-command-bootstrap.js +6 -0
- package/dist/src/functions/commands/scopes-audit.d.ts +1 -0
- package/dist/src/functions/commands/scopes-audit.js +37 -0
- package/dist/src/functions/commands/scopes-prune.d.ts +14 -0
- package/dist/src/functions/commands/scopes-prune.js +50 -0
- package/dist/src/functions/commands/scopes-shared.d.ts +39 -0
- package/dist/src/functions/commands/scopes-shared.js +83 -0
- package/dist/src/functions/commands/serve.js +4 -2
- package/dist/src/functions/commands/skills.js +18 -10
- package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.js +2 -1
- package/dist/src/functions/wirings/console/serialize-console-functions.js +6 -0
- package/dist/src/functions/wirings/credentials/serialize-credentials-types.js +22 -0
- package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-function-types.js +2 -2
- package/dist/src/functions/wirings/functions/serialize-function-types.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-function-types.js +14 -16
- package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.js +6 -2
- package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.d.ts +1 -0
- package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.js +21 -0
- package/dist/src/functions/wirings/graph/serialize-graph-wirings.d.ts +5 -0
- package/dist/src/functions/wirings/graph/serialize-graph-wirings.js +14 -0
- package/dist/src/functions/wirings/http/serialize-http-types.js +2 -30
- package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +1 -0
- package/dist/src/functions/wirings/package/pikku-command-package-types.js +14 -1
- package/dist/src/functions/wirings/package/serialize-package-types.d.ts +1 -0
- package/dist/src/functions/wirings/package/serialize-package-types.js +5 -0
- package/dist/src/functions/wirings/permissions/pikku-command-permissions.js +1 -3
- package/dist/src/functions/wirings/permissions/serialize-permissions-imports.d.ts +6 -1
- package/dist/src/functions/wirings/permissions/serialize-permissions-imports.js +7 -64
- package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.d.ts +5 -0
- package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.js +20 -0
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +8 -3
- package/dist/src/functions/wirings/scopes/pikku-command-scopes.d.ts +7 -0
- package/dist/src/functions/wirings/scopes/pikku-command-scopes.js +34 -0
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +15 -0
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +86 -0
- package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +13 -0
- package/dist/src/functions/wirings/variables/serialize-variables-types.js +15 -2
- package/dist/src/functions/wirings/webhook/pikku-command-webhook.d.ts +1 -0
- package/dist/src/functions/wirings/webhook/pikku-command-webhook.js +25 -0
- package/dist/src/functions/wirings/webhook/serialize-webhook.d.ts +14 -0
- package/dist/src/functions/wirings/webhook/serialize-webhook.js +34 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +29 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +3 -0
- package/dist/src/functions/workflows/all.workflow.js +23 -3
- package/dist/src/services.d.ts +1 -0
- package/dist/src/services.js +1 -0
- package/dist/src/utils/pikku-cli-config.js +20 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -8
- package/skills/pikku-addon/SKILL.md +7 -3
- package/skills/pikku-ai-agent/SKILL.md +6 -3
- package/skills/pikku-ai-vercel/SKILL.md +6 -3
- package/skills/pikku-ai-voice/SKILL.md +6 -3
- package/skills/pikku-audit/SKILL.md +10 -3
- package/skills/pikku-aws/SKILL.md +9 -5
- package/skills/pikku-backblaze/SKILL.md +4 -3
- package/skills/pikku-better-auth/SKILL.md +10 -5
- package/skills/pikku-cli/SKILL.md +6 -3
- package/skills/pikku-concepts/SKILL.md +9 -4
- package/skills/pikku-concepts/references/concept-mapping.md +12 -10
- package/skills/pikku-config/SKILL.md +9 -5
- package/skills/pikku-cron/SKILL.md +6 -3
- package/skills/pikku-deploy-azure/SKILL.md +5 -3
- package/skills/pikku-deploy-cloudflare/SKILL.md +5 -3
- package/skills/pikku-deploy-express/SKILL.md +6 -3
- package/skills/pikku-deploy-fastify/SKILL.md +6 -3
- package/skills/pikku-deploy-lambda/SKILL.md +6 -3
- package/skills/pikku-deploy-nextjs/SKILL.md +5 -3
- package/skills/pikku-deploy-uws/SKILL.md +7 -4
- package/skills/pikku-deps/SKILL.md +13 -6
- package/skills/pikku-emails/SKILL.md +10 -5
- package/skills/pikku-feature/SKILL.md +1 -1
- package/skills/pikku-gateway-slack/SKILL.md +6 -3
- package/skills/pikku-http/SKILL.md +15 -21
- package/skills/pikku-http/references/http-options.md +0 -2
- package/skills/pikku-info/SKILL.md +9 -4
- package/skills/pikku-jose/SKILL.md +6 -3
- package/skills/pikku-kysely/SKILL.md +13 -5
- package/skills/pikku-machine-auth/SKILL.md +9 -3
- package/skills/pikku-mcp/SKILL.md +7 -3
- package/skills/pikku-middleware/SKILL.md +11 -6
- package/skills/pikku-mongodb/SKILL.md +8 -5
- package/skills/pikku-n8n-import/SKILL.md +109 -0
- package/skills/pikku-n8n-import/SPEC.md +84 -0
- package/skills/pikku-n8n-import/references/addon-mapping.md +121 -0
- package/skills/pikku-n8n-import/references/code-translation.md +121 -0
- package/skills/pikku-n8n-import/references/loops-and-control.md +87 -0
- package/skills/pikku-permissions/SKILL.md +26 -15
- package/skills/pikku-pino/SKILL.md +5 -3
- package/skills/pikku-product-second-opinion/README.md +43 -0
- package/skills/pikku-product-second-opinion/SKILL.md +158 -0
- package/skills/pikku-product-second-opinion/example/sample-report.md +90 -0
- package/skills/pikku-product-second-opinion/references/report-template.md +73 -0
- package/skills/pikku-queue/SKILL.md +7 -4
- package/skills/pikku-redis/SKILL.md +9 -6
- package/skills/pikku-rpc/SKILL.md +7 -4
- package/skills/pikku-rtl/SKILL.md +1 -1
- package/skills/pikku-scenario/SKILL.md +215 -0
- package/skills/pikku-schedule/SKILL.md +6 -3
- package/skills/pikku-schema-ajv/SKILL.md +5 -3
- package/skills/pikku-schema-cfworker/SKILL.md +6 -3
- package/skills/pikku-security/SKILL.md +8 -4
- package/skills/pikku-services/SKILL.md +8 -4
- package/skills/pikku-software-archaeology/README.md +70 -0
- package/skills/pikku-software-archaeology/SKILL.md +186 -0
- package/skills/pikku-software-archaeology/references/blueprint.schema.json +625 -0
- package/skills/pikku-software-archaeology/references/pikku-mapping.md +49 -0
- package/skills/pikku-software-archaeology/scripts/validate.mjs +173 -0
- package/skills/pikku-template-clone/SKILL.md +1 -1
- package/skills/pikku-trigger/SKILL.md +7 -3
- package/skills/pikku-versioning/SKILL.md +7 -3
- package/skills/pikku-websocket/SKILL.md +8 -4
- package/skills/pikku-workflow/SKILL.md +7 -3
- package/skills/pikku-ws/SKILL.md +5 -3
- package/skills/pikku-n8n-addon-map/SKILL.md +0 -178
- package/skills/pikku-n8n-code-translate/SKILL.md +0 -166
- package/skills/pikku-testing/SKILL.md +0 -328
- package/skills/pikku-testing/references/cucumber-bdd-testing.md +0 -176
|
@@ -6,7 +6,19 @@
|
|
|
6
6
|
"Bootstrap inspect": {
|
|
7
7
|
"nodeId": "Bootstrap inspect",
|
|
8
8
|
"flow": "inline",
|
|
9
|
-
"next": "Bootstrap
|
|
9
|
+
"next": "Bootstrap scope definition types"
|
|
10
|
+
},
|
|
11
|
+
"Bootstrap scope definition types": {
|
|
12
|
+
"nodeId": "Bootstrap scope definition types",
|
|
13
|
+
"rpcName": "pikkuScopeDefinitionTypes",
|
|
14
|
+
"next": "Bootstrap scopes",
|
|
15
|
+
"stepHash": "94d48581c462"
|
|
16
|
+
},
|
|
17
|
+
"Bootstrap scopes": {
|
|
18
|
+
"nodeId": "Bootstrap scopes",
|
|
19
|
+
"rpcName": "pikkuScopes",
|
|
20
|
+
"next": "Bootstrap function types split",
|
|
21
|
+
"stepHash": "41fa180b51ca"
|
|
10
22
|
},
|
|
11
23
|
"Bootstrap function types split": {
|
|
12
24
|
"nodeId": "Bootstrap function types split",
|
|
@@ -213,9 +225,15 @@
|
|
|
213
225
|
"Public agent scaffold": {
|
|
214
226
|
"nodeId": "Public agent scaffold",
|
|
215
227
|
"rpcName": "pikkuPublicAgent",
|
|
216
|
-
"next": "
|
|
228
|
+
"next": "Graph wirings",
|
|
217
229
|
"stepHash": "64d807033007"
|
|
218
230
|
},
|
|
231
|
+
"Graph wirings": {
|
|
232
|
+
"nodeId": "Graph wirings",
|
|
233
|
+
"rpcName": "pikkuGraphWirings",
|
|
234
|
+
"next": "Public RPC",
|
|
235
|
+
"stepHash": "441f296ab859"
|
|
236
|
+
},
|
|
219
237
|
"Public RPC": {
|
|
220
238
|
"nodeId": "Public RPC",
|
|
221
239
|
"rpcName": "pikkuPublicRPC",
|
|
@@ -267,9 +285,21 @@
|
|
|
267
285
|
"Credentials": {
|
|
268
286
|
"nodeId": "Credentials",
|
|
269
287
|
"rpcName": "pikkuCredentials",
|
|
270
|
-
"next": "
|
|
288
|
+
"next": "Scope definition types",
|
|
271
289
|
"stepHash": "3e4cb364d6f2"
|
|
272
290
|
},
|
|
291
|
+
"Scope definition types": {
|
|
292
|
+
"nodeId": "Scope definition types",
|
|
293
|
+
"rpcName": "pikkuScopeDefinitionTypes",
|
|
294
|
+
"next": "Scopes",
|
|
295
|
+
"stepHash": "578ebaf38e55"
|
|
296
|
+
},
|
|
297
|
+
"Scopes": {
|
|
298
|
+
"nodeId": "Scopes",
|
|
299
|
+
"rpcName": "pikkuScopes",
|
|
300
|
+
"next": "Variable definition types",
|
|
301
|
+
"stepHash": "1ca929a3b6de"
|
|
302
|
+
},
|
|
273
303
|
"Variable definition types": {
|
|
274
304
|
"nodeId": "Variable definition types",
|
|
275
305
|
"rpcName": "pikkuVariableDefinitionTypes",
|
|
@@ -326,9 +356,15 @@
|
|
|
326
356
|
"RPC exposed map": {
|
|
327
357
|
"nodeId": "RPC exposed map",
|
|
328
358
|
"rpcName": "pikkuRPCExposedMap",
|
|
329
|
-
"next": "
|
|
359
|
+
"next": "RPC remote map",
|
|
330
360
|
"stepHash": "20b6c409e9fb"
|
|
331
361
|
},
|
|
362
|
+
"RPC remote map": {
|
|
363
|
+
"nodeId": "RPC remote map",
|
|
364
|
+
"rpcName": "pikkuRPCRemoteMap",
|
|
365
|
+
"next": "Workflow",
|
|
366
|
+
"stepHash": "218a42566e2c"
|
|
367
|
+
},
|
|
332
368
|
"Workflow": {
|
|
333
369
|
"nodeId": "Workflow",
|
|
334
370
|
"rpcName": "pikkuWorkflow",
|
|
@@ -338,9 +374,15 @@
|
|
|
338
374
|
"Remote RPC": {
|
|
339
375
|
"nodeId": "Remote RPC",
|
|
340
376
|
"rpcName": "pikkuRemoteRPC",
|
|
341
|
-
"next": "
|
|
377
|
+
"next": "Webhook",
|
|
342
378
|
"stepHash": "82751ee2ed4b"
|
|
343
379
|
},
|
|
380
|
+
"Webhook": {
|
|
381
|
+
"nodeId": "Webhook",
|
|
382
|
+
"rpcName": "pikkuWebhook",
|
|
383
|
+
"next": "Workflow routes",
|
|
384
|
+
"stepHash": "a7d0991ef74f"
|
|
385
|
+
},
|
|
344
386
|
"Workflow routes": {
|
|
345
387
|
"nodeId": "Workflow routes",
|
|
346
388
|
"rpcName": "pikkuWorkflowRoutes",
|
|
@@ -562,5 +604,5 @@
|
|
|
562
604
|
"entryNodeIds": [
|
|
563
605
|
"Bootstrap inspect"
|
|
564
606
|
],
|
|
565
|
-
"graphHash": "
|
|
607
|
+
"graphHash": "d41d0307c719"
|
|
566
608
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* This file was generated by @pikku/cli@0.12.
|
|
2
|
+
* This file was generated by @pikku/cli@0.12.83
|
|
3
3
|
*/
|
|
4
4
|
import { WorkflowCancelledException } from '@pikku/core/workflow';
|
|
5
5
|
import { template } from '@pikku/core/workflow';
|
|
@@ -85,6 +85,7 @@ type NodeInputType<FuncMap extends Record<string, string>, K extends keyof FuncM
|
|
|
85
85
|
type NodeOutputKeys<FuncMap extends Record<string, string>, N extends string> = N extends keyof FuncMap ? FuncMap[N] extends keyof FlattenedRPCMap ? keyof FlattenedRPCMap[FuncMap[N]]['output'] & string : FuncMap[N] extends keyof FlattenedWorkflowMap ? keyof FlattenedWorkflowMap[FuncMap[N]]['output'] & string : FuncMap[N] extends keyof FlattenedAgentMap ? keyof FlattenedAgentMap[FuncMap[N]]['output'] & string : string : string;
|
|
86
86
|
type RefFunction<FuncMap extends Record<string, string>> = {
|
|
87
87
|
<N extends Extract<keyof FuncMap, string>>(nodeId: N, path: NodeOutputKeys<FuncMap, N>): TypedRef<unknown>;
|
|
88
|
+
<N extends Extract<keyof FuncMap, string>>(nodeId: N): TypedRef<unknown>;
|
|
88
89
|
(nodeId: 'trigger' | '$item', path?: string): TypedRef<unknown>;
|
|
89
90
|
};
|
|
90
91
|
type TemplateFunction = (templateStr: string, refs: TypedRef<unknown>[]) => TemplateString;
|
|
@@ -93,6 +94,8 @@ type GraphNodeConfigMap<FuncMap extends Record<string, string>> = {
|
|
|
93
94
|
next?: NextConfig<Extract<keyof FuncMap, string>>;
|
|
94
95
|
input?: NodeInputType<FuncMap, K> | (() => NodeInputType<FuncMap, K>) | ((ref: RefFunction<FuncMap>, template: TemplateFunction) => NodeInputType<FuncMap, K>);
|
|
95
96
|
onError?: Extract<keyof FuncMap, string> | Extract<keyof FuncMap, string>[];
|
|
97
|
+
/** Free-text node documentation. Non-semantic — excluded from graphHash. */
|
|
98
|
+
notes?: string;
|
|
96
99
|
};
|
|
97
100
|
};
|
|
98
101
|
type NextConfig<NodeIds extends string> = NodeIds | NodeIds[] | {
|
package/dist/bin/pikku-bin.mjs
CHANGED
|
@@ -11,8 +11,8 @@ async function checkForUpdate() {
|
|
|
11
11
|
})
|
|
12
12
|
if (!res.ok) return
|
|
13
13
|
const { version: latest } = await res.json()
|
|
14
|
-
if (latest !== '0.12.
|
|
15
|
-
process.stderr.write(`\n Update available 0.12.
|
|
14
|
+
if (latest !== '0.12.83') {
|
|
15
|
+
process.stderr.write(`\n Update available 0.12.83 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
|
|
16
16
|
}
|
|
17
17
|
} catch {}
|
|
18
18
|
}
|
package/dist/src/cli.wiring.js
CHANGED
|
@@ -21,6 +21,8 @@ import { dbGenerate } from './functions/commands/db-generate.js';
|
|
|
21
21
|
import { dbSeed } from './functions/commands/db-seed.js';
|
|
22
22
|
import { dbReset } from './functions/commands/db-reset.js';
|
|
23
23
|
import { dbAudit } from './functions/commands/db-audit.js';
|
|
24
|
+
import { scopesAudit } from './functions/commands/scopes-audit.js';
|
|
25
|
+
import { scopesPrune } from './functions/commands/scopes-prune.js';
|
|
24
26
|
import { pikkuAudit } from './functions/commands/audit.js';
|
|
25
27
|
import { workspaceValidate, renderWorkspaceValidate, } from './functions/commands/workspace-validate.js';
|
|
26
28
|
import { scenarioRun, scenarioList } from './functions/commands/scenario.js';
|
|
@@ -33,8 +35,9 @@ import { pikkuNewWiring } from './functions/commands/new-wiring.js';
|
|
|
33
35
|
import { pikkuNewMiddleware } from './functions/commands/new-middleware.js';
|
|
34
36
|
import { pikkuNewPermission } from './functions/commands/new-permission.js';
|
|
35
37
|
import { pikkuNewAddon } from './functions/commands/new-addon.js';
|
|
38
|
+
import { pikkuImportN8n } from './functions/commands/import-n8n.js';
|
|
36
39
|
import { pikkuInfoFunctions, pikkuInfoTags, pikkuInfoMiddleware, pikkuInfoPermissions, } from './functions/commands/info.js';
|
|
37
|
-
import { enableRpc, enableConsole, enableScenarios, enableAgent, enableWorkflow, enableEvents, enableRemoteRpc, } from './functions/commands/enable.js';
|
|
40
|
+
import { enableRpc, enableConsole, enableScenarios, enableAgent, enableWorkflow, enableEvents, enableRemoteRpc, enableWebhook, } from './functions/commands/enable.js';
|
|
38
41
|
import { pikkuRealtime } from './functions/wirings/realtime/pikku-command-realtime.js';
|
|
39
42
|
import { binary } from './functions/commands/binary.js';
|
|
40
43
|
import { deployPlan } from './functions/commands/deploy-plan.js';
|
|
@@ -332,6 +335,26 @@ wireCLI({
|
|
|
332
335
|
}),
|
|
333
336
|
},
|
|
334
337
|
},
|
|
338
|
+
scopes: {
|
|
339
|
+
description: 'Inspect and maintain declared authorization scopes',
|
|
340
|
+
subcommands: {
|
|
341
|
+
audit: pikkuCLICommand({
|
|
342
|
+
func: scopesAudit,
|
|
343
|
+
description: 'Report scopes in the database that are no longer declared in code, and the roles holding them',
|
|
344
|
+
}),
|
|
345
|
+
prune: pikkuCLICommand({
|
|
346
|
+
func: scopesPrune,
|
|
347
|
+
description: 'Remove scopes that are no longer declared in code, cascading them out of every role',
|
|
348
|
+
options: {
|
|
349
|
+
yes: {
|
|
350
|
+
description: 'Actually delete. Without it, prune only reports the blast radius',
|
|
351
|
+
short: 'y',
|
|
352
|
+
default: false,
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
}),
|
|
356
|
+
},
|
|
357
|
+
},
|
|
335
358
|
workspace: {
|
|
336
359
|
description: 'Workspace-level validation and maintenance commands',
|
|
337
360
|
subcommands: {
|
|
@@ -483,6 +506,10 @@ wireCLI({
|
|
|
483
506
|
},
|
|
484
507
|
},
|
|
485
508
|
}),
|
|
509
|
+
webhook: pikkuCLICommand({
|
|
510
|
+
func: enableWebhook,
|
|
511
|
+
description: 'Enable the outgoing webhook delivery queue worker (scaffolds webhook.gen.ts)',
|
|
512
|
+
}),
|
|
486
513
|
},
|
|
487
514
|
},
|
|
488
515
|
new: {
|
|
@@ -564,7 +591,7 @@ wireCLI({
|
|
|
564
591
|
default: false,
|
|
565
592
|
},
|
|
566
593
|
oauth: {
|
|
567
|
-
description: 'Include OAuth2 credential wiring
|
|
594
|
+
description: 'Include OAuth2 credential wiring; the API service reads its access token from the credential service',
|
|
568
595
|
default: false,
|
|
569
596
|
},
|
|
570
597
|
credential: {
|
|
@@ -592,6 +619,22 @@ wireCLI({
|
|
|
592
619
|
}),
|
|
593
620
|
},
|
|
594
621
|
},
|
|
622
|
+
import: {
|
|
623
|
+
description: 'Import workflows from other systems',
|
|
624
|
+
subcommands: {
|
|
625
|
+
n8n: pikkuCLICommand({
|
|
626
|
+
func: pikkuImportN8n,
|
|
627
|
+
description: 'Import an n8n workflow JSON export (a single workflow, an export array, or a directory of exports) into Pikku workflow graphs + stub functions',
|
|
628
|
+
parameters: '<file>',
|
|
629
|
+
options: {
|
|
630
|
+
out: {
|
|
631
|
+
description: 'Output directory (defaults to scaffold.functionDir or cwd)',
|
|
632
|
+
short: 'o',
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
}),
|
|
636
|
+
},
|
|
637
|
+
},
|
|
595
638
|
versions: {
|
|
596
639
|
description: 'Manage function contract versions',
|
|
597
640
|
subcommands: {
|
|
@@ -680,7 +723,7 @@ wireCLI({
|
|
|
680
723
|
},
|
|
681
724
|
},
|
|
682
725
|
skills: {
|
|
683
|
-
description: 'Install bundled agent skills (Claude Code
|
|
726
|
+
description: 'Install bundled agent skills (Claude Code, opencode, pi; Codex/Gemini coming soon)',
|
|
684
727
|
subcommands: {
|
|
685
728
|
list: pikkuCLICommand({
|
|
686
729
|
func: pikkuSkillsList,
|
|
@@ -691,7 +734,7 @@ wireCLI({
|
|
|
691
734
|
description: 'Copy bundled skills into the current project',
|
|
692
735
|
options: {
|
|
693
736
|
agent: {
|
|
694
|
-
description: 'Target agent (claude | opencode |
|
|
737
|
+
description: 'Target agent (claude | opencode | pi). Default: claude',
|
|
695
738
|
default: 'claude',
|
|
696
739
|
},
|
|
697
740
|
only: {
|
|
@@ -31,6 +31,7 @@ export function analyzeDeployment(state, options) {
|
|
|
31
31
|
funcId.startsWith('workflowStart:') ||
|
|
32
32
|
funcId.startsWith('workflow:') ||
|
|
33
33
|
funcId.startsWith('workflowStatus:') ||
|
|
34
|
+
funcId.startsWith('workflowApprove:') ||
|
|
34
35
|
funcId.startsWith('pikkuWorkflowWorker:') ||
|
|
35
36
|
funcId.startsWith('pikkuWorkflowOrchestrator:')) {
|
|
36
37
|
continue;
|
|
@@ -419,6 +420,11 @@ function buildWorkflows(graphMeta, functionsMeta, rpcMeta, _httpMeta, units, wor
|
|
|
419
420
|
route: `/workflow/${graph.name}/status/:runId`,
|
|
420
421
|
pikkuFuncId: `workflowStatus:${graph.name}`,
|
|
421
422
|
},
|
|
423
|
+
{
|
|
424
|
+
method: 'post',
|
|
425
|
+
route: `/workflow/${graph.name}/approve/:runId`,
|
|
426
|
+
pikkuFuncId: `workflowApprove:${graph.name}`,
|
|
427
|
+
},
|
|
422
428
|
{
|
|
423
429
|
method: 'post',
|
|
424
430
|
route: `/workflow/${graph.name}/graph/:nodeId`,
|
|
@@ -661,7 +661,7 @@ export declare const fabricCommands: {
|
|
|
661
661
|
}, {
|
|
662
662
|
proxyUrl: string;
|
|
663
663
|
apiKey: string;
|
|
664
|
-
format: "
|
|
664
|
+
format: "json" | "text" | "shell" | "env";
|
|
665
665
|
}, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
666
666
|
shell?: boolean | undefined;
|
|
667
667
|
env?: boolean | undefined;
|
|
@@ -669,7 +669,7 @@ export declare const fabricCommands: {
|
|
|
669
669
|
}, {
|
|
670
670
|
proxyUrl: string;
|
|
671
671
|
apiKey: string;
|
|
672
|
-
format: "
|
|
672
|
+
format: "json" | "text" | "shell" | "env";
|
|
673
673
|
}, "rpc" | "session", import("../../types/application-types.js").Services> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
674
674
|
shell?: boolean | undefined;
|
|
675
675
|
env?: boolean | undefined;
|
|
@@ -677,7 +677,7 @@ export declare const fabricCommands: {
|
|
|
677
677
|
}, {
|
|
678
678
|
proxyUrl: string;
|
|
679
679
|
apiKey: string;
|
|
680
|
-
format: "
|
|
680
|
+
format: "json" | "text" | "shell" | "env";
|
|
681
681
|
}, "rpc" | "session", import("../../types/application-types.js").Services>, undefined, undefined>, import("../../.pikku/pikku-types.gen.js").PikkuMiddleware, (services: import("../../types/application-types.js").SingletonServices, data: any, session?: import("../../types/application-types.js").UserSession | undefined) => void | Promise<void>, string>;
|
|
682
682
|
};
|
|
683
683
|
};
|
|
@@ -8,8 +8,8 @@ export declare const FabricLLMKeyOutput: z.ZodObject<{
|
|
|
8
8
|
proxyUrl: z.ZodString;
|
|
9
9
|
apiKey: z.ZodString;
|
|
10
10
|
format: z.ZodEnum<{
|
|
11
|
-
text: "text";
|
|
12
11
|
json: "json";
|
|
12
|
+
text: "text";
|
|
13
13
|
shell: "shell";
|
|
14
14
|
env: "env";
|
|
15
15
|
}>;
|
|
@@ -21,7 +21,7 @@ export declare const FabricLLMKey: import("../../../.pikku/pikku-types.gen.js").
|
|
|
21
21
|
}, {
|
|
22
22
|
proxyUrl: string;
|
|
23
23
|
apiKey: string;
|
|
24
|
-
format: "
|
|
24
|
+
format: "json" | "text" | "shell" | "env";
|
|
25
25
|
}, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
|
|
26
26
|
shell?: boolean | undefined;
|
|
27
27
|
env?: boolean | undefined;
|
|
@@ -29,7 +29,7 @@ export declare const FabricLLMKey: import("../../../.pikku/pikku-types.gen.js").
|
|
|
29
29
|
}, {
|
|
30
30
|
proxyUrl: string;
|
|
31
31
|
apiKey: string;
|
|
32
|
-
format: "
|
|
32
|
+
format: "json" | "text" | "shell" | "env";
|
|
33
33
|
}, "rpc" | "session", import("../../../types/application-types.js").Services> | import("../../../.pikku/pikku-types.gen.js").PikkuFunction<{
|
|
34
34
|
shell?: boolean | undefined;
|
|
35
35
|
env?: boolean | undefined;
|
|
@@ -37,7 +37,7 @@ export declare const FabricLLMKey: import("../../../.pikku/pikku-types.gen.js").
|
|
|
37
37
|
}, {
|
|
38
38
|
proxyUrl: string;
|
|
39
39
|
apiKey: string;
|
|
40
|
-
format: "
|
|
40
|
+
format: "json" | "text" | "shell" | "env";
|
|
41
41
|
}, "rpc" | "session", import("../../../types/application-types.js").Services>, undefined, undefined>;
|
|
42
42
|
export declare const renderLLMKey: (_services: unknown, data: {
|
|
43
43
|
proxyUrl: string;
|
|
@@ -1058,8 +1058,48 @@ export async function runValidate(startDir = process.cwd()) {
|
|
|
1058
1058
|
}
|
|
1059
1059
|
// ── packages/theme + packages/components ──────────────────────────────
|
|
1060
1060
|
const designDocUrl = 'https://pikkufabric.dev/docs/design';
|
|
1061
|
-
|
|
1062
|
-
|
|
1061
|
+
const themePkgDir = join(root, 'packages', 'mantine-theme');
|
|
1062
|
+
if (!existsSync(themePkgDir)) {
|
|
1063
|
+
info('theme-missing', 'packages/mantine-theme/ not found — Fabric design features require a theme package', themePkgDir, `Create packages/mantine-theme/ with your Mantine theme tokens. See ${designDocUrl}`);
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
// The Fabric console's Design tab lists a theme only when it can read a
|
|
1067
|
+
// themes/<id>.json spec (+ active.json pointing at one) — that spec is the
|
|
1068
|
+
// single source of truth the app runtime and the console both consume. A
|
|
1069
|
+
// package that only hand-writes createTheme() renders fine but the console
|
|
1070
|
+
// reports "no theme set" and cannot edit it. Mirror getSandboxThemes' file
|
|
1071
|
+
// logic (themes/<id>.json where id matches THEME_ID_RE, + active.json.id).
|
|
1072
|
+
const themeIdRe = /^[a-z][a-z0-9-]{0,38}$/;
|
|
1073
|
+
const themesDir = join(themePkgDir, 'themes');
|
|
1074
|
+
let specIds = [];
|
|
1075
|
+
if (existsSync(themesDir)) {
|
|
1076
|
+
try {
|
|
1077
|
+
specIds = (await readdir(themesDir))
|
|
1078
|
+
.filter((f) => f.endsWith('.json'))
|
|
1079
|
+
.map((f) => f.slice(0, -'.json'.length))
|
|
1080
|
+
.filter((id) => themeIdRe.test(id));
|
|
1081
|
+
}
|
|
1082
|
+
catch {
|
|
1083
|
+
// readdir failure — treat as no specs
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
if (specIds.length === 0) {
|
|
1087
|
+
info('theme-no-spec', 'packages/mantine-theme/ has no themes/<id>.json spec — the Fabric console Design tab reports "no theme set" (and cannot edit the theme) even if the app is branded via a hand-written createTheme()', themesDir, lines('Add a theme spec the console can read:', '1. Create packages/mantine-theme/themes/<id>.json (id is kebab-case), e.g.:', '{', ' "name": "My Brand",', ' "brand": { "colors": { "primary": "#4f46e5" }, "fonts": { "body": "Inter" } },', ' "structure": { "defaultRadius": "md", "defaultColorScheme": "light" }', '}', '2. Create packages/mantine-theme/active.json: { "id": "<id>" }', '3. Build the Mantine theme from the active spec in index.ts.', `See ${designDocUrl}`));
|
|
1088
|
+
}
|
|
1089
|
+
else {
|
|
1090
|
+
// A spec exists — active.json must point at one, else the console has no
|
|
1091
|
+
// active theme (getSandboxThemes falls back to a "default" id that may
|
|
1092
|
+
// not exist among the specs).
|
|
1093
|
+
const activePath = join(themePkgDir, 'active.json');
|
|
1094
|
+
const active = await readJsonSafe(activePath);
|
|
1095
|
+
const activeId = typeof active?.id === 'string' ? active.id : null;
|
|
1096
|
+
if (!activeId) {
|
|
1097
|
+
info('theme-no-active', 'packages/mantine-theme/active.json is missing or has no string "id" — the Fabric console falls back to the "default" theme id, which may not match any themes/<id>.json', activePath, lines('Create packages/mantine-theme/active.json pointing at an existing spec:', `{ "id": "${specIds[0]}" }`));
|
|
1098
|
+
}
|
|
1099
|
+
else if (!specIds.includes(activeId)) {
|
|
1100
|
+
info('theme-active-mismatch', `packages/mantine-theme/active.json points at "${activeId}" but no themes/${activeId}.json exists — the Fabric console has no active theme`, activePath, lines(`Point active.json at an existing spec (${specIds.join(', ')}):`, `{ "id": "${specIds[0]}" }`));
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1063
1103
|
}
|
|
1064
1104
|
if (!existsSync(join(root, 'packages', 'components'))) {
|
|
1065
1105
|
info('components-missing', 'packages/components/ not found — Fabric design features require a components package', join(root, 'packages', 'components'), `Create packages/components/ with your shared UI components. See ${designDocUrl}`);
|
|
@@ -3,6 +3,8 @@ export const bootstrap = pikkuVoidFunc({
|
|
|
3
3
|
remote: true,
|
|
4
4
|
func: async ({ logger, getInspectorState }, _data, { rpc }) => {
|
|
5
5
|
await getInspectorState(false, true, true);
|
|
6
|
+
// Before function types: they import ScopeId from the scopes codegen.
|
|
7
|
+
await rpc.invoke('pikkuScopes', { bootstrap: true });
|
|
6
8
|
await rpc.invoke('pikkuFunctionTypesSplit', { bootstrap: true });
|
|
7
9
|
// Stub auth.types.ts (if better-auth is used) so the pikkuBetterAuth
|
|
8
10
|
// re-export resolves before any user file is imported.
|
|
@@ -18,6 +20,7 @@ export const bootstrap = pikkuVoidFunc({
|
|
|
18
20
|
await rpc.invoke('pikkuAIAgentTypes');
|
|
19
21
|
await rpc.invoke('pikkuNodeTypes');
|
|
20
22
|
await rpc.invoke('pikkuSecretDefinitionTypes');
|
|
23
|
+
await rpc.invoke('pikkuScopeDefinitionTypes');
|
|
21
24
|
await rpc.invoke('pikkuCLITypes', { bootstrap: true });
|
|
22
25
|
if (logger.hasCriticalErrors()) {
|
|
23
26
|
process.exit(1);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { join, resolve } from 'path';
|
|
2
2
|
import { pikkuSessionlessFunc } from '#pikku';
|
|
3
3
|
import chokidar from 'chokidar';
|
|
4
|
-
import { pikkuDevReloader, reloadGeneratedMeta } from '@pikku/core/dev';
|
|
5
|
-
import { ConsoleLogger, LocalEmailService, spy, InMemoryQueueService, InMemoryWorkflowService, InMemoryTriggerService, InMemoryAIRunStateService, } from '@pikku/core/services';
|
|
4
|
+
import { pikkuDevReloader, reloadGeneratedMeta, reconcileAddonRegistry, } from '@pikku/core/dev';
|
|
5
|
+
import { ConsoleLogger, LocalEmailService, spy, InMemoryQueueService, InMemoryWorkflowService, InMemoryTriggerService, InMemoryAIRunStateService, QueueWebhookService, } from '@pikku/core/services';
|
|
6
6
|
import { KyselyAIStorageService, KyselyAIRunStateService, KyselyAgentRunService, } from '@pikku/kysely';
|
|
7
7
|
import { stopSingletonServices } from '@pikku/core';
|
|
8
8
|
import { pikkuState } from '@pikku/core/internal';
|
|
@@ -182,6 +182,7 @@ export const dev = pikkuSessionlessFunc({
|
|
|
182
182
|
// services.ts. Its EventHub is shared into the singleton services so
|
|
183
183
|
// function-side broadcasts reach the sockets the transport holds.
|
|
184
184
|
const eventHub = await devServerRunner.createEventHub();
|
|
185
|
+
const devQueueService = new InMemoryQueueService();
|
|
185
186
|
const inMemoryServices = {
|
|
186
187
|
logger: devLogger,
|
|
187
188
|
...(aiAgentRunner ? { aiAgentRunner } : {}),
|
|
@@ -191,7 +192,8 @@ export const dev = pikkuSessionlessFunc({
|
|
|
191
192
|
metaService: new LocalMetaService(pikkuDir),
|
|
192
193
|
...(coverageService ? { coverageService } : {}),
|
|
193
194
|
schedulerService,
|
|
194
|
-
queueService:
|
|
195
|
+
queueService: devQueueService,
|
|
196
|
+
webhookService: new QueueWebhookService(devQueueService),
|
|
195
197
|
workflowService,
|
|
196
198
|
workflowRunService: workflowService,
|
|
197
199
|
triggerService: new InMemoryTriggerService(),
|
|
@@ -292,6 +294,15 @@ export const dev = pikkuSessionlessFunc({
|
|
|
292
294
|
// this post-codegen pass (the reloader's instant pass ran too
|
|
293
295
|
// early to see it).
|
|
294
296
|
await devReloader?.reimportPending();
|
|
297
|
+
// reimportPending only re-runs wire* for changed/added files, so a
|
|
298
|
+
// DELETED *.addon.ts leaves its wireAddon entry stranded in the
|
|
299
|
+
// live registry. Prune it against the inspection runAllWithCommandState
|
|
300
|
+
// already produced this pass — a plain read (no refresh) reuses that
|
|
301
|
+
// fresh post-change cache. Forcing refresh=true here re-inspected the
|
|
302
|
+
// whole project a SECOND time: the codegen writes after that inspection
|
|
303
|
+
// bump the ts-write generation, so refresh treats the cache as stale.
|
|
304
|
+
const { rpc } = await getInspectorState();
|
|
305
|
+
reconcileAddonRegistry(rpc.wireAddonDeclarations.keys(), logger);
|
|
295
306
|
logger.info({
|
|
296
307
|
message: `✓ Generated in ${Date.now() - start}ms`,
|
|
297
308
|
type: 'timing',
|
|
@@ -5,3 +5,4 @@ export declare const enableAgent: import("#pikku").PikkuFunctionConfig<void, voi
|
|
|
5
5
|
export declare const enableWorkflow: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").Services> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").Services>, undefined, undefined>;
|
|
6
6
|
export declare const enableEvents: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").Services> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").Services>, undefined, undefined>;
|
|
7
7
|
export declare const enableRemoteRpc: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").Services> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").Services>, undefined, undefined>;
|
|
8
|
+
export declare const enableWebhook: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").Services> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").Services>, undefined, undefined>;
|
|
@@ -23,11 +23,13 @@ async function enableFeature(feature, logger, config, data) {
|
|
|
23
23
|
}
|
|
24
24
|
// The console is an admin surface — every RPC requires a session, so it can
|
|
25
25
|
// never be scaffolded no-auth (the --no-auth flag is ignored for it).
|
|
26
|
-
const value = feature === '
|
|
27
|
-
?
|
|
28
|
-
:
|
|
29
|
-
? '
|
|
30
|
-
:
|
|
26
|
+
const value = feature === 'webhook'
|
|
27
|
+
? true
|
|
28
|
+
: feature === 'console'
|
|
29
|
+
? 'auth'
|
|
30
|
+
: noAuth
|
|
31
|
+
? 'no-auth'
|
|
32
|
+
: FEATURE_DEFAULTS[feature];
|
|
31
33
|
json.scaffold[feature] = value;
|
|
32
34
|
await writeFile(configPath, JSON.stringify(json, null, 2) + '\n', 'utf-8');
|
|
33
35
|
logger.info(`Enabled scaffold.${feature} = '${value}' in ${configPath}`);
|
|
@@ -53,3 +55,6 @@ export const enableEvents = pikkuVoidFunc({
|
|
|
53
55
|
export const enableRemoteRpc = pikkuVoidFunc({
|
|
54
56
|
func: async ({ logger, config }, data) => enableFeature('remoteRpc', logger, config, data),
|
|
55
57
|
});
|
|
58
|
+
export const enableWebhook = pikkuVoidFunc({
|
|
59
|
+
func: async ({ logger, config }, data) => enableFeature('webhook', logger, config, data),
|
|
60
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const pikkuImportN8n: import("#pikku").PikkuFunctionConfig<{
|
|
2
|
+
file: string;
|
|
3
|
+
out?: string;
|
|
4
|
+
}, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<{
|
|
5
|
+
file: string;
|
|
6
|
+
out?: string;
|
|
7
|
+
}, void, "rpc" | "session", import("#pikku").Services> | import("#pikku").PikkuFunction<{
|
|
8
|
+
file: string;
|
|
9
|
+
out?: string;
|
|
10
|
+
}, void, "rpc" | "session", import("#pikku").Services>, undefined, undefined>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { basename, isAbsolute, join, resolve } from 'path';
|
|
3
|
+
import { mkdir, readdir, readFile, stat, writeFile } from 'fs/promises';
|
|
4
|
+
import { pikkuSessionlessFunc } from '#pikku';
|
|
5
|
+
import { parseN8n, generateWorkflowFromN8n } from '@pikku/n8n-import';
|
|
6
|
+
async function writeFiles(baseDir, files) {
|
|
7
|
+
const written = [];
|
|
8
|
+
for (const [relativePath, content] of Object.entries(files)) {
|
|
9
|
+
const fullPath = join(baseDir, relativePath);
|
|
10
|
+
await mkdir(join(fullPath, '..'), { recursive: true });
|
|
11
|
+
await writeFile(fullPath, content, 'utf-8');
|
|
12
|
+
written.push(fullPath);
|
|
13
|
+
}
|
|
14
|
+
return written;
|
|
15
|
+
}
|
|
16
|
+
// A single n8n export file may hold one workflow object, a bare array of
|
|
17
|
+
// workflows (n8n `export:workflow --all`), or a `{ workflows: [...] }` wrapper.
|
|
18
|
+
// Flatten whichever shape into one job per workflow.
|
|
19
|
+
function collectJobs(raw, nameHint, jobs) {
|
|
20
|
+
const list = Array.isArray(raw)
|
|
21
|
+
? raw
|
|
22
|
+
: raw && Array.isArray(raw.workflows)
|
|
23
|
+
? raw.workflows
|
|
24
|
+
: null;
|
|
25
|
+
if (list) {
|
|
26
|
+
list.forEach((wf, i) => {
|
|
27
|
+
const own = wf?.name?.trim();
|
|
28
|
+
jobs.push({ raw: wf, nameHint: own || `${nameHint}-${i + 1}` });
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
jobs.push({ raw, nameHint });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function importOne({ raw, nameHint }, baseDir, logger) {
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = parseN8n(raw, nameHint);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
logger.error(`Failed to parse "${nameHint}": ${err.message}`);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const { files, manifest, credentialInstances, diagnostics } = generateWorkflowFromN8n(parsed);
|
|
45
|
+
// A single-file import can only resolve self-references; any cross-workflow
|
|
46
|
+
// sub-workflow reference is un-importable here. Report and skip rather than
|
|
47
|
+
// write a partial, un-runnable scaffold.
|
|
48
|
+
if (diagnostics.some((d) => d.type === 'error')) {
|
|
49
|
+
logger.error(`Cannot import "${parsed.name}":`);
|
|
50
|
+
for (const d of diagnostics) {
|
|
51
|
+
logger.error(` [${d.reason}] ${d.message}`);
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const written = await writeFiles(baseDir, files);
|
|
56
|
+
logger.info(`Imported "${parsed.name}" (${parsed.shape}) → ${written.length} file(s) in ${baseDir}`);
|
|
57
|
+
if (manifest.length > 0) {
|
|
58
|
+
logger.info(` ${manifest.length} integration node(s) recorded in ${parsed.slug}.integrations.json`);
|
|
59
|
+
}
|
|
60
|
+
if (credentialInstances.length > 0) {
|
|
61
|
+
logger.info(` ${credentialInstances.length} addon instance(s) wired in ${parsed.slug}.addons.gen.ts: ${credentialInstances
|
|
62
|
+
.map((i) => i.instanceName)
|
|
63
|
+
.join(', ')}`);
|
|
64
|
+
}
|
|
65
|
+
const stubCount = written.filter((f) => f.includes('/functions/')).length;
|
|
66
|
+
if (stubCount > 0) {
|
|
67
|
+
logger.info(` ${stubCount} stub function(s) to implement — run the pikku-n8n-import skill to fill them in`);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
export const pikkuImportN8n = pikkuSessionlessFunc({
|
|
72
|
+
func: async ({ logger, config }, { file, out }) => {
|
|
73
|
+
const inputPath = isAbsolute(file) ? file : resolve(process.cwd(), file);
|
|
74
|
+
if (!existsSync(inputPath)) {
|
|
75
|
+
logger.error(`n8n workflow file not found: ${inputPath}`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const baseDir = out
|
|
79
|
+
? isAbsolute(out)
|
|
80
|
+
? out
|
|
81
|
+
: resolve(process.cwd(), out)
|
|
82
|
+
: config.scaffold?.functionDir || process.cwd();
|
|
83
|
+
const jobs = [];
|
|
84
|
+
if ((await stat(inputPath)).isDirectory()) {
|
|
85
|
+
const entries = (await readdir(inputPath))
|
|
86
|
+
.filter((f) => f.toLowerCase().endsWith('.json'))
|
|
87
|
+
.sort();
|
|
88
|
+
if (entries.length === 0) {
|
|
89
|
+
logger.error(`No .json workflow files found in ${inputPath}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
try {
|
|
94
|
+
const raw = JSON.parse(await readFile(join(inputPath, entry), 'utf-8'));
|
|
95
|
+
collectJobs(raw, entry.replace(/\.json$/i, ''), jobs);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
logger.error(`Failed to read ${entry}: ${err.message}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
let raw;
|
|
104
|
+
try {
|
|
105
|
+
raw = JSON.parse(await readFile(inputPath, 'utf-8'));
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
logger.error(`Failed to parse n8n workflow: ${err.message}`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
collectJobs(raw, basename(inputPath).replace(/\.json$/i, ''), jobs);
|
|
112
|
+
}
|
|
113
|
+
if (jobs.length === 0) {
|
|
114
|
+
logger.error('No workflows found to import');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
let failed = 0;
|
|
118
|
+
for (const job of jobs) {
|
|
119
|
+
if (!(await importOne(job, baseDir, logger)))
|
|
120
|
+
failed++;
|
|
121
|
+
}
|
|
122
|
+
if (jobs.length > 1) {
|
|
123
|
+
const ok = jobs.length - failed;
|
|
124
|
+
logger.info(`Imported ${ok}/${jobs.length} workflow(s) into ${baseDir}${failed > 0 ? ` — ${failed} failed` : ''}`);
|
|
125
|
+
}
|
|
126
|
+
if (failed > 0) {
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
});
|