@pikku/core 0.12.13 → 0.12.15

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 (150) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/errors/errors.d.ts +18 -0
  3. package/dist/errors/errors.js +33 -0
  4. package/dist/function/function-runner.d.ts +1 -1
  5. package/dist/function/function-runner.js +10 -5
  6. package/dist/function/functions.types.js +1 -0
  7. package/dist/function/index.d.ts +2 -1
  8. package/dist/function/index.js +1 -0
  9. package/dist/handle-error.d.ts +2 -2
  10. package/dist/handle-error.js +8 -8
  11. package/dist/index.d.ts +1 -2
  12. package/dist/index.js +1 -2
  13. package/dist/middleware/index.d.ts +2 -0
  14. package/dist/middleware/index.js +2 -0
  15. package/dist/middleware/remote-auth.js +5 -2
  16. package/dist/permissions.d.ts +13 -1
  17. package/dist/permissions.js +51 -0
  18. package/dist/pikku-state.d.ts +0 -1
  19. package/dist/pikku-state.js +2 -4
  20. package/dist/remote.d.ts +10 -0
  21. package/dist/remote.js +32 -0
  22. package/dist/schema.js +2 -0
  23. package/dist/services/credential-service.d.ts +11 -0
  24. package/dist/services/credential-wire-service.d.ts +14 -3
  25. package/dist/services/credential-wire-service.js +49 -6
  26. package/dist/services/deployment-service.d.ts +12 -1
  27. package/dist/services/in-memory-queue-service.d.ts +7 -0
  28. package/dist/services/in-memory-queue-service.js +28 -0
  29. package/dist/services/index.d.ts +4 -1
  30. package/dist/services/index.js +2 -1
  31. package/dist/services/local-credential-service.d.ts +2 -0
  32. package/dist/services/local-credential-service.js +20 -0
  33. package/dist/services/logger-console.d.ts +26 -40
  34. package/dist/services/logger-console.js +102 -46
  35. package/dist/services/logger.d.ts +5 -0
  36. package/dist/services/meta-service.d.ts +175 -0
  37. package/dist/services/meta-service.js +310 -0
  38. package/dist/services/pikku-user-id.d.ts +3 -0
  39. package/dist/services/pikku-user-id.js +16 -0
  40. package/dist/services/typed-credential-service.d.ts +2 -0
  41. package/dist/services/typed-credential-service.js +6 -0
  42. package/dist/services/workflow-service.d.ts +6 -1
  43. package/dist/testing/service-tests.js +0 -8
  44. package/dist/types/core.types.d.ts +14 -2
  45. package/dist/types/state.types.d.ts +9 -2
  46. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +21 -0
  47. package/dist/wirings/ai-agent/ai-agent-prepare.js +90 -21
  48. package/dist/wirings/ai-agent/ai-agent-registry.js +2 -2
  49. package/dist/wirings/ai-agent/ai-agent-runner.js +24 -2
  50. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
  51. package/dist/wirings/ai-agent/ai-agent-stream.js +61 -3
  52. package/dist/wirings/ai-agent/ai-agent.types.d.ts +25 -4
  53. package/dist/wirings/ai-agent/index.d.ts +1 -1
  54. package/dist/wirings/ai-agent/index.js +1 -1
  55. package/dist/wirings/channel/channel-runner.js +3 -3
  56. package/dist/wirings/cli/cli-runner.js +4 -3
  57. package/dist/wirings/cli/command-parser.js +7 -3
  58. package/dist/wirings/http/http-runner.d.ts +1 -1
  59. package/dist/wirings/http/http-runner.js +23 -15
  60. package/dist/wirings/http/http.types.d.ts +2 -0
  61. package/dist/wirings/mcp/mcp-runner.js +5 -3
  62. package/dist/wirings/queue/queue-runner.d.ts +3 -1
  63. package/dist/wirings/queue/queue-runner.js +8 -3
  64. package/dist/wirings/queue/queue.types.d.ts +6 -0
  65. package/dist/wirings/rpc/rpc-runner.js +57 -90
  66. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -1
  67. package/dist/wirings/scheduler/scheduler-runner.js +9 -5
  68. package/dist/wirings/trigger/trigger-runner.js +4 -2
  69. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +2 -0
  70. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +1 -1
  71. package/dist/wirings/workflow/dsl/workflow-runner.js +6 -9
  72. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -1
  73. package/dist/wirings/workflow/graph/graph-runner.js +18 -4
  74. package/dist/wirings/workflow/index.d.ts +4 -2
  75. package/dist/wirings/workflow/index.js +4 -2
  76. package/dist/wirings/workflow/pikku-workflow-service.d.ts +16 -4
  77. package/dist/wirings/workflow/pikku-workflow-service.js +218 -24
  78. package/dist/wirings/workflow/workflow-queue-workers.d.ts +40 -0
  79. package/dist/wirings/workflow/workflow-queue-workers.js +41 -0
  80. package/dist/wirings/workflow/workflow.types.d.ts +19 -1
  81. package/package.json +4 -1
  82. package/src/errors/errors.ts +44 -0
  83. package/src/function/function-runner.ts +24 -13
  84. package/src/function/functions.types.ts +1 -0
  85. package/src/function/index.ts +10 -0
  86. package/src/handle-error.test.ts +2 -2
  87. package/src/handle-error.ts +8 -8
  88. package/src/index.ts +1 -2
  89. package/src/middleware/index.ts +2 -0
  90. package/src/middleware/remote-auth.test.ts +4 -4
  91. package/src/middleware/remote-auth.ts +7 -2
  92. package/src/permissions.ts +70 -0
  93. package/src/pikku-state.test.ts +0 -26
  94. package/src/pikku-state.ts +2 -5
  95. package/src/remote.ts +46 -0
  96. package/src/schema.ts +1 -0
  97. package/src/services/credential-service.ts +13 -0
  98. package/src/services/credential-wire-service.test.ts +174 -0
  99. package/src/services/credential-wire-service.ts +52 -8
  100. package/src/services/deployment-service.ts +17 -1
  101. package/src/services/in-memory-queue-service.ts +46 -0
  102. package/src/services/index.ts +21 -1
  103. package/src/services/local-credential-service.ts +22 -0
  104. package/src/services/logger-console.ts +127 -47
  105. package/src/services/logger.ts +6 -0
  106. package/src/services/meta-service.ts +523 -0
  107. package/src/services/pikku-user-id.test.ts +62 -0
  108. package/src/services/pikku-user-id.ts +17 -0
  109. package/src/services/typed-credential-service.ts +8 -0
  110. package/src/services/workflow-service.ts +8 -0
  111. package/src/testing/service-tests.ts +0 -10
  112. package/src/types/core.types.ts +16 -2
  113. package/src/types/state.types.ts +7 -2
  114. package/src/wirings/ai-agent/ai-agent-prepare.ts +122 -41
  115. package/src/wirings/ai-agent/ai-agent-registry.ts +3 -3
  116. package/src/wirings/ai-agent/ai-agent-runner.ts +22 -3
  117. package/src/wirings/ai-agent/ai-agent-stream.ts +115 -3
  118. package/src/wirings/ai-agent/ai-agent.types.ts +27 -4
  119. package/src/wirings/ai-agent/index.ts +1 -0
  120. package/src/wirings/channel/channel-handler.ts +0 -1
  121. package/src/wirings/channel/channel-runner.ts +4 -5
  122. package/src/wirings/cli/cli-runner.test.ts +8 -7
  123. package/src/wirings/cli/cli-runner.ts +5 -4
  124. package/src/wirings/cli/command-parser.ts +8 -3
  125. package/src/wirings/http/http-runner.ts +27 -18
  126. package/src/wirings/http/http.types.ts +2 -0
  127. package/src/wirings/mcp/mcp-runner.ts +7 -10
  128. package/src/wirings/queue/queue-runner.test.ts +5 -11
  129. package/src/wirings/queue/queue-runner.ts +12 -4
  130. package/src/wirings/queue/queue.types.ts +6 -0
  131. package/src/wirings/rpc/rpc-runner.ts +91 -118
  132. package/src/wirings/scheduler/scheduler-runner.test.ts +5 -11
  133. package/src/wirings/scheduler/scheduler-runner.ts +13 -5
  134. package/src/wirings/trigger/trigger-runner.test.ts +10 -11
  135. package/src/wirings/trigger/trigger-runner.ts +6 -4
  136. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +2 -0
  137. package/src/wirings/workflow/dsl/workflow-runner.ts +11 -10
  138. package/src/wirings/workflow/graph/graph-runner.ts +19 -4
  139. package/src/wirings/workflow/index.ts +17 -6
  140. package/src/wirings/workflow/pikku-workflow-service.ts +286 -24
  141. package/src/wirings/workflow/workflow-queue-workers.ts +85 -0
  142. package/src/wirings/workflow/workflow.types.ts +18 -1
  143. package/tsconfig.tsbuildinfo +1 -1
  144. package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +0 -6
  145. package/dist/wirings/ai-agent/agent-dynamic-workflow.js +0 -468
  146. package/dist/wirings/workflow/workflow-helpers.d.ts +0 -36
  147. package/dist/wirings/workflow/workflow-helpers.js +0 -38
  148. package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -610
  149. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  150. package/src/wirings/workflow/workflow-helpers.ts +0 -79
