@pikku/cli 0.12.36 → 0.12.38

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/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-types.gen.d.ts +1 -1
  6. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  7. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  8. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  9. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  10. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  12. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  13. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  14. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  15. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  16. package/dist/.pikku/function/pikku-functions-meta.gen.json +179 -179
  17. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  18. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  19. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  20. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  21. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  22. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  23. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  24. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  25. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  26. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  27. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  28. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  29. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  30. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  31. package/dist/.pikku/pikku-types.gen.js +1 -1
  32. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  33. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  34. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  35. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  36. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  37. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  38. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  39. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  40. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  41. package/dist/.pikku/schemas/register.gen.js +9 -9
  42. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  43. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  44. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  45. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  46. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  47. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  48. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  49. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  50. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  51. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  52. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  53. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  54. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  55. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  56. package/dist/bin/pikku-bin.mjs +2 -2
  57. package/dist/src/fabric/functions/validate-core.js +7 -7
  58. package/dist/src/fabric/functions/validate.function.js +40 -28
  59. package/dist/src/fabric/lib/config.d.ts +4 -4
  60. package/dist/src/fabric/lib/config.js +2 -2
  61. package/dist/src/functions/db/better-auth-schema.js +33 -11
  62. package/dist/src/functions/db/db-codegen.js +9 -5
  63. package/dist/src/functions/db/local-db.d.ts +2 -2
  64. package/dist/src/functions/db/local-db.js +111 -5
  65. package/dist/src/functions/db/sqlite/sqlite-runtime-node.js +2 -1
  66. package/dist/src/scaffold/rpc-remote.gen.js +1 -1
  67. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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' };
@@ -119,7 +119,6 @@
119
119
  "pikkuMCPJSON": "pikkuMCPJSON",
120
120
  "pikkuMCPTypes": "pikkuMCPTypes",
121
121
  "pikkuMCP": "pikkuMCP",
122
- "pikkuMiddleware": "pikkuMiddleware",
123
122
  "pikkuSecretDefinitionTypes": "pikkuSecretDefinitionTypes",
124
123
  "pikkuVariableDefinitionTypes": "pikkuVariableDefinitionTypes",
125
124
  "pikkuPackage": "pikkuPackage",
@@ -129,6 +128,7 @@
129
128
  "pikkuCommandQueue": "pikkuCommandQueue",
130
129
  "pikkuQueueMap": "pikkuQueueMap",
131
130
  "pikkuQueue": "pikkuQueue",
131
+ "pikkuMiddleware": "pikkuMiddleware",
132
132
  "pikkuEventsScaffold": "pikkuEventsScaffold",
133
133
  "pikkuPublicRPC": "pikkuPublicRPC",
134
134
  "pikkuRemoteRPC": "pikkuRemoteRPC",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
3
3
  */
4
4
  import { addSchema } from '@pikku/core/schema';
5
5
  import * as PikkuSchemasOutput from './schemas/PikkuSchemasOutput.schema.json' with { type: 'json' };
@@ -180,20 +180,16 @@ import * as PikkuMetaClientsInput from './schemas/PikkuMetaClientsInput.schema.j
180
180
  addSchema('PikkuMetaClientsInput', PikkuMetaClientsInput);
181
181
  import * as RemoteRPCHandlerInput from './schemas/RemoteRPCHandlerInput.schema.json' with { type: 'json' };
182
182
  addSchema('RemoteRPCHandlerInput', RemoteRPCHandlerInput);
183
+ import * as PikkuAIAgentOutput from './schemas/PikkuAIAgentOutput.schema.json' with { type: 'json' };
184
+ addSchema('PikkuAIAgentOutput', PikkuAIAgentOutput);
185
+ import * as PikkuPublicAgentOutput from './schemas/PikkuPublicAgentOutput.schema.json' with { type: 'json' };
186
+ addSchema('PikkuPublicAgentOutput', PikkuPublicAgentOutput);
183
187
  import * as PikkuCommandChannelsOutput from './schemas/PikkuCommandChannelsOutput.schema.json' with { type: 'json' };
