@pikku/cli 0.12.16 → 0.12.19
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.
- package/cli.schema.json +1 -1
- package/console-app/assets/{index-DvrDbftC.css → index-BpY2pSuA.css} +10 -1
- package/console-app/assets/index-DAQHIRK3.js +717 -0
- package/console-app/index.html +2 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +7 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +204 -67
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.json +62 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +2 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +2 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +2 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +2 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +6 -6
- package/dist/.pikku/pikku-services.gen.js +4 -4
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +15 -8
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +21 -3
- package/dist/.pikku/schemas/schemas/GraphStarterInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/GraphStarterOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/WorkflowRunStatus.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowRunnerInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowStarterInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowStarterOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowStatusCheckerInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowStatusStreamFullInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/WorkflowStatusStreamInput.schema.json +1 -0
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +442 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +5 -2
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +2 -4
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +5 -2
- package/dist/src/cli.wiring.js +5 -0
- package/dist/src/deploy/analyzer/analyzer.d.ts +1 -0
- package/dist/src/deploy/analyzer/analyzer.js +18 -15
- package/dist/src/deploy/codegen/per-unit-codegen.js +3 -3
- package/dist/src/functions/commands/all.js +2 -186
- package/dist/src/functions/commands/bootstrap.js +10 -10
- package/dist/src/functions/commands/console.js +1 -1
- package/dist/src/functions/commands/watch.js +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-react-query.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/pikku-command-react-query.js +33 -0
- package/dist/src/functions/wirings/rpc/serialize-react-query-hooks.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/serialize-react-query-hooks.js +108 -0
- package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +3 -3
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +6 -4
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +126 -27
- package/dist/src/functions/workflows/all.workflow.d.ts +1 -0
- package/dist/src/functions/workflows/all.workflow.js +212 -0
- package/dist/src/scaffold/rpc-remote.gen.js +1 -1
- package/dist/src/scaffold/workflow-routes.gen.d.ts +84 -0
- package/dist/src/scaffold/workflow-routes.gen.js +197 -0
- package/dist/src/services.js +2 -0
- package/dist/src/utils/pikku-cli-config.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -6
- package/console-app/assets/index-CzMWJFqj.js +0 -700
- package/dist/.pikku/agent/pikku-agent-wirings-meta.gen.d.ts +0 -1
- package/dist/.pikku/agent/pikku-agent-wirings-meta.gen.js +0 -6
- package/dist/.pikku/agent/pikku-agent-wirings-meta.gen.json +0 -3
- package/dist/.pikku/agent/pikku-agent-wirings.gen.d.ts +0 -4
- package/dist/.pikku/agent/pikku-agent-wirings.gen.js +0 -4
- package/dist/.pikku/channel/pikku-channels-meta.gen.d.ts +0 -1
- package/dist/.pikku/channel/pikku-channels-meta.gen.js +0 -6
- package/dist/.pikku/channel/pikku-channels-meta.gen.json +0 -1
- package/dist/.pikku/channel/pikku-channels.gen.d.ts +0 -4
- package/dist/.pikku/channel/pikku-channels.gen.js +0 -5
- package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.d.ts +0 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +0 -8
- package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.json +0 -5
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +0 -4
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +0 -5
- package/dist/.pikku/pikku-websocket.gen.d.ts +0 -45
- package/dist/.pikku/pikku-websocket.gen.js +0 -63
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.d.ts +0 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +0 -6
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.json +0 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +0 -4
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +0 -5
- package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.d.ts +0 -17
- package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +0 -25
- package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.d.ts +0 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +0 -6
- package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.json +0 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +0 -4
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +0 -5
|
@@ -1,191 +1,7 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
2
1
|
import { pikkuVoidFunc } from '#pikku';
|
|
3
|
-
const scaffoldFiles = (config) => {
|
|
4
|
-
const files = [];
|
|
5
|
-
if (config.scaffold?.rpc && config.publicRpcFile)
|
|
6
|
-
files.push({ file: config.publicRpcFile, generator: 'pikkuPublicRPC' });
|
|
7
|
-
if (config.scaffold?.console && config.consoleFunctionsFile)
|
|
8
|
-
files.push({
|
|
9
|
-
file: config.consoleFunctionsFile,
|
|
10
|
-
generator: 'pikkuConsoleFunctions',
|
|
11
|
-
});
|
|
12
|
-
if (config.scaffold?.agent && config.publicAgentFile)
|
|
13
|
-
files.push({
|
|
14
|
-
file: config.publicAgentFile,
|
|
15
|
-
generator: 'pikkuPublicAgent',
|
|
16
|
-
});
|
|
17
|
-
return files;
|
|
18
|
-
};
|
|
19
2
|
export const all = pikkuVoidFunc({
|
|
20
3
|
remote: true,
|
|
21
|
-
func: async (
|
|
22
|
-
|
|
23
|
-
let typesDeclarationFileExists = true;
|
|
24
|
-
if (!existsSync(config.outDir)) {
|
|
25
|
-
logger.debug(`• .pikku directory not found, running bootstrap first...`);
|
|
26
|
-
await getInspectorState(false, false, true);
|
|
27
|
-
await rpc.invoke('pikkuFunctionTypes', null);
|
|
28
|
-
await rpc.invoke('pikkuFunctionTypesSplit', null);
|
|
29
|
-
await rpc.invoke('pikkuHTTPTypes', null);
|
|
30
|
-
await rpc.invoke('pikkuChannelTypes', null);
|
|
31
|
-
await rpc.invoke('pikkuSchedulerTypes', null);
|
|
32
|
-
await rpc.invoke('pikkuQueueTypes', null);
|
|
33
|
-
await rpc.invoke('pikkuWorkflow', null);
|
|
34
|
-
await rpc.invoke('pikkuMCPTypes', null);
|
|
35
|
-
await rpc.invoke('pikkuAIAgentTypes', null);
|
|
36
|
-
await rpc.invoke('pikkuCLITypes', null);
|
|
37
|
-
await getInspectorState(true);
|
|
38
|
-
}
|
|
39
|
-
if (!existsSync(config.typesDeclarationFile)) {
|
|
40
|
-
typesDeclarationFileExists = false;
|
|
41
|
-
}
|
|
42
|
-
const missingScaffolds = scaffoldFiles(config).filter((s) => !existsSync(s.file));
|
|
43
|
-
if (missingScaffolds.length > 0) {
|
|
44
|
-
for (const { generator } of missingScaffolds) {
|
|
45
|
-
await rpc.invoke(generator, null);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
await rpc.invoke('pikkuFunctionTypes', null);
|
|
49
|
-
if (!typesDeclarationFileExists || missingScaffolds.length > 0) {
|
|
50
|
-
logger.debug(`• Type file or scaffolds first created, inspecting again...`);
|
|
51
|
-
await getInspectorState(true);
|
|
52
|
-
}
|
|
53
|
-
await rpc.invoke('pikkuFunctionTypesSplit', null);
|
|
54
|
-
await rpc.invoke('pikkuTriggerTypes', null);
|
|
55
|
-
await rpc.invoke('pikkuAIAgentTypes', null);
|
|
56
|
-
if (!config.addon) {
|
|
57
|
-
await rpc.invoke('pikkuHTTPTypes', null);
|
|
58
|
-
await rpc.invoke('pikkuChannelTypes', null);
|
|
59
|
-
await rpc.invoke('pikkuSchedulerTypes', null);
|
|
60
|
-
await rpc.invoke('pikkuQueueTypes', null);
|
|
61
|
-
await rpc.invoke('pikkuMCPTypes', null);
|
|
62
|
-
await rpc.invoke('pikkuCLITypes', null);
|
|
63
|
-
}
|
|
64
|
-
const middleware = await rpc.invoke('pikkuMiddleware', null);
|
|
65
|
-
if (middleware) {
|
|
66
|
-
allImports.push(config.middlewareFile);
|
|
67
|
-
}
|
|
68
|
-
const permissions = await rpc.invoke('pikkuPermissions', null);
|
|
69
|
-
if (permissions) {
|
|
70
|
-
allImports.push(config.permissionsFile);
|
|
71
|
-
}
|
|
72
|
-
await rpc.invoke('pikkuServices', null);
|
|
73
|
-
const hasPackageFactories = await rpc.invoke('pikkuPackage', null);
|
|
74
|
-
if (hasPackageFactories) {
|
|
75
|
-
allImports.push(config.packageFile);
|
|
76
|
-
}
|
|
77
|
-
const hasInternalRPCs = await rpc.invoke('pikkuRPC', null);
|
|
78
|
-
const agents = await rpc.invoke('pikkuAIAgent', null);
|
|
79
|
-
if (agents) {
|
|
80
|
-
allImports.push(config.agentWiringMetaFile, config.agentWiringsFile);
|
|
81
|
-
if (config.scaffold?.agent) {
|
|
82
|
-
await rpc.invoke('pikkuPublicAgent', null);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
await rpc.invoke('pikkuPublicRPC', null);
|
|
86
|
-
await rpc.invoke('pikkuConsoleFunctions', null);
|
|
87
|
-
await rpc.invoke('pikkuNodeTypes', null);
|
|
88
|
-
await rpc.invoke('pikkuSecretDefinitionTypes', null);
|
|
89
|
-
await rpc.invoke('pikkuSecrets', null);
|
|
90
|
-
await rpc.invoke('pikkuCredentials', null);
|
|
91
|
-
await rpc.invoke('pikkuVariableDefinitionTypes', null);
|
|
92
|
-
await rpc.invoke('pikkuVariables', null);
|
|
93
|
-
await rpc.invoke('pikkuAddonTypes', null);
|
|
94
|
-
if (hasInternalRPCs) {
|
|
95
|
-
allImports.push(config.rpcInternalWiringMetaFile);
|
|
96
|
-
}
|
|
97
|
-
if (agents || !config.addon) {
|
|
98
|
-
await getInspectorState(true);
|
|
99
|
-
}
|
|
100
|
-
const schemas = await rpc.invoke('pikkuSchemas', null);
|
|
101
|
-
if (schemas) {
|
|
102
|
-
allImports.push(`${config.schemaDirectory}/register.gen.ts`);
|
|
103
|
-
}
|
|
104
|
-
await rpc.invoke('pikkuRPCInternalMap', null);
|
|
105
|
-
await rpc.invoke('pikkuRPCExposedMap', null);
|
|
106
|
-
const workflows = await rpc.invoke('pikkuWorkflow', null);
|
|
107
|
-
let remoteRPC = false;
|
|
108
|
-
let workflowRoutes = false;
|
|
109
|
-
if (!config.addon) {
|
|
110
|
-
remoteRPC = await rpc.invoke('pikkuRemoteRPC', null);
|
|
111
|
-
if (workflows) {
|
|
112
|
-
workflowRoutes = await rpc.invoke('pikkuWorkflowRoutes', null);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (workflows || remoteRPC || workflowRoutes) {
|
|
116
|
-
await getInspectorState(true);
|
|
117
|
-
await rpc.invoke('pikkuSchemas', null);
|
|
118
|
-
}
|
|
119
|
-
if (!config.addon) {
|
|
120
|
-
const http = await rpc.invoke('pikkuHTTP', null);
|
|
121
|
-
if (http) {
|
|
122
|
-
await rpc.invoke('pikkuHTTPMap', null);
|
|
123
|
-
await rpc.invoke('pikkuFetch', null);
|
|
124
|
-
await rpc.invoke('pikkuRPCClient', null);
|
|
125
|
-
allImports.push(config.httpWiringMetaFile, config.httpWiringsFile);
|
|
126
|
-
}
|
|
127
|
-
const scheduler = await rpc.invoke('pikkuScheduler', null);
|
|
128
|
-
if (scheduler) {
|
|
129
|
-
allImports.push(config.schedulersWiringMetaFile, config.schedulersWiringFile);
|
|
130
|
-
}
|
|
131
|
-
const triggers = await rpc.invoke('pikkuTrigger', null);
|
|
132
|
-
if (triggers) {
|
|
133
|
-
allImports.push(config.triggersWiringMetaFile, config.triggerSourcesMetaFile, config.triggersWiringFile);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const hasFunctionRegistrations = await rpc.invoke('pikkuFunctions', null);
|
|
137
|
-
allImports.push(config.functionsMetaFile);
|
|
138
|
-
if (hasFunctionRegistrations) {
|
|
139
|
-
allImports.push(config.functionsFile);
|
|
140
|
-
}
|
|
141
|
-
if (workflows) {
|
|
142
|
-
allImports.push(config.workflowsWiringFile);
|
|
143
|
-
}
|
|
144
|
-
if (!config.addon) {
|
|
145
|
-
const queues = await rpc.invoke('pikkuQueue', null);
|
|
146
|
-
if (queues) {
|
|
147
|
-
await rpc.invoke('pikkuQueueMap', null);
|
|
148
|
-
await rpc.invoke('pikkuQueueService', null);
|
|
149
|
-
allImports.push(config.queueWorkersWiringMetaFile, config.queueWorkersWiringFile);
|
|
150
|
-
}
|
|
151
|
-
const channels = await rpc.invoke('pikkuChannels', null);
|
|
152
|
-
if (channels) {
|
|
153
|
-
await rpc.invoke('pikkuChannelsMap', null);
|
|
154
|
-
await rpc.invoke('pikkuWebSocketTyped', null);
|
|
155
|
-
allImports.push(config.channelsWiringMetaFile, config.channelsWiringFile);
|
|
156
|
-
}
|
|
157
|
-
const gateways = await rpc.invoke('pikkuGateway', null);
|
|
158
|
-
if (gateways) {
|
|
159
|
-
allImports.push(config.gatewaysWiringFile);
|
|
160
|
-
}
|
|
161
|
-
const mcp = await rpc.invoke('pikkuMCP', null);
|
|
162
|
-
if (mcp) {
|
|
163
|
-
await rpc.invoke('pikkuMCPJSON', null);
|
|
164
|
-
allImports.push(config.mcpWiringsMetaFile, config.mcpWiringsFile);
|
|
165
|
-
}
|
|
166
|
-
const cli = await rpc.invoke('pikkuCLI', null);
|
|
167
|
-
if (cli) {
|
|
168
|
-
await rpc.invoke('pikkuCLIEntry', null);
|
|
169
|
-
allImports.push(config.cliWiringMetaFile, config.cliWiringsFile);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
await rpc.invoke('pikkuNodesMeta', null);
|
|
173
|
-
if (config.clientFiles?.nextBackendFile ||
|
|
174
|
-
config.clientFiles?.nextHTTPFile) {
|
|
175
|
-
await rpc.invoke('pikkuNext', null);
|
|
176
|
-
}
|
|
177
|
-
if (config.openAPI) {
|
|
178
|
-
logger.debug(`• OpenAPI requires a reinspection to pickup new generated types..`);
|
|
179
|
-
await getInspectorState(true);
|
|
180
|
-
await rpc.invoke('pikkuOpenAPI', null);
|
|
181
|
-
}
|
|
182
|
-
try {
|
|
183
|
-
await rpc.invoke('pikkuVersionsUpdate', null);
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
logger.warn(`Run 'pikku versions init' to enable contract versioning.`);
|
|
187
|
-
}
|
|
188
|
-
await rpc.invoke('pikkuBootstrap', { allImports });
|
|
189
|
-
await rpc.invoke('pikkuSummary', null);
|
|
4
|
+
func: async (services, _data, { rpc }) => {
|
|
5
|
+
await services.workflowService.runToCompletion('allWorkflow', {}, rpc);
|
|
190
6
|
},
|
|
191
7
|
});
|
|
@@ -3,16 +3,16 @@ export const bootstrap = pikkuVoidFunc({
|
|
|
3
3
|
remote: true,
|
|
4
4
|
func: async ({ logger, getInspectorState }, _data, { rpc }) => {
|
|
5
5
|
await getInspectorState(false, false, true);
|
|
6
|
-
await rpc.invoke('pikkuFunctionTypes'
|
|
7
|
-
await rpc.invoke('pikkuFunctionTypesSplit'
|
|
8
|
-
await rpc.invoke('pikkuHTTPTypes'
|
|
9
|
-
await rpc.invoke('pikkuChannelTypes'
|
|
10
|
-
await rpc.invoke('pikkuSchedulerTypes'
|
|
11
|
-
await rpc.invoke('pikkuQueueTypes'
|
|
12
|
-
await rpc.invoke('pikkuWorkflow'
|
|
13
|
-
await rpc.invoke('pikkuMCPTypes'
|
|
14
|
-
await rpc.invoke('pikkuAIAgentTypes'
|
|
15
|
-
await rpc.invoke('pikkuCLITypes'
|
|
6
|
+
await rpc.invoke('pikkuFunctionTypes');
|
|
7
|
+
await rpc.invoke('pikkuFunctionTypesSplit');
|
|
8
|
+
await rpc.invoke('pikkuHTTPTypes');
|
|
9
|
+
await rpc.invoke('pikkuChannelTypes');
|
|
10
|
+
await rpc.invoke('pikkuSchedulerTypes');
|
|
11
|
+
await rpc.invoke('pikkuQueueTypes');
|
|
12
|
+
await rpc.invoke('pikkuWorkflow');
|
|
13
|
+
await rpc.invoke('pikkuMCPTypes');
|
|
14
|
+
await rpc.invoke('pikkuAIAgentTypes');
|
|
15
|
+
await rpc.invoke('pikkuCLITypes');
|
|
16
16
|
if (logger.hasCriticalErrors()) {
|
|
17
17
|
process.exit(1);
|
|
18
18
|
}
|
|
@@ -88,7 +88,7 @@ export const consoleCommand = pikkuSessionlessFunc({
|
|
|
88
88
|
const handle = async () => {
|
|
89
89
|
try {
|
|
90
90
|
const start = Date.now();
|
|
91
|
-
await rpc.invoke('all'
|
|
91
|
+
await rpc.invoke('all');
|
|
92
92
|
logger.info({
|
|
93
93
|
message: `✓ Generated in ${Date.now() - start}ms`,
|
|
94
94
|
type: 'timing',
|
|
@@ -26,7 +26,7 @@ export const watch = pikkuSessionlessFunc({
|
|
|
26
26
|
const handle = async () => {
|
|
27
27
|
try {
|
|
28
28
|
const start = Date.now();
|
|
29
|
-
await rpc.invoke('all'
|
|
29
|
+
await rpc.invoke('all');
|
|
30
30
|
logger.info({
|
|
31
31
|
message: `✓ Generated in ${Date.now() - start}ms`,
|
|
32
32
|
type: 'timing',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuReactQuery: import("#pikku").PikkuFunctionConfig<void, void, "session" | "rpc", import("#pikku").PikkuFunctionSessionless<void, void, "session" | "rpc", import("#pikku").Services> | import("#pikku").PikkuFunction<void, void, "session" | "rpc", import("#pikku").Services>, undefined, undefined>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '#pikku';
|
|
2
|
+
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
|
+
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { serializeReactQueryHooks } from './serialize-react-query-hooks.js';
|
|
6
|
+
export const pikkuReactQuery = pikkuSessionlessFunc({
|
|
7
|
+
func: async ({ logger, config, getInspectorState }) => {
|
|
8
|
+
const reactQueryFile = config.clientFiles?.reactQueryFile;
|
|
9
|
+
const { rpcMapDeclarationFile, workflowMapDeclarationFile, packageMappings, } = config;
|
|
10
|
+
if (!reactQueryFile) {
|
|
11
|
+
logger.debug({
|
|
12
|
+
message: "Skipping generating React Query hooks since reactQueryFile isn't set in the pikku config.",
|
|
13
|
+
type: 'skip',
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const { workflows } = await getInspectorState();
|
|
18
|
+
const hasWorkflows = Object.keys(workflows?.meta ?? {}).length > 0;
|
|
19
|
+
const rpcMapPath = getFileImportRelativePath(reactQueryFile, rpcMapDeclarationFile, packageMappings);
|
|
20
|
+
let workflowMapPath;
|
|
21
|
+
if (hasWorkflows) {
|
|
22
|
+
workflowMapPath = getFileImportRelativePath(reactQueryFile, workflowMapDeclarationFile, packageMappings);
|
|
23
|
+
}
|
|
24
|
+
const content = serializeReactQueryHooks(rpcMapPath, workflowMapPath);
|
|
25
|
+
await writeFileInDir(logger, reactQueryFile, content);
|
|
26
|
+
},
|
|
27
|
+
middleware: [
|
|
28
|
+
logCommandInfoAndTime({
|
|
29
|
+
commandStart: 'Generating React Query hooks',
|
|
30
|
+
commandEnd: 'Generated React Query hooks',
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const serializeReactQueryHooks: (rpcMapPath: string, workflowMapPath?: string) => string;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export const serializeReactQueryHooks = (rpcMapPath, workflowMapPath) => {
|
|
2
|
+
const workflowImport = workflowMapPath
|
|
3
|
+
? `\nimport type { FlattenedWorkflowMap } from '${workflowMapPath}'`
|
|
4
|
+
: '';
|
|
5
|
+
const workflowHooks = workflowMapPath
|
|
6
|
+
? `
|
|
7
|
+
export const useRunWorkflow = <Name extends keyof FlattenedWorkflowMap>(
|
|
8
|
+
name: Name,
|
|
9
|
+
options?: Omit<UseMutationOptions<FlattenedWorkflowMap[Name]['output'], Error, FlattenedWorkflowMap[Name]['input']>, 'mutationFn'>
|
|
10
|
+
) => {
|
|
11
|
+
const rpc = usePikkuRPC<{ runWorkflow: <N extends keyof FlattenedWorkflowMap>(name: N, input: FlattenedWorkflowMap[N]['input']) => Promise<FlattenedWorkflowMap[N]['output']> }>()
|
|
12
|
+
return useMutation<FlattenedWorkflowMap[Name]['output'], Error, FlattenedWorkflowMap[Name]['input']>({
|
|
13
|
+
mutationFn: (input) => rpc.runWorkflow(name, input),
|
|
14
|
+
...options,
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const useStartWorkflow = <Name extends keyof FlattenedWorkflowMap>(
|
|
19
|
+
name: Name,
|
|
20
|
+
options?: Omit<UseMutationOptions<{ runId: string }, Error, FlattenedWorkflowMap[Name]['input']>, 'mutationFn'>
|
|
21
|
+
) => {
|
|
22
|
+
const rpc = usePikkuRPC<{ startWorkflow: <N extends keyof FlattenedWorkflowMap>(name: N, input: FlattenedWorkflowMap[N]['input']) => Promise<{ runId: string }> }>()
|
|
23
|
+
return useMutation<{ runId: string }, Error, FlattenedWorkflowMap[Name]['input']>({
|
|
24
|
+
mutationFn: (input) => rpc.startWorkflow(name, input),
|
|
25
|
+
...options,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type WorkflowRunStatus = {
|
|
30
|
+
id: string
|
|
31
|
+
status: 'running' | 'suspended' | 'completed' | 'failed' | 'cancelled'
|
|
32
|
+
output?: unknown
|
|
33
|
+
error?: { message?: string }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const useWorkflowStatus = (
|
|
37
|
+
workflowName: keyof FlattenedWorkflowMap & string,
|
|
38
|
+
runId?: string,
|
|
39
|
+
options?: Omit<UseQueryOptions<WorkflowRunStatus, Error>, 'queryKey' | 'queryFn' | 'enabled'>
|
|
40
|
+
) => {
|
|
41
|
+
const rpc = usePikkuRPC<{ workflowStatus: (name: string, runId: string) => Promise<WorkflowRunStatus> }>()
|
|
42
|
+
return useQuery<WorkflowRunStatus, Error>({
|
|
43
|
+
queryKey: ['workflowStatus', workflowName, runId],
|
|
44
|
+
queryFn: () => {
|
|
45
|
+
if (!runId) throw new Error('runId is required')
|
|
46
|
+
return rpc.workflowStatus(workflowName, runId)
|
|
47
|
+
},
|
|
48
|
+
enabled: !!runId,
|
|
49
|
+
...options,
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
`
|
|
53
|
+
: '';
|
|
54
|
+
return `import { useQuery, useInfiniteQuery, useMutation, type UseQueryOptions, type UseInfiniteQueryOptions, type UseMutationOptions, type InfiniteData } from '@tanstack/react-query'
|
|
55
|
+
import { usePikkuRPC } from '@pikku/react'
|
|
56
|
+
import type { FlattenedRPCMap } from '${rpcMapPath}'${workflowImport}
|
|
57
|
+
|
|
58
|
+
type RPCInvoke = <Name extends keyof FlattenedRPCMap>(name: Name, data: FlattenedRPCMap[Name]['input']) => Promise<FlattenedRPCMap[Name]['output']>
|
|
59
|
+
|
|
60
|
+
export const usePikkuQuery = <Name extends keyof FlattenedRPCMap>(
|
|
61
|
+
name: Name,
|
|
62
|
+
data: FlattenedRPCMap[Name]['input'],
|
|
63
|
+
options?: Omit<UseQueryOptions<FlattenedRPCMap[Name]['output'], Error>, 'queryKey' | 'queryFn'>
|
|
64
|
+
) => {
|
|
65
|
+
const rpc = usePikkuRPC<{ invoke: RPCInvoke }>()
|
|
66
|
+
return useQuery<FlattenedRPCMap[Name]['output'], Error>({
|
|
67
|
+
queryKey: [name, data],
|
|
68
|
+
queryFn: () => rpc.invoke(name, data),
|
|
69
|
+
...options,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const usePikkuMutation = <Name extends keyof FlattenedRPCMap>(
|
|
74
|
+
name: Name,
|
|
75
|
+
options?: Omit<UseMutationOptions<FlattenedRPCMap[Name]['output'], Error, FlattenedRPCMap[Name]['input']>, 'mutationFn'>
|
|
76
|
+
) => {
|
|
77
|
+
const rpc = usePikkuRPC<{ invoke: RPCInvoke }>()
|
|
78
|
+
return useMutation<FlattenedRPCMap[Name]['output'], Error, FlattenedRPCMap[Name]['input']>({
|
|
79
|
+
mutationFn: (data) => rpc.invoke(name, data),
|
|
80
|
+
...options,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type PaginatedKeys = {
|
|
85
|
+
[K in keyof FlattenedRPCMap]: FlattenedRPCMap[K]['output'] extends { nextCursor?: string | null } ? K : never
|
|
86
|
+
}[keyof FlattenedRPCMap]
|
|
87
|
+
|
|
88
|
+
type InfiniteOpts<Name extends PaginatedKeys> = Omit<
|
|
89
|
+
UseInfiniteQueryOptions<FlattenedRPCMap[Name]['output'], Error, InfiniteData<FlattenedRPCMap[Name]['output'], string | undefined>, readonly unknown[], string | undefined>,
|
|
90
|
+
'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'
|
|
91
|
+
>
|
|
92
|
+
|
|
93
|
+
export const usePikkuInfiniteQuery = <Name extends PaginatedKeys>(
|
|
94
|
+
name: Name,
|
|
95
|
+
data: Omit<FlattenedRPCMap[Name]['input'], 'nextCursor'>,
|
|
96
|
+
options?: InfiniteOpts<Name>
|
|
97
|
+
) => {
|
|
98
|
+
const rpc = usePikkuRPC<{ invoke: RPCInvoke }>()
|
|
99
|
+
return useInfiniteQuery({
|
|
100
|
+
queryKey: [name, data] as const,
|
|
101
|
+
queryFn: ({ pageParam }: { pageParam: string | undefined }) => rpc.invoke(name, { ...data, nextCursor: pageParam } as FlattenedRPCMap[Name]['input']),
|
|
102
|
+
initialPageParam: undefined as string | undefined,
|
|
103
|
+
getNextPageParam: (lastPage: FlattenedRPCMap[Name]['output']) => (lastPage as { nextCursor?: string }).nextCursor ?? undefined,
|
|
104
|
+
...options,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
${workflowHooks}`;
|
|
108
|
+
};
|
|
@@ -59,9 +59,9 @@ export class PikkuRPC {
|
|
|
59
59
|
* @param data - The data to pass to the server function
|
|
60
60
|
* @returns A promise that resolves with the function's return value
|
|
61
61
|
*/
|
|
62
|
-
invoke
|
|
63
|
-
return
|
|
64
|
-
}
|
|
62
|
+
invoke = ((rpcName: string, data?: unknown) => {
|
|
63
|
+
return this.pikkuFetch.post(\`${globalHTTPPrefix}/rpc/\${String(rpcName)}\` as never, { rpcName: String(rpcName), data }) as any
|
|
64
|
+
}) as RPCInvoke
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Starts a workflow by name with the given input.
|
|
@@ -41,13 +41,15 @@ ${addonImports}
|
|
|
41
41
|
${mergedRPCMap}
|
|
42
42
|
|
|
43
43
|
export type RPCInvoke = <Name extends keyof FlattenedRPCMap>(
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
...args: FlattenedRPCMap[Name]['input'] extends void | null
|
|
45
|
+
? [name: Name]
|
|
46
|
+
: [name: Name, data: FlattenedRPCMap[Name]['input']]
|
|
46
47
|
) => Promise<FlattenedRPCMap[Name]['output']>
|
|
47
48
|
|
|
48
49
|
export type RPCRemote = <Name extends keyof FlattenedRPCMap>(
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
...args: FlattenedRPCMap[Name]['input'] extends void | null
|
|
51
|
+
? [name: Name]
|
|
52
|
+
: [name: Name, data: FlattenedRPCMap[Name]['input']]
|
|
51
53
|
) => Promise<FlattenedRPCMap[Name]['output']>
|
|
52
54
|
|
|
53
55
|
${workflowMapPath ? `import type { FlattenedWorkflowMap } from '${workflowMapPath}'` : `type FlattenedWorkflowMap = {}`}
|
|
@@ -15,6 +15,10 @@ function assertWorkflowService(workflowService: unknown): asserts workflowServic
|
|
|
15
15
|
if (!workflowService) throw new MissingServiceError('workflowService is required')
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function assertWorkflowRunService(workflowRunService: unknown): asserts workflowRunService {
|
|
19
|
+
if (!workflowRunService) throw new MissingServiceError('workflowRunService is required')
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
export const workflowStarter = pikkuSessionlessFunc<
|
|
19
23
|
{ workflowName: string; data?: unknown },
|
|
20
24
|
{ runId: string }
|
|
@@ -49,48 +53,137 @@ export const workflowStatusChecker = pikkuSessionlessFunc<
|
|
|
49
53
|
},
|
|
50
54
|
})
|
|
51
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Minimal workflow status stream — sends step names and statuses only.
|
|
58
|
+
* Use this for user-facing frontends where internal details should not be exposed.
|
|
59
|
+
*/
|
|
52
60
|
export const workflowStatusStream = pikkuSessionlessFunc<
|
|
53
61
|
{ workflowName: string; runId: string },
|
|
54
|
-
|
|
62
|
+
unknown
|
|
55
63
|
>({
|
|
56
64
|
auth: ${authFlag},
|
|
57
|
-
func: async ({
|
|
58
|
-
|
|
65
|
+
func: async ({ workflowRunService }, { runId }, { channel }) => {
|
|
66
|
+
assertWorkflowRunService(workflowRunService)
|
|
67
|
+
if (!channel) return
|
|
68
|
+
|
|
59
69
|
const terminalStatuses = new Set(['completed', 'failed', 'cancelled'])
|
|
60
|
-
|
|
61
|
-
const maxWaitMs = 300_000
|
|
70
|
+
let lastHash = ''
|
|
62
71
|
|
|
63
|
-
const
|
|
64
|
-
|
|
72
|
+
const poll = async () => {
|
|
73
|
+
const run = await workflowRunService.getRun(runId)
|
|
74
|
+
if (!run) {
|
|
75
|
+
channel.close()
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
const status = await workflowService.getRunStatus(runId)
|
|
68
|
-
if (!status) throw new Error(\`Run not found: \${runId}\`)
|
|
79
|
+
const steps = await workflowRunService.getRunSteps(runId)
|
|
69
80
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
const hash = JSON.stringify({
|
|
82
|
+
s: run.status,
|
|
83
|
+
steps: steps.map((s: { stepName: string; status: string }) => [s.stepName, s.status]),
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
if (hash !== lastHash) {
|
|
87
|
+
lastHash = hash
|
|
88
|
+
channel.send({
|
|
89
|
+
type: 'update',
|
|
90
|
+
status: run.status,
|
|
91
|
+
steps: steps.map((s: { stepName: string; status: string }) => ({
|
|
92
|
+
stepName: s.stepName,
|
|
93
|
+
status: s.status,
|
|
94
|
+
})),
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (terminalStatuses.has(run.status)) {
|
|
99
|
+
channel.send({ type: 'done' })
|
|
100
|
+
channel.close()
|
|
101
|
+
return false
|
|
76
102
|
}
|
|
103
|
+
return true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const shouldContinue = await poll()
|
|
107
|
+
if (!shouldContinue) return
|
|
77
108
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
109
|
+
await new Promise<void>((resolve) => {
|
|
110
|
+
const interval = setInterval(async () => {
|
|
111
|
+
const cont = await poll()
|
|
112
|
+
if (!cont) {
|
|
113
|
+
clearInterval(interval)
|
|
114
|
+
resolve()
|
|
81
115
|
}
|
|
82
|
-
|
|
116
|
+
}, 500)
|
|
117
|
+
})
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Full workflow status stream — includes output, error, and child run IDs.
|
|
123
|
+
* Use this for admin consoles and internal tooling.
|
|
124
|
+
*/
|
|
125
|
+
export const workflowStatusStreamFull = pikkuSessionlessFunc<
|
|
126
|
+
{ workflowName: string; runId: string },
|
|
127
|
+
unknown
|
|
128
|
+
>({
|
|
129
|
+
auth: ${authFlag},
|
|
130
|
+
func: async ({ workflowRunService }, { runId }, { channel }) => {
|
|
131
|
+
assertWorkflowRunService(workflowRunService)
|
|
132
|
+
if (!channel) return
|
|
133
|
+
|
|
134
|
+
const terminalStatuses = new Set(['completed', 'failed', 'cancelled'])
|
|
135
|
+
let lastHash = ''
|
|
136
|
+
|
|
137
|
+
const poll = async () => {
|
|
138
|
+
const run = await workflowRunService.getRun(runId)
|
|
139
|
+
if (!run) {
|
|
140
|
+
channel.close()
|
|
141
|
+
return false
|
|
83
142
|
}
|
|
84
143
|
|
|
85
|
-
|
|
86
|
-
|
|
144
|
+
const steps = await workflowRunService.getRunSteps(runId)
|
|
145
|
+
|
|
146
|
+
const hash = JSON.stringify({
|
|
147
|
+
s: run.status,
|
|
148
|
+
o: run.output,
|
|
149
|
+
steps: steps.map((s: { stepName: string; status: string }) => [s.stepName, s.status]),
|
|
150
|
+
})
|
|
87
151
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
152
|
+
if (hash !== lastHash) {
|
|
153
|
+
lastHash = hash
|
|
154
|
+
channel.send({
|
|
155
|
+
type: 'update',
|
|
156
|
+
status: run.status,
|
|
157
|
+
output: run.output,
|
|
158
|
+
error: run.error,
|
|
159
|
+
steps: steps.map((s: { stepName: string; status: string; childRunId?: string }) => ({
|
|
160
|
+
stepName: s.stepName,
|
|
161
|
+
status: s.status,
|
|
162
|
+
...(s.childRunId ? { childRunId: s.childRunId } : {}),
|
|
163
|
+
})),
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (terminalStatuses.has(run.status)) {
|
|
168
|
+
channel.send({ type: 'done' })
|
|
169
|
+
channel.close()
|
|
170
|
+
return false
|
|
171
|
+
}
|
|
172
|
+
return true
|
|
92
173
|
}
|
|
93
|
-
|
|
174
|
+
|
|
175
|
+
const shouldContinue = await poll()
|
|
176
|
+
if (!shouldContinue) return
|
|
177
|
+
|
|
178
|
+
await new Promise<void>((resolve) => {
|
|
179
|
+
const interval = setInterval(async () => {
|
|
180
|
+
const cont = await poll()
|
|
181
|
+
if (!cont) {
|
|
182
|
+
clearInterval(interval)
|
|
183
|
+
resolve()
|
|
184
|
+
}
|
|
185
|
+
}, 500)
|
|
186
|
+
})
|
|
94
187
|
},
|
|
95
188
|
})
|
|
96
189
|
|
|
@@ -128,6 +221,12 @@ wireHTTPRoutes({
|
|
|
128
221
|
sse: true,
|
|
129
222
|
func: workflowStatusStream,
|
|
130
223
|
},
|
|
224
|
+
workflowStatusStreamFull: {
|
|
225
|
+
route: '/workflow/:workflowName/status/:runId/stream/full',
|
|
226
|
+
method: 'get',
|
|
227
|
+
sse: true,
|
|
228
|
+
func: workflowStatusStreamFull,
|
|
229
|
+
},
|
|
131
230
|
graphStart: {
|
|
132
231
|
route: '/workflow/:workflowName/graph/:nodeId',
|
|
133
232
|
method: 'post',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const allWorkflow: import("../../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<void, void, "workflow">;
|