@pikku/cli 0.12.0 → 0.12.1

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 (185) hide show
  1. package/cli.schema.json +1 -1
  2. package/console-app/assets/index-DiYPTQU_.js +676 -0
  3. package/console-app/index.html +6 -1
  4. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +30 -3
  5. package/dist/.pikku/agent/pikku-agent-types.gen.js +13 -0
  6. package/dist/.pikku/agent/pikku-agent-wirings-meta.gen.js +2 -2
  7. package/dist/.pikku/agent/pikku-agent-wirings.gen.d.ts +1 -1
  8. package/dist/.pikku/agent/pikku-agent-wirings.gen.js +1 -1
  9. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  10. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  11. package/dist/.pikku/channel/pikku-channels-meta.gen.js +2 -2
  12. package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
  13. package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-channel.js +57 -3
  15. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  16. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  17. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  18. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  19. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +2 -2
  20. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +228 -10
  21. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  22. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  23. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  24. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  25. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  26. package/dist/.pikku/function/pikku-function-types.gen.d.ts +14 -11
  27. package/dist/.pikku/function/pikku-function-types.gen.js +25 -13
  28. package/dist/.pikku/function/pikku-functions-meta.gen.js +2 -2
  29. package/dist/.pikku/function/pikku-functions-meta.gen.json +359 -105
  30. package/dist/.pikku/function/pikku-functions.gen.js +3 -3
  31. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  32. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  33. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +2 -2
  34. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  35. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  36. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  37. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  38. package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +2 -2
  39. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
  40. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
  41. package/dist/.pikku/pikku-bootstrap.gen.js +2 -2
  42. package/dist/.pikku/pikku-services.gen.d.ts +2 -1
  43. package/dist/.pikku/pikku-services.gen.js +1 -0
  44. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  45. package/dist/.pikku/pikku-types.gen.js +1 -1
  46. package/dist/.pikku/pikku-websocket.gen.d.ts +1 -1
  47. package/dist/.pikku/pikku-websocket.gen.js +1 -1
  48. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  49. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  50. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +2 -2
  51. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  52. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  53. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +1 -1
  54. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +2 -2
  55. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +15 -6
  56. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  57. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  58. package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +2 -2
  59. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
  60. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
  61. package/dist/.pikku/schemas/register.gen.js +15 -5
  62. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  63. package/dist/.pikku/schemas/schemas/PikkuNewAddonInput.schema.json +1 -0
  64. package/dist/.pikku/schemas/schemas/PikkuNewFunctionInput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/PikkuNewMiddlewareInput.schema.json +1 -0
  66. package/dist/.pikku/schemas/schemas/PikkuNewPermissionInput.schema.json +1 -0
  67. package/dist/.pikku/schemas/schemas/PikkuNewWiringInput.schema.json +1 -0
  68. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  69. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  70. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  71. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  72. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  73. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  74. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  75. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  76. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  77. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  78. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  79. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  80. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +2 -2
  81. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +1 -1
  82. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  83. package/dist/src/cli.wiring.js +190 -9
  84. package/dist/src/functions/commands/all.js +6 -6
  85. package/dist/src/functions/commands/info.d.ts +9 -0
  86. package/dist/src/functions/commands/info.js +283 -0
  87. package/dist/src/functions/commands/new-addon.d.ts +34 -0
  88. package/dist/src/functions/commands/new-addon.js +636 -0
  89. package/dist/src/functions/commands/new-function.d.ts +10 -0
  90. package/dist/src/functions/commands/new-function.js +79 -0
  91. package/dist/src/functions/commands/new-middleware.d.ts +10 -0
  92. package/dist/src/functions/commands/new-middleware.js +48 -0
  93. package/dist/src/functions/commands/new-permission.d.ts +10 -0
  94. package/dist/src/functions/commands/new-permission.js +45 -0
  95. package/dist/src/functions/commands/new-wiring.d.ts +10 -0
  96. package/dist/src/functions/commands/new-wiring.js +102 -0
  97. package/dist/src/functions/commands/pikku-command-bootstrap.js +11 -40
  98. package/dist/src/functions/commands/versions-check.js +85 -3
  99. package/dist/src/functions/commands/versions-update.js +1 -1
  100. package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +0 -4
  101. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.js +3 -2
  102. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.js +5 -5
  103. package/dist/src/functions/wirings/ai-agent/serialize-agent-map.d.ts +1 -1
  104. package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.d.ts +1 -1
  105. package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.js +48 -3
  106. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +30 -52
  107. package/dist/src/functions/wirings/channels/pikku-channels.js +1 -1
  108. package/dist/src/functions/wirings/channels/pikku-command-channel-types.js +2 -2
  109. package/dist/src/functions/wirings/channels/pikku-command-channels.js +1 -1
  110. package/dist/src/functions/wirings/channels/serialize-typed-channel-map.d.ts +4 -4
  111. package/dist/src/functions/wirings/cli/pikku-command-cli.js +1 -1
  112. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.d.ts +2 -2
  113. package/dist/src/functions/wirings/cli/serialize-channel-cli.d.ts +1 -1
  114. package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.d.ts +1 -1
  115. package/dist/src/functions/wirings/console/pikku-command-console-functions.js +2 -1
  116. package/dist/src/functions/wirings/console/pikku-command-nodes-meta.js +1 -1
  117. package/dist/src/functions/wirings/console/serialize-console-functions.d.ts +1 -1
  118. package/dist/src/functions/wirings/console/serialize-console-functions.js +18 -157
  119. package/dist/src/functions/wirings/functions/pikku-command-addon-types.d.ts +1 -0
  120. package/dist/src/functions/wirings/functions/pikku-command-addon-types.js +33 -0
  121. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
  122. package/dist/src/functions/wirings/functions/pikku-command-function-types.js +4 -4
  123. package/dist/src/functions/wirings/functions/pikku-command-functions.js +8 -14
  124. package/dist/src/functions/wirings/functions/schemas.js +1 -1
  125. package/dist/src/functions/wirings/functions/serialize-addon-types.d.ts +1 -0
  126. package/dist/src/functions/wirings/functions/{serialize-external-types.js → serialize-addon-types.js} +16 -15
  127. package/dist/src/functions/wirings/functions/serialize-function-imports.d.ts +3 -3
  128. package/dist/src/functions/wirings/functions/serialize-function-imports.js +3 -3
  129. package/dist/src/functions/wirings/functions/serialize-function-types.js +28 -14
  130. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.d.ts +1 -1
  131. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.js +2 -2
  132. package/dist/src/functions/wirings/http/pikku-command-http-routes.js +1 -1
  133. package/dist/src/functions/wirings/http/pikku-http-routes.js +1 -1
  134. package/dist/src/functions/wirings/http/serialize-typed-http-map.d.ts +3 -3
  135. package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +1 -1
  136. package/dist/src/functions/wirings/package/pikku-command-package.js +5 -5
  137. package/dist/src/functions/wirings/package/serialize-package.js +2 -2
  138. package/dist/src/functions/wirings/permissions/pikku-command-permissions.js +0 -5
  139. package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +2 -2
  140. package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +1 -1
  141. package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.js +6 -6
  142. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +2 -4
  143. package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +25 -16
  144. package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +43 -7
  145. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.d.ts +8 -3
  146. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +41 -31
  147. package/dist/src/functions/wirings/scheduler/serialize-scheduler-meta.d.ts +1 -1
  148. package/dist/src/functions/wirings/secrets/serialize-secrets-types.d.ts +2 -2
  149. package/dist/src/functions/wirings/triggers/serialize-trigger-meta.d.ts +1 -1
  150. package/dist/src/functions/wirings/triggers/serialize-trigger-meta.js +2 -2
  151. package/dist/src/functions/wirings/variables/serialize-variables-types.d.ts +2 -2
  152. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +2 -2
  153. package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +2 -2
  154. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +2 -2
  155. package/dist/src/services/cli-logger-forwarder.service.d.ts +4 -3
  156. package/dist/src/services/cli-logger.service.d.ts +3 -2
  157. package/dist/src/services.d.ts +4 -3
  158. package/dist/src/services.js +2 -3
  159. package/dist/src/utils/check-required-types.d.ts +1 -1
  160. package/dist/src/utils/contract-versions.d.ts +1 -1
  161. package/dist/src/utils/file-writer.d.ts +6 -1
  162. package/dist/src/utils/file-writer.js +14 -1
  163. package/dist/src/utils/generate-bootstrap-file.d.ts +2 -2
  164. package/dist/src/utils/openapi/codegen.d.ts +19 -0
  165. package/dist/src/utils/openapi/codegen.js +288 -0
  166. package/dist/src/utils/openapi/naming.d.ts +30 -0
  167. package/dist/src/utils/openapi/naming.js +167 -0
  168. package/dist/src/utils/openapi/parse-openapi.d.ts +36 -0
  169. package/dist/src/utils/openapi/parse-openapi.js +196 -0
  170. package/dist/src/utils/openapi/zod-codegen.d.ts +53 -0
  171. package/dist/src/utils/openapi/zod-codegen.js +251 -0
  172. package/dist/src/utils/pikku-cli-config.d.ts +2 -2
  173. package/dist/src/utils/pikku-cli-config.js +8 -14
  174. package/dist/src/utils/pikku-files-and-methods.d.ts +1 -1
  175. package/dist/src/utils/pikku-files-and-methods.js +1 -1
  176. package/dist/src/utils/serialize-import-map.d.ts +2 -2
  177. package/dist/src/utils/serialize-import-map.js +1 -1
  178. package/dist/src/utils/serialize-meta-ts.js +1 -1
  179. package/dist/src/utils/serialize-schemas.d.ts +2 -2
  180. package/dist/tsconfig.tsbuildinfo +1 -1
  181. package/package.json +3 -3
  182. package/console-app/assets/index-C19L3UJu.js +0 -637
  183. package/dist/src/functions/wirings/functions/pikku-command-external-types.d.ts +0 -1
  184. package/dist/src/functions/wirings/functions/pikku-command-external-types.js +0 -33
  185. package/dist/src/functions/wirings/functions/serialize-external-types.d.ts +0 -1