184
188
  addSchema('PikkuCommandChannelsOutput', PikkuCommandChannelsOutput);
185
189
  import * as PikkuCLIEntryOutput from './schemas/PikkuCLIEntryOutput.schema.json' with { type: 'json' };
186
190
  addSchema('PikkuCLIEntryOutput', PikkuCLIEntryOutput);
187
191
  import * as PikkuCLIOutput from './schemas/PikkuCLIOutput.schema.json' with { type: 'json' };
188
192
  addSchema('PikkuCLIOutput', PikkuCLIOutput);
189
- import * as PikkuAIAgentOutput from './schemas/PikkuAIAgentOutput.schema.json' with { type: 'json' };
190
- addSchema('PikkuAIAgentOutput', PikkuAIAgentOutput);
191
- import * as PikkuPublicAgentOutput from './schemas/PikkuPublicAgentOutput.schema.json' with { type: 'json' };
192
- addSchema('PikkuPublicAgentOutput', PikkuPublicAgentOutput);
193
- import * as PikkuConsoleFunctionsOutput from './schemas/PikkuConsoleFunctionsOutput.schema.json' with { type: 'json' };
194
- addSchema('PikkuConsoleFunctionsOutput', PikkuConsoleFunctionsOutput);
195
- import * as PikkuNodesMetaOutput from './schemas/PikkuNodesMetaOutput.schema.json' with { type: 'json' };
196
- addSchema('PikkuNodesMetaOutput', PikkuNodesMetaOutput);
197
193
  import * as PikkuFunctionTypesSplitInput from './schemas/PikkuFunctionTypesSplitInput.schema.json' with { type: 'json' };
198
194
  addSchema('PikkuFunctionTypesSplitInput', PikkuFunctionTypesSplitInput);
199
195
  import * as PikkuFunctionTypesInput from './schemas/PikkuFunctionTypesInput.schema.json' with { type: 'json' };
@@ -234,5 +230,9 @@ import * as PikkuTriggerOutput from './schemas/PikkuTriggerOutput.schema.json' w
234
230
  addSchema('PikkuTriggerOutput', PikkuTriggerOutput);
235
231
  import * as PikkuWorkflowRoutesOutput from './schemas/PikkuWorkflowRoutesOutput.schema.json' with { type: 'json' };
236
232
  addSchema('PikkuWorkflowRoutesOutput', PikkuWorkflowRoutesOutput);
233
+ import * as PikkuConsoleFunctionsOutput from './schemas/PikkuConsoleFunctionsOutput.schema.json' with { type: 'json' };
234
+ addSchema('PikkuConsoleFunctionsOutput', PikkuConsoleFunctionsOutput);
235
+ import * as PikkuNodesMetaOutput from './schemas/PikkuNodesMetaOutput.schema.json' with { type: 'json' };
236
+ addSchema('PikkuNodesMetaOutput', PikkuNodesMetaOutput);
237
237
  import * as PikkuCLIConfig from './schemas/PikkuCLIConfig.schema.json' with { type: 'json' };
238
238
  addSchema('PikkuCLIConfig', PikkuCLIConfig);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36
