@pikku/cli 0.12.28 → 0.12.29

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 (67) hide show
  1. package/console-app/assets/{index-Ca6xJwNm.js → index-ClGe-ul_.js} +110 -110
  2. package/console-app/index.html +1 -1
  3. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  4. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  5. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  6. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  7. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  8. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  10. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  14. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  15. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  16. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  17. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  18. package/dist/.pikku/function/pikku-functions-meta.gen.json +74 -74
  19. package/dist/.pikku/function/pikku-functions.gen.js +3 -1
  20. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  21. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  22. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  23. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  24. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  25. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  26. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  27. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  28. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  29. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  30. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  31. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  32. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  33. package/dist/.pikku/pikku-types.gen.js +1 -1
  34. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  35. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  36. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  37. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.json +4 -0
  38. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  39. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  40. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  41. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +12 -12
  42. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  43. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  44. package/dist/.pikku/schemas/register.gen.js +5 -5
  45. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  46. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  47. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  48. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  49. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  50. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  51. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  52. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  53. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  54. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  55. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +8 -2
  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/fabric/functions/validate-core.js +65 -0
  62. package/dist/src/functions/commands/dev.js +8 -8
  63. package/dist/src/functions/db/local-db.d.ts +7 -0
  64. package/dist/src/functions/db/local-db.js +14 -0
  65. package/dist/src/scaffold/rpc-remote.gen.js +1 -1
  66. package/package.json +2 -2
  67. package/skills/pikku-workflow/SKILL.md +22 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.28
2
+ * This file was generated by @pikku/cli@0.12.29
3
3
  */
4
4
  import { addSchema } from '@pikku/core/schema';
5
5
  import * as PikkuSchemasOutput from './schemas/PikkuSchemasOutput.schema.json' with { type: 'json' };
@@ -192,12 +192,12 @@ import * as PikkuCLIEntryOutput from './schemas/PikkuCLIEntryOutput.schema.json'
192
192
  addSchema('PikkuCLIEntryOutput', PikkuCLIEntryOutput);
193
193
  import * as PikkuCLIOutput from './schemas/PikkuCLIOutput.schema.json' with { type: 'json' };
194
194
  addSchema('PikkuCLIOutput', PikkuCLIOutput);
195
- import * as PikkuGatewayOutput from './schemas/PikkuGatewayOutput.schema.json' with { type: 'json' };
196
- addSchema('PikkuGatewayOutput', PikkuGatewayOutput);
197
195
  import * as PikkuFunctionTypesSplitInput from './schemas/PikkuFunctionTypesSplitInput.schema.json' with { type: 'json' };
198
196
  addSchema('PikkuFunctionTypesSplitInput', PikkuFunctionTypesSplitInput);
199
197
  import * as PikkuFunctionsOutput from './schemas/PikkuFunctionsOutput.schema.json' with { type: 'json' };
200
198
  addSchema('PikkuFunctionsOutput', PikkuFunctionsOutput);
199
+ import * as PikkuGatewayOutput from './schemas/PikkuGatewayOutput.schema.json' with { type: 'json' };
200
+ addSchema('PikkuGatewayOutput', PikkuGatewayOutput);
201
201
  import * as PikkuCommandHTTPOutput from './schemas/PikkuCommandHTTPOutput.schema.json' with { type: 'json' };
202
202
  addSchema('PikkuCommandHTTPOutput', PikkuCommandHTTPOutput);
203
203
  import * as PikkuHTTPOutput from './schemas/PikkuHTTPOutput.schema.json' with { type: 'json' };
@@ -222,13 +222,13 @@ import * as PikkuTriggerTypesInput from './schemas/PikkuTriggerTypesInput.schema
222
222
  addSchema('PikkuTriggerTypesInput', PikkuTriggerTypesInput);
223
223
  import * as PikkuTriggerOutput from './schemas/PikkuTriggerOutput.schema.json' with { type: 'json' };
224
224
  addSchema('PikkuTriggerOutput', PikkuTriggerOutput);
