@pikku/core 0.12.80 → 0.12.82
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/CHANGELOG.md +312 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/function/function-runner.js +2 -5
- package/dist/function/index.d.ts +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +3 -3
- package/dist/pikku-state.js +4 -0
- package/dist/services/ai-agent-runner-service.d.ts +7 -0
- package/dist/services/ai-run-state-service.d.ts +10 -0
- package/dist/services/in-memory-ai-run-state-service.d.ts +5 -1
- package/dist/services/in-memory-ai-run-state-service.js +9 -0
- package/dist/services/index.d.ts +15 -15
- package/dist/services/index.js +5 -5
- package/dist/services/scoped-credential-service.d.ts +21 -0
- package/dist/services/scoped-credential-service.js +53 -0
- package/dist/testing/service-tests/ai-storage-service-tests.js +76 -0
- package/dist/types/core.types.d.ts +0 -2
- package/dist/types/state.types.d.ts +13 -0
- package/dist/wirings/actor-flow/index.d.ts +1 -1
- package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +58 -0
- package/dist/wirings/ai-agent/ai-agent-finalize.js +138 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +1 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +2 -8
- package/dist/wirings/ai-agent/ai-agent-memory.js +34 -17
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +44 -1
- package/dist/wirings/ai-agent/ai-agent-prepare.js +2 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +61 -40
- package/dist/wirings/ai-agent/ai-agent-stream.js +89 -36
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +1 -0
- package/dist/wirings/ai-agent/ai-agent-turn.js +1 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +46 -1
- package/dist/wirings/ai-agent/index.d.ts +8 -7
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +26 -0
- package/dist/wirings/ai-scorer/ai-scorer-grade.js +33 -0
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +17 -0
- package/dist/wirings/ai-scorer/ai-scorer-judge.js +92 -0
- package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +15 -0
- package/dist/wirings/ai-scorer/ai-scorer-live.js +38 -0
- package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +18 -0
- package/dist/wirings/ai-scorer/ai-scorer-registry.js +46 -0
- package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +8 -0
- package/dist/wirings/ai-scorer/ai-scorer-sampling.js +31 -0
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +10 -0
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +40 -0
- package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +15 -0
- package/dist/wirings/ai-scorer/ai-scorer-worker.js +58 -0
- package/dist/wirings/ai-scorer/ai-scorer.d.ts +39 -0
- package/dist/wirings/ai-scorer/ai-scorer.js +40 -0
- package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +90 -0
- package/dist/wirings/ai-scorer/ai-scorer.types.js +4 -0
- package/dist/wirings/ai-scorer/index.d.ts +6 -0
- package/dist/wirings/ai-scorer/index.js +5 -0
- package/dist/wirings/channel/index.d.ts +5 -6
- package/dist/wirings/channel/index.js +3 -4
- package/dist/wirings/channel/local/local-channel-runner.js +8 -1
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +9 -1
- package/dist/wirings/cli/channel/index.d.ts +1 -2
- package/dist/wirings/cli/channel/index.js +0 -1
- package/dist/wirings/cli/cli-runner.js +13 -1
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/gateway/index.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +8 -2
- package/dist/wirings/http/index.d.ts +1 -2
- package/dist/wirings/mcp/index.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +15 -0
- package/dist/wirings/mcp/mcp-runner.js +18 -5
- package/dist/wirings/persona/index.d.ts +3 -4
- package/dist/wirings/persona/index.js +2 -3
- package/dist/wirings/queue/index.d.ts +1 -3
- package/dist/wirings/queue/index.js +1 -3
- package/dist/wirings/rpc/addon-runner.d.ts +4 -0
- package/dist/wirings/rpc/addon-runner.js +19 -3
- package/dist/wirings/rpc/rpc-runner.js +2 -0
- package/dist/wirings/rpc/rpc-types.d.ts +4 -0
- package/dist/wirings/rpc/wire-addon.d.ts +13 -0
- package/dist/wirings/rpc/wire-addon.js +4 -0
- package/dist/wirings/scheduler/index.d.ts +1 -1
- package/dist/wirings/trigger/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.d.ts +5 -6
- package/dist/wirings/virtual-user/index.js +2 -4
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +85 -15
- package/dist/wirings/workflow/index.d.ts +6 -6
- package/dist/wirings/workflow/index.js +2 -2
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +7 -7
- package/dist/wirings/workflow/pikku-scenario-service.js +39 -13
- package/dist/wirings/workflow/pikku-workflow-service.js +17 -3
- package/dist/wirings/workflow/scenario-step.types.d.ts +8 -0
- package/dist/wirings/workflow/workflow-approval-audit.d.ts +16 -0
- package/dist/wirings/workflow/workflow-approval-audit.js +40 -0
- package/dist/wirings/workflow/workflow-approval-policy.d.ts +20 -0
- package/dist/wirings/workflow/workflow-approval-policy.js +48 -0
- package/dist/wirings/workflow/workflow-approval.d.ts +29 -1
- package/dist/wirings/workflow/workflow-approval.js +65 -2
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +2 -1
- package/dist/wirings/workflow/workflow-run-ownership.js +2 -1
- package/dist/wirings/workflow/workflow.types.d.ts +1 -1
- package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +32 -0
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +39 -0
- package/knowledge/decisions/internals/index.md +30 -3
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +115 -0
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +37 -0
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +30 -14
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +59 -0
- package/knowledge/decisions/security/index.md +3 -1
- package/knowledge/questions/index.md +1 -1
- package/package.json +3 -1
- package/scripts/generate-api-report.mts +143 -18
- package/src/api-report.test.ts +2 -2
- package/src/errors/index.ts +1 -1
- package/src/function/function-runner.test.ts +52 -0
- package/src/function/function-runner.ts +5 -9
- package/src/function/index.ts +0 -2
- package/src/index.ts +0 -35
- package/src/pikku-state.ts +5 -0
- package/src/public-surface.json +70 -94
- package/src/services/ai-agent-runner-service.ts +12 -1
- package/src/services/ai-run-state-service.ts +11 -0
- package/src/services/in-memory-ai-run-state-service.ts +13 -0
- package/src/services/index.ts +3 -43
- package/src/services/scoped-credential-service.test.ts +86 -0
- package/src/services/scoped-credential-service.ts +63 -0
- package/src/testing/service-tests/ai-storage-service-tests.ts +93 -0
- package/src/types/core.types.ts +3 -6
- package/src/types/state.types.ts +16 -0
- package/src/wirings/actor-flow/index.ts +0 -3
- package/src/wirings/ai-agent/ai-agent-finalize.test.ts +186 -0
- package/src/wirings/ai-agent/ai-agent-finalize.ts +197 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +1 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +54 -38
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +72 -3
- package/src/wirings/ai-agent/ai-agent-model-config.ts +49 -1
- package/src/wirings/ai-agent/ai-agent-prepare.ts +2 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +71 -40
- package/src/wirings/ai-agent/ai-agent-stream-output-hooks.test.ts +353 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +116 -54
- package/src/wirings/ai-agent/ai-agent-turn.test.ts +67 -0
- package/src/wirings/ai-agent/ai-agent-turn.ts +1 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +64 -4
- package/src/wirings/ai-agent/index.ts +2 -16
- package/src/wirings/ai-scorer/ai-scorer-grade.test.ts +106 -0
- package/src/wirings/ai-scorer/ai-scorer-grade.ts +55 -0
- package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +143 -0
- package/src/wirings/ai-scorer/ai-scorer-judge.ts +120 -0
- package/src/wirings/ai-scorer/ai-scorer-live.test.ts +174 -0
- package/src/wirings/ai-scorer/ai-scorer-live.ts +56 -0
- package/src/wirings/ai-scorer/ai-scorer-registry.ts +63 -0
- package/src/wirings/ai-scorer/ai-scorer-sampling.test.ts +34 -0
- package/src/wirings/ai-scorer/ai-scorer-sampling.ts +36 -0
- package/src/wirings/ai-scorer/ai-scorer-snapshots.test.ts +49 -0
- package/src/wirings/ai-scorer/ai-scorer-snapshots.ts +46 -0
- package/src/wirings/ai-scorer/ai-scorer-worker.test.ts +122 -0
- package/src/wirings/ai-scorer/ai-scorer-worker.ts +69 -0
- package/src/wirings/ai-scorer/ai-scorer.ts +76 -0
- package/src/wirings/ai-scorer/ai-scorer.types.ts +107 -0
- package/src/wirings/ai-scorer/index.ts +24 -0
- package/src/wirings/channel/index.ts +1 -20
- package/src/wirings/channel/local/local-channel-runner.test.ts +68 -0
- package/src/wirings/channel/local/local-channel-runner.ts +8 -1
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +23 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +12 -1
- package/src/wirings/cli/channel/index.ts +0 -7
- package/src/wirings/cli/cli-runner.test.ts +68 -0
- package/src/wirings/cli/cli-runner.ts +18 -1
- package/src/wirings/credential/index.ts +0 -1
- package/src/wirings/gateway/index.ts +0 -3
- package/src/wirings/http/http-runner.test.ts +66 -0
- package/src/wirings/http/http-runner.ts +10 -2
- package/src/wirings/http/index.ts +1 -1
- package/src/wirings/mcp/index.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +181 -0
- package/src/wirings/mcp/mcp-runner.ts +35 -5
- package/src/wirings/persona/index.ts +0 -8
- package/src/wirings/queue/index.ts +0 -14
- package/src/wirings/rpc/addon-runner.ts +34 -3
- package/src/wirings/rpc/addon-secrets.test.ts +261 -0
- package/src/wirings/rpc/rpc-runner.test.ts +2 -0
- package/src/wirings/rpc/rpc-runner.ts +2 -0
- package/src/wirings/rpc/rpc-types.ts +4 -0
- package/src/wirings/rpc/wire-addon.ts +17 -0
- package/src/wirings/scheduler/index.ts +0 -1
- package/src/wirings/trigger/index.ts +0 -1
- package/src/wirings/virtual-user/index.ts +0 -16
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +96 -16
- package/src/wirings/workflow/graph/graph-runner.test.ts +72 -0
- package/src/wirings/workflow/index.ts +2 -20
- package/src/wirings/workflow/pikku-scenario-service.ts +60 -15
- package/src/wirings/workflow/pikku-workflow-service.test.ts +13 -12
- package/src/wirings/workflow/pikku-workflow-service.ts +28 -4
- package/src/wirings/workflow/scenario-expectations.test.ts +75 -0
- package/src/wirings/workflow/scenario-hooks.test.ts +3 -2
- package/src/wirings/workflow/scenario-step.types.ts +8 -0
- package/src/wirings/workflow/workflow-approval-audit.ts +47 -0
- package/src/wirings/workflow/workflow-approval-policy.test.ts +524 -0
- package/src/wirings/workflow/workflow-approval-policy.ts +68 -0
- package/src/wirings/workflow/workflow-approval.ts +113 -9
- package/src/wirings/workflow/workflow-run-authority.test.ts +12 -15
- package/src/wirings/workflow/workflow-run-ownership.ts +2 -1
- package/src/wirings/workflow/workflow.types.ts +0 -9
- package/src/wirings-stay-decoupled.test.ts +6 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/internal.d.ts +0 -3
- package/dist/internal.js +0 -2
- package/dist/middleware/timeout.d.ts +0 -9
- package/dist/middleware/timeout.js +0 -15
- package/dist/pikku-response.d.ts +0 -6
- package/dist/pikku-response.js +0 -6
- package/dist/services/gopass-secrets.d.ts +0 -15
- package/dist/services/gopass-secrets.js +0 -76
- package/dist/services/http-scenario-actors.d.ts +0 -75
- package/dist/services/http-scenario-actors.js +0 -195
- package/dist/services/http-user-flow-actors.d.ts +0 -67
- package/dist/services/http-user-flow-actors.js +0 -193
- package/dist/services/scenario-actors-service.d.ts +0 -127
- package/dist/services/scenario-actors-service.js +0 -40
- package/dist/services/user-flow-actors-service.d.ts +0 -39
- package/dist/services/user-flow-actors-service.js +0 -1
- package/dist/wirings/credential/wire-credential.d.ts +0 -48
- package/dist/wirings/credential/wire-credential.js +0 -47
- package/dist/wirings/oauth2/oauth2-client.d.ts +0 -47
- package/dist/wirings/oauth2/oauth2-client.js +0 -263
- package/dist/wirings/oauth2/oauth2-routes.d.ts +0 -35
- package/dist/wirings/oauth2/oauth2-routes.js +0 -146
- package/dist/wirings/scope/wire-scope.d.ts +0 -33
- package/dist/wirings/scope/wire-scope.js +0 -32
- package/dist/wirings/workflow/dsl/index.d.ts +0 -5
- package/dist/wirings/workflow/dsl/index.js +0 -4
- package/dist/wirings/workflow/graph/index.d.ts +0 -5
- package/dist/wirings/workflow/graph/index.js +0 -4
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
* disagree — so a member-level change is a reviewable diff rather than a
|
|
17
17
|
* surprise in someone else's CI.
|
|
18
18
|
*
|
|
19
|
+
* A member per line, and no member bodies. Both are load-bearing rather than
|
|
20
|
+
* cosmetic: the report exists to be diffed, and a class emitted as one long
|
|
21
|
+
* line of its own source is neither reviewable nor mergeable.
|
|
22
|
+
*
|
|
19
23
|
* Run: yarn api-report
|
|
20
24
|
*/
|
|
21
25
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
@@ -50,7 +54,132 @@ const program = ts.createProgram(
|
|
|
50
54
|
)
|
|
51
55
|
const checker = program.getTypeChecker()
|
|
52
56
|
|
|
53
|
-
/**
|
|
57
|
+
/** Comments are noise in a report the diff is read for. */
|
|
58
|
+
const stripComments = (text: string): string =>
|
|
59
|
+
text.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/[^\n]*/g, '')
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Punctuation that makes a line and its successor one thing.
|
|
63
|
+
*
|
|
64
|
+
* Read from both ends rather than one, because the closers are ambiguous from
|
|
65
|
+
* behind: `string[]`, `Promise<T>` and `= {}` all end in a closing bracket and
|
|
66
|
+
* none of them is a continuation. What the *next* line starts with is not.
|
|
67
|
+
*/
|
|
68
|
+
const CONTINUES = /(=>|[,;{([<|&=])$/
|
|
69
|
+
const CLOSES = /^(=>|extends\b|[}\])>,;|&])/
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A member's own text on one line — long, but never long enough to matter.
|
|
73
|
+
*
|
|
74
|
+
* Inside an object type the author's newline *was* the separator, so collapsing
|
|
75
|
+
* without restoring it produces `{ a: string b: number }`, which is not the
|
|
76
|
+
* type it describes and does not parse in the ```ts fence it is printed into.
|
|
77
|
+
*/
|
|
78
|
+
const oneLine = (text: string): string => {
|
|
79
|
+
const lines = stripComments(text)
|
|
80
|
+
.split('\n')
|
|
81
|
+
.map((l) => l.trim())
|
|
82
|
+
.filter(Boolean)
|
|
83
|
+
let depth = 0
|
|
84
|
+
const joined = lines
|
|
85
|
+
.map((line, index) => {
|
|
86
|
+
const inObjectType = depth > 0
|
|
87
|
+
for (const character of line) {
|
|
88
|
+
if (character === '{') depth++
|
|
89
|
+
else if (character === '}') depth--
|
|
90
|
+
}
|
|
91
|
+
const next = lines[index + 1]
|
|
92
|
+
return inObjectType &&
|
|
93
|
+
next !== undefined &&
|
|
94
|
+
!CONTINUES.test(line) &&
|
|
95
|
+
!CLOSES.test(next)
|
|
96
|
+
? `${line};`
|
|
97
|
+
: line
|
|
98
|
+
})
|
|
99
|
+
.join(' ')
|
|
100
|
+
return joined.replace(/\(\s+/g, '(').replace(/\s+\)/g, ')')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* A class member as a consumer sees it: the signature, and nothing after it.
|
|
105
|
+
*
|
|
106
|
+
* The body is where every character of this report used to come from — a class
|
|
107
|
+
* arrived as its own source, so the report promised implementation details and
|
|
108
|
+
* a one-word change to a method rewrote the whole declaration. Truncating at
|
|
109
|
+
* the body leaves exactly the part a compatibility promise covers.
|
|
110
|
+
*/
|
|
111
|
+
const memberSignature = (member: ts.ClassElement | ts.TypeElement): string => {
|
|
112
|
+
const source = member.getSourceFile().text
|
|
113
|
+
const start = member.getStart()
|
|
114
|
+
|
|
115
|
+
const body = (member as { body?: ts.Node }).body
|
|
116
|
+
if (body) {
|
|
117
|
+
const head = oneLine(source.slice(start, body.getStart())).replace(
|
|
118
|
+
/\s*$/,
|
|
119
|
+
''
|
|
120
|
+
)
|
|
121
|
+
// An inferred return type is still a return type a consumer depends on, and
|
|
122
|
+
// truncating at the body is what threw the author's away.
|
|
123
|
+
if (ts.isMethodDeclaration(member) || ts.isGetAccessorDeclaration(member)) {
|
|
124
|
+
const signature = member.type
|
|
125
|
+
? undefined
|
|
126
|
+
: checker.getSignatureFromDeclaration(member)
|
|
127
|
+
if (signature) {
|
|
128
|
+
const returns = checker.getReturnTypeOfSignature(signature)
|
|
129
|
+
return `${head}: ${checker.typeToString(returns, undefined, ts.TypeFormatFlags.NoTruncation)}`
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return head
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// A property's initializer is a body by another name. Its annotation stands in
|
|
136
|
+
// for it, and the checker supplies one when the author left it inferred.
|
|
137
|
+
if (ts.isPropertyDeclaration(member) && member.initializer) {
|
|
138
|
+
if (member.type) return oneLine(source.slice(start, member.type.end))
|
|
139
|
+
const type = checker.getTypeAtLocation(member)
|
|
140
|
+
return `${oneLine(source.slice(start, member.name.end))}: ${checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation)}`
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return oneLine(member.getText())
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Members a consumer can reach, so a private field is not a promise. */
|
|
147
|
+
const isPublic = (member: ts.ClassElement | ts.TypeElement): boolean =>
|
|
148
|
+
!(ts.getModifiers(member as ts.HasModifiers) ?? []).some(
|
|
149
|
+
(modifier) => modifier.kind === ts.SyntaxKind.PrivateKeyword
|
|
150
|
+
) && !(member.name && ts.isPrivateIdentifier(member.name))
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A declaration with members, one member per line.
|
|
154
|
+
*
|
|
155
|
+
* The line break is the point. Two branches that touch different methods of the
|
|
156
|
+
* same class are a textual conflict when the class is one line and an ordinary
|
|
157
|
+
* merge when it is not, which is a tax the whole repo was paying: every rebase
|
|
158
|
+
* over this file stopped to re-resolve a forty-thousand-character line by hand.
|
|
159
|
+
*/
|
|
160
|
+
const membered = (
|
|
161
|
+
declaration:
|
|
162
|
+
| ts.ClassDeclaration
|
|
163
|
+
| ts.InterfaceDeclaration
|
|
164
|
+
| ts.EnumDeclaration,
|
|
165
|
+
members: ts.NodeArray<ts.ClassElement | ts.TypeElement | ts.EnumMember>
|
|
166
|
+
): string => {
|
|
167
|
+
if (members.length === 0) return oneLine(declaration.getText())
|
|
168
|
+
const source = declaration.getSourceFile().text
|
|
169
|
+
// `members.pos` is the offset just past the `{`, so the header comes with its
|
|
170
|
+
// own brace and needs no reassembling.
|
|
171
|
+
const header = oneLine(source.slice(declaration.getStart(), members.pos))
|
|
172
|
+
const lines = ts.isEnumDeclaration(declaration)
|
|
173
|
+
? (members as readonly ts.EnumMember[]).map(
|
|
174
|
+
(member) => `${oneLine(member.getText())},`
|
|
175
|
+
)
|
|
176
|
+
: (members as readonly (ts.ClassElement | ts.TypeElement)[])
|
|
177
|
+
.filter(isPublic)
|
|
178
|
+
.map(memberSignature)
|
|
179
|
+
return [header, ...lines.map((line) => ` ${line}`), '}'].join('\n')
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** How a symbol is declared, in as many lines as its members need. */
|
|
54
183
|
const signature = (exported: ts.Symbol): string => {
|
|
55
184
|
// A re-export is an alias; the declaration that matters is the target's, so
|
|
56
185
|
// an interface re-exported through a barrel still reports its members.
|
|
@@ -62,20 +191,21 @@ const signature = (exported: ts.Symbol): string => {
|
|
|
62
191
|
if (!declaration) return exported.getName()
|
|
63
192
|
|
|
64
193
|
if (
|
|
65
|
-
ts.isInterfaceDeclaration(declaration) ||
|
|
66
194
|
ts.isClassDeclaration(declaration) ||
|
|
67
|
-
ts.
|
|
195
|
+
ts.isInterfaceDeclaration(declaration) ||
|
|
68
196
|
ts.isEnumDeclaration(declaration)
|
|
69
197
|
) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
198
|
+
return membered(declaration, declaration.members)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (ts.isTypeAliasDeclaration(declaration)) {
|
|
202
|
+
// No members to walk, so the author's own line breaks are the ones that
|
|
203
|
+
// keep a long union reviewable.
|
|
204
|
+
return stripComments(declaration.getText())
|
|
75
205
|
.split('\n')
|
|
76
|
-
.map((l) => l.
|
|
77
|
-
.filter(
|
|
78
|
-
.join('
|
|
206
|
+
.map((l) => l.trimEnd())
|
|
207
|
+
.filter((l) => l.trim())
|
|
208
|
+
.join('\n')
|
|
79
209
|
}
|
|
80
210
|
|
|
81
211
|
const type = checker.getTypeOfSymbolAtLocation(symbol, declaration)
|
|
@@ -92,17 +222,12 @@ const ECOSYSTEM_SUBPATHS = new Set(['./ecosystem', './internal'])
|
|
|
92
222
|
|
|
93
223
|
type Exported = { name: string; members: number; signature: string }
|
|
94
224
|
|
|
95
|
-
/**
|
|
225
|
+
/** The members the report lists, which is what the tally is counting. */
|
|
96
226
|
const memberCount = (declaration: ts.Declaration): number => {
|
|
97
227
|
if (ts.isInterfaceDeclaration(declaration)) return declaration.members.length
|
|
98
228
|
if (ts.isEnumDeclaration(declaration)) return declaration.members.length
|
|
99
229
|
if (!ts.isClassDeclaration(declaration)) return 0
|
|
100
|
-
return declaration.members.filter(
|
|
101
|
-
(member) =>
|
|
102
|
-
!(ts.getModifiers(member) ?? []).some(
|
|
103
|
-
(modifier) => modifier.kind === ts.SyntaxKind.PrivateKeyword
|
|
104
|
-
) && !(member.name && ts.isPrivateIdentifier(member.name))
|
|
105
|
-
).length
|
|
230
|
+
return declaration.members.filter(isPublic).length
|
|
106
231
|
}
|
|
107
232
|
|
|
108
233
|
const modules = new Map<string, Exported[]>()
|
package/src/api-report.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, test } from 'node:test'
|
|
2
2
|
import assert from 'node:assert/strict'
|
|
3
3
|
import { execFileSync } from 'node:child_process'
|
|
4
|
-
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
6
|
import { join, dirname } from 'node:path'
|
|
7
7
|
|
|
@@ -39,7 +39,7 @@ describe('the API report matches the code', () => {
|
|
|
39
39
|
const firstDiff = regeneratedLines.findIndex(
|
|
40
40
|
(line, i) => line !== committedLines[i]
|
|
41
41
|
)
|
|
42
|
-
|
|
42
|
+
writeFileSync(reportPath, committed)
|
|
43
43
|
|
|
44
44
|
assert.fail(
|
|
45
45
|
'the public API changed but api-report.md was not regenerated.\n' +
|
package/src/errors/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './errors.js'
|
|
2
|
-
export { PikkuError, addError
|
|
2
|
+
export { PikkuError, addError } from './error-handler.js'
|
|
@@ -14,6 +14,7 @@ import type { CorePermissionGroup } from './functions.types.js'
|
|
|
14
14
|
import { PikkuSessionService } from '../services/user-session-service.js'
|
|
15
15
|
import { MissingScopeError, ReadonlySessionError } from '../errors/errors.js'
|
|
16
16
|
import { createInvocationAudit } from '../services/audit-service.js'
|
|
17
|
+
import { SecretAccessDeniedError } from '../services/secretless.js'
|
|
17
18
|
|
|
18
19
|
beforeEach(() => {
|
|
19
20
|
resetPikkuState()
|
|
@@ -1563,3 +1564,54 @@ describe('runPikkuFunc - scopes', () => {
|
|
|
1563
1564
|
})
|
|
1564
1565
|
})
|
|
1565
1566
|
})
|
|
1567
|
+
|
|
1568
|
+
describe('runPikkuFunc - secrets', () => {
|
|
1569
|
+
const singletonServicesWithSecrets = {
|
|
1570
|
+
...mockSingletonServices,
|
|
1571
|
+
secrets: { getSecret: async () => 'super-secret' },
|
|
1572
|
+
} as any
|
|
1573
|
+
|
|
1574
|
+
const addSecretReadingFunction = (
|
|
1575
|
+
funcName: string,
|
|
1576
|
+
seen: { error?: unknown }
|
|
1577
|
+
) => {
|
|
1578
|
+
addTestFunction(funcName, {
|
|
1579
|
+
func: async (services: any) => {
|
|
1580
|
+
try {
|
|
1581
|
+
return services.secrets
|
|
1582
|
+
} catch (error) {
|
|
1583
|
+
seen.error = error
|
|
1584
|
+
return 'denied'
|
|
1585
|
+
}
|
|
1586
|
+
},
|
|
1587
|
+
})
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
const run = (funcName: string) =>
|
|
1591
|
+
runPikkuFunc('rpc', Math.random().toString(), funcName, {
|
|
1592
|
+
singletonServices: singletonServicesWithSecrets,
|
|
1593
|
+
getAllServices: () => singletonServicesWithSecrets,
|
|
1594
|
+
data: () => ({}),
|
|
1595
|
+
auth: false,
|
|
1596
|
+
wire: {},
|
|
1597
|
+
})
|
|
1598
|
+
|
|
1599
|
+
test('a function never receives the secrets service', async () => {
|
|
1600
|
+
const seen: { error?: unknown } = {}
|
|
1601
|
+
addSecretReadingFunction('readsSecrets', seen)
|
|
1602
|
+
|
|
1603
|
+
assert.equal(await run('readsSecrets'), 'denied')
|
|
1604
|
+
assert.ok(seen.error instanceof SecretAccessDeniedError)
|
|
1605
|
+
})
|
|
1606
|
+
|
|
1607
|
+
test('no metadata flag can restore the secrets service', async () => {
|
|
1608
|
+
const seen: { error?: unknown } = {}
|
|
1609
|
+
addSecretReadingFunction('claimsAnExemption', seen)
|
|
1610
|
+
Object.assign(pikkuState(null, 'function', 'meta')['claimsAnExemption']!, {
|
|
1611
|
+
secretBroker: true,
|
|
1612
|
+
})
|
|
1613
|
+
|
|
1614
|
+
assert.equal(await run('claimsAnExemption'), 'denied')
|
|
1615
|
+
assert.ok(seen.error instanceof SecretAccessDeniedError)
|
|
1616
|
+
})
|
|
1617
|
+
})
|
|
@@ -177,8 +177,6 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
177
177
|
|
|
178
178
|
const resolvedFunctionId = funcMeta.pikkuFuncId ?? funcName
|
|
179
179
|
|
|
180
|
-
const keepsSecrets = funcMeta.secretBroker === true
|
|
181
|
-
|
|
182
180
|
const resolvedSingletonServices = packageName
|
|
183
181
|
? await getOrCreatePackageSingletonServices(
|
|
184
182
|
packageName,
|
|
@@ -363,12 +361,10 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
363
361
|
|
|
364
362
|
await runPermissions({
|
|
365
363
|
funcPermissions: funcConfig.permissions,
|
|
366
|
-
services:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
'a permission'
|
|
371
|
-
) as CoreSingletonServices),
|
|
364
|
+
services: withoutSecrets(
|
|
365
|
+
resolvedSingletonServices,
|
|
366
|
+
'a permission'
|
|
367
|
+
) as CoreSingletonServices,
|
|
372
368
|
// knowledge: decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md
|
|
373
369
|
wire: invocationWire as PermissionWire,
|
|
374
370
|
data: actualData,
|
|
@@ -420,7 +416,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
420
416
|
enumerable: true,
|
|
421
417
|
})
|
|
422
418
|
return await funcConfig.func(
|
|
423
|
-
|
|
419
|
+
withoutSecrets(services, 'a pikku function'),
|
|
424
420
|
actualData,
|
|
425
421
|
invocationWire
|
|
426
422
|
)
|
package/src/function/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,12 +17,10 @@ export type {
|
|
|
17
17
|
CreateConfig,
|
|
18
18
|
ServerLifecycle,
|
|
19
19
|
FunctionMeta,
|
|
20
|
-
FunctionRuntimeMeta,
|
|
21
20
|
FunctionServicesMeta,
|
|
22
21
|
FunctionWiresMeta,
|
|
23
22
|
FunctionsMeta,
|
|
24
23
|
FunctionsRuntimeMeta,
|
|
25
|
-
JSONPrimitive,
|
|
26
24
|
JSONValue,
|
|
27
25
|
MakeRequired,
|
|
28
26
|
MiddlewareMetadata,
|
|
@@ -43,7 +41,6 @@ export type {
|
|
|
43
41
|
SecuritySeverity,
|
|
44
42
|
SecurityUpdateLevel,
|
|
45
43
|
SerializedError,
|
|
46
|
-
WireServices,
|
|
47
44
|
} from './types/core.types.js'
|
|
48
45
|
export {
|
|
49
46
|
pikkuAIMiddleware,
|
|
@@ -57,7 +54,6 @@ export type {
|
|
|
57
54
|
CorePikkuAuthConfig,
|
|
58
55
|
CorePikkuFunction,
|
|
59
56
|
CorePikkuFunctionConfig,
|
|
60
|
-
CorePikkuFunctionHook,
|
|
61
57
|
CorePikkuPermission,
|
|
62
58
|
CorePikkuPermissionConfig,
|
|
63
59
|
CorePikkuPermissionFactory,
|
|
@@ -75,8 +71,6 @@ export type {
|
|
|
75
71
|
ListInput,
|
|
76
72
|
ListOutput,
|
|
77
73
|
Filter,
|
|
78
|
-
LeafFilter,
|
|
79
|
-
LeafValue,
|
|
80
74
|
} from './function/list.types.js'
|
|
81
75
|
export { pikkuCLIRender } from './wirings/cli/cli-runner.js'
|
|
82
76
|
export { PikkuRequest } from './pikku-request.js'
|
|
@@ -92,9 +86,6 @@ export {
|
|
|
92
86
|
} from './version.js'
|
|
93
87
|
export {
|
|
94
88
|
AbandonedError,
|
|
95
|
-
beginChanges,
|
|
96
|
-
getAbortScope,
|
|
97
|
-
runInAbortScope,
|
|
98
89
|
type AbortScope,
|
|
99
90
|
} from './function/abort-scope.js'
|
|
100
91
|
export { fetch } from './wirings/http/http-runner.js'
|
|
@@ -152,7 +143,6 @@ export type { QueueService } from './wirings/queue/queue.types.js'
|
|
|
152
143
|
export type { JWTService } from './services/jwt-service.js'
|
|
153
144
|
export type {
|
|
154
145
|
EmailService,
|
|
155
|
-
EmailTemplateReference,
|
|
156
146
|
SendEmailInput,
|
|
157
147
|
SendEmailResult,
|
|
158
148
|
SendHTMLEmailInput,
|
|
@@ -188,8 +178,6 @@ export type { SessionService } from './services/user-session-service.js'
|
|
|
188
178
|
export {
|
|
189
179
|
NoopAuditService,
|
|
190
180
|
createInvocationAudit,
|
|
191
|
-
resolveAuditConfig,
|
|
192
|
-
resolveAuditUserIdentityFromWire,
|
|
193
181
|
} from './services/audit-service.js'
|
|
194
182
|
export type {
|
|
195
183
|
AuditConfig,
|
|
@@ -198,31 +186,14 @@ export type {
|
|
|
198
186
|
AuditEventBatch,
|
|
199
187
|
AuditFacets,
|
|
200
188
|
AuditLog,
|
|
201
|
-
AuditLogWriteInput,
|
|
202
|
-
AuditOutcome,
|
|
203
189
|
AuditQuery,
|
|
204
190
|
AuditQueryResult,
|
|
205
191
|
AuditService,
|
|
206
|
-
AuditSource,
|
|
207
192
|
AuditUserIdentity,
|
|
208
193
|
ResolvedAuditConfig,
|
|
209
194
|
} from './services/audit-service.js'
|
|
210
195
|
export type {
|
|
211
196
|
AIAgentRunnerService,
|
|
212
|
-
AIEmbedManyParams,
|
|
213
|
-
AIEmbedManyResult,
|
|
214
|
-
AIEmbedParams,
|
|
215
|
-
AIEmbedResult,
|
|
216
|
-
AIGenerateImageParams,
|
|
217
|
-
AIGenerateImagePrompt,
|
|
218
|
-
AIGenerateImageResult,
|
|
219
|
-
AIGenerateSpeechParams,
|
|
220
|
-
AIGenerateSpeechResult,
|
|
221
|
-
AIProviderOptions,
|
|
222
|
-
AIRerankParams,
|
|
223
|
-
AIRerankResult,
|
|
224
|
-
AITranscriptionParams,
|
|
225
|
-
AITranscriptionResult,
|
|
226
197
|
} from './services/ai-agent-runner-service.js'
|
|
227
198
|
export type { AIEmbeddingService } from './services/ai-embedding-service.js'
|
|
228
199
|
export type { AIRunStateService } from './services/ai-run-state-service.js'
|
|
@@ -230,8 +201,6 @@ export type { AIStorageService } from './services/ai-storage-service.js'
|
|
|
230
201
|
export type {
|
|
231
202
|
EmailsMeta,
|
|
232
203
|
EmailTemplateMeta,
|
|
233
|
-
EmailTemplateLocaleMeta,
|
|
234
|
-
EmailTemplateAssets,
|
|
235
204
|
MetaService,
|
|
236
205
|
} from './services/meta-service.js'
|
|
237
206
|
export type { HTTPMethod } from './wirings/http/http.types.js'
|
|
@@ -266,7 +235,6 @@ export type {
|
|
|
266
235
|
Secret,
|
|
267
236
|
Classification,
|
|
268
237
|
AnonymizeStrategy,
|
|
269
|
-
ColumnClassification,
|
|
270
238
|
ClassificationManifest,
|
|
271
239
|
ColumnForm,
|
|
272
240
|
WrappedValue,
|
|
@@ -276,9 +244,6 @@ export type {
|
|
|
276
244
|
|
|
277
245
|
export {
|
|
278
246
|
hashToken,
|
|
279
|
-
unsafeAsWrapped,
|
|
280
|
-
unsafeAsSealed,
|
|
281
|
-
unsafeAsHashed,
|
|
282
247
|
} from './column-form.js'
|
|
283
248
|
|
|
284
249
|
export type { SecretValue, Safe } from './secret-value.js'
|
package/src/pikku-state.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
MCPPromptMeta,
|
|
11
11
|
} from './wirings/mcp/mcp.types.js'
|
|
12
12
|
import type { AIAgentMeta } from './wirings/ai-agent/ai-agent.types.js'
|
|
13
|
+
import type { ScorerMeta } from './wirings/ai-scorer/ai-scorer.types.js'
|
|
13
14
|
import type { GatewaysMeta } from './wirings/gateway/gateway.types.js'
|
|
14
15
|
import type { ScheduledTasksMeta } from './wirings/scheduler/scheduler.types.js'
|
|
15
16
|
import type { TriggerMeta } from './wirings/trigger/trigger.types.js'
|
|
@@ -118,6 +119,9 @@ const createEmptyPackageState = (): PikkuPackageState => ({
|
|
|
118
119
|
agent: {
|
|
119
120
|
agents: new Map(),
|
|
120
121
|
agentsMeta: {} as AIAgentMeta,
|
|
122
|
+
scorers: new Map(),
|
|
123
|
+
scorersMeta: {} as ScorerMeta,
|
|
124
|
+
modelAliases: {},
|
|
121
125
|
},
|
|
122
126
|
gateway: {
|
|
123
127
|
gateways: new Map(),
|
|
@@ -151,6 +155,7 @@ const createEmptyPackageState = (): PikkuPackageState => ({
|
|
|
151
155
|
authFactory: null,
|
|
152
156
|
credentialsMeta: null,
|
|
153
157
|
requiredParentServices: null,
|
|
158
|
+
declaredSecrets: null,
|
|
154
159
|
},
|
|
155
160
|
})
|
|
156
161
|
|