2
+ * This file was generated by @pikku/cli@0.12.38
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.36') {
15
- process.stderr.write(`\n Update available 0.12.36 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.38') {
15
+ process.stderr.write(`\n Update available 0.12.38 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
@@ -79,16 +79,16 @@ export async function runFabricValidate(startDir = process.cwd()) {
79
79
  catch {
80
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
81
  }
82
- const fabricConfigPath = join(root, 'fabric.config.json');
82
+ const fabricConfigPath = join(root, 'pikkufabric.config.json');
83
83
  const fabricConfig = await readJsonSafe(fabricConfigPath);
84
84
  if (!fabricConfig) {
85
- info('fabric-config-missing', 'fabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, 'Run `pikku fabric link` to create it, or create manually: {"projectId": "__PROJECT_ID__"}');
85
+ info('fabric-config-missing', 'pikkufabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, 'Run `pikku fabric link` to create it, or create manually: {"projectId": "__PROJECT_ID__"}');
86
86
  }
87
87
  else if (!fabricConfig.projectId) {
88
- info('fabric-config-no-project-id', 'fabric.config.json is missing "projectId"', fabricConfigPath, 'Add "projectId": "<your-project-id>" to fabric.config.json, or run `pikku fabric link`');
88
+ info('fabric-config-no-project-id', 'pikkufabric.config.json is missing "projectId"', fabricConfigPath, 'Add "projectId": "<your-project-id>" to pikkufabric.config.json, or run `pikku fabric link`');
89
89
  }
90
90
  else if (fabricConfig.projectId === '__PROJECT_ID__') {
91
- info('fabric-config-placeholder-project-id', 'fabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, 'Run `pikku fabric link` to replace the placeholder with a real project ID');
91
+ info('fabric-config-placeholder-project-id', 'pikkufabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, 'Run `pikku fabric link` to replace the placeholder with a real project ID');
92
92
  }
93
93
  const rootPkgPath = join(root, 'package.json');
94
94
  const rootPkg = await readJsonSafe(rootPkgPath);
@@ -103,7 +103,7 @@ export async function runFabricValidate(startDir = process.cwd()) {
103
103
  }
104
104
  const fnDir = join(root, 'packages', 'functions');
105
105
  const functionsSdkPkgName = (await readJsonSafe(join(root, 'packages', 'functions-sdk', 'package.json')))?.name;
106
- const themePkgName = (await readJsonSafe(join(root, 'packages', 'theme', 'package.json')))?.name;
106
+ const themePkgName = (await readJsonSafe(join(root, 'packages', 'mantine-theme', 'package.json')))?.name;
107
107
  const componentsPkgName = (await readJsonSafe(join(root, 'packages', 'components', 'package.json')))?.name;
108
108
  if (existsSync(fnDir)) {
109
109
  const fnPkgPath = join(fnDir, 'package.json');
@@ -241,8 +241,8 @@ export async function runFabricValidate(startDir = process.cwd()) {
241
241
  }
242
242
  }
243
243
  const designDocUrl = 'https://pikkufabric.dev/docs/design';
244
- if (!existsSync(join(root, 'packages', 'theme'))) {
245
- info('theme-missing', 'packages/theme/ not found — Fabric design features require a theme package', join(root, 'packages', 'theme'), `Create packages/theme/ with your Mantine theme tokens. See ${designDocUrl}`);
244
+ if (!existsSync(join(root, 'packages', 'mantine-theme'))) {
245
+ info('theme-missing', 'packages/mantine-theme/ not found — Fabric design features require a theme package', join(root, 'packages', 'mantine-theme'), `Create packages/mantine-theme/ with your Mantine theme tokens. See ${designDocUrl}`);
246
246
  }
247
247
  if (!existsSync(join(root, 'packages', 'components'))) {
248
248
  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}`);
@@ -20,8 +20,9 @@ export const FabricValidateOutput = z.object({
20
20
  async function findProjectRoot(startDir) {
21
21
  let dir = startDir;
22
22
  while (true) {
23
- if (existsSync(join(dir, 'fabric.config.json')))
23
+ if (existsSync(join(dir, 'pikkufabric.config.json'))) {
24
24
  return dir;
25
+ }
25
26
  if (existsSync(join(dir, 'package.json'))) {
26
27
  try {
27
28
  const pkg = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8'));
@@ -83,19 +84,19 @@ export async function runValidate(startDir = process.cwd()) {
83
84
  const info = (id, message, path, fixHint) => {
84
85
  findings.push({ id, severity: 'info', message, path, fixHint });
85
86
  };
86
- // ── fabric.config.json ─────────────────────────────────────────────────
87
+ // ── pikkufabric.config.json ────────────────────────────────────────────
87
88
  // Not required to run validate — downgraded to info so any pikku project
88
89
  // can be checked for compatibility before it is linked to a fabric account.
89
- const fabricConfigPath = join(root, 'fabric.config.json');
90
+ const fabricConfigPath = join(root, 'pikkufabric.config.json');
90
91
  const fabricConfig = await readJsonSafe(fabricConfigPath);
91
92
  if (!fabricConfig) {
92
- info('fabric-config-missing', 'fabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, 'Run `pikku fabric link` to create it, or create manually: {"projectId": "__PROJECT_ID__"}');
93
+ info('fabric-config-missing', 'pikkufabric.config.json not found — project has not been linked to fabric yet', fabricConfigPath, 'Run `pikku fabric link` to create it, or create manually: {"projectId": "__PROJECT_ID__"}');
93
94
  }
94
95
  else if (!fabricConfig.projectId) {
95
- info('fabric-config-no-project-id', 'fabric.config.json is missing "projectId"', fabricConfigPath, 'Add "projectId": "<your-project-id>" to fabric.config.json, or run `pikku fabric link`');
96
+ info('fabric-config-no-project-id', 'pikkufabric.config.json is missing "projectId"', fabricConfigPath, 'Add "projectId": "<your-project-id>" to pikkufabric.config.json, or run `pikku fabric link`');
96
97
  }
97
98
  else if (fabricConfig.projectId === '__PROJECT_ID__') {
98
- info('fabric-config-placeholder-project-id', 'fabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, 'Run `pikku fabric link` to replace the placeholder with a real project ID');
99
+ info('fabric-config-placeholder-project-id', 'pikkufabric.config.json has a placeholder projectId ("__PROJECT_ID__") — project is not linked', fabricConfigPath, 'Run `pikku fabric link` to replace the placeholder with a real project ID');
99
100
  }
100
101
  // ── root pikku.config.json ─────────────────────────────────────────────
101
102
  const pikkuConfigPath = join(root, 'pikku.config.json');
@@ -114,6 +115,7 @@ export async function runValidate(startDir = process.cwd()) {
114
115
  info('pikku-config-no-client-files', 'pikku.config.json missing "clientFiles" — no generated SDK or React Query hooks', pikkuConfigPath, 'Add clientFiles.rpcMapDeclarationFile and clientFiles.reactQueryFile pointing to packages/functions-sdk/src/pikku/');
115
116
  }
116
117
  }
118
+ const dbEngine = pikkuConfig?.db?.engine ?? 'sqlite';
117
119
  const rootPkgPath = join(root, 'package.json');
118
120
  const rootPkg = await readJsonSafe(rootPkgPath);
119
121
  if (!rootPkg) {
@@ -149,7 +151,7 @@ export async function runValidate(startDir = process.cwd()) {
149
151
  // ── packages/functions/ ────────────────────────────────────────────────
150
152
  const fnDir = join(root, 'packages', 'functions');
151
153
  const functionsSdkPkgName = (await readJsonSafe(join(root, 'packages', 'functions-sdk', 'package.json')))?.name;
152
- const themePkgName = (await readJsonSafe(join(root, 'packages', 'theme', 'package.json')))?.name;
154
+ const themePkgName = (await readJsonSafe(join(root, 'packages', 'mantine-theme', 'package.json')))?.name;
153
155
  const componentsPkgName = (await readJsonSafe(join(root, 'packages', 'components', 'package.json')))?.name;
154
156
  if (!existsSync(fnDir)) {
155
157
  e('functions-pkg-missing', 'packages/functions/ directory not found', fnDir, 'Create packages/functions/ as a yarn workspace containing pikku.config.json, src/, and db/sqlite/');
@@ -161,12 +163,16 @@ export async function runValidate(startDir = process.cwd()) {
161
163
  if (fnPkg.type !== 'module') {
162
164
  w('functions-pkg-no-esm', 'packages/functions/package.json is missing "type": "module"', fnPkgPath, 'Add "type": "module" to packages/functions/package.json — Cloudflare Workers require ES modules');
163
165
  }
166
+ // #pikku bare import — required by the injected fabric-telemetry.wiring.ts
167
+ if (!fnPkg.imports?.['#pikku']) {
168
+ e('functions-pkg-missing-pikku-import', 'packages/functions/package.json is missing a bare "#pikku" entry in "imports" — the Fabric-injected telemetry middleware imports from "#pikku" and will fail to bundle without it', fnPkgPath, 'Add to "imports": { "#pikku": "./.pikku/pikku-types.gen.ts", "#pikku/*": "./.pikku/*" }');
169
+ }
164
170
  const fnAllDeps = {
165
171
  ...fnPkg.dependencies,
166
172
  ...fnPkg.devDependencies,
167
173
  ...fnPkg.peerDependencies,
168
174
  };
169
- if (fnAllDeps['@pikku/kysely-postgres']) {
175
+ if (dbEngine !== 'postgres' && fnAllDeps['@pikku/kysely-postgres']) {
170
176
  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');
171
177
  }
172
178
  }
@@ -181,25 +187,26 @@ export async function runValidate(startDir = process.cwd()) {
181
187
  const usesLibsql = servicesText.includes('@pikku/kysely-sqlite') ||
182
188
  servicesText.includes('LibsqlWebDialect');
183
189
  const usesProcessEnv = /\bprocess\.env\.[A-Z_]/.test(servicesText);
184
- if (usesKysely && !usesLibsql) {
190
+ if (dbEngine !== 'postgres' && usesKysely && !usesLibsql) {
185
191
  e('services-wrong-db-adapter', 'services.ts uses Kysely but not LibsqlWebDialect — Fabric injects a Turso/libSQL DATABASE_URL at runtime, not a PostgreSQL URL', servicesPath, 'Import LibsqlWebDialect from @pikku/kysely-sqlite and replace the dialect: new Kysely({ dialect: new LibsqlWebDialect({ url: databaseUrl }) })');
186
192
  }
187
193
  if (usesProcessEnv) {
188
194
  info('services-process-env', 'services.ts reads process.env directly — prefer variables.get() for portable secret/variable access', servicesPath, 'Replace process.env.SOME_VAR with await variables.get("SOME_VAR") — declare the binding with wireVariable/wireSecret; process.env is fine for optional/non-secret config');
189
195
  }
190
- if (usesLibsql &&
196
+ if (dbEngine !== 'postgres' &&
197
+ usesLibsql &&
191
198
  rootPkg &&
192
199
  !rootPkg.dependencies?.['@pikku/kysely-sqlite'] &&
193
200
  !rootPkg.devDependencies?.['@pikku/kysely-sqlite']) {
194
201
  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');
195
202
  }
196
203
  }
197
- // db/sqlite/ presence, numbering and SQL dialect
198
- // Mirrors local-db.ts which resolves migrationsDir from the config root as
199
- // db/sqlite (SQLite/libSQL) or db/postgres (PostgreSQL).
200
- const migrationsDir = join(root, 'db', 'sqlite');
204
+ // Database layout is declared by pikku.config.json db.engine.
205
+ const migrationsDir = join(root, 'db', dbEngine === 'postgres' ? 'postgres' : 'sqlite');
201
206
  if (!existsSync(migrationsDir)) {
202
- e('migrations-dir-missing', 'db/sqlite/ not found', migrationsDir, 'Create db/sqlite/ and add numbered .sql files (e.g. 0001-init.sql) using SQLite-compatible syntax');
207
+ e('migrations-dir-missing', `db/${dbEngine === 'postgres' ? 'postgres' : 'sqlite'}/ not found`, migrationsDir, dbEngine === 'postgres'
208
+ ? 'Create db/postgres/ and add numbered .sql files (e.g. 0001-init.sql) using PostgreSQL-compatible syntax'
209
+ : 'Create db/sqlite/ and add numbered .sql files (e.g. 0001-init.sql) using SQLite-compatible syntax');
203
210
  }
204
211
  else {
205
212
  try {
@@ -219,14 +226,16 @@ export async function runValidate(startDir = process.cwd()) {
219
226
  break;
220
227
  }
221
228
  }
222
- // Check for PostgreSQL-specific syntax — Fabric uses Turso (SQLite/libSQL)
223
- for (const f of files) {
224
- const sql = await readTextSafe(join(migrationsDir, f));
225
- if (!sql)
226
- continue;
227
- const hits = POSTGRES_SQL_PATTERNS.filter(({ re }) => re.test(sql)).map(({ label }) => label);
228
- if (hits.length > 0) {
229
- e(`migration-postgres-sql-${f.replace(/[^a-z0-9]/gi, '-')}`, `${f} contains PostgreSQL syntax (${hits.join(', ')}) — Fabric uses SQLite/libSQL (Turso)`, join(migrationsDir, f), "Rewrite the migration using SQLite-compatible syntax: TEXT instead of JSONB, INTEGER PRIMARY KEY for auto-increment, datetime('now') instead of NOW(), no :: casts");
229
+ if (dbEngine !== 'postgres') {
230
+ // Check for PostgreSQL-specific syntax Fabric uses Turso (SQLite/libSQL)
231
+ for (const f of files) {
232
+ const sql = await readTextSafe(join(migrationsDir, f));
233
+ if (!sql)
234
+ continue;
235
+ const hits = POSTGRES_SQL_PATTERNS.filter(({ re }) => re.test(sql)).map(({ label }) => label);
236
+ if (hits.length > 0) {
237
+ e(`migration-postgres-sql-${f.replace(/[^a-z0-9]/gi, '-')}`, `${f} contains PostgreSQL syntax (${hits.join(', ')}) — Fabric uses SQLite/libSQL (Turso)`, join(migrationsDir, f), "Rewrite the migration using SQLite-compatible syntax: TEXT instead of JSONB, INTEGER PRIMARY KEY for auto-increment, datetime('now') instead of NOW(), no :: casts");
238
+ }
230
239
  }
231
240
  }
232
241
  }
@@ -234,10 +243,13 @@ export async function runValidate(startDir = process.cwd()) {
234
243
  // readdir failure — skip
235
244
  }
236
245
  }
237
- // db/sqlite-seed.sql
238
- const seedPath = join(root, 'db', 'sqlite-seed.sql');
246
+ const seedPath = join(root, 'db', dbEngine === 'postgres' ? 'postgres-seed.sql' : 'sqlite-seed.sql');
239
247
  if (!existsSync(seedPath)) {
240
- e('seed-sql-missing', 'db/sqlite-seed.sql not found', seedPath, 'Create db/sqlite-seed.sql with idempotent INSERT OR IGNORE statements for demo/test data');
248
+ e('seed-sql-missing', dbEngine === 'postgres'
249
+ ? 'db/postgres-seed.sql not found'
250
+ : 'db/sqlite-seed.sql not found', seedPath, dbEngine === 'postgres'
251
+ ? 'Create db/postgres-seed.sql with idempotent seed data for local/test data'
252
+ : 'Create db/sqlite-seed.sql with idempotent INSERT OR IGNORE statements for demo/test data');
241
253
  }
242
254
  // audit table — info if not present (optional feature)
243
255
  if (existsSync(migrationsDir)) {
@@ -324,8 +336,8 @@ export async function runValidate(startDir = process.cwd()) {
324
336
  }
325
337
  // ── packages/theme + packages/components ──────────────────────────────
326
338
  const designDocUrl = 'https://pikkufabric.dev/docs/design';
327
- if (!existsSync(join(root, 'packages', 'theme'))) {
328
- info('theme-missing', 'packages/theme/ not found — Fabric design features require a theme package', join(root, 'packages', 'theme'), `Create packages/theme/ with your Mantine theme tokens. See ${designDocUrl}`);
339
+ if (!existsSync(join(root, 'packages', 'mantine-theme'))) {
340
+ info('theme-missing', 'packages/mantine-theme/ not found — Fabric design features require a theme package', join(root, 'packages', 'mantine-theme'), `Create packages/mantine-theme/ with your Mantine theme tokens. See ${designDocUrl}`);
329
341
  }
330
342
  if (!existsSync(join(root, 'packages', 'components'))) {
331
343
  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}`);
@@ -1,7 +1,7 @@
1
1
  /**
2
- * `fabric.config.json` lives next to `pikku.config.json` in the project root.
3
- * Pins the project link (id, default api url) and declares deployable apps
4
- * + production domain. Discovered by walking up from cwd until found.
2
+ * `pikkufabric.config.json` lives next to `pikku.config.json` in the project
3
+ * root. Pins the project link (id, default api url) and declares deployable
4
+ * apps + production domain. Discovered by walking up from cwd until found.
5
5
  */
6
6
  export interface ProjectConfig {
7
7
  projectId: string;
@@ -53,7 +53,7 @@ export interface ResolvedApiContext {
53
53
  /**
54
54
  * Stitch together the api-url + auth token from the standard sources:
55
55
  * 1. explicit override (e.g. --api-url flag)
56
- * 2. fabric.config.json apiUrl
56
+ * 2. pikkufabric.config.json apiUrl
57
57
  * 3. FABRIC_API_URL env var
58
58
  * 4. hardcoded default
59
59
  *
@@ -3,7 +3,7 @@ import { existsSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
5
  const DEFAULT_API_URL = 'http://localhost:7103';
6
- const projectConfigName = 'fabric.config.json';
6
+ const projectConfigName = 'pikkufabric.config.json';
7
7
  const authFilePath = join(homedir(), '.fabric', 'auth.json');
8
8
  export async function findProjectConfig(startDir = process.cwd()) {
9
9
  let dir = startDir;
@@ -41,7 +41,7 @@ export async function writeAuthFile(file) {
41
41
  /**
42
42
  * Stitch together the api-url + auth token from the standard sources:
43
43
  * 1. explicit override (e.g. --api-url flag)
44
- * 2. fabric.config.json apiUrl
44
+ * 2. pikkufabric.config.json apiUrl
45
45
  * 3. FABRIC_API_URL env var
46
46
  * 4. hardcoded default
47
47
  *
@@ -3,6 +3,7 @@ import { pathToFileURL } from 'node:url';
3
3
  import { readdirSync, statSync, readFileSync, existsSync } from 'node:fs';
4
4
  import { join, extname, dirname } from 'node:path';
5
5
  import { PIKKU_BETTER_AUTH } from '@pikku/better-auth';
6
+ import { LocalSecretService, LocalVariablesService } from '@pikku/core/services';
6
7
  import { loadUserModule } from '../commands/load-user-project.js';
7
8
  let cachedGetMigrations = null;
8
9
  async function loadGetMigrations() {
@@ -87,24 +88,43 @@ async function loadAuthFactory(sourceFile) {
87
88
  return null;
88
89
  }
89
90
  function schemaServicesStub(kysely, logger) {
90
- const dummy = 'x'.repeat(32);
91
- const fromKeys = (keys) => Object.fromEntries(keys.map((k) => [k, dummy]));
91
+ const variables = new LocalVariablesService();
92
+ const secrets = new LocalSecretService(variables);
92
93
  const base = {
93
94
  kysely,
94
95
  logger,
95
- secrets: {
96
- getSecret: async () => dummy,
97
- getSecrets: async (keys) => fromKeys(keys),
98
- },
99
- variables: {
100
- getVariable: async () => dummy,
101
- getVariables: async (keys) => fromKeys(keys),
102
- },
96
+ secrets,
97
+ variables,
103
98
  };
104
99
  return new Proxy(base, {
105
100
  get: (target, prop) => typeof prop === 'string' && prop in target ? target[prop] : undefined,
106
101
  });
107
102
  }
103
+ function findUserConfigFactoryFile(rootDir, srcDirectories) {
104
+ for (const srcDir of srcDirectories) {
105
+ for (const name of ['config.ts', 'config.js']) {
106
+ const candidate = join(rootDir, srcDir, name);
107
+ if (existsSync(candidate))
108
+ return candidate;
109
+ }
110
+ }
111
+ for (const name of ['config.ts', 'config.js']) {
112
+ const candidate = join(rootDir, name);
113
+ if (existsSync(candidate))
114
+ return candidate;
115
+ }
116
+ return null;
117
+ }
118
+ async function loadAuthConfig(opts) {
119
+ const configFactoryFile = findUserConfigFactoryFile(opts.rootDir, opts.srcDirectories);
120
+ if (!configFactoryFile)
121
+ return undefined;
122
+ const configModule = await loadUserModule(configFactoryFile);
123
+ const userCreateConfig = configModule.createConfig;
124
+ if (typeof userCreateConfig !== 'function')
125
+ return undefined;
126
+ return userCreateConfig(new LocalVariablesService());
127
+ }
108
128
  export async function loadAuthOptions(opts) {
109
129
  const sourceFile = findAuthSourceFile(opts.rootDir, opts.srcDirectories);
110
130
  if (!sourceFile)
@@ -112,7 +132,9 @@ export async function loadAuthOptions(opts) {
112
132
  const factory = await loadAuthFactory(sourceFile);
113
133
  if (!factory)
114
134
  return null;
115
- const instance = await factory(schemaServicesStub(opts.kysely, opts.logger));
135
+ const services = schemaServicesStub(opts.kysely, opts.logger);
136
+ services.config = await loadAuthConfig(opts);
137
+ const instance = await factory(services);
116
138
  const options = instance.options;
117
139
  return options ?? null;
118
140
  }
@@ -28,6 +28,12 @@ function snakeToPascal(name) {
28
28
  .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
29
29
  .join('');
30
30
  }
31
+ function tableToInterfaceName(name) {
32
+ return name
33
+ .split('.')
34
+ .map((part) => snakeToPascal(part))
35
+ .join('');
36
+ }
31
37
  function snakeToCamel(name) {
32
38
  return name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
33
39
  }
@@ -110,9 +116,7 @@ function columnTypeExpression(col, annotation, classification) {
110
116
  return wrap(nullable ? 'Uuid | null' : 'Uuid');
111
117
  }
112
118
  if (annotation?.tsType) {
113
- const base = nullable
114
- ? `${annotation.tsType} | null`
115
- : annotation.tsType;
119
+ const base = nullable ? `${annotation.tsType} | null` : annotation.tsType;
116
120
  return wrap(base);
117
121
  }
118
122
  if (annotation?.kind === 'json') {
@@ -146,7 +150,7 @@ function bareTableName(name) {
146
150
  return dot >= 0 ? name.slice(dot + 1) : name;
147
151
  }
148
152
  function emitInterface(table, camelCase, explicitAnnotations, dialect, enumByName, formatHints, warnings) {
149
- const ifaceName = snakeToPascal(table.name);
153
+ const ifaceName = tableToInterfaceName(table.name);
150
154
  const bare = bareTableName(table.name);
151
155
  const tableCols = explicitAnnotations[bare] ?? {};
152
156
  const fields = table.columns
@@ -352,7 +356,7 @@ export async function generateSchemaTypes(introspector, options) {
352
356
  const safe = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableKey)
353
357
  ? tableKey
354
358
  : JSON.stringify(tableKey);
355
- return ` ${safe}: ${snakeToPascal(t.name)}`;
359
+ return ` ${safe}: ${tableToInterfaceName(t.name)}`;
356
360
  })
357
361
  .join('\n');
358
362
  const schemaBody = [
@@ -1,4 +1,4 @@
1
- import type { Kysely } from 'kysely';
1
+ import { Kysely } from 'kysely';
2
2
  import { type MigrateResult } from './db-migrator.js';
3
3
  import { type CodegenResult } from './db-codegen.js';
4
4
  import { type ZodCodegenResult } from './zod-codegen.js';
@@ -58,7 +58,7 @@ export interface DesiredAuthSchema {
58
58
  tables: SchemaMap;
59
59
  sql: string;
60
60
  }
61
- export declare function desiredAuthSchema(rootDir: string, srcDirectories: string[], logger: {
61
+ export declare function desiredAuthSchema(resolved: ResolvedDb, rootDir: string, srcDirectories: string[], logger: {
62
62
  error: (msg: string) => void;
63
63
  }): Promise<DesiredAuthSchema | null>;
64
64
  export declare function introspectSchema(resolved: ResolvedDb): Promise<SchemaMap>;