225
- import * as PikkuWorkflowRoutesOutput from './schemas/PikkuWorkflowRoutesOutput.schema.json' with { type: 'json' };
226
- addSchema('PikkuWorkflowRoutesOutput', PikkuWorkflowRoutesOutput);
227
225
  import * as PikkuPublicRPCOutput from './schemas/PikkuPublicRPCOutput.schema.json' with { type: 'json' };
228
226
  addSchema('PikkuPublicRPCOutput', PikkuPublicRPCOutput);
229
227
  import * as PikkuRemoteRPCOutput from './schemas/PikkuRemoteRPCOutput.schema.json' with { type: 'json' };
230
228
  addSchema('PikkuRemoteRPCOutput', PikkuRemoteRPCOutput);
231
229
  import * as PikkuRPCOutput from './schemas/PikkuRPCOutput.schema.json' with { type: 'json' };
232
230
  addSchema('PikkuRPCOutput', PikkuRPCOutput);
231
+ import * as PikkuWorkflowRoutesOutput from './schemas/PikkuWorkflowRoutesOutput.schema.json' with { type: 'json' };
232
+ addSchema('PikkuWorkflowRoutesOutput', PikkuWorkflowRoutesOutput);
233
233
  import * as PikkuCLIConfig from './schemas/PikkuCLIConfig.schema.json' with { type: 'json' };
234
234
  addSchema('PikkuCLIConfig', PikkuCLIConfig);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  const VARIABLES_META = {};
@@ -225,9 +225,15 @@
225
225
  "Events scaffold": {
226
226
  "nodeId": "Events scaffold",
227
227
  "rpcName": "pikkuEventsScaffold",
228
- "next": "Secret definition types",
228
+ "next": "Emails",
229
229
  "stepHash": "b5a547ac59ef"
230
230
  },
