@pikku/cli 0.12.48 → 0.12.50

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 (81) hide show
  1. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  2. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  3. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  4. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  5. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  6. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  7. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  8. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  10. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  11. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  15. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  16. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  17. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  18. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  19. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  20. package/dist/.pikku/function/pikku-functions-meta.gen.json +165 -165
  21. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  22. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  23. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  24. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  25. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  26. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  27. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  28. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  29. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  30. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  31. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  32. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  33. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  34. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  35. package/dist/.pikku/pikku-types.gen.js +1 -1
  36. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  37. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  38. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  39. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  40. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  41. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  42. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +2 -2
  43. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  44. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  45. package/dist/.pikku/schemas/register.gen.js +11 -11
  46. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  47. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  48. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  49. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  50. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  51. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  52. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  53. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  54. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  55. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  56. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  57. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  58. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  59. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  60. package/dist/bin/pikku-bin.mjs +2 -2
  61. package/dist/src/deploy/server-entry.d.ts +1 -1
  62. package/dist/src/deploy/server-entry.js +3 -1
  63. package/dist/src/fabric/functions/validate.function.js +102 -0
  64. package/dist/src/fabric/lib/config.js +1 -1
  65. package/dist/src/functions/commands/dev-ai-runner.d.ts +19 -0
  66. package/dist/src/functions/commands/dev-ai-runner.js +70 -0
  67. package/dist/src/functions/commands/dev.js +16 -0
  68. package/dist/src/functions/commands/tests-coverage.js +6 -0
  69. package/dist/src/functions/db/db-codegen.d.ts +9 -6
  70. package/dist/src/functions/db/db-codegen.js +62 -5
  71. package/dist/src/functions/db/db-introspector.d.ts +6 -0
  72. package/dist/src/functions/db/local-db.d.ts +1 -0
  73. package/dist/src/functions/db/local-db.js +3 -0
  74. package/dist/src/functions/db/sqlite/sqlite-introspector.d.ts +8 -0
  75. package/dist/src/functions/db/sqlite/sqlite-introspector.js +27 -0
  76. package/dist/src/scaffold/rpc-remote.gen.js +1 -1
  77. package/dist/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +2 -2
  79. package/skills/pikku-paraglide/SKILL.md +117 -0
  80. package/dist/src/fabric/functions/validate-core.d.ts +0 -20
  81. package/dist/src/fabric/functions/validate-core.js +0 -287
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import './rpc/pikku-rpc-wirings-meta.internal.gen.js';
5
5
  import './http/pikku-http-wirings-meta.gen.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { LocalMetaService } from '@pikku/core/services/local-meta';