@@ -0,0 +1,310 @@
1
+ import { readFile, readdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Node.js filesystem implementation of MetaService.
5
+ * Reads .gen.json files from a local .pikku directory.
6
+ */
7
+ export class LocalMetaService {
8
+ basePath;
9
+ httpMetaCache = null;
10
+ channelsMetaCache = null;
11
+ schedulerMetaCache = null;
12
+ queueMetaCache = null;
13
+ cliMetaCache = null;
14
+ mcpMetaCache = null;
15
+ rpcMetaCache = null;
16
+ workflowMetaCache = null;
17
+ triggerMetaCache = null;
18
+ triggerSourceMetaCache = null;
19
+ functionsMetaCache = null;
20
+ servicesMetaCache = null;
21
+ secretsMetaCache = null;
22
+ credentialsMetaCache = null;
23
+ variablesMetaCache = null;
24
+ middlewareGroupsMetaCache = null;
25
+ permissionsGroupsMetaCache = null;
26
+ agentsMetaCache = null;
27
+ schemaCache = new Map();
28
+ constructor(basePath) {
29
+ this.basePath = basePath;
30
+ }
31
+ async readFile(relativePath) {
32
+ try {
33
+ return await readFile(join(this.basePath, relativePath), 'utf-8');
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ async readDir(relativePath) {
40
+ try {
41
+ return await readdir(join(this.basePath, relativePath));
42
+ }
43
+ catch {
44
+ return [];
45
+ }
46
+ }
47
+ clearCache() {
48
+ this.httpMetaCache = null;
49
+ this.channelsMetaCache = null;
50
+ this.schedulerMetaCache = null;
51
+ this.queueMetaCache = null;
52
+ this.cliMetaCache = null;
53
+ this.mcpMetaCache = null;
54
+ this.rpcMetaCache = null;
55
+ this.workflowMetaCache = null;
56
+ this.triggerMetaCache = null;
57
+ this.triggerSourceMetaCache = null;
58
+ this.functionsMetaCache = null;
59
+ this.servicesMetaCache = null;
60
+ this.secretsMetaCache = null;
61
+ this.credentialsMetaCache = null;
62
+ this.variablesMetaCache = null;
63
+ this.middlewareGroupsMetaCache = null;
64
+ this.permissionsGroupsMetaCache = null;
65
+ this.agentsMetaCache = null;
66
+ this.schemaCache.clear();
67
+ }
68
+ // -- Private helpers --
69
+ async readMetaJson(dir, baseName) {
70
+ const verbose = await this.readFile(`${dir}/${baseName}-verbose.gen.json`);
71
+ if (verbose)
72
+ return verbose;
73
+ const minimal = await this.readFile(`${dir}/${baseName}.gen.json`);
74
+ if (minimal)
75
+ return minimal;
76
+ return null;
77
+ }
78
+ // -- Typed metadata accessors --
79
+ async getHttpMeta() {
80
+ if (this.httpMetaCache)
81
+ return this.httpMetaCache;
82
+ const content = await this.readMetaJson('http', 'pikku-http-wirings-meta');
83
+ this.httpMetaCache = content
84
+ ? JSON.parse(content)
85
+ : {
86
+ get: {},
87
+ post: {},
88
+ put: {},
89
+ delete: {},
90
+ patch: {},
91
+ head: {},
92
+ options: {},
93
+ };
94
+ return this.httpMetaCache;
95
+ }
96
+ async getChannelsMeta() {
97
+ if (this.channelsMetaCache)
98
+ return this.channelsMetaCache;
99
+ const content = await this.readMetaJson('channel', 'pikku-channels-meta');
100
+ this.channelsMetaCache = content ? JSON.parse(content) : {};
101
+ return this.channelsMetaCache;
102
+ }
103
+ async getSchedulerMeta() {
104
+ if (this.schedulerMetaCache)
105
+ return this.schedulerMetaCache;
106
+ const content = await this.readMetaJson('scheduler', 'pikku-schedulers-wirings-meta');
107
+ this.schedulerMetaCache = content ? JSON.parse(content) : {};
108
+ return this.schedulerMetaCache;
109
+ }
110
+ async getQueueMeta() {
111
+ if (this.queueMetaCache)
112
+ return this.queueMetaCache;
113
+ const content = await this.readMetaJson('queue', 'pikku-queue-workers-wirings-meta');
114
+ this.queueMetaCache = content ? JSON.parse(content) : {};
115
+ return this.queueMetaCache;
116
+ }
117
+ async getCliMeta() {
118
+ if (this.cliMetaCache)
119
+ return this.cliMetaCache;
120
+ const content = await this.readMetaJson('cli', 'pikku-cli-wirings-meta');
121
+ this.cliMetaCache = content
122
+ ? JSON.parse(content)
123
+ : { programs: {}, renderers: {} };
124
+ return this.cliMetaCache;
125
+ }
126
+ async getMcpMeta() {
127
+ if (this.mcpMetaCache)
128
+ return this.mcpMetaCache;
129
+ const content = await this.readMetaJson('mcp', 'pikku-mcp-wirings-meta');
130
+ if (content) {
131
+ const mcpData = JSON.parse(content);
132
+ this.mcpMetaCache = {
133
+ resources: mcpData.resourcesMeta || {},
134
+ tools: mcpData.toolsMeta || {},
135
+ prompts: mcpData.promptsMeta || {},
136
+ };
137
+ }
138
+ else {
139
+ this.mcpMetaCache = { resources: {}, tools: {}, prompts: {} };
140
+ }
141
+ return this.mcpMetaCache;
142
+ }
143
+ async getRpcMeta() {
144
+ if (this.rpcMetaCache)
145
+ return this.rpcMetaCache;
146
+ try {
147
+ const content = await this.readFile('rpc/pikku-rpc-wirings-meta.gen.json');
148
+ this.rpcMetaCache = content ? JSON.parse(content) : {};
149
+ return this.rpcMetaCache;
150
+ }
151
+ catch (error) {
152
+ console.error('Error reading RPC wirings metadata:', error);
153
+ this.rpcMetaCache = {};
154
+ return this.rpcMetaCache;
155
+ }
156
+ }
157
+ async getWorkflowMeta() {
158
+ if (this.workflowMetaCache)
159
+ return this.workflowMetaCache;
160
+ try {
161
+ const files = await this.readDir('workflow/meta');
162
+ const jsonFiles = files.filter((f) => f.endsWith('.gen.json'));
163
+ const verboseFiles = jsonFiles.filter((f) => f.includes('-verbose'));
164
+ const minimalFiles = jsonFiles.filter((f) => !f.includes('-verbose'));
165
+ const verboseNames = new Set(verboseFiles.map((f) => f.replace('-verbose.gen.json', '')));
166
+ const filesToRead = [
167
+ ...verboseFiles,
168
+ ...minimalFiles.filter((f) => !verboseNames.has(f.replace('.gen.json', ''))),
169
+ ];
170
+ const result = {};
171
+ await Promise.all(filesToRead.map(async (file) => {
172
+ const content = await this.readFile(`workflow/meta/${file}`);
173
+ if (content) {
174
+ const meta = JSON.parse(content);
175
+ result[meta.name] = meta;
176
+ }
177
+ }));
178
+ this.workflowMetaCache = result;
179
+ return this.workflowMetaCache;
180
+ }
181
+ catch (error) {
182
+ console.error('Error reading Workflow wirings metadata:', error);
183
+ this.workflowMetaCache = {};
184
+ return this.workflowMetaCache;
185
+ }
186
+ }
187
+ async getTriggerMeta() {
188
+ if (this.triggerMetaCache)
189
+ return this.triggerMetaCache;
190
+ const content = await this.readMetaJson('trigger', 'pikku-trigger-wirings-meta');
191
+ this.triggerMetaCache = content ? JSON.parse(content) : {};
192
+ return this.triggerMetaCache;
193
+ }
194
+ async getTriggerSourceMeta() {
195
+ if (this.triggerSourceMetaCache)
196
+ return this.triggerSourceMetaCache;
197
+ const content = await this.readMetaJson('trigger', 'pikku-trigger-sources-meta');
198
+ this.triggerSourceMetaCache = content ? JSON.parse(content) : {};
199
+ return this.triggerSourceMetaCache;
200
+ }
201
+ async getFunctionsMeta() {
202
+ if (this.functionsMetaCache)
203
+ return this.functionsMetaCache;
204
+ const content = await this.readMetaJson('function', 'pikku-functions-meta');
205
+ this.functionsMetaCache = content ? JSON.parse(content) : {};
206
+ return this.functionsMetaCache;
207
+ }
208
+ async getMiddlewareGroupsMeta() {
209
+ if (this.middlewareGroupsMetaCache)
210
+ return this.middlewareGroupsMetaCache;
211
+ const content = await this.readMetaJson('middleware', 'pikku-middleware-groups-meta');
212
+ this.middlewareGroupsMetaCache = content
213
+ ? JSON.parse(content)
214
+ : { definitions: {}, instances: {}, httpGroups: {}, tagGroups: {} };
215
+ return this.middlewareGroupsMetaCache;
216
+ }
217
+ async getPermissionsGroupsMeta() {
218
+ if (this.permissionsGroupsMetaCache)
219
+ return this.permissionsGroupsMetaCache;
220
+ const content = await this.readMetaJson('permissions', 'pikku-permissions-groups-meta');
221
+ this.permissionsGroupsMetaCache = content
222
+ ? JSON.parse(content)
223
+ : { definitions: {}, httpGroups: {}, tagGroups: {} };
224
+ return this.permissionsGroupsMetaCache;
225
+ }
226
+ async getAgentsMeta() {
227
+ if (this.agentsMetaCache)
228
+ return this.agentsMetaCache;
229
+ const content = await this.readMetaJson('agent', 'pikku-agent-wirings-meta');
230
+ if (content) {
231
+ const parsed = JSON.parse(content);
232
+ this.agentsMetaCache = parsed.agentsMeta || parsed;
233
+ }
234
+ else {
235
+ this.agentsMetaCache = {};
236
+ }
237
+ return this.agentsMetaCache;
238
+ }
239
+ async getSecretsMeta() {
240
+ if (this.secretsMetaCache)
241
+ return this.secretsMetaCache;
242
+ const content = await this.readFile('secrets/pikku-secrets-meta.gen.json');
243
+ this.secretsMetaCache = content ? JSON.parse(content) : {};
244
+ return this.secretsMetaCache;
245
+ }
246
+ async getCredentialsMeta() {
247
+ if (this.credentialsMetaCache)
248
+ return this.credentialsMetaCache;
249
+ const content = await this.readFile('credentials/pikku-credentials-meta.gen.json');
250
+ this.credentialsMetaCache = content ? JSON.parse(content) : {};
251
+ return this.credentialsMetaCache;
252
+ }
253
+ async getVariablesMeta() {
254
+ if (this.variablesMetaCache)
255
+ return this.variablesMetaCache;
256
+ const content = await this.readFile('variables/pikku-variables-meta.gen.json');
257
+ this.variablesMetaCache = content ? JSON.parse(content) : {};
258
+ return this.variablesMetaCache;
259
+ }
260
+ async getServicesMeta() {
261
+ if (this.servicesMetaCache)
262
+ return this.servicesMetaCache;
263
+ try {
264
+ const files = await this.readDir('services');
265
+ const jsonFiles = files.filter((f) => f.endsWith('.gen.json'));
266
+ const result = {};
267
+ await Promise.all(jsonFiles.map(async (file) => {
268
+ const content = await this.readFile(`services/${file}`);
269
+ if (content) {
270
+ const meta = JSON.parse(content);
271
+ result[meta.name] = meta;
272
+ }
273
+ }));
274
+ this.servicesMetaCache = result;
275
+ return this.servicesMetaCache;
276
+ }
277
+ catch (error) {
278
+ console.error('Error reading Services metadata:', error);
279
+ this.servicesMetaCache = {};
280
+ return this.servicesMetaCache;
281
+ }
282
+ }
283
+ async getSchema(schemaName) {
284
+ if (this.schemaCache.has(schemaName)) {
285
+ return this.schemaCache.get(schemaName);
286
+ }
287
+ if (!/^[a-zA-Z0-9_\-\.]+$/.test(schemaName)) {
288
+ return null;
289
+ }
290
+ try {
291
+ const content = await this.readFile(`schemas/schemas/${schemaName}.schema.json`);
292
+ if (!content)
293
+ return null;
294
+ const schema = JSON.parse(content);
295
+ this.schemaCache.set(schemaName, schema);
296
+ return schema;
297
+ }
298
+ catch (error) {
299
+ console.error(`Error reading schema ${schemaName}:`, error);
300
+ return null;
301
+ }
302
+ }
303
+ async getSchemas(schemaNames) {
304
+ const results = {};
305
+ await Promise.all(schemaNames.map(async (name) => {
306
+ results[name] = await this.getSchema(name);
307
+ }));
308
+ return results;
309
+ }
310
+ }
@@ -0,0 +1,3 @@
1
+ import type { PikkuWire } from '../types/core.types.js';
2
+ export type PikkuUserIdResolver = (wire: PikkuWire) => string | undefined;
3
+ export declare const defaultPikkuUserIdResolver: PikkuUserIdResolver;
@@ -0,0 +1,16 @@
1
+ export const defaultPikkuUserIdResolver = (wire) => {
2
+ // Explicit pikkuUserId on wire (set by earlier middleware or runner)
3
+ if (wire.pikkuUserId)
4
+ return wire.pikkuUserId;
5
+ // Session userId (from auth middleware — user-defined session shape)
6
+ const session = wire.session;
7
+ if (session?.userId && typeof session.userId === 'string')
8
+ return session.userId;
9
+ // Queue job: carried in job metadata
10
+ if (wire.queue?.pikkuUserId)
11
+ return wire.queue.pikkuUserId;
12
+ // Workflow: carried in run wire metadata
13
+ if (wire.workflow?.pikkuUserId)
14
+ return wire.workflow.pikkuUserId;
15
+ return undefined;
16
+ };
@@ -22,6 +22,8 @@ export declare class TypedCredentialService<TMap = Record<string, unknown>> impl
22
22
  delete(name: string, userId?: string): Promise<void>;
23
23
  has(name: string, userId?: string): Promise<boolean>;
24
24
  getAll(userId: string): Promise<Record<string, unknown>>;
25
+ getUsersWithCredential(name: string): Promise<string[]>;
26
+ getAllUsers(): Promise<string[]>;
25
27
  getAllStatus(userId?: string): Promise<CredentialStatusInfo[]>;
26
28
  getMissing(userId?: string): Promise<CredentialStatusInfo[]>;
27
29
  }
@@ -20,6 +20,12 @@ export class TypedCredentialService {
20
20
  async getAll(userId) {
21
21
  return this.credentials.getAll(userId);
22
22
  }
23
+ async getUsersWithCredential(name) {
24
+ return this.credentials.getUsersWithCredential(name);
25
+ }
26
+ async getAllUsers() {
27
+ return this.credentials.getAllUsers();
28
+ }
23
29
  async getAllStatus(userId) {
24
30
  const results = [];
25
31
  for (const [name, meta] of Object.entries(this.credentialsMeta)) {
@@ -1,5 +1,5 @@
1
1
  import type { SerializedError } from '../types/core.types.js';
2
- import type { WorkflowRun, WorkflowRunWire, StepState, WorkflowStatus, WorkflowVersionStatus } from '../wirings/workflow/workflow.types.js';
2
+ import type { WorkflowRun, WorkflowRunWire, WorkflowRunStatus, StepState, WorkflowStatus, WorkflowVersionStatus } from '../wirings/workflow/workflow.types.js';
3
3
  /**
4
4
  * Interface for workflow orchestration
5
5
  * Handles workflow execution, replay, orchestration logic, and run-level state
@@ -7,6 +7,7 @@ import type { WorkflowRun, WorkflowRunWire, StepState, WorkflowStatus, WorkflowV
7
7
  export interface WorkflowService {
8
8
  createRun(workflowName: string, input: any, inline: boolean, graphHash: string, wire: WorkflowRunWire): Promise<string>;
9
9
  getRun(id: string): Promise<WorkflowRun | null>;
10
+ getRunStatus(id: string): Promise<WorkflowRunStatus | null>;
10
11
  getRunHistory(runId: string): Promise<Array<StepState & {
11
12
  stepName: string;
12
13
  }>>;
@@ -20,6 +21,10 @@ export interface WorkflowService {
20
21
  }): Promise<{
21
22
  runId: string;
22
23
  }>;
24
+ runToCompletion<I>(name: string, input: I, rpcService: any, options?: {
25
+ pollIntervalMs?: number;
26
+ wire?: WorkflowRunWire;
27
+ }): Promise<unknown>;
23
28
  runWorkflowJob(runId: string, rpcService: any): Promise<void>;
24
29
  orchestrateWorkflow(runId: string, rpcService: any): Promise<void>;
25
30
  executeWorkflowSleepCompleted(runId: string, stepId: string): Promise<void>;
@@ -482,14 +482,6 @@ export function defineServiceTests(config) {
482
482
  endpoint: 'http://localhost:3000',
483
483
  functions: ['funcA', 'funcB'],
484
484
  });
485
- const infos = await service.findFunction('funcA');
486
- assert.ok(infos.length >= 1);
487
- assert.equal(infos[0].deploymentId, 'deploy-1');
488
- assert.equal(infos[0].endpoint, 'http://localhost:3000');
489
- });
490
- test('findFunction returns empty for unknown function', async () => {
491
- const infos = await service.findFunction('unknown-func');
492
- assert.deepEqual(infos, []);
493
485
  });
494
486
  });
495
487
  }
@@ -24,6 +24,7 @@ import type { AgentRunService } from '../wirings/ai-agent/ai-agent.types.js';
24
24
  import type { PikkuAIMiddlewareHooks } from '../wirings/ai-agent/ai-agent.types.js';
25
25
  import type { WorkflowRunService } from '../wirings/workflow/workflow.types.js';
26
26
  import type { CredentialService } from '../services/credential-service.js';
27
+ import type { MetaService } from '../services/meta-service.js';
27
28
  export type PikkuWiringTypes = 'http' | 'scheduler' | 'trigger' | 'channel' | 'rpc' | 'queue' | 'mcp' | 'cli' | 'workflow' | 'agent' | 'gateway';
28
29
  export interface FunctionServicesMeta {
29
30
  optimized: boolean;
@@ -75,6 +76,7 @@ export type FunctionRuntimeMeta = {
75
76
  remote?: boolean;
76
77
  mcp?: boolean;
77
78
  readonly?: boolean;
79
+ deploy?: 'serverless' | 'server' | 'auto';
78
80
  sessionless?: boolean;
79
81
  version?: number;
80
82
  approvalRequired?: boolean;
@@ -94,6 +96,8 @@ export type FunctionMeta = FunctionRuntimeMeta & Partial<{
94
96
  middleware: MiddlewareMetadata[];
95
97
  permissions: PermissionMetadata[];
96
98
  isDirectFunction: boolean;
99
+ sourceFile: string;
100
+ exportedName: string;
97
101
  } & CommonWireMeta>;
98
102
  export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>;
99
103
  export type FunctionsMeta = Record<string, FunctionMeta>;
@@ -175,6 +179,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
175
179
  workflowRunService?: WorkflowRunService;
176
180
  /** Credential service for dynamic/managed credentials (OAuth tokens, per-user API keys) */
177
181
  credentialService?: CredentialService;
182
+ /** Meta service for reading .pikku metadata files (filesystem on Node, R2/KV on CF) */
183
+ metaService?: MetaService;
178
184
  }
179
185
  /**
180
186
  * Represents different forms of wire within Pikku and the outside world.
@@ -182,6 +188,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
182
188
  export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boolean = false, UserSession extends CoreUserSession = CoreUserSession, TypedRPC extends PikkuRPC = PikkuRPC, IsChannel extends true | null = null, MCPTools extends string | never = never, TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire, TriggerOutput = unknown> = Partial<{
183
189
  wireType: PikkuWiringTypes;
184
190
  wireId: string;
191
+ /** Trace ID for distributed tracing — propagated across remote RPC calls via x-trace-id header */
192
+ traceId: string;
185
193
  http: PikkuHTTP<In>;
186
194
  mcp: PikkuMCP<MCPTools>;
187
195
  rpc: TypedRPC;
@@ -203,10 +211,14 @@ export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boo
203
211
  getSession: () => Promise<UserSession> | UserSession | undefined;
204
212
  /** Whether the session was modified during this run */
205
213
  hasSessionChanged: () => boolean;
214
+ /** The resolved user identity for credential lookups */
215
+ pikkuUserId: string;
206
216
  /** Set a credential value (available in middleware) */
207
217
  setCredential: (name: string, value: unknown) => void;
208
- /** Get all resolved credentials (only available in pikkuWireServices) */
209
- getCredentials: () => Record<string, unknown>;
218
+ /** Get a single credential by name lazy-loads from CredentialService on first call, sync thereafter */
219
+ getCredential: <T = unknown>(name: string) => T | null | Promise<T | null>;
220
+ /** Get all resolved credentials — lazy-loads from CredentialService on first call, sync thereafter */
221
+ getCredentials: () => Record<string, unknown> | Promise<Record<string, unknown>>;
210
222
  }>;
211
223
  /**
212
224
  * A function that can wrap an wire and be called before or after
@@ -130,7 +130,14 @@ export interface PikkuPackageState {
130
130
  } | null;
131
131
  /** Cached singleton services for this package */
132
132
  singletonServices: CoreSingletonServices | null;
133
- /** Absolute path to this package's .pikku directory */
134
- metaDir: string | null;
133
+ /** Credential metadata for this addon package */
134
+ credentialsMeta: Record<string, {
135
+ name: string;
136
+ displayName: string;
137
+ type: string;
138
+ oauth2?: boolean;
139
+ }> | null;
140
+ /** Services this addon needs from the parent project */
141
+ requiredParentServices: string[] | null;
135
142
  };
136
143
  }
@@ -19,6 +19,27 @@ export declare class ToolApprovalRequired extends PikkuError {
19
19
  readonly agentRunId?: string;
20
20
  constructor(toolCallId: string, toolName: string, args: unknown, reason?: string, displayToolName?: string, displayArgs?: unknown, agentRunId?: string);
21
21
  }
22
+ export declare class ToolCredentialRequired extends PikkuError {
23
+ readonly toolCallId: string;
24
+ readonly toolName: string;
25
+ readonly args: unknown;
26
+ readonly credentialName: string;
27
+ readonly credentialType: 'oauth2' | 'apikey';
28
+ readonly connectUrl?: string;
29
+ constructor(toolCallId: string, toolName: string, args: unknown, credentialName: string, credentialType: 'oauth2' | 'apikey', connectUrl?: string);
30
+ }
31
+ export interface AddonCredentialRequirement {
32
+ credentialName: string;
33
+ displayName: string;
34
+ addonNamespace: string;
35
+ type: 'wire';
36
+ oauth2: boolean;
37
+ }
38
+ /**
39
+ * Given a list of tool names (e.g. ["oauth-api:getProfile"]),
40
+ * returns the wire OAuth credentials required by their addons.
41
+ */
42
+ export declare function getAddonCredentialRequirements(toolNames: string[]): AddonCredentialRequirement[];
22
43
  export type StreamContext = {
23
44
  channel: AIStreamChannel;
24
45
  options?: StreamAIAgentOptions;