231
+ "Emails": {
232
+ "nodeId": "Emails",
233
+ "rpcName": "pikkuEmails",
234
+ "next": "Secret definition types",
235
+ "stepHash": "bb8361cb96cf"
236
+ },
231
237
  "Secret definition types": {
232
238
  "nodeId": "Secret definition types",
233
239
  "rpcName": "pikkuSecretDefinitionTypes",
@@ -521,5 +527,5 @@
521
527
  "entryNodeIds": [
522
528
  "Bootstrap inspect"
523
529
  ],
524
- "graphHash": "1c85dee2bb48"
530
+ "graphHash": "359c0b7178dc"
525
531
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28
2
+ * This file was generated by @pikku/cli@0.12.29
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.28') {
15
- process.stderr.write(`\n Update available 0.12.28 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.29') {
15
+ process.stderr.write(`\n Update available 0.12.29 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { readdir } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
+ import { readFile } from 'node:fs/promises';
4
5
  import { z } from 'zod';
5
6
  import { added, changed, dim, removed } from '../lib/output.js';
6
7
  import { WorkspaceValidateOutput, readJsonSafe, readTextSafe, runWorkspaceValidate, } from '../../functions/validate/workspace-validate.js';
@@ -31,6 +32,53 @@ export async function runFabricValidate(startDir = process.cwd()) {
31
32
  const info = (id, message, path, fixHint) => {
32
33
  findings.push({ id, severity: 'info', message, path, fixHint });
33
34
  };
35
+ // These dirs are generated/runtime artefacts; committing them bloats PRs and causes stale issues
36
+ const gitignorePath = join(root, '.gitignore');
37
+ const REQUIRED_GITIGNORE_ENTRIES = [
38
+ {
39
+ name: '.pikku',
40
+ patterns: ['.pikku', '.pikku/', '/.pikku', '/.pikku/'],
41
+ reason: 'generated codegen artifacts will pollute commits and PRs',
42
+ },
43
+ {
44
+ name: '.pikku-runtime',
45
+ patterns: [
46
+ '.pikku-runtime',
47
+ '.pikku-runtime/',
48
+ '/.pikku-runtime',
49
+ '/.pikku-runtime/',
50
+ ],
51
+ reason: 'runtime state directory should not be committed',
52
+ },
53
+ {
54
+ name: '.opencode',
55
+ patterns: ['.opencode', '.opencode/', '/.opencode', '/.opencode/'],
56
+ reason: 'OpenCode session data should not be committed',
57
+ },
58
+ {
59
+ name: '*.gen.ts',
60
+ patterns: ['*.gen.ts', '**/*.gen.ts'],
61
+ reason: 'generated TypeScript files (by pikku and TanStack Start) should not be committed — they are regenerated at build time',
62
+ },
63
+ {
64
+ name: '*.gen.js',
65
+ patterns: ['*.gen.js', '**/*.gen.js'],
66
+ reason: 'generated JavaScript files (by pikku and TanStack Start) should not be committed — they are regenerated at build time',
67
+ },
68
+ ];
69
+ try {
70
+ const gitignoreText = await readFile(gitignorePath, 'utf8');
71
+ const lines = gitignoreText.split('\n').map((l) => l.trim());
72
+ for (const entry of REQUIRED_GITIGNORE_ENTRIES) {
73
+ const covered = lines.some((l) => entry.patterns.includes(l));
74
+ if (!covered) {
75
+ w(`${entry.name.replace(/[^a-z0-9]/gi, '-')}-not-gitignored`, `${entry.name} is not listed in .gitignore — ${entry.reason}`, gitignorePath, `Add "${entry.name}" to .gitignore`);
76
+ }
77
+ }
78
+ }
79
+ catch {
80
+ w('gitignore-missing', '.gitignore not found at project root — generated artifacts (.pikku, .pikku-runtime, .opencode) may be committed accidentally', gitignorePath, 'Create .gitignore and add ".pikku", ".pikku-runtime", and ".opencode" to it');
81
+ }
34
82
  const fabricConfigPath = join(root, 'fabric.config.json');
35
83
  const fabricConfig = await readJsonSafe(fabricConfigPath);
36
84
  if (!fabricConfig) {
@@ -69,6 +117,12 @@ export async function runFabricValidate(startDir = process.cwd()) {
69
117
  if (fnAllDeps['@pikku/kysely-postgres']) {
70
118
  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');
71
119
  }
120
+ if (!fnPkg.dependencies?.['@pikku/schema-cfworker']) {
121
+ e('missing-schema-cfworker', '@pikku/schema-cfworker is not in dependencies — every Cloudflare worker entry requires it', fnPkgPath, 'Run `yarn add @pikku/schema-cfworker` in packages/functions — must be in dependencies, not devDependencies');
122
+ }
123
+ if (!fnPkg.dependencies?.['@pikku/kysely']) {
124
+ e('missing-pikku-kysely', '@pikku/kysely is not in dependencies — every Cloudflare worker entry requires it (KyselySecretService)', fnPkgPath, 'Run `yarn add @pikku/kysely` in packages/functions — must be in dependencies, not devDependencies');
125
+ }
72
126
  }
73
127
  const servicesPath = join(fnDir, 'src', 'services.ts');
74
128
  const servicesText = await readTextSafe(servicesPath);
@@ -90,6 +144,17 @@ export async function runFabricValidate(startDir = process.cwd()) {
90
144
  e('missing-kysely-sqlite', 'services.ts imports @pikku/kysely-sqlite but it is not in root package.json', rootPkgPath, 'Add "@pikku/kysely-sqlite": "file:./vendor/pikku-kysely-sqlite.tgz" to dependencies');
91
145
  }
92
146
  }
147
+ // agent units — require explicit deps rather than CI injection
148
+ const agentMetaPath = join(fnDir, '.pikku', 'agent', 'pikku-agent-wirings-meta.gen.json');
149
+ const agentMeta = await readJsonSafe(agentMetaPath);
150
+ if (agentMeta && Object.keys(agentMeta.agentsMeta ?? {}).length > 0) {
151
+ if (!fnPkg?.dependencies?.['@pikku/ai-vercel']) {
152
+ e('missing-ai-vercel', 'Project declares agent units but @pikku/ai-vercel is not in dependencies', fnPkgPath, 'Run `yarn add @pikku/ai-vercel` in packages/functions — must be in dependencies, not devDependencies');
153
+ }
154
+ if (!fnPkg?.dependencies?.['@ai-sdk/openai-compatible']) {
155
+ e('missing-ai-sdk-openai-compatible', 'Project declares agent units but @ai-sdk/openai-compatible is not in dependencies', fnPkgPath, 'Run `yarn add @ai-sdk/openai-compatible` in packages/functions — must be in dependencies, not devDependencies');
156
+ }
157
+ }
93
158
  // db/sqlite/ — presence, numbering and SQL dialect
94
159
  const migrationsDir = join(fnDir, 'db', 'sqlite');
95
160
  if (!existsSync(migrationsDir)) {
@@ -14,11 +14,11 @@ import { pikkuWebsocketHandler } from '@pikku/ws';
14
14
  import { PikkuNodeHTTPServer } from '@pikku/node-http-server';
15
15
  import { WebSocketServer } from 'ws';
16
16
  import { InMemorySchedulerService } from '@pikku/schedule';
17
- import { resolveDb, createKysely } from '../db/local-db.js';
17
+ import { resolveDb, createKysely, parseDatabaseUrl, } from '../db/local-db.js';
18
18
  import { loadUserBootstrap, loadUserModule } from './load-user-project.js';
19
19
  export const dev = pikkuSessionlessFunc({
20
20
  remote: true,
21
- func: async ({ logger, config, getInspectorState }, { port, watch, hmr }, { rpc }) => {
21
+ func: async ({ logger, config, getInspectorState, variables }, { port, watch, hmr }, { rpc }) => {
22
22
  const resolvedPort = parseInt(port || '3000', 10);
23
23
  const hostname = 'localhost';
24
24
  const enableWatch = watch !== false;
@@ -116,12 +116,12 @@ export const dev = pikkuSessionlessFunc({
116
116
  const userCreateConfig = configModule[pikkuConfigFactory.variable];
117
117
  const userCreateSingletonServices = servicesModule[singletonServicesFactory.variable];
118
118
  const userConfig = await userCreateConfig();
119
- const resolvedDb = resolveDb(userConfig, config.rootDir, config.outDir, config.runtimeDir);
120
- const resolvedLocalDb = resolvedDb?.dialect === 'sqlite'
121
- ? resolvedDb
122
- : userConfig.sqliteDb
123
- ? resolveDb({ sqliteDb: userConfig.sqliteDb }, config.rootDir, config.outDir, config.runtimeDir)
124
- : undefined;
119
+ const envDatabaseUrl = await variables.get('DATABASE_URL');
120
+ const effectiveDbConfig = envDatabaseUrl
121
+ ? parseDatabaseUrl(envDatabaseUrl)
122
+ : userConfig;
123
+ const resolvedDb = resolveDb(effectiveDbConfig, config.rootDir, config.outDir, config.runtimeDir);
124
+ const resolvedLocalDb = resolvedDb?.dialect === 'sqlite' ? resolvedDb : undefined;
125
125
  const kysely = resolvedLocalDb
126
126
  ? await createKysely(resolvedLocalDb)
127
127
  : undefined;
@@ -27,6 +27,13 @@ export interface ResolvedPostgresDb extends ResolvedDbBase {
27
27
  connectionString: string;
28
28
  }
29
29
  export type ResolvedDb = ResolvedSqliteDb | ResolvedPostgresDb;
30
+ /**
31
+ * Parse a DATABASE_URL string into the subset of UserConfigShape that resolveDb understands.
32
+ * - postgres(ql):// → { postgresUrl }
33
+ * - libsql:// or http(s):// → {} (remote, not handled by the CLI layer)
34
+ * - anything else → { sqliteDb } (local file path)
35
+ */
36
+ export declare function parseDatabaseUrl(url: string): Pick<UserConfigShape, 'sqliteDb' | 'postgresUrl'>;
30
37
  /**
31
38
  * Resolve a UserConfigShape into an absolute-path descriptor.
32
39
  * Returns null when neither sqliteDb nor postgresUrl is configured.
@@ -15,6 +15,19 @@ import { seed as runSeed } from './sqlite/seed.js';
15
15
  import { PostgresMigrationExecutor } from './postgres/postgres-migrator.js';
16
16
  import { PostgresIntrospector } from './postgres/postgres-introspector.js';
17
17
  // ─── Resolution ───────────────────────────────────────────────────────────────
18
+ /**
19
+ * Parse a DATABASE_URL string into the subset of UserConfigShape that resolveDb understands.
20
+ * - postgres(ql):// → { postgresUrl }
21
+ * - libsql:// or http(s):// → {} (remote, not handled by the CLI layer)
22
+ * - anything else → { sqliteDb } (local file path)
23
+ */
24
+ export function parseDatabaseUrl(url) {
25
+ if (/^postgres(ql)?:\/\//.test(url))
26
+ return { postgresUrl: url };
27
+ if (/^(libsql|https?):\/\//.test(url))
28
+ return {};
29
+ return { sqliteDb: url };
30
+ }
18
31
  /**
19
32
  * Resolve a UserConfigShape into an absolute-path descriptor.
20
33
  * Returns null when neither sqliteDb nor postgresUrl is configured.
@@ -108,6 +121,7 @@ export async function migrateAndCodegen(resolved) {
108
121
  manifestFile: resolved.manifestFile,
109
122
  classificationMapFile: resolved.classificationMapFile,
110
123
  camelCase: resolved.camelCase,
124
+ rootDir: resolved.rootDir,
111
125
  migrationsDir: resolved.migrationsDir,
112
126
  });
113
127
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.28
2
+ * This file was generated by @pikku/cli@0.12.29
3
3
  */
4
4
  /**
5
5
  * Auto-generated remote internal RPC queue worker and HTTP endpoint
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/cli",
3
- "version": "0.12.28",
3
+ "version": "0.12.29",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "BUSL-1.1",
6
6
  "imports": {
@@ -29,7 +29,7 @@
29
29
  "@pikku/core": "^0.12.27",
30
30
  "@pikku/deploy-cloudflare": "^0.12.3",
31
31
  "@pikku/fetch": "^0.12.2",
32
- "@pikku/inspector": "^0.12.14",
32
+ "@pikku/inspector": "^0.12.15",
33
33
  "@pikku/kysely": "^0.12.14",
34
34
  "@pikku/kysely-node-sqlite": "^0.12.1",
35
35
  "@pikku/node-http-server": "^0.12.1",
@@ -71,6 +71,28 @@ await workflow.sleep('Wait 5 minutes', '5min')
71
71
  await workflow.suspend('Awaiting approval')
72
72
  ```
73
73
 
74
+ ### Choosing the right wrapper
75
+
76
+ | Wrapper | When to use |
77
+ |---|---|
78
+ | `pikkuWorkflowFunc` | **Default.** Use for all new workflows. DSL mode — serialisable, replay-safe. |
79
+ | `pikkuWorkflowComplexFunc` | **Only with explicit user approval.** For workflows with patterns the DSL extractor cannot handle (e.g. dynamic inline functions). Not a general escape hatch — restructure first. |
80
+ | `pikkuWorkflowGraph` | **Only with explicit user approval.** For genuine DAGs where there is a cyclic dependency between nodes or a Node.js-only import DSL cannot express. |
81
+
82
+ **Conditional results** — the correct DSL pattern when a step only runs under some condition:
83
+
84
+ ```typescript
85
+ // ✅ Declare at top level, assign inside block
86
+ let result: { id: string } | null = null
87
+ if (input.createFoo) {
88
+ result = await workflow.do('Create foo', 'createFoo', { ... })
89
+ }
90
+ // Use result?.id downstream
91
+
92
+ // ❌ Do NOT declare const inside a block — DSL forbids block-scoped declarations
93
+ // ❌ Do NOT switch to pikkuWorkflowComplexFunc to avoid the restriction
94
+ ```
95
+
74
96
  ### `pikkuWorkflowGraph(config)` — DAG Workflows
75
97
 
76
98
  ```typescript