5
5
  export declare class PikkuMetaService extends LocalMetaService {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { LocalMetaService } from '@pikku/core/services/local-meta';
5
5
  export class PikkuMetaService extends LocalMetaService {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import type { SingletonServices } from '../types/application-types.d.js';
5
5
  import type { Services } from '../types/application-types.d.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Main type export hub - re-exports all wiring-specific types
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Main type export hub - re-exports all wiring-specific types
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Queue-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Queue-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { pikkuState } from '@pikku/core/internal';
5
5
  import metaData from './pikku-queue-workers-wirings-meta.gen.json' with { type: 'json' };
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import '../../src/scaffold/rpc-remote.gen.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /* The files with an addQueueWorkers function call */
5
5
  import '../../src/scaffold/rpc-remote.gen.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { pikkuState } from '@pikku/core/internal';
5
5
  import metaData from './pikku-rpc-wirings-meta.internal.gen.json' with { type: 'json' };
@@ -109,15 +109,15 @@
109
109
  "pikkuCommandChannels": "pikkuCommandChannels",
110
110
  "pikkuCLIEntry": "pikkuCLIEntry",
111
111
  "pikkuCLI": "pikkuCLI",
112
+ "pikkuCredentials": "pikkuCredentials",
112
113
  "pikkuConsoleFunctions": "pikkuConsoleFunctions",
113
114
  "pikkuNodeTypes": "pikkuNodeTypes",
114
115
  "pikkuNodesMeta": "pikkuNodesMeta",
115
- "pikkuCredentials": "pikkuCredentials",
116
+ "pikkuGateway": "pikkuGateway",
116
117
  "pikkuFunctionTypesSplit": "pikkuFunctionTypesSplit",
117
118
  "pikkuFunctionTypes": "pikkuFunctionTypes",
118
119
  "pikkuFunctions": "pikkuFunctions",
119
120
  "pikkuServices": "pikkuServices",
120
- "pikkuGateway": "pikkuGateway",
121
121
  "pikkuHTTPMap": "pikkuHTTPMap",
122
122
  "pikkuCommandHTTP": "pikkuCommandHTTP",
123
123
  "pikkuHTTPTypes": "pikkuHTTPTypes",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Scheduler-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Scheduler-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { addSchema } from '@pikku/core/schema';
5
5
  import * as PikkuSchemasOutput from './schemas/PikkuSchemasOutput.schema.json' with { type: 'json' };
@@ -202,14 +202,14 @@ import * as PikkuPublicAgentOutput from './schemas/PikkuPublicAgentOutput.schema
202
202
  addSchema('PikkuPublicAgentOutput', PikkuPublicAgentOutput);
203
203
  import * as PikkuCommandChannelsOutput from './schemas/PikkuCommandChannelsOutput.schema.json' with { type: 'json' };
204
204
  addSchema('PikkuCommandChannelsOutput', PikkuCommandChannelsOutput);
205
- import * as PikkuCLIEntryOutput from './schemas/PikkuCLIEntryOutput.schema.json' with { type: 'json' };
206
- addSchema('PikkuCLIEntryOutput', PikkuCLIEntryOutput);
207
- import * as PikkuCLIOutput from './schemas/PikkuCLIOutput.schema.json' with { type: 'json' };
208
- addSchema('PikkuCLIOutput', PikkuCLIOutput);
209
205
  import * as PikkuConsoleFunctionsOutput from './schemas/PikkuConsoleFunctionsOutput.schema.json' with { type: 'json' };
210
206
  addSchema('PikkuConsoleFunctionsOutput', PikkuConsoleFunctionsOutput);
211
207
  import * as PikkuNodesMetaOutput from './schemas/PikkuNodesMetaOutput.schema.json' with { type: 'json' };
212
208
  addSchema('PikkuNodesMetaOutput', PikkuNodesMetaOutput);
209
+ import * as PikkuCLIEntryOutput from './schemas/PikkuCLIEntryOutput.schema.json' with { type: 'json' };
210
+ addSchema('PikkuCLIEntryOutput', PikkuCLIEntryOutput);
211
+ import * as PikkuCLIOutput from './schemas/PikkuCLIOutput.schema.json' with { type: 'json' };
212
+ addSchema('PikkuCLIOutput', PikkuCLIOutput);
213
213
  import * as PikkuFunctionTypesSplitInput from './schemas/PikkuFunctionTypesSplitInput.schema.json' with { type: 'json' };
214
214
  addSchema('PikkuFunctionTypesSplitInput', PikkuFunctionTypesSplitInput);
215
215
  import * as PikkuFunctionTypesInput from './schemas/PikkuFunctionTypesInput.schema.json' with { type: 'json' };
@@ -236,12 +236,6 @@ import * as PikkuQueueOutput from './schemas/PikkuQueueOutput.schema.json' with
236
236
  addSchema('PikkuQueueOutput', PikkuQueueOutput);
237
237
  import * as PikkuEventsScaffoldOutput from './schemas/PikkuEventsScaffoldOutput.schema.json' with { type: 'json' };
238
238
  addSchema('PikkuEventsScaffoldOutput', PikkuEventsScaffoldOutput);
239
- import * as PikkuPublicRPCOutput from './schemas/PikkuPublicRPCOutput.schema.json' with { type: 'json' };
240
- addSchema('PikkuPublicRPCOutput', PikkuPublicRPCOutput);
241
- import * as PikkuRemoteRPCOutput from './schemas/PikkuRemoteRPCOutput.schema.json' with { type: 'json' };
242
- addSchema('PikkuRemoteRPCOutput', PikkuRemoteRPCOutput);
243
- import * as PikkuRPCOutput from './schemas/PikkuRPCOutput.schema.json' with { type: 'json' };
244
- addSchema('PikkuRPCOutput', PikkuRPCOutput);
245
239
  import * as PikkuSchedulerOutput from './schemas/PikkuSchedulerOutput.schema.json' with { type: 'json' };
246
240
  addSchema('PikkuSchedulerOutput', PikkuSchedulerOutput);
247
241
  import * as PikkuTriggerTypesInput from './schemas/PikkuTriggerTypesInput.schema.json' with { type: 'json' };
@@ -250,5 +244,11 @@ import * as PikkuTriggerOutput from './schemas/PikkuTriggerOutput.schema.json' w
250
244
  addSchema('PikkuTriggerOutput', PikkuTriggerOutput);
251
245
  import * as PikkuWorkflowRoutesOutput from './schemas/PikkuWorkflowRoutesOutput.schema.json' with { type: 'json' };
252
246
  addSchema('PikkuWorkflowRoutesOutput', PikkuWorkflowRoutesOutput);
247
+ import * as PikkuPublicRPCOutput from './schemas/PikkuPublicRPCOutput.schema.json' with { type: 'json' };
248
+ addSchema('PikkuPublicRPCOutput', PikkuPublicRPCOutput);
249
+ import * as PikkuRemoteRPCOutput from './schemas/PikkuRemoteRPCOutput.schema.json' with { type: 'json' };
250
+ addSchema('PikkuRemoteRPCOutput', PikkuRemoteRPCOutput);
251
+ import * as PikkuRPCOutput from './schemas/PikkuRPCOutput.schema.json' with { type: 'json' };
252
+ addSchema('PikkuRPCOutput', PikkuRPCOutput);
253
253
  import * as PikkuCLIConfig from './schemas/PikkuCLIConfig.schema.json' with { type: 'json' };
254
254
  addSchema('PikkuCLIConfig', PikkuCLIConfig);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  export { wireSecret } from '@pikku/core/secret';
5
5
  export type { CoreSecret, SecretDefinitionMeta, SecretDefinitionsMeta } from '@pikku/core/secret';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  export { wireSecret } from '@pikku/core/secret';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  import type { SecretService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  const CREDENTIALS_META = {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  export { wireVariable } from '@pikku/core/variable';
5
5
  export type { CoreVariable, VariableDefinitionMeta, VariableDefinitionsMeta } from '@pikku/core/variable';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  export { wireVariable } from '@pikku/core/variable';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  import type { VariablesService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  const VARIABLES_META = {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { pikkuState } from '@pikku/core/internal';
5
5
  import allWorkflowMeta from './meta/allWorkflow.gen.json' with { type: 'json' };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.48
2
+ * This file was generated by @pikku/cli@0.12.50
3
3
  */
4
4
  import { addWorkflow } from '@pikku/core/workflow';
5
5
  import './pikku-workflow-wirings-meta.gen.js';
@@ -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.48') {
15
- process.stderr.write(`\n Update available 0.12.48 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.50') {
15
+ process.stderr.write(`\n Update available 0.12.50 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
@@ -12,5 +12,5 @@
12
12
  */
13
13
  import type { EntryGenerationContext } from './provider-adapter.js';
14
14
  export declare function generateServerEntrySource(ctx: EntryGenerationContext): string;
15
- export declare const SERVER_DOCKERFILE = "# Generated by @pikku/cli \u2014 do not edit\nFROM node:22-slim\n\nRUN apt-get update \\\n && apt-get install -y --no-install-recommends tini ca-certificates \\\n && rm -rf /var/lib/apt/lists/*\n\nRUN groupadd -r pikku && useradd -r -g pikku -u 1001 pikku\n\nWORKDIR /app\n\n# Pikku bundles user code + first-party deps inline; only externalised deps\n# (typically empty for pure-JS apps) are listed in package.json. We ship no\n# lockfile because the bundle has already pinned everything via the\n# extracted exact-dependencies \u2014 `npm install --omit=dev` resolves the\n# leftover externals (if any) at build time.\nCOPY --chown=pikku:pikku package.json ./\nRUN npm install --omit=dev --no-audit --no-fund\n\nCOPY --chown=pikku:pikku bundle.js ./\n\nUSER pikku\nENV NODE_ENV=production\nENV PORT=8080\nEXPOSE 8080\n\nENTRYPOINT [\"/usr/bin/tini\", \"--\"]\nCMD [\"node\", \"bundle.js\"]\n";
15
+ export declare const SERVER_DOCKERFILE = "# Generated by @pikku/cli \u2014 do not edit\n# Full image (not -slim): carries the build toolchain so externalised deps with\n# native addons can compile from source at `npm install` time.\nFROM node:26\n\nRUN apt-get update \\\n && apt-get install -y --no-install-recommends tini ca-certificates \\\n && rm -rf /var/lib/apt/lists/*\n\nRUN groupadd -r pikku && useradd -r -g pikku -u 1001 pikku\n\nWORKDIR /app\n\n# Pikku bundles user code + first-party deps inline; only externalised deps\n# (typically empty for pure-JS apps) are listed in package.json. We ship no\n# lockfile because the bundle has already pinned everything via the\n# extracted exact-dependencies \u2014 `npm install --omit=dev` resolves the\n# leftover externals (if any) at build time.\nCOPY --chown=pikku:pikku package.json ./\nRUN npm install --omit=dev --no-audit --no-fund\n\nCOPY --chown=pikku:pikku bundle.js ./\n\nUSER pikku\nENV NODE_ENV=production\nENV PORT=8080\nEXPOSE 8080\n\nENTRYPOINT [\"/usr/bin/tini\", \"--\"]\nCMD [\"node\", \"bundle.js\"]\n";
16
16
  export declare const SERVER_DOCKERIGNORE = "node_modules\n.git\n*.log\nmetafile.json\nexact-dependencies.json\n";
@@ -45,7 +45,9 @@ export function generateServerEntrySource(ctx) {
45
45
  return lines.join('\n');
46
46
  }
47
47
  export const SERVER_DOCKERFILE = `# Generated by @pikku/cli — do not edit
48
- FROM node:22-slim
48
+ # Full image (not -slim): carries the build toolchain so externalised deps with
49
+ # native addons can compile from source at \`npm install\` time.
50
+ FROM node:26
49
51
 
50
52
  RUN apt-get update \\
51
53
  && apt-get install -y --no-install-recommends tini ca-certificates \\
@@ -180,8 +180,84 @@ export async function runValidate(startDir = process.cwd()) {
180
180
  if (!pikkuConfig.clientFiles) {
181
181
  info('pikku-config-no-client-files', 'pikku.config.json missing "clientFiles" — generated RPC client files and React Query hooks will not be written', pikkuConfigPath, lines('Add a `clientFiles` block to `pikku.config.json`.', 'Recommended values:', '"clientFiles": {', ' "rpcMapDeclarationFile": "packages/functions-sdk/src/pikku/rpc-map.gen.d.ts",', ' "reactQueryFile": "packages/functions-sdk/src/pikku/api.gen.ts"', '}', 'Those files should live in `packages/functions-sdk/src/pikku/` and are generated by Pikku.'));
182
182
  }
183
+ // Each scaffold key gates generation of a public surface the Fabric console
184
+ // calls. Missing one means those endpoints are never generated, so the
185
+ // console 404s even though the functions/agents/workflows are wired. The
186
+ // generated file paths auto-derive from the flag (see pikku-cli-config), so
187
+ // setting the flag is sufficient. console/rpc/agent/workflow gate HTTP/RPC
188
+ // endpoints the console hits directly → error; events gates the realtime
189
+ // channel (feature-dependent, no template ships it yet) → warn.
190
+ const REQUIRED_SCAFFOLD = [
191
+ {
192
+ key: 'console',
193
+ severity: 'error',
194
+ surface: 'app introspection (console:getFunctionsMeta and friends) — the sandbox builder shows no functions',
195
+ value: '"no-auth"',
196
+ },
197
+ {
198
+ key: 'rpc',
199
+ severity: 'error',
200
+ surface: 'the generic /rpc/:name endpoint',
201
+ value: 'true',
202
+ },
203
+ {
204
+ key: 'agent',
205
+ severity: 'error',
206
+ surface: 'the agent endpoints (/rpc/agent/:agentName) — the agent playground 404s',
207
+ value: '"no-auth"',
208
+ },
209
+ {
210
+ key: 'workflow',
211
+ severity: 'error',
212
+ surface: 'the workflow endpoints (/workflow/:workflowName/start) — triggering a workflow 404s',
213
+ value: '"no-auth"',
214
+ },
215
+ {
216
+ key: 'events',
217
+ severity: 'warn',
218
+ surface: 'the realtime events channel',
219
+ value: 'true',
220
+ },
221
+ ];
222
+ for (const s of REQUIRED_SCAFFOLD) {
223
+ if (pikkuConfig.scaffold?.[s.key])
224
+ continue;
225
+ const report = s.severity === 'error' ? e : w;
226
+ report(`pikku-config-no-scaffold-${s.key}`, `pikku.config.json scaffold is missing "${s.key}" — ${s.surface} is never generated, so the Fabric console 404s for it`, pikkuConfigPath, lines(`Add "${s.key}" to the scaffold block in pikku.config.json:`, '"scaffold": {', ' "pikkuDir": "packages/functions/src/scaffold",', ` "${s.key}": ${s.value}`, '}', 'Then re-run codegen (`pikku all`) and restart the dev server.'));
227
+ }
183
228
  }
184
229
  const dbEngine = pikkuConfig?.db?.engine ?? 'sqlite';
230
+ // ── .gitignore must ignore generated/runtime artifacts ─────────────────
231
+ // These are regenerated on every dev boot / scaffold / codegen. Committing
232
+ // them lets a stale copy shadow the freshly generated one — a committed
233
+ // __fabric_scaffold.vite.config.mjs or .pikku-runtime breaks the sandbox dev
234
+ // server — and pollutes diffs. Tolerate trailing/leading slashes.
235
+ {
236
+ const requiredIgnores = [
237
+ '.opencode',
238
+ '.pikku',
239
+ '.pikku-runtime',
240
+ '.reports',
241
+ '__fabric_scaffold.vite.config.mjs',
242
+ ];
243
+ const gitignorePath = join(root, '.gitignore');
244
+ const gitignoreText = await readTextSafe(gitignorePath);
245
+ const norm = (s) => s.replace(/^\//, '').replace(/\/$/, '');
246
+ const ignored = new Set((gitignoreText ?? '')
247
+ .split('\n')
248
+ .map((l) => norm(l.trim()))
249
+ .filter(Boolean));
250
+ const missing = requiredIgnores.filter((entry) => !ignored.has(norm(entry)));
251
+ // Generated files: accept a single `*.gen.*` glob or the explicit
252
+ // `*.gen.ts` + `*.gen.js` pair (the canonical scaffold uses the pair).
253
+ const genIgnored = ignored.has('*.gen.*') ||
254
+ (ignored.has('*.gen.ts') && ignored.has('*.gen.js'));
255
+ if (!genIgnored)
256
+ missing.push('*.gen.*');
257
+ if (missing.length > 0) {
258
+ w('gitignore-missing-generated', `.gitignore does not ignore Fabric generated/runtime artifacts: ${missing.join(', ')} — committing them lets a stale copy shadow the freshly generated one (e.g. a committed __fabric_scaffold.vite.config.mjs or .pikku-runtime breaks the sandbox dev server)`, gitignorePath, lines('Add these entries to .gitignore:', ...missing.map((entry) => ` ${entry}`), 'They are regenerated on every dev boot / scaffold / codegen and must never be committed.'));
259
+ }
260
+ }
185
261
  const rootPkgPath = join(root, 'package.json');
186
262
  const rootPkg = await readJsonSafe(rootPkgPath);
187
263
  if (!rootPkg) {
@@ -291,6 +367,32 @@ export async function runValidate(startDir = process.cwd()) {
291
367
  if (dbEngine !== 'postgres' && fnAllDeps['@pikku/kysely-postgres']) {
292
368
  e('fn-pkg-postgres-dep', '@pikku/kysely-postgres is in packages/functions dependencies — Fabric uses SQLite/libSQL (Turso), not PostgreSQL', fnPkgPath, 'Remove @pikku/kysely-postgres and use @pikku/kysely-sqlite with LibsqlWebDialect instead');
293
369
  }
370
+ // CF worker runtime deps — must be in dependencies (not dev), every
371
+ // worker entry resolves them at deploy time.
372
+ if (!fnPkg.dependencies?.['@pikku/schema-cfworker']) {
373
+ e('missing-schema-cfworker', '@pikku/schema-cfworker is not in packages/functions dependencies — every Cloudflare worker entry requires it', fnPkgPath, 'Run `yarn add @pikku/schema-cfworker` in packages/functions — must be in dependencies, not devDependencies');
374
+ }
375
+ if (!fnPkg.dependencies?.['@pikku/kysely']) {
376
+ e('missing-pikku-kysely', '@pikku/kysely is not in packages/functions dependencies — every Cloudflare worker entry requires it (KyselySecretService)', fnPkgPath, 'Run `yarn add @pikku/kysely` in packages/functions — must be in dependencies, not devDependencies');
377
+ }
378
+ }
379
+ // Agent units require the AI SDK deps explicitly (not CI-injected). Gate on
380
+ // the generated agent meta so non-agent projects aren't flagged.
381
+ const agentMeta = await readJsonSafe(join(fnDir, '.pikku', 'agent', 'pikku-agent-wirings-meta.gen.json'));
382
+ if (agentMeta && Object.keys(agentMeta.agentsMeta ?? {}).length > 0) {
383
+ const fnPkgPath = join(fnDir, 'package.json');
384
+ if (!fnPkg?.dependencies?.['@pikku/ai-vercel']) {
385
+ e('missing-ai-vercel', 'Project declares agent units but @pikku/ai-vercel is not in packages/functions dependencies', fnPkgPath, 'Run `yarn add @pikku/ai-vercel` in packages/functions — must be in dependencies, not devDependencies');
386
+ }
387
+ if (!fnPkg?.dependencies?.['@ai-sdk/openai-compatible']) {
388
+ e('missing-ai-sdk-openai-compatible', 'Project declares agent units but @ai-sdk/openai-compatible is not in packages/functions dependencies', fnPkgPath, 'Run `yarn add @ai-sdk/openai-compatible` in packages/functions — must be in dependencies, not devDependencies');
389
+ }
390
+ // `ai` is a peer dep of @pikku/ai-vercel — not auto-installed. Without it
391
+ // `pikku dev` can't construct the agent runner and agents 503 with
392
+ // AIProviderNotConfiguredError.
393
+ if (!fnPkg?.dependencies?.['ai']) {
394
+ e('missing-ai-sdk-core', 'Project declares agent units but `ai` (the Vercel AI SDK) is not in packages/functions dependencies — it is a peer dependency of @pikku/ai-vercel and is not installed automatically', fnPkgPath, 'Run `yarn add ai` in packages/functions — must be in dependencies, not devDependencies');
395
+ }
294
396
  }
295
397
  // services.ts
296
398
  const servicesPath = join(fnDir, 'src', 'services.ts');
@@ -2,7 +2,7 @@ import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
- const DEFAULT_API_URL = 'http://localhost:7103';
5
+ const DEFAULT_API_URL = 'https://api.pikkufabric.com';
6
6
  const projectConfigName = 'pikkufabric.config.json';
7
7
  const authFilePath = join(homedir(), '.fabric', 'auth.json');
8
8
  export async function findProjectConfig(startDir = process.cwd()) {
@@ -0,0 +1,19 @@
1
+ import type { Logger, VariablesService } from '@pikku/core/services';
2
+ import type { AIAgentRunnerService } from '@pikku/core/services';
3
+ /**
4
+ * Build the AI agent runner for `pikku dev` from env.
5
+ *
6
+ * Deployed agent units get their runner wired by the bundler; the dev server
7
+ * has no equivalent, so agents 503 with AIProviderNotConfiguredError unless we
8
+ * construct one here. When an OpenAI-compatible base URL + key are present
9
+ * (fabric injects LITELLM_PROXY_URL/LITELLM_API_KEY; the standard OPENAI_*
10
+ * vars are also honored) we point a single openai-compatible provider at it and
11
+ * register it under every common provider prefix. Returns undefined when no AI
12
+ * env is configured (agents stay disabled, with the clear downstream error) or
13
+ * when the AI SDK packages aren't installed in the project.
14
+ */
15
+ export declare function createDevAIAgentRunner({ logger, projectRoot, variables, }: {
16
+ logger: Logger;
17
+ projectRoot: string;
18
+ variables: VariablesService;
19
+ }): Promise<AIAgentRunnerService | undefined>;
@@ -0,0 +1,70 @@
1
+ import { createRequire } from 'module';
2
+ import { join } from 'path';
3
+ import { pathToFileURL } from 'url';
4
+ // Provider prefixes a fabric/proxy baseURL fronts. Models are written as
5
+ // `openai/gpt-4o-mini`, `openai/deepseek-v4-flash`, etc. — the runner splits on
6
+ // the first `/`, so the prefix only selects the provider entry and the bare
7
+ // model name is forwarded to the OpenAI-compatible proxy, which routes it.
8
+ const PROXY_PROVIDER_NAMES = [
9
+ 'openai',
10
+ 'anthropic',
11
+ 'google',
12
+ 'gemini',
13
+ 'deepseek',
14
+ 'xai',
15
+ 'litellm',
16
+ ];
17
+ /**
18
+ * Build the AI agent runner for `pikku dev` from env.
19
+ *
20
+ * Deployed agent units get their runner wired by the bundler; the dev server
21
+ * has no equivalent, so agents 503 with AIProviderNotConfiguredError unless we
22
+ * construct one here. When an OpenAI-compatible base URL + key are present
23
+ * (fabric injects LITELLM_PROXY_URL/LITELLM_API_KEY; the standard OPENAI_*
24
+ * vars are also honored) we point a single openai-compatible provider at it and
25
+ * register it under every common provider prefix. Returns undefined when no AI
26
+ * env is configured (agents stay disabled, with the clear downstream error) or
27
+ * when the AI SDK packages aren't installed in the project.
28
+ */
29
+ export async function createDevAIAgentRunner({ logger, projectRoot, variables, }) {
30
+ // Pair the URL with its matching key — coalescing each var independently could
31
+ // combine an OPENAI_BASE_URL with a LITELLM_API_KEY (or vice versa) and
32
+ // misroute or 401 every call. Take a complete OpenAI pair first, else LiteLLM.
33
+ const openAIBaseURL = await variables.get('OPENAI_BASE_URL');
34
+ const openAIApiKey = await variables.get('OPENAI_API_KEY');
35
+ const liteLLMBaseURL = await variables.get('LITELLM_PROXY_URL');
36
+ const liteLLMApiKey = await variables.get('LITELLM_API_KEY');
37
+ const [baseURL, apiKey] = openAIBaseURL && openAIApiKey
38
+ ? [openAIBaseURL, openAIApiKey]
39
+ : liteLLMBaseURL && liteLLMApiKey
40
+ ? [liteLLMBaseURL, liteLLMApiKey]
41
+ : [undefined, undefined];
42
+ if (!baseURL || !apiKey) {
43
+ logger.debug('pikku dev: no AI provider env (OPENAI_BASE_URL/OPENAI_API_KEY or LITELLM_PROXY_URL/LITELLM_API_KEY) — AI agents disabled');
44
+ return undefined;
45
+ }
46
+ // Resolve from the project's node_modules — the AI SDK packages are the
47
+ // project's deps, not the CLI's, so they share the project's `ai` version.
48
+ const require = createRequire(pathToFileURL(join(projectRoot, 'package.json')).href);
49
+ let VercelAIAgentRunner;
50
+ let createOpenAICompatible;
51
+ try {
52
+ ;
53
+ ({ VercelAIAgentRunner } = await import(pathToFileURL(require.resolve('@pikku/ai-vercel')).href));
54
+ ({ createOpenAICompatible } = await import(pathToFileURL(require.resolve('@ai-sdk/openai-compatible')).href));
55
+ }
56
+ catch (error) {
57
+ logger.warn(`pikku dev: AI provider env is set but the AI SDK packages could not be loaded (install @pikku/ai-vercel, @ai-sdk/openai-compatible, and ai) — AI agents disabled: ${error instanceof Error ? error.message : String(error)}`);
58
+ return undefined;
59
+ }
60
+ const buildProviders = (key) => {
61
+ const provider = createOpenAICompatible({
62
+ name: 'pikku-dev',
63
+ baseURL,
64
+ apiKey: key,
65
+ });
66
+ return Object.fromEntries(PROXY_PROVIDER_NAMES.map((name) => [name, provider]));
67
+ };
68
+ logger.info(`pikku dev: AI agent runner wired to ${baseURL}`);
69
+ return new VercelAIAgentRunner(buildProviders(apiKey), buildProviders);
70
+ }
@@ -15,6 +15,7 @@ import { WebSocketServer } from 'ws';
15
15
  import { InMemorySchedulerService } from '@pikku/schedule';
16
16
  import { resolveDb, createKysely, parseDatabaseUrl, } from '../db/local-db.js';
17
17
  import { loadUserBootstrap, loadUserModule } from './load-user-project.js';
18
+ import { createDevAIAgentRunner } from './dev-ai-runner.js';
18
19
  export const dev = pikkuSessionlessFunc({
19
20
  remote: true,
20
21
  func: async ({ logger, config, getInspectorState, variables }, { port, watch, hmr }, { rpc }) => {
@@ -153,8 +154,23 @@ export const dev = pikkuSessionlessFunc({
153
154
  // can read runs in dev without projects having to wire their own backing
154
155
  // store.
155
156
  const devLogger = new ConsoleLogger();
157
+ // Deployed agent units get their runner from the bundler; the dev server
158
+ // has no equivalent, so construct one from env or agents 503 with
159
+ // AIProviderNotConfiguredError. The template forwards injected services
160
+ // (`...existingServices`) so this reaches getSingletonServices().
161
+ // Only when the project declares agents — otherwise the runner's
162
+ // missing-SDK warning fires spuriously for projects with global AI env.
163
+ const hasAgents = Object.keys(inspectorState.agents.agentsMeta).length > 0;
164
+ const aiAgentRunner = hasAgents
165
+ ? await createDevAIAgentRunner({
166
+ logger,
167
+ projectRoot: config.rootDir,
168
+ variables,
169
+ })
170
+ : undefined;
156
171
  const inMemoryServices = {
157
172
  logger: devLogger,
173
+ ...(aiAgentRunner ? { aiAgentRunner } : {}),
158
174
  emailService: new LocalEmailService(),
159
175
  metaService: new LocalMetaService(pikkuDir),
160
176
  schedulerService,
@@ -165,6 +165,12 @@ export const pikkuTestsCoverage = pikkuSessionlessFunc({
165
165
  '--require',
166
166
  'tests/tests/support/**/*.ts',
167
167
  'tests/tests/features/**/*.feature',
168
+ '--format',
169
+ 'progress',
170
+ // Persist the HTML report so the console can parse scenarios back out
171
+ // of it (readAllMeta attaches them per function).
172
+ '--format',
173
+ 'html:tests/tests/reports/cucumber-report.html',
168
174
  ], { cwd: functionsDir, stdio: 'inherit', env: spawnEnv });
169
175
  if (res.status !== 0) {
170
176
  logger.error(`Test run failed (exit ${res.status})`);