@@ -0,0 +1,79 @@
1
+ import { existsSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { mkdir, writeFile } from 'fs/promises';
4
+ import { pikkuSessionlessFunc } from '#pikku';
5
+ import { scaffoldFilePath } from '../../utils/file-writer.js';
6
+ function capitalize(s) {
7
+ return s.charAt(0).toUpperCase() + s.slice(1);
8
+ }
9
+ export const pikkuNewFunction = pikkuSessionlessFunc({
10
+ func: async ({ logger, config }, { name, type = 'sessionless' }) => {
11
+ const filePath = scaffoldFilePath(config, 'functions', name, '.functions.ts', config.scaffold?.functionDir);
12
+ if (existsSync(filePath)) {
13
+ logger.error(`File already exists: ${filePath}`);
14
+ process.exit(1);
15
+ }
16
+ const inputName = capitalize(name) + 'Input';
17
+ const outputName = capitalize(name) + 'Output';
18
+ let content;
19
+ switch (type) {
20
+ case 'func':
21
+ content = `import { pikkuFunc } from '#pikku'
22
+
23
+ export type ${inputName} = {
24
+ // TODO: define input
25
+ }
26
+
27
+ export type ${outputName} = {
28
+ // TODO: define output
29
+ }
30
+
31
+ export const ${name} = pikkuFunc<${inputName}, ${outputName}>({
32
+ func: async ({ logger }, data, { session }) => {
33
+ // TODO: implement
34
+ return {} as ${outputName}
35
+ },
36
+ })
37
+ `;
38
+ break;
39
+ case 'void':
40
+ content = `import { pikkuVoidFunc } from '#pikku'
41
+
42
+ export type ${inputName} = {
43
+ // TODO: define input
44
+ }
45
+
46
+ export const ${name} = pikkuVoidFunc<${inputName}>({
47
+ func: async ({ logger }, data) => {
48
+ // TODO: implement
49
+ },
50
+ })
51
+ `;
52
+ break;
53
+ case 'sessionless':
54
+ default:
55
+ content = `import { pikkuSessionlessFunc } from '#pikku'
56
+
57
+ export type ${inputName} = {
58
+ // TODO: define input
59
+ }
60
+
61
+ export type ${outputName} = {
62
+ // TODO: define output
63
+ }
64
+
65
+ export const ${name} = pikkuSessionlessFunc<${inputName}, ${outputName}>({
66
+ func: async ({ logger }, data) => {
67
+ // TODO: implement
68
+ return {} as ${outputName}
69
+ },
70
+ })
71
+ `;
72
+ break;
73
+ }
74
+ await mkdir(dirname(filePath), { recursive: true });
75
+ await writeFile(filePath, content, 'utf-8');
76
+ logger.info(`Created function at ${filePath}`);
77
+ console.log(filePath);
78
+ },
79
+ });
@@ -0,0 +1,10 @@
1
+ export declare const pikkuNewMiddleware: import("#pikku").PikkuFunctionConfig<{
2
+ name: string;
3
+ type?: string;
4
+ }, void, "session" | "rpc", import("#pikku").PikkuFunctionSessionless<{
5
+ name: string;
6
+ type?: string;
7
+ }, void, "session" | "rpc", import("#pikku").Services> | import("#pikku").PikkuFunction<{
8
+ name: string;
9
+ type?: string;
10
+ }, void, "session" | "rpc", import("#pikku").Services>, undefined, undefined>;
@@ -0,0 +1,48 @@
1
+ import { existsSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { mkdir, writeFile } from 'fs/promises';
4
+ import { pikkuSessionlessFunc } from '#pikku';
5
+ import { scaffoldFilePath } from '../../utils/file-writer.js';
6
+ export const pikkuNewMiddleware = pikkuSessionlessFunc({
7
+ func: async ({ logger, config }, { name, type = 'simple' }) => {
8
+ const filePath = scaffoldFilePath(config, 'middleware', name, '.ts', config.scaffold?.middlewareDir);
9
+ if (existsSync(filePath)) {
10
+ logger.error(`File already exists: ${filePath}`);
11
+ process.exit(1);
12
+ }
13
+ let content;
14
+ switch (type) {
15
+ case 'factory':
16
+ content = `import { pikkuMiddlewareFactory } from '#pikku'
17
+
18
+ export const ${name} = pikkuMiddlewareFactory(
19
+ (param: string) =>
20
+ async ({ logger }, _data, next) => {
21
+ logger.info(\`[\${param}] before\`)
22
+ const result = await next()
23
+ logger.info(\`[\${param}] after\`)
24
+ return result
25
+ }
26
+ )
27
+ `;
28
+ break;
29
+ case 'simple':
30
+ default:
31
+ content = `import { pikkuMiddleware } from '#pikku'
32
+
33
+ export const ${name} = pikkuMiddleware(
34
+ async ({ logger }, _data, next) => {
35
+ // TODO: implement
36
+ const result = await next()
37
+ return result
38
+ }
39
+ )
40
+ `;
41
+ break;
42
+ }
43
+ await mkdir(dirname(filePath), { recursive: true });
44
+ await writeFile(filePath, content, 'utf-8');
45
+ logger.info(`Created middleware at ${filePath}`);
46
+ console.log(filePath);
47
+ },
48
+ });
@@ -0,0 +1,10 @@
1
+ export declare const pikkuNewPermission: import("#pikku").PikkuFunctionConfig<{
2
+ name: string;
3
+ type?: string;
4
+ }, void, "session" | "rpc", import("#pikku").PikkuFunctionSessionless<{
5
+ name: string;
6
+ type?: string;
7
+ }, void, "session" | "rpc", import("#pikku").Services> | import("#pikku").PikkuFunction<{
8
+ name: string;
9
+ type?: string;
10
+ }, void, "session" | "rpc", import("#pikku").Services>, undefined, undefined>;
@@ -0,0 +1,45 @@
1
+ import { existsSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { mkdir, writeFile } from 'fs/promises';
4
+ import { pikkuSessionlessFunc } from '#pikku';
5
+ import { scaffoldFilePath } from '../../utils/file-writer.js';
6
+ export const pikkuNewPermission = pikkuSessionlessFunc({
7
+ func: async ({ logger, config }, { name, type = 'simple' }) => {
8
+ const filePath = scaffoldFilePath(config, 'permissions', name, '.ts', config.scaffold?.permissionDir);
9
+ if (existsSync(filePath)) {
10
+ logger.error(`File already exists: ${filePath}`);
11
+ process.exit(1);
12
+ }
13
+ let content;
14
+ switch (type) {
15
+ case 'factory':
16
+ content = `import { pikkuPermissionFactory } from '#pikku'
17
+
18
+ export const ${name} = pikkuPermissionFactory(
19
+ (param: string) =>
20
+ async ({ logger }, _data, { session }) => {
21
+ // TODO: implement permission check
22
+ return true
23
+ }
24
+ )
25
+ `;
26
+ break;
27
+ case 'simple':
28
+ default:
29
+ content = `import { pikkuPermission } from '#pikku'
30
+
31
+ export const ${name} = pikkuPermission(
32
+ async ({ logger }, _data, { session }) => {
33
+ // TODO: implement permission check
34
+ return true
35
+ }
36
+ )
37
+ `;
38
+ break;
39
+ }
40
+ await mkdir(dirname(filePath), { recursive: true });
41
+ await writeFile(filePath, content, 'utf-8');
42
+ logger.info(`Created permission at ${filePath}`);
43
+ console.log(filePath);
44
+ },
45
+ });
@@ -0,0 +1,10 @@
1
+ export declare const pikkuNewWiring: import("#pikku").PikkuFunctionConfig<{
2
+ name: string;
3
+ type?: string;
4
+ }, void, "session" | "rpc", import("#pikku").PikkuFunctionSessionless<{
5
+ name: string;
6
+ type?: string;
7
+ }, void, "session" | "rpc", import("#pikku").Services> | import("#pikku").PikkuFunction<{
8
+ name: string;
9
+ type?: string;
10
+ }, void, "session" | "rpc", import("#pikku").Services>, undefined, undefined>;
@@ -0,0 +1,102 @@
1
+ import { existsSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { mkdir, writeFile } from 'fs/promises';
4
+ import { pikkuSessionlessFunc } from '#pikku';
5
+ import { scaffoldFilePath } from '../../utils/file-writer.js';
6
+ function getWiringTemplate(type, name) {
7
+ switch (type) {
8
+ case 'http':
9
+ return `import { wireHTTP } from '#pikku'
10
+ // import { myFunc } from '../functions/${name}.functions.js'
11
+
12
+ wireHTTP({
13
+ method: 'get',
14
+ route: '/api/${name}',
15
+ func: myFunc,
16
+ auth: false,
17
+ })
18
+ `;
19
+ case 'channel':
20
+ return `import { wireChannel } from '#pikku'
21
+ // import { onConnect, onMessage, onDisconnect } from '../functions/${name}.functions.js'
22
+
23
+ wireChannel({
24
+ name: '${name}',
25
+ route: '/',
26
+ onConnect,
27
+ onDisconnect,
28
+ onMessage,
29
+ auth: true,
30
+ })
31
+ `;
32
+ case 'scheduler':
33
+ return `import { wireScheduler } from '#pikku'
34
+ // import { myTask } from '../functions/${name}.functions.js'
35
+
36
+ wireScheduler({
37
+ name: '${name}',
38
+ schedule: '0 * * * *',
39
+ func: myTask,
40
+ })
41
+ `;
42
+ case 'queue':
43
+ return `import { wireQueueWorker } from '#pikku'
44
+ // import { processItem } from '../functions/${name}.functions.js'
45
+
46
+ wireQueueWorker({
47
+ name: '${name}',
48
+ func: processItem,
49
+ })
50
+ `;
51
+ case 'mcp':
52
+ return `import { wireMCPResource } from '#pikku'
53
+ // import { myResource } from '../functions/${name}.functions.js'
54
+
55
+ wireMCPResource({
56
+ uri: '${name}',
57
+ title: '${name}',
58
+ description: 'TODO: describe this resource',
59
+ func: myResource,
60
+ })
61
+ `;
62
+ case 'cli':
63
+ return `import { wireCLI, pikkuCLICommand } from '#pikku'
64
+ // import { myCommand } from '../functions/${name}.functions.js'
65
+
66
+ wireCLI({
67
+ program: '${name}',
68
+ commands: {
69
+ example: pikkuCLICommand({
70
+ func: myCommand,
71
+ description: 'TODO: describe this command',
72
+ }),
73
+ },
74
+ })
75
+ `;
76
+ case 'trigger':
77
+ return `import { wireTrigger } from '#pikku'
78
+ // import { handleEvent } from '../functions/${name}.functions.js'
79
+
80
+ wireTrigger({
81
+ name: '${name}',
82
+ func: handleEvent,
83
+ })
84
+ `;
85
+ default:
86
+ return `// ${type} wiring for ${name}\n`;
87
+ }
88
+ }
89
+ export const pikkuNewWiring = pikkuSessionlessFunc({
90
+ func: async ({ logger, config }, { name, type = 'http' }) => {
91
+ const filePath = scaffoldFilePath(config, 'wirings', name, '.wiring.ts', config.scaffold?.wiringDir);
92
+ if (existsSync(filePath)) {
93
+ logger.error(`File already exists: ${filePath}`);
94
+ process.exit(1);
95
+ }
96
+ const content = getWiringTemplate(type, name);
97
+ await mkdir(dirname(filePath), { recursive: true });
98
+ await writeFile(filePath, content, 'utf-8');
99
+ logger.info(`Created wiring at ${filePath}`);
100
+ console.log(filePath);
101
+ },
102
+ });
@@ -4,45 +4,17 @@ import { writeFileInDir } from '../../utils/file-writer.js';
4
4
  export const pikkuBootstrap = pikkuSessionlessFunc({
5
5
  func: async ({ logger, config, getInspectorState }, { allImports }) => {
6
6
  const stateBeforeBootstrap = await getInspectorState();
7
- const externalPackageBootstraps = [];
8
- const usedExternalPackages = {};
9
- if (config.externalPackages) {
10
- for (const [namespace, externalPkg] of Object.entries(config.externalPackages)) {
11
- const isUsed = stateBeforeBootstrap.rpc?.usedExternalPackages?.has(namespace);
12
- if (isUsed || externalPkg.forceInclude) {
13
- const packageName = externalPkg.package;
14
- const packageBootstrap = `${packageName}/.pikku/pikku-bootstrap.gen.js`;
15
- externalPackageBootstraps.push(packageBootstrap);
16
- usedExternalPackages[namespace] = {
17
- package: packageName,
18
- rpcEndpoint: externalPkg.rpcEndpoint,
19
- };
20
- logger.debug(`• External package ${externalPkg.forceInclude && !isUsed ? 'force-included' : 'detected'}: ${namespace} (${packageName})`);
21
- }
22
- }
7
+ const addonBootstraps = [];
8
+ for (const [, decl] of stateBeforeBootstrap.rpc?.wireAddonDeclarations ??
9
+ []) {
10
+ addonBootstraps.push(`${decl.package}/.pikku/pikku-bootstrap.gen.js`);
11
+ logger.debug(`• Addon bootstrap: ${decl.package}`);
23
12
  }
13
+ const wireAddonFileImports = Array.from(stateBeforeBootstrap.rpc?.wireAddonFiles ?? []).map((to) => `import '${getFileImportRelativePath(config.bootstrapFile, to, config.packageMappings)}'`);
24
14
  const localImports = allImports.map((to) => `import '${getFileImportRelativePath(config.bootstrapFile, to, config.packageMappings)}'`);
25
- const externalImports = externalPackageBootstraps.map((packagePath) => `import '${packagePath}'`);
26
- let externalPackagesRegistration = '';
27
- if (Object.keys(usedExternalPackages).length > 0) {
28
- externalPackagesRegistration = `
29
- // Register external package mappings
30
- import { pikkuState } from '@pikku/core'
31
- const externalPackages = pikkuState(null, 'rpc', 'externalPackages')
32
- ${Object.entries(usedExternalPackages)
33
- .map(([ns, cfg]) => {
34
- const rpcEndpointPart = cfg.rpcEndpoint
35
- ? `, rpcEndpoint: '${cfg.rpcEndpoint}'`
36
- : '';
37
- return `externalPackages.set('${ns}', { package: '${cfg.package}'${rpcEndpointPart} })`;
38
- })
39
- .join('\n')}
40
- `;
41
- }
42
- const packageNameArg = config.externalPackageName
43
- ? `'${config.externalPackageName}'`
44
- : 'null';
45
- const metaDirRegistration = `import { pikkuState as __pikkuState } from '@pikku/core'
15
+ const addonImports = addonBootstraps.map((packagePath) => `import '${packagePath}'`);
16
+ const packageNameArg = config.addonName ? `'${config.addonName}'` : 'null';
17
+ const metaDirRegistration = `import { pikkuState as __pikkuState } from '@pikku/core/internal'
46
18
  try {
47
19
  const { fileURLToPath: __fileURLToPath } = await import('url')
48
20
  const { dirname: __dirname } = await import('path')
@@ -50,7 +22,7 @@ try {
50
22
  } catch {}
51
23
  `;
52
24
  const allBootstrapImports = metaDirRegistration +
53
- [...localImports, ...externalImports]
25
+ [...localImports, ...wireAddonFileImports, ...addonImports]
54
26
  .sort((a, b) => {
55
27
  const aMeta = a.includes('meta');
56
28
  const bMeta = b.includes('meta');
@@ -60,8 +32,7 @@ try {
60
32
  return 1;
61
33
  return 0;
62
34
  })
63
- .join('\n') +
64
- externalPackagesRegistration;
35
+ .join('\n');
65
36
  await writeFileInDir(logger, config.bootstrapFile, allBootstrapImports);
66
37
  },
67
38
  });
@@ -1,16 +1,98 @@
1
1
  import { join } from 'path';
2
2
  import { pikkuSessionlessFunc } from '#pikku';
3
3
  import { ErrorCode } from '@pikku/inspector';
4
+ function hashArrow(prev, curr) {
5
+ const p = (prev ?? 'unknown').slice(0, 8);
6
+ const c = (curr ?? 'unknown').slice(0, 8);
7
+ if (p === c) {
8
+ return `${p} (unchanged)`;
9
+ }
10
+ return `${p} → ${c}`;
11
+ }
4
12
  export const pikkuVersionsCheck = pikkuSessionlessFunc({
5
13
  func: async ({ logger, config, getInspectorState }) => {
6
14
  const visitState = await getInspectorState();
7
15
  if (!visitState.manifest.initial) {
8
16
  const manifestPath = join(config.outDir, 'versions.json');
9
- throw new Error(`[${ErrorCode.MANIFEST_MISSING}] Version manifest not found at ${manifestPath}. Run 'pikku init' to create one.`);
17
+ throw new Error(`[${ErrorCode.MANIFEST_MISSING}] Version manifest not found at ${manifestPath}. Run 'pikku versions init' to create one.`);
10
18
  }
11
19
  if (visitState.manifest.errors.length > 0) {
12
- const messages = visitState.manifest.errors.map((e) => `[${e.code}] ${e.message}`);
13
- throw new Error(messages.join('\n'));
20
+ for (const error of visitState.manifest.errors) {
21
+ if (error.code === ErrorCode.CONTRACT_CHANGED_REQUIRES_BUMP &&
22
+ error.functionKey) {
23
+ logger.info(`✗ ${error.functionKey} — contract changed without version bump`);
24
+ if (error.previousInputHash !== undefined ||
25
+ error.currentInputHash !== undefined) {
26
+ logger.info(` Input schema hash: ${hashArrow(error.previousInputHash, error.currentInputHash)}`);
27
+ logger.info(` Output schema hash: ${hashArrow(error.previousOutputHash, error.currentOutputHash)}`);
28
+ }
29
+ logger.info(``);
30
+ if (error.nextVersion !== undefined) {
31
+ logger.info(` Set \`version: ${error.nextVersion}\` on the function, then run:`);
32
+ }
33
+ logger.info(` npx pikku versions-update`);
34
+ }
35
+ else if (error.code === ErrorCode.FUNCTION_VERSION_MODIFIED &&
36
+ error.functionKey) {
37
+ logger.info(`✗ ${error.functionKey}@v${error.version} — published contract was modified`);
38
+ if (error.previousInputHash !== undefined ||
39
+ error.currentInputHash !== undefined) {
40
+ logger.info(` Recorded hash: ${(error.previousInputHash ?? 'unknown').slice(0, 8)}`);
41
+ logger.info(` Current hash: ${(error.currentInputHash ?? 'unknown').slice(0, 8)}`);
42
+ }
43
+ logger.info(``);
44
+ logger.info(` Published versions are immutable. Either revert`);
45
+ logger.info(` the schema change or create version ${(error.version ?? 1) + 1} instead.`);
46
+ }
47
+ else if (error.code === ErrorCode.VERSION_REGRESSION_OR_CONFLICT &&
48
+ error.functionKey) {
49
+ logger.info(`✗ ${error.functionKey}@v${error.version} — version missing from manifest`);
50
+ if (error.latestVersion !== undefined) {
51
+ logger.info(` Latest recorded version: ${error.latestVersion}`);
52
+ }
53
+ logger.info(` Version ${error.version} exists in code but not in versions.json`);
54
+ logger.info(``);
55
+ logger.info(` This usually means a merge conflict in versions.json.`);
56
+ logger.info(` Resolve the conflict, then run:`);
57
+ logger.info(` npx pikku versions-update`);
58
+ }
59
+ else if (error.code === ErrorCode.VERSION_GAP_NOT_ALLOWED &&
60
+ error.functionKey) {
61
+ logger.info(`✗ ${error.functionKey}@v${error.version} — version gap detected`);
62
+ if (error.latestVersion !== undefined) {
63
+ logger.info(` Latest version: ${error.latestVersion}`);
64
+ }
65
+ if (error.expectedNextVersion !== undefined) {
66
+ logger.info(` Expected next: ${error.expectedNextVersion}`);
67
+ }
68
+ if (error.version !== undefined) {
69
+ logger.info(` Found: ${error.version}`);
70
+ }
71
+ logger.info(``);
72
+ if (error.expectedNextVersion !== undefined) {
73
+ logger.info(` Versions must be sequential. Set \`version: ${error.expectedNextVersion}\``);
74
+ logger.info(` on the function.`);
75
+ }
76
+ }
77
+ else if (error.code === ErrorCode.MANIFEST_INTEGRITY_ERROR &&
78
+ error.functionKey) {
79
+ logger.info(`✗ ${error.functionKey} — versions.json integrity error`);
80
+ if (error.latestVersion !== undefined) {
81
+ logger.info(` "latest" field: ${error.latestVersion}`);
82
+ }
83
+ if (error.expectedNextVersion !== undefined) {
84
+ logger.info(` Highest version key: ${error.expectedNextVersion}`);
85
+ }
86
+ logger.info(``);
87
+ logger.info(` The manifest is corrupted. Run:`);
88
+ logger.info(` npx pikku versions-update`);
89
+ }
90
+ else {
91
+ logger.info(`[${error.code}] ${error.message}`);
92
+ }
93
+ logger.info(``);
94
+ }
95
+ throw new Error('Version check failed.');
14
96
  }
15
97
  logger.info('Version manifest check passed.');
16
98
  },
@@ -7,7 +7,7 @@ export const pikkuVersionsUpdate = pikkuSessionlessFunc({
7
7
  const manifestPath = join(config.outDir, 'versions.json');
8
8
  const visitState = await getInspectorState();
9
9
  if (!visitState.manifest.initial) {
10
- throw new Error(`Version manifest not found at ${manifestPath}. Run 'pikku init' to create one.`);
10
+ throw new Error(`Version manifest not found at ${manifestPath}. Run 'pikku versions init' to create one.`);
11
11
  }
12
12
  const immutabilityErrors = visitState.manifest.errors.filter((e) => e.code === ErrorCode.FUNCTION_VERSION_MODIFIED);
13
13
  if (immutabilityErrors.length > 0) {
@@ -1,5 +1,4 @@
1
1
  export const serializeNextJsBackendWrapper = (bootstrapPath, routesMapPath, rpcMapPath, configImport, singleServicesFactoryImport, wireServicesImport) => {
2
- const hasWireServices = !!wireServicesImport;
3
2
  return `'server-only'
4
3
 
5
4
  /**
@@ -15,7 +14,6 @@ type RouteContext = { params: Promise<Record<string, string | string[]>> }
15
14
 
16
15
  ${configImport}
17
16
  ${singleServicesFactoryImport}
18
- ${wireServicesImport ? wireServicesImport : ''}
19
17
 
20
18
  import '${bootstrapPath}'
21
19
 
@@ -31,7 +29,6 @@ export const pikku = (_options?: any) => {
31
29
  _pikku = new PikkuNextJS(
32
30
  createConfig as any,
33
31
  createSingletonServices as any,
34
- ${hasWireServices ? 'createWireServices' : 'undefined'}
35
32
  )
36
33
  }
37
34
 
@@ -248,7 +245,6 @@ export const pikkuAPIRequest = (
248
245
  _pikku = new PikkuNextJS(
249
246
  createConfig as any,
250
247
  createSingletonServices as any,
251
- ${hasWireServices ? 'createWireServices' : 'undefined'}
252
248
  )
253
249
  }
254
250
  if (_removeAPIPrefix) {
@@ -5,9 +5,10 @@ import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-
5
5
  import { serializeAIAgentTypes } from './serialize-ai-agent-types.js';
6
6
  export const pikkuAIAgentTypes = pikkuSessionlessFunc({
7
7
  func: async ({ logger, config }) => {
8
- const { agentTypesFile, functionTypesFile, packageMappings } = config;
8
+ const { agentTypesFile, functionTypesFile, agentMapDeclarationFile, packageMappings, } = config;
9
9
  const functionTypesImportPath = getFileImportRelativePath(agentTypesFile, functionTypesFile, packageMappings);
10
- const content = serializeAIAgentTypes(functionTypesImportPath);
10
+ const agentMapImportPath = getFileImportRelativePath(agentTypesFile, agentMapDeclarationFile, packageMappings);
11
+ const content = serializeAIAgentTypes(functionTypesImportPath, agentMapImportPath);
11
12
  await writeFileInDir(logger, agentTypesFile, content);
12
13
  },
13
14
  middleware: [
@@ -7,7 +7,7 @@ import { serializeAgentMap } from './serialize-agent-map.js';
7
7
  export const pikkuAIAgent = pikkuSessionlessFunc({
8
8
  func: async ({ logger, config, getInspectorState }) => {
9
9
  const { agents, functions } = await getInspectorState();
10
- const { agentWiringsFile, agentWiringMetaFile, agentWiringMetaJsonFile, agentMapDeclarationFile, packageMappings, schema, externalPackageName, } = config;
10
+ const { agentWiringsFile, agentWiringMetaFile, agentWiringMetaJsonFile, agentMapDeclarationFile, packageMappings, schema, addonName, } = config;
11
11
  const lines = [];
12
12
  const hasAgents = agents.files.size > 0;
13
13
  if (hasAgents) {
@@ -24,7 +24,7 @@ export const pikkuAIAgent = pikkuSessionlessFunc({
24
24
  lines.push(`import { ${exportedName} } from '${importPath}'`);
25
25
  }
26
26
  lines.push('');
27
- const packageArg = externalPackageName ? `, '${externalPackageName}'` : '';
27
+ const packageArg = addonName ? `, '${addonName}'` : '';
28
28
  for (const [agentName, { exportedName }] of sortedAgents) {
29
29
  lines.push(`addAIAgent('${agentName}', ${exportedName}${packageArg})`);
30
30
  }
@@ -44,7 +44,7 @@ export const pikkuAIAgent = pikkuSessionlessFunc({
44
44
  ? `import metaData from '${jsonImportPath}' with { type: 'json' }`
45
45
  : `import metaData from '${jsonImportPath}'`;
46
46
  const modelConfigLines = [];
47
- if (!externalPackageName &&
47
+ if (!addonName &&
48
48
  (config.models || config.agentDefaults || config.agentOverrides)) {
49
49
  modelConfigLines.push(`\npikkuState(null, 'models', 'config', ${JSON.stringify({
50
50
  models: config.models,
@@ -52,10 +52,10 @@ export const pikkuAIAgent = pikkuSessionlessFunc({
52
52
  agentOverrides: config.agentOverrides,
53
53
  })} as any)`);
54
54
  }
55
- await writeFileInDir(logger, agentWiringMetaFile, `import { pikkuState } from '@pikku/core'
55
+ await writeFileInDir(logger, agentWiringMetaFile, `import { pikkuState } from '@pikku/core/internal'
56
56
  import type { AIAgentMeta } from '@pikku/core/ai-agent'
57
57
  ${importStatement}
58
- pikkuState(${externalPackageName ? `'${externalPackageName}'` : 'null'}, 'agent', 'agentsMeta', metaData.agentsMeta as AIAgentMeta)${modelConfigLines.join('')}`);
58
+ pikkuState(${addonName ? `'${addonName}'` : 'null'}, 'agent', 'agentsMeta', metaData.agentsMeta as AIAgentMeta)${modelConfigLines.join('')}`);
59
59
  await writeFileInDir(logger, agentMapDeclarationFile, serializeAgentMap(logger, agentMapDeclarationFile, packageMappings, functions.typesMap, agents.agentsMeta));
60
60
  return true;
61
61
  },
@@ -1,4 +1,4 @@
1
1
  import type { AIAgentMeta } from '@pikku/core/ai-agent';
2
2
  import { type TypesMap } from '@pikku/inspector';
3
- import { Logger } from '@pikku/core/services';
3
+ import type { Logger } from '@pikku/core/services';
4
4
  export declare const serializeAgentMap: (logger: Logger, relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, agentsMeta: AIAgentMeta) => string;
@@ -1 +1 @@
1
- export declare const serializeAIAgentTypes: (functionTypesImportPath: string) => string;
1
+ export declare const serializeAIAgentTypes: (functionTypesImportPath: string, agentMapImportPath: string) => string;
@@ -1,11 +1,18 @@
1
- export const serializeAIAgentTypes = (functionTypesImportPath) => {
1
+ export const serializeAIAgentTypes = (functionTypesImportPath, agentMapImportPath) => {
2
2
  return `import {
3
3
  CoreAIAgent,
4
4
  PikkuAIMiddlewareHooks,
5
5
  } from '@pikku/core/ai-agent'
6
- import type { PikkuPermission, PikkuMiddleware, Services } from '${functionTypesImportPath}'
6
+ import {
7
+ agent as coreAgent,
8
+ agentStream as coreAgentStream,
9
+ agentResume as coreAgentResume,
10
+ agentApprove as coreAgentApprove,
11
+ } from '@pikku/core/ai-agent'
12
+ import type { PikkuPermission, PikkuMiddleware, Services, PikkuFunctionConfig } from '${functionTypesImportPath}'
7
13
  import type { StandardSchemaV1 } from '@standard-schema/spec'
8
- import type { AIAgentMemoryConfig } from '@pikku/core/ai-agent'
14
+ import type { AIAgentMemoryConfig, AIAgentInput } from '@pikku/core/ai-agent'
15
+ import type { AgentMap } from '${agentMapImportPath}'
9
16
 
10
17
  type AIAgentConfig = Omit<CoreAIAgent<PikkuPermission, PikkuMiddleware>, 'tools' | 'agents' | 'memory'> & {
11
18
  input?: StandardSchemaV1
@@ -27,5 +34,43 @@ export const pikkuAIMiddleware = <
27
34
  >(
28
35
  hooks: PikkuAIMiddlewareHooks<State, RequiredServices>
29
36
  ): PikkuAIMiddlewareHooks<State, RequiredServices> => hooks
37
+
38
+ export const agent = <Name extends keyof AgentMap>(
39
+ agentName: Name
40
+ ) => {
41
+ return coreAgent<AgentMap>(agentName as string & keyof AgentMap) as PikkuFunctionConfig<
42
+ AIAgentInput,
43
+ { runId: string; result: AgentMap[Name]['output']; usage: { inputTokens: number; outputTokens: number } },
44
+ 'session' | 'rpc'
45
+ >
46
+ }
47
+
48
+ export const agentStream = <Name extends keyof AgentMap>(
49
+ agentName?: Name
50
+ ) => {
51
+ return coreAgentStream<AgentMap>(agentName as string & keyof AgentMap) as PikkuFunctionConfig<
52
+ { agentName?: string; message: string; threadId: string; resourceId: string },
53
+ void,
54
+ 'session' | 'rpc'
55
+ >
56
+ }
57
+
58
+ export const agentResume = () => {
59
+ return coreAgentResume() as PikkuFunctionConfig<
60
+ { runId: string; toolCallId: string; approved: boolean },
61
+ void,
62
+ 'session' | 'rpc'
63
+ >
64
+ }
65
+
66
+ export const agentApprove = <Name extends keyof AgentMap>(
67
+ agentName: Name
68
+ ) => {
69
+ return coreAgentApprove<AgentMap>(agentName as string & keyof AgentMap) as PikkuFunctionConfig<
70
+ { runId: string; approvals: { toolCallId: string; approved: boolean }[] },
71
+ unknown,
72
+ 'session' | 'rpc'
73
+ >
74
+ }
30
75
  `;
31
76
  };