@pikku/cli 0.12.85 → 0.12.86
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/console-app/assets/{index-CEv-kj3J.js → index-Cr3_cO3Z.js} +161 -147
- package/console-app/index.html +1 -1
- 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 +1 -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-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +4 -0
- 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 +4 -0
- 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 +39 -15
- package/dist/.pikku/function/pikku-functions.gen.js +3 -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/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 +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -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 +2 -1
- package/dist/.pikku/pikku-services.gen.js +1 -0
- 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 +1 -0
- 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 +3 -1
- package/dist/.pikku/schemas/schemas/FabricLoginInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuUserAdminFunctionsOutput.schema.json +1 -0
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- 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 +8 -2
- 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 +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/fabric/fabric-commands.d.ts +6 -3
- package/dist/src/fabric/fabric-commands.js +4 -0
- package/dist/src/fabric/functions/llm-key.function.d.ts +4 -4
- package/dist/src/fabric/functions/login.function.d.ts +4 -0
- package/dist/src/fabric/functions/login.function.js +45 -4
- package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.js +6 -2
- package/dist/src/functions/wirings/ai-agent/serialize-public-agent.d.ts +5 -1
- package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +81 -48
- package/dist/src/functions/wirings/auth/pikku-command-auth.js +4 -0
- package/dist/src/functions/wirings/console/pikku-command-console-functions.js +6 -2
- package/dist/src/functions/wirings/console/serialize-console-functions.d.ts +5 -1
- package/dist/src/functions/wirings/console/serialize-console-functions.js +55 -23
- package/dist/src/functions/wirings/functions/schemas.js +10 -1
- package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.js +2 -0
- package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.js +8 -2
- package/dist/src/functions/wirings/realtime/serialize-events-scaffold.d.ts +5 -4
- package/dist/src/functions/wirings/realtime/serialize-events-scaffold.js +17 -7
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +6 -2
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +6 -2
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +5 -1
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +16 -5
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +5 -1
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +16 -5
- package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +8 -2
- package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +5 -1
- package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +22 -16
- package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.d.ts +1 -0
- package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +49 -0
- package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.d.ts +24 -0
- package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +283 -0
- package/dist/src/functions/wirings/webhook/pikku-command-webhook.js +6 -2
- package/dist/src/functions/wirings/webhook/serialize-webhook.d.ts +5 -8
- package/dist/src/functions/wirings/webhook/serialize-webhook.js +19 -12
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.js +8 -2
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.d.ts +5 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +61 -31
- package/dist/src/functions/workflows/all.workflow.js +8 -0
- package/dist/src/utils/pikku-cli-config.js +40 -10
- package/dist/src/utils/remove-legacy-scaffold-file.d.ts +3 -0
- package/dist/src/utils/remove-legacy-scaffold-file.js +43 -0
- package/dist/src/utils/serialize-schemas.js +57 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/skills/pikku-addon/SKILL.md +1 -0
- package/skills/pikku-ai-agent/SKILL.md +2 -1
- package/skills/pikku-ai-vercel/SKILL.md +1 -0
- package/skills/pikku-better-auth/SKILL.md +57 -0
- package/skills/pikku-concepts/SKILL.md +1 -1
- package/skills/pikku-concepts/references/concept-mapping.md +11 -9
- package/skills/pikku-emails/SKILL.md +1 -0
- package/skills/pikku-fabric-debug/SKILL.md +112 -0
- package/skills/pikku-permissions/SKILL.md +8 -8
- package/skills/pikku-react/SKILL.md +32 -3
- package/skills/pikku-react-query/SKILL.md +38 -1
- package/skills/pikku-realtime/SKILL.md +1 -1
- package/skills/pikku-security/SKILL.md +3 -3
- package/skills/pikku-template-clone/SKILL.md +1 -0
- package/cli.schema.json +0 -1
|
@@ -1,28 +1,69 @@
|
|
|
1
1
|
export const serializePublicAgent = (pathToPikkuTypes, requireAuth = true, globalHTTPPrefix = '') => {
|
|
2
2
|
const authFlag = requireAuth ? 'true' : 'false';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
const schemas = `/**
|
|
4
|
+
* Auto-generated public agent schemas
|
|
5
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod'
|
|
8
|
+
|
|
9
|
+
export const Attachment = z.object({
|
|
10
|
+
type: z.enum(['image', 'file']),
|
|
11
|
+
data: z.string().optional(),
|
|
12
|
+
url: z.string().optional(),
|
|
13
|
+
mediaType: z.string().optional(),
|
|
14
|
+
filename: z.string().optional(),
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export const AgentCall = z.object({
|
|
18
|
+
agentName: z.string(),
|
|
19
|
+
message: z.string(),
|
|
20
|
+
threadId: z.string(),
|
|
21
|
+
resourceId: z.string(),
|
|
22
|
+
attachments: z.array(Attachment).optional(),
|
|
23
|
+
model: z.string().optional(),
|
|
24
|
+
temperature: z.number().optional(),
|
|
25
|
+
context: z.string().optional(),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export const AgentApproval = z.object({
|
|
29
|
+
agentName: z.string(),
|
|
30
|
+
runId: z.string(),
|
|
31
|
+
approvals: z.array(
|
|
32
|
+
z.object({ toolCallId: z.string(), approved: z.boolean() })
|
|
33
|
+
),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export const AgentResume = z.object({
|
|
37
|
+
agentName: z.string(),
|
|
38
|
+
runId: z.string(),
|
|
39
|
+
toolCallId: z.string(),
|
|
40
|
+
approved: z.boolean(),
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
export const ThreadsQuery = z.object({
|
|
44
|
+
agentName: z.string().optional(),
|
|
45
|
+
resourceId: z.string().optional(),
|
|
46
|
+
limit: z.number().optional(),
|
|
47
|
+
offset: z.number().optional(),
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
export const ThreadRef = z.object({
|
|
51
|
+
threadId: z.string(),
|
|
52
|
+
resourceId: z.string().optional(),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export const ThreadDeleted = z.object({ deleted: z.boolean() })
|
|
56
|
+
`;
|
|
57
|
+
const functions = `import { canAccessThread, threadOwnerConstraint } from '@pikku/core/ai-agent'
|
|
25
58
|
import { pikkuSessionlessFunc, pikkuPermission, defineHTTPRoutes, wireHTTPRoutes } from '${pathToPikkuTypes}'
|
|
59
|
+
import {
|
|
60
|
+
AgentCall,
|
|
61
|
+
AgentApproval,
|
|
62
|
+
AgentResume,
|
|
63
|
+
ThreadsQuery,
|
|
64
|
+
ThreadRef,
|
|
65
|
+
ThreadDeleted,
|
|
66
|
+
} from './agent.schemas.gen.js'
|
|
26
67
|
|
|
27
68
|
/**
|
|
28
69
|
* Thread reads are keyed by a caller-supplied \`threadId\`, so ownership cannot
|
|
@@ -39,9 +80,10 @@ export const isThreadOwner = pikkuPermission<{ threadId: string }>(
|
|
|
39
80
|
}
|
|
40
81
|
)
|
|
41
82
|
|
|
42
|
-
export const agentCaller = pikkuSessionlessFunc
|
|
83
|
+
export const agentCaller = pikkuSessionlessFunc({
|
|
43
84
|
tags: ['pikku'],
|
|
44
85
|
auth: ${authFlag},
|
|
86
|
+
input: AgentCall,
|
|
45
87
|
func: async (_services, data, { rpc }) => {
|
|
46
88
|
return await rpc.agent.run(data.agentName as any, {
|
|
47
89
|
message: data.message,
|
|
@@ -55,9 +97,10 @@ export const agentCaller = pikkuSessionlessFunc<${callerInput}, unknown>({
|
|
|
55
97
|
},
|
|
56
98
|
})
|
|
57
99
|
|
|
58
|
-
export const agentStreamCaller = pikkuSessionlessFunc
|
|
100
|
+
export const agentStreamCaller = pikkuSessionlessFunc({
|
|
59
101
|
tags: ['pikku'],
|
|
60
102
|
auth: ${authFlag},
|
|
103
|
+
input: AgentCall,
|
|
61
104
|
func: async (_services, data, { rpc }) => {
|
|
62
105
|
await rpc.agent.stream(data.agentName as any, {
|
|
63
106
|
message: data.message,
|
|
@@ -71,23 +114,19 @@ export const agentStreamCaller = pikkuSessionlessFunc<${callerInput}, void>({
|
|
|
71
114
|
},
|
|
72
115
|
})
|
|
73
116
|
|
|
74
|
-
export const agentApproveCaller = pikkuSessionlessFunc
|
|
75
|
-
{ agentName: string; runId: string; approvals: { toolCallId: string; approved: boolean }[] },
|
|
76
|
-
unknown
|
|
77
|
-
>({
|
|
117
|
+
export const agentApproveCaller = pikkuSessionlessFunc({
|
|
78
118
|
tags: ['pikku'],
|
|
79
119
|
auth: ${authFlag},
|
|
120
|
+
input: AgentApproval,
|
|
80
121
|
func: async (_services, { runId, approvals, agentName }, { rpc }) => {
|
|
81
122
|
return await rpc.agent.approve(runId, approvals, agentName)
|
|
82
123
|
},
|
|
83
124
|
})
|
|
84
125
|
|
|
85
|
-
export const agentResumeCaller = pikkuSessionlessFunc
|
|
86
|
-
{ agentName: string; runId: string; toolCallId: string; approved: boolean },
|
|
87
|
-
void
|
|
88
|
-
>({
|
|
126
|
+
export const agentResumeCaller = pikkuSessionlessFunc({
|
|
89
127
|
tags: ['pikku'],
|
|
90
128
|
auth: ${authFlag},
|
|
129
|
+
input: AgentResume,
|
|
91
130
|
func: async (_services, data, { rpc }) => {
|
|
92
131
|
await rpc.agent.resume(data.runId, {
|
|
93
132
|
toolCallId: data.toolCallId,
|
|
@@ -96,11 +135,9 @@ export const agentResumeCaller = pikkuSessionlessFunc<
|
|
|
96
135
|
},
|
|
97
136
|
})
|
|
98
137
|
|
|
99
|
-
export const getAgentThreads = pikkuSessionlessFunc
|
|
100
|
-
{ agentName?: string; resourceId?: string; limit?: number; offset?: number },
|
|
101
|
-
any[]
|
|
102
|
-
>({
|
|
138
|
+
export const getAgentThreads = pikkuSessionlessFunc({
|
|
103
139
|
tags: ['pikku', 'pikku:agent'],
|
|
140
|
+
input: ThreadsQuery,
|
|
104
141
|
title: 'Get Agent Threads',
|
|
105
142
|
description:
|
|
106
143
|
'Returns the caller\\'s AI agent threads from storage. Accepts optional filters: agentName, resourceId, limit, and offset for pagination.',
|
|
@@ -119,11 +156,9 @@ export const getAgentThreads = pikkuSessionlessFunc<
|
|
|
119
156
|
},
|
|
120
157
|
})
|
|
121
158
|
|
|
122
|
-
export const getAgentThreadMessages = pikkuSessionlessFunc
|
|
123
|
-
{ threadId: string; resourceId?: string },
|
|
124
|
-
any[]
|
|
125
|
-
>({
|
|
159
|
+
export const getAgentThreadMessages = pikkuSessionlessFunc({
|
|
126
160
|
tags: ['pikku', 'pikku:agent'],
|
|
161
|
+
input: ThreadRef,
|
|
127
162
|
title: 'Get Agent Thread Messages',
|
|
128
163
|
description:
|
|
129
164
|
'Returns all messages for a given AI agent thread, ordered by creation time.',
|
|
@@ -135,11 +170,9 @@ export const getAgentThreadMessages = pikkuSessionlessFunc<
|
|
|
135
170
|
},
|
|
136
171
|
})
|
|
137
172
|
|
|
138
|
-
export const getAgentThreadRuns = pikkuSessionlessFunc
|
|
139
|
-
{ threadId: string; resourceId?: string },
|
|
140
|
-
any[]
|
|
141
|
-
>({
|
|
173
|
+
export const getAgentThreadRuns = pikkuSessionlessFunc({
|
|
142
174
|
tags: ['pikku', 'pikku:agent'],
|
|
175
|
+
input: ThreadRef,
|
|
143
176
|
title: 'Get Agent Thread Runs',
|
|
144
177
|
description:
|
|
145
178
|
'Returns the run history for a given AI agent thread, ordered by creation time.',
|
|
@@ -151,11 +184,10 @@ export const getAgentThreadRuns = pikkuSessionlessFunc<
|
|
|
151
184
|
},
|
|
152
185
|
})
|
|
153
186
|
|
|
154
|
-
export const deleteAgentThread = pikkuSessionlessFunc
|
|
155
|
-
{ threadId: string; resourceId?: string },
|
|
156
|
-
{ deleted: boolean }
|
|
157
|
-
>({
|
|
187
|
+
export const deleteAgentThread = pikkuSessionlessFunc({
|
|
158
188
|
tags: ['pikku', 'pikku:agent'],
|
|
189
|
+
input: ThreadRef,
|
|
190
|
+
output: ThreadDeleted,
|
|
159
191
|
title: 'Delete Agent Thread',
|
|
160
192
|
description:
|
|
161
193
|
'Deletes an AI agent thread and all of its persisted state.',
|
|
@@ -199,4 +231,5 @@ export const agentRoutes = defineHTTPRoutes({
|
|
|
199
231
|
|
|
200
232
|
wireHTTPRoutes({ routes: { agent: agentRoutes } })
|
|
201
233
|
`;
|
|
234
|
+
return { schemas, functions };
|
|
202
235
|
};
|
|
@@ -4,6 +4,7 @@ import { rm } from 'node:fs/promises';
|
|
|
4
4
|
import { pikkuSessionlessFunc } from '#pikku';
|
|
5
5
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
6
6
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
7
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
7
8
|
import { serializeAuthGen } from './serialize-auth-gen.js';
|
|
8
9
|
import { serializeAuthTypes, serializeAuthTypesBootstrap, } from './serialize-auth-types.js';
|
|
9
10
|
import { serializeAuthMeta } from './serialize-auth-meta.js';
|
|
@@ -49,6 +50,9 @@ export const pikkuAuth = pikkuSessionlessFunc({
|
|
|
49
50
|
else if (existsSync(middlewareFile)) {
|
|
50
51
|
await rm(middlewareFile, { force: true });
|
|
51
52
|
}
|
|
53
|
+
for (const file of [authFile, secretsFile, middlewareFile]) {
|
|
54
|
+
await removeLegacyScaffoldFile(file);
|
|
55
|
+
}
|
|
52
56
|
// Static metadata of the enabled providers/plugins for the console SSO page,
|
|
53
57
|
// following the `*-meta.gen.json` convention. Read at runtime by the console
|
|
54
58
|
// getAuthProviders function instead of a runtime registry.
|
|
@@ -3,6 +3,7 @@ import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
5
|
import { projectDeclaresBetterAuth } from '../../../utils/detect-better-auth.js';
|
|
6
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
6
7
|
import { serializeConsoleFunctions } from './serialize-console-functions.js';
|
|
7
8
|
export const pikkuConsoleFunctions = pikkuSessionlessFunc({
|
|
8
9
|
func: async ({ logger, config, variables }) => {
|
|
@@ -10,7 +11,7 @@ export const pikkuConsoleFunctions = pikkuSessionlessFunc({
|
|
|
10
11
|
if (deployCodegenFlag === '1') {
|
|
11
12
|
return false;
|
|
12
13
|
}
|
|
13
|
-
if (config.scaffold?.console) {
|
|
14
|
+
if (config.scaffold?.console && config.consoleSchemasFile) {
|
|
14
15
|
// Every console RPC now requires an authenticated session (the console is
|
|
15
16
|
// an admin surface), so scaffolding it without an auth strategy produces a
|
|
16
17
|
// console that 403s on every call. Better Auth is the supported strategy —
|
|
@@ -25,7 +26,10 @@ export const pikkuConsoleFunctions = pikkuSessionlessFunc({
|
|
|
25
26
|
}
|
|
26
27
|
const pathToPikkuTypes = getFileImportRelativePath(config.consoleFunctionsFile, config.typesDeclarationFile, config.packageMappings);
|
|
27
28
|
const pathToAgentTypes = getFileImportRelativePath(config.consoleFunctionsFile, config.agentTypesFile, config.packageMappings);
|
|
28
|
-
|
|
29
|
+
const { schemas, functions } = serializeConsoleFunctions(pathToPikkuTypes, pathToAgentTypes, config.globalHTTPPrefix || '');
|
|
30
|
+
await writeFileInDir(logger, config.consoleSchemasFile, schemas);
|
|
31
|
+
await writeFileInDir(logger, config.consoleFunctionsFile, functions);
|
|
32
|
+
await removeLegacyScaffoldFile(config.consoleFunctionsFile);
|
|
29
33
|
return true;
|
|
30
34
|
}
|
|
31
35
|
return false;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface ConsoleGenOutput {
|
|
2
|
+
schemas: string;
|
|
3
|
+
functions: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const serializeConsoleFunctions: (pathToPikkuTypes: string, _pathToAgentTypes: string, globalHTTPPrefix?: string) => ConsoleGenOutput;
|
|
@@ -1,28 +1,62 @@
|
|
|
1
1
|
export const serializeConsoleFunctions = (pathToPikkuTypes, _pathToAgentTypes, globalHTTPPrefix = '') => {
|
|
2
|
-
|
|
2
|
+
const schemas = `/**
|
|
3
|
+
* Auto-generated console function schemas
|
|
4
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod'
|
|
3
7
|
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
8
|
+
export const SecretRef = z.object({ secretId: z.string() })
|
|
9
|
+
|
|
10
|
+
export const SetSecret = z.object({
|
|
11
|
+
secretId: z.string(),
|
|
12
|
+
value: z.unknown(),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export const VariableRef = z.object({ variableId: z.string() })
|
|
16
|
+
|
|
17
|
+
export const SetVariable = z.object({
|
|
18
|
+
variableId: z.string(),
|
|
19
|
+
value: z.unknown(),
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export const ValueResult = z.object({
|
|
23
|
+
exists: z.boolean(),
|
|
24
|
+
value: z.unknown().nullable(),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const Exists = z.object({ exists: z.boolean() })
|
|
28
|
+
|
|
29
|
+
export const Success = z.object({ success: z.boolean() })
|
|
30
|
+
`;
|
|
31
|
+
const functions = `import { pikkuFunc, defineHTTPRoutes, wireHTTPRoutes, ref, wireAddon } from '${pathToPikkuTypes}'
|
|
32
|
+
import {
|
|
33
|
+
SecretRef,
|
|
34
|
+
SetSecret,
|
|
35
|
+
VariableRef,
|
|
36
|
+
SetVariable,
|
|
37
|
+
ValueResult,
|
|
38
|
+
Exists,
|
|
39
|
+
Success,
|
|
40
|
+
} from './console.schemas.gen.js'
|
|
41
|
+
|
|
42
|
+
export const pikkuConsoleSetSecret = pikkuFunc({
|
|
10
43
|
tags: ['pikku'],
|
|
11
44
|
description: 'Set the value of a secret',
|
|
12
45
|
expose: true,
|
|
46
|
+
input: SetSecret,
|
|
47
|
+
output: Success,
|
|
13
48
|
func: async ({ secrets }, { secretId, value }) => {
|
|
14
49
|
await secrets.setSecret(secretId, value)
|
|
15
50
|
return { success: true }
|
|
16
51
|
},
|
|
17
52
|
})
|
|
18
53
|
|
|
19
|
-
export const pikkuConsoleGetVariable = pikkuFunc
|
|
20
|
-
{ variableId: string },
|
|
21
|
-
{ exists: boolean; value: unknown | null }
|
|
22
|
-
>({
|
|
54
|
+
export const pikkuConsoleGetVariable = pikkuFunc({
|
|
23
55
|
tags: ['pikku'],
|
|
24
56
|
description: 'Get the current value of a variable',
|
|
25
57
|
expose: true,
|
|
58
|
+
input: VariableRef,
|
|
59
|
+
output: ValueResult,
|
|
26
60
|
func: async ({ variables }, { variableId }) => {
|
|
27
61
|
const exists = await variables.has(variableId)
|
|
28
62
|
if (!exists) {
|
|
@@ -38,13 +72,12 @@ export const pikkuConsoleGetVariable = pikkuFunc<
|
|
|
38
72
|
},
|
|
39
73
|
})
|
|
40
74
|
|
|
41
|
-
export const pikkuConsoleSetVariable = pikkuFunc
|
|
42
|
-
{ variableId: string; value: unknown },
|
|
43
|
-
{ success: boolean }
|
|
44
|
-
>({
|
|
75
|
+
export const pikkuConsoleSetVariable = pikkuFunc({
|
|
45
76
|
tags: ['pikku'],
|
|
46
77
|
description: 'Set the value of a variable',
|
|
47
78
|
expose: true,
|
|
79
|
+
input: SetVariable,
|
|
80
|
+
output: Success,
|
|
48
81
|
func: async ({ variables }, { variableId, value }) => {
|
|
49
82
|
if (typeof value === 'string') {
|
|
50
83
|
await variables.set(variableId, value)
|
|
@@ -55,26 +88,24 @@ export const pikkuConsoleSetVariable = pikkuFunc<
|
|
|
55
88
|
},
|
|
56
89
|
})
|
|
57
90
|
|
|
58
|
-
export const pikkuConsoleHasSecret = pikkuFunc
|
|
59
|
-
{ secretId: string },
|
|
60
|
-
{ exists: boolean }
|
|
61
|
-
>({
|
|
91
|
+
export const pikkuConsoleHasSecret = pikkuFunc({
|
|
62
92
|
tags: ['pikku'],
|
|
63
93
|
description: 'Check if a secret exists without reading its value',
|
|
64
94
|
expose: true,
|
|
95
|
+
input: SecretRef,
|
|
96
|
+
output: Exists,
|
|
65
97
|
func: async ({ secrets }, { secretId }) => {
|
|
66
98
|
const exists = await secrets.hasSecret(secretId)
|
|
67
99
|
return { exists }
|
|
68
100
|
},
|
|
69
101
|
})
|
|
70
102
|
|
|
71
|
-
export const pikkuConsoleGetSecret = pikkuFunc
|
|
72
|
-
{ secretId: string },
|
|
73
|
-
{ exists: boolean; value: unknown | null }
|
|
74
|
-
>({
|
|
103
|
+
export const pikkuConsoleGetSecret = pikkuFunc({
|
|
75
104
|
tags: ['pikku'],
|
|
76
105
|
description: 'Get the current value of a secret',
|
|
77
106
|
expose: true,
|
|
107
|
+
input: SecretRef,
|
|
108
|
+
output: ValueResult,
|
|
78
109
|
func: async ({ secrets }, { secretId }) => {
|
|
79
110
|
const exists = await secrets.hasSecret(secretId)
|
|
80
111
|
if (!exists) {
|
|
@@ -107,4 +138,5 @@ export const consoleRoutes = defineHTTPRoutes({
|
|
|
107
138
|
wireAddon({ name: 'console', package: '@pikku/addon-console' })
|
|
108
139
|
wireHTTPRoutes({ basePath: '${globalHTTPPrefix}', routes: { console: consoleRoutes } })
|
|
109
140
|
`;
|
|
141
|
+
return { schemas, functions };
|
|
110
142
|
};
|
|
@@ -4,7 +4,16 @@ import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-
|
|
|
4
4
|
export const pikkuSchemas = pikkuSessionlessFunc({
|
|
5
5
|
func: async ({ logger, config, getInspectorState }) => {
|
|
6
6
|
const visitState = await getInspectorState();
|
|
7
|
-
|
|
7
|
+
// Bodies missing while functions still DECLARE schemas means the inspection pass
|
|
8
|
+
// was partial. Writing from it would empty register.gen.ts and delete the files
|
|
9
|
+
// behind schemas that are still required — unregistering the whole app off a bad
|
|
10
|
+
// read. Leave the previous output alone.
|
|
11
|
+
//
|
|
12
|
+
// Zero REQUIRED schemas is a different thing entirely and must still be written:
|
|
13
|
+
// that is a project whose last schema was removed, and it is the case where the
|
|
14
|
+
// files left by earlier runs have to be cleared.
|
|
15
|
+
if (visitState.requiredSchemas.size > 0 &&
|
|
16
|
+
Object.keys(visitState.schemas).length === 0) {
|
|
8
17
|
return undefined;
|
|
9
18
|
}
|
|
10
19
|
await saveSchemas(logger, config.schemaDirectory, visitState.schemas, visitState.requiredSchemas, config.schema?.supportsImportAttributes ?? true, config.addonName || null);
|
|
@@ -2,12 +2,14 @@ import { pikkuSessionlessFunc } from '#pikku';
|
|
|
2
2
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
5
6
|
import { serializeGraphWirings } from './serialize-graph-wirings.js';
|
|
6
7
|
export const pikkuGraphWirings = pikkuSessionlessFunc({
|
|
7
8
|
func: async ({ logger, config }) => {
|
|
8
9
|
if (config.scaffold?.graph && config.graphWiringsFile) {
|
|
9
10
|
const pathToPikkuTypes = getFileImportRelativePath(config.graphWiringsFile, config.typesDeclarationFile, config.packageMappings);
|
|
10
11
|
await writeFileInDir(logger, config.graphWiringsFile, serializeGraphWirings(pathToPikkuTypes));
|
|
12
|
+
await removeLegacyScaffoldFile(config.graphWiringsFile);
|
|
11
13
|
return true;
|
|
12
14
|
}
|
|
13
15
|
return false;
|
|
@@ -2,10 +2,13 @@ import { pikkuSessionlessFunc } from '#pikku';
|
|
|
2
2
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
5
6
|
import { serializeEventsScaffold } from './serialize-events-scaffold.js';
|
|
6
7
|
export const pikkuEventsScaffold = pikkuSessionlessFunc({
|
|
7
8
|
func: async ({ logger, config }) => {
|
|
8
|
-
if (!config.scaffold?.events ||
|
|
9
|
+
if (!config.scaffold?.events ||
|
|
10
|
+
!config.eventsChannelFile ||
|
|
11
|
+
!config.eventsSchemasFile) {
|
|
9
12
|
logger.debug({
|
|
10
13
|
message: 'Skipping events scaffold (set scaffold.events in pikku.config.json to enable).',
|
|
11
14
|
type: 'skip',
|
|
@@ -14,7 +17,10 @@ export const pikkuEventsScaffold = pikkuSessionlessFunc({
|
|
|
14
17
|
}
|
|
15
18
|
const authRequired = config.scaffold.events === 'auth';
|
|
16
19
|
const pikkuTypesImportPath = getFileImportRelativePath(config.eventsChannelFile, config.typesDeclarationFile, config.packageMappings);
|
|
17
|
-
|
|
20
|
+
const { schemas, functions } = serializeEventsScaffold(authRequired, pikkuTypesImportPath);
|
|
21
|
+
await writeFileInDir(logger, config.eventsSchemasFile, schemas);
|
|
22
|
+
await writeFileInDir(logger, config.eventsChannelFile, functions);
|
|
23
|
+
await removeLegacyScaffoldFile(config.eventsChannelFile);
|
|
18
24
|
return true;
|
|
19
25
|
},
|
|
20
26
|
middleware: [
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export interface EventsGenOutput {
|
|
2
|
+
schemas: string;
|
|
3
|
+
functions: string;
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* Generates the server-side `events.gen.ts` scaffold.
|
|
3
7
|
*
|
|
@@ -16,8 +20,5 @@
|
|
|
16
20
|
* Both routes call `eventHub.subscribe`/`unsubscribe` with the channel id;
|
|
17
21
|
* publish-side ergonomics (envelope shape) are documented in the
|
|
18
22
|
* pikku-realtime skill.
|
|
19
|
-
*
|
|
20
|
-
* Uses TypeScript generics (not named Zod schema constants) so schemas and
|
|
21
|
-
* wiring calls can safely coexist in a single generated file.
|
|
22
23
|
*/
|
|
23
|
-
export declare const serializeEventsScaffold: (authRequired: boolean, pikkuTypesImportPath: string) =>
|
|
24
|
+
export declare const serializeEventsScaffold: (authRequired: boolean, pikkuTypesImportPath: string) => EventsGenOutput;
|
|
@@ -16,19 +16,25 @@
|
|
|
16
16
|
* Both routes call `eventHub.subscribe`/`unsubscribe` with the channel id;
|
|
17
17
|
* publish-side ergonomics (envelope shape) are documented in the
|
|
18
18
|
* pikku-realtime skill.
|
|
19
|
-
*
|
|
20
|
-
* Uses TypeScript generics (not named Zod schema constants) so schemas and
|
|
21
|
-
* wiring calls can safely coexist in a single generated file.
|
|
22
19
|
*/
|
|
23
20
|
export const serializeEventsScaffold = (authRequired, pikkuTypesImportPath) => {
|
|
24
21
|
const auth = authRequired ? 'true' : 'false';
|
|
25
|
-
|
|
22
|
+
const schemas = `/**
|
|
23
|
+
* Auto-generated realtime event schemas
|
|
24
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
25
|
+
*/
|
|
26
|
+
import { z } from 'zod'
|
|
27
|
+
|
|
28
|
+
export const TopicRef = z.object({ topic: z.string() })
|
|
29
|
+
`;
|
|
30
|
+
const functions = `import {
|
|
26
31
|
pikkuChannelFunc,
|
|
27
32
|
pikkuSessionlessFunc,
|
|
28
33
|
wireChannel,
|
|
29
34
|
wireHTTP,
|
|
30
35
|
defineChannelRoutes,
|
|
31
36
|
} from '${pikkuTypesImportPath}'
|
|
37
|
+
import { TopicRef } from './events.schemas.gen.js'
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
40
|
* Topic envelope clients receive: \`{ topic, data }\`. Functions that publish
|
|
@@ -40,13 +46,15 @@ export const serializeEventsScaffold = (authRequired, pikkuTypesImportPath) => {
|
|
|
40
46
|
* the duplication; pick whichever style your project prefers.
|
|
41
47
|
*/
|
|
42
48
|
|
|
43
|
-
export const realtimeSubscribe = pikkuChannelFunc
|
|
49
|
+
export const realtimeSubscribe = pikkuChannelFunc({
|
|
50
|
+
input: TopicRef,
|
|
44
51
|
func: async ({ eventHub }, { topic }, { channel }) => {
|
|
45
52
|
await eventHub?.subscribe(topic, channel.channelId)
|
|
46
53
|
},
|
|
47
54
|
})
|
|
48
55
|
|
|
49
|
-
export const realtimeUnsubscribe = pikkuChannelFunc
|
|
56
|
+
export const realtimeUnsubscribe = pikkuChannelFunc({
|
|
57
|
+
input: TopicRef,
|
|
50
58
|
func: async ({ eventHub }, { topic }, { channel }) => {
|
|
51
59
|
await eventHub?.unsubscribe(topic, channel.channelId)
|
|
52
60
|
},
|
|
@@ -74,7 +82,8 @@ wireChannel({
|
|
|
74
82
|
* SSE per-topic stream. One connection = one subscription. The eventHub
|
|
75
83
|
* cleans up automatically when the channel closes (onChannelClosed).
|
|
76
84
|
*/
|
|
77
|
-
export const realtimeEventStream = pikkuSessionlessFunc
|
|
85
|
+
export const realtimeEventStream = pikkuSessionlessFunc({
|
|
86
|
+
input: TopicRef,
|
|
78
87
|
description: 'Auto-generated SSE stream for a single event-hub topic',
|
|
79
88
|
func: async ({ eventHub }, { topic }, { channel }) => {
|
|
80
89
|
if (!channel) {
|
|
@@ -95,4 +104,5 @@ wireHTTP({
|
|
|
95
104
|
tags: ['pikku:realtime', 'sse'],
|
|
96
105
|
})
|
|
97
106
|
`;
|
|
107
|
+
return { schemas, functions };
|
|
98
108
|
};
|
|
@@ -2,6 +2,7 @@ import { pikkuSessionlessFunc } from '#pikku';
|
|
|
2
2
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
5
6
|
import { serializePublicRPC } from './serialize-public-rpc.js';
|
|
6
7
|
export const pikkuPublicRPC = pikkuSessionlessFunc({
|
|
7
8
|
func: async ({ logger, config, variables }) => {
|
|
@@ -9,9 +10,12 @@ export const pikkuPublicRPC = pikkuSessionlessFunc({
|
|
|
9
10
|
if (deployCodegenFlag === '1') {
|
|
10
11
|
return false;
|
|
11
12
|
}
|
|
12
|
-
if (config.scaffold?.rpc) {
|
|
13
|
+
if (config.scaffold?.rpc && config.publicRpcSchemasFile) {
|
|
13
14
|
const pathToPikkuTypes = getFileImportRelativePath(config.publicRpcFile, config.typesDeclarationFile, config.packageMappings);
|
|
14
|
-
|
|
15
|
+
const { schemas, functions } = serializePublicRPC(pathToPikkuTypes, config.scaffold.rpc === 'auth', config.globalHTTPPrefix || '');
|
|
16
|
+
await writeFileInDir(logger, config.publicRpcSchemasFile, schemas);
|
|
17
|
+
await writeFileInDir(logger, config.publicRpcFile, functions);
|
|
18
|
+
await removeLegacyScaffoldFile(config.publicRpcFile);
|
|
15
19
|
return true;
|
|
16
20
|
}
|
|
17
21
|
return false;
|
|
@@ -2,6 +2,7 @@ import { pikkuSessionlessFunc } from '#pikku';
|
|
|
2
2
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
5
6
|
import { serializeRemoteRPC } from './serialize-remote-rpc.js';
|
|
6
7
|
export const pikkuRemoteRPC = pikkuSessionlessFunc({
|
|
7
8
|
func: async ({ logger, config, variables }) => {
|
|
@@ -9,9 +10,12 @@ export const pikkuRemoteRPC = pikkuSessionlessFunc({
|
|
|
9
10
|
if (deployCodegenFlag === '1') {
|
|
10
11
|
return false;
|
|
11
12
|
}
|
|
12
|
-
if (config.remoteRpcWorkersFile) {
|
|
13
|
+
if (config.remoteRpcWorkersFile && config.remoteRpcSchemasFile) {
|
|
13
14
|
const pathToPikkuTypes = getFileImportRelativePath(config.remoteRpcWorkersFile, config.typesDeclarationFile, config.packageMappings);
|
|
14
|
-
|
|
15
|
+
const { schemas, functions } = serializeRemoteRPC(pathToPikkuTypes);
|
|
16
|
+
await writeFileInDir(logger, config.remoteRpcSchemasFile, schemas);
|
|
17
|
+
await writeFileInDir(logger, config.remoteRpcWorkersFile, functions);
|
|
18
|
+
await removeLegacyScaffoldFile(config.remoteRpcWorkersFile);
|
|
15
19
|
return true;
|
|
16
20
|
}
|
|
17
21
|
return false;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
export interface PublicRPCGenOutput {
|
|
2
|
+
schemas: string;
|
|
3
|
+
functions: string;
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* Generate public RPC HTTP endpoint
|
|
3
7
|
*/
|
|
4
|
-
export declare const serializePublicRPC: (pathToPikkuTypes: string, requireAuth?: boolean, globalHTTPPrefix?: string) =>
|
|
8
|
+
export declare const serializePublicRPC: (pathToPikkuTypes: string, requireAuth?: boolean, globalHTTPPrefix?: string) => PublicRPCGenOutput;
|
|
@@ -3,18 +3,28 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const serializePublicRPC = (pathToPikkuTypes, requireAuth = true, globalHTTPPrefix = '') => {
|
|
5
5
|
const authFlag = requireAuth ? 'true' : 'false';
|
|
6
|
-
|
|
6
|
+
const schemas = `/**
|
|
7
|
+
* Auto-generated public RPC endpoint schemas
|
|
8
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod'
|
|
11
|
+
|
|
12
|
+
export const RPCCall = z.object({
|
|
13
|
+
rpcName: z.string(),
|
|
14
|
+
data: z.unknown().optional(),
|
|
15
|
+
})
|
|
16
|
+
`;
|
|
17
|
+
const functions = `/**
|
|
7
18
|
* Auto-generated public RPC HTTP endpoint
|
|
8
19
|
* Do not edit manually - regenerate with 'npx pikku'
|
|
9
20
|
*/
|
|
10
21
|
import { pikkuSessionlessFunc, wireHTTP } from '${pathToPikkuTypes}'
|
|
22
|
+
import { RPCCall } from './rpc-public.schemas.gen.js'
|
|
11
23
|
|
|
12
|
-
export const rpcCaller = pikkuSessionlessFunc
|
|
13
|
-
{ rpcName: string; data?: unknown },
|
|
14
|
-
unknown
|
|
15
|
-
>({
|
|
24
|
+
export const rpcCaller = pikkuSessionlessFunc({
|
|
16
25
|
tags: ['pikku'],
|
|
17
26
|
auth: ${authFlag},
|
|
27
|
+
input: RPCCall,
|
|
18
28
|
func: async (_services, { rpcName, data }, { rpc }) => {
|
|
19
29
|
return await rpc.exposed(rpcName, data)
|
|
20
30
|
},
|
|
@@ -28,4 +38,5 @@ wireHTTP({
|
|
|
28
38
|
func: rpcCaller,
|
|
29
39
|
})
|
|
30
40
|
`;
|
|
41
|
+
return { schemas, functions };
|
|
31
42
|
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
export interface RemoteRPCGenOutput {
|
|
2
|
+
schemas: string;
|
|
3
|
+
functions: string;
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* Generate remote internal RPC queue worker and HTTP endpoint
|
|
3
7
|
*/
|
|
4
|
-
export declare const serializeRemoteRPC: (pathToPikkuTypes: string) =>
|
|
8
|
+
export declare const serializeRemoteRPC: (pathToPikkuTypes: string) => RemoteRPCGenOutput;
|