@turingpulse/sdk 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +38 -0
- package/.github/workflows/ci.yml +246 -0
- package/.github/workflows/framework-compat.yml +169 -0
- package/.github/workflows/security.yml +336 -0
- package/CHANGELOG.md +29 -0
- package/LICENSE +13 -0
- package/MIGRATION.md +30 -0
- package/README.md +221 -0
- package/dist/attachments.d.ts +28 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +59 -0
- package/dist/attachments.js.map +1 -0
- package/dist/config.d.ts +72 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +126 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +163 -0
- package/dist/context.js.map +1 -0
- package/dist/decorators.d.ts +6 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +52 -0
- package/dist/decorators.js.map +1 -0
- package/dist/deploy.d.ts +89 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +203 -0
- package/dist/deploy.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +34 -0
- package/dist/errors.js.map +1 -0
- package/dist/eventBuilder.d.ts +21 -0
- package/dist/eventBuilder.d.ts.map +1 -0
- package/dist/eventBuilder.js +127 -0
- package/dist/eventBuilder.js.map +1 -0
- package/dist/fingerprint.d.ts +158 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +339 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/governance.d.ts +47 -0
- package/dist/governance.d.ts.map +1 -0
- package/dist/governance.js +104 -0
- package/dist/governance.js.map +1 -0
- package/dist/http.d.ts +62 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +181 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.d.ts +40 -0
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/instrumentation.js +31 -0
- package/dist/instrumentation.js.map +1 -0
- package/dist/integrations/mastra.d.ts +64 -0
- package/dist/integrations/mastra.d.ts.map +1 -0
- package/dist/integrations/mastra.js +256 -0
- package/dist/integrations/mastra.js.map +1 -0
- package/dist/kpi.d.ts +21 -0
- package/dist/kpi.d.ts.map +1 -0
- package/dist/kpi.js +83 -0
- package/dist/kpi.js.map +1 -0
- package/dist/llmDetector.d.ts +22 -0
- package/dist/llmDetector.d.ts.map +1 -0
- package/dist/llmDetector.js +269 -0
- package/dist/llmDetector.js.map +1 -0
- package/dist/plugin.d.ts +33 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +312 -0
- package/dist/plugin.js.map +1 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +18 -0
- package/dist/registry.js.map +1 -0
- package/dist/tracing.d.ts +10 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +30 -0
- package/dist/tracing.js.map +1 -0
- package/dist/triggerState.d.ts +5 -0
- package/dist/triggerState.d.ts.map +1 -0
- package/dist/triggerState.js +19 -0
- package/dist/triggerState.js.map +1 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +72 -0
- package/dist/utils.js.map +1 -0
- package/package.json +37 -0
- package/packages/anthropic/package.json +16 -0
- package/packages/anthropic/src/index.ts +5 -0
- package/packages/anthropic/src/wrapper.ts +102 -0
- package/packages/anthropic/tsconfig.build.json +20 -0
- package/packages/langchain/package.json +16 -0
- package/packages/langchain/src/index.ts +7 -0
- package/packages/langchain/src/wrapper.ts +51 -0
- package/packages/mastra/package.json +17 -0
- package/packages/mastra/src/index.ts +8 -0
- package/packages/mastra/src/wrapper.ts +301 -0
- package/packages/openai/package.json +16 -0
- package/packages/openai/src/index.ts +8 -0
- package/packages/openai/src/wrapper.ts +103 -0
- package/packages/openai/tsconfig.build.json +20 -0
- package/packages/openclaw/openclaw.plugin.json +100 -0
- package/packages/openclaw/package.json +41 -0
- package/packages/openclaw/src/buffer.ts +99 -0
- package/packages/openclaw/src/config.ts +139 -0
- package/packages/openclaw/src/hooks/governance.ts +267 -0
- package/packages/openclaw/src/hooks/lifecycle.ts +75 -0
- package/packages/openclaw/src/hooks/telemetry.ts +207 -0
- package/packages/openclaw/src/index.ts +91 -0
- package/packages/openclaw/src/mapper.ts +233 -0
- package/packages/openclaw/src/session-tracker.ts +181 -0
- package/packages/openclaw/src/types.ts +220 -0
- package/packages/openclaw/tests/buffer.test.ts +148 -0
- package/packages/openclaw/tests/config.test.ts +122 -0
- package/packages/openclaw/tests/governance.test.ts +232 -0
- package/packages/openclaw/tests/mapper.test.ts +242 -0
- package/packages/openclaw/tests/session-tracker.test.ts +124 -0
- package/packages/openclaw/tsconfig.json +18 -0
- package/packages/openclaw/vitest.config.ts +8 -0
- package/packages/vercel-ai/package.json +16 -0
- package/packages/vercel-ai/src/index.ts +5 -0
- package/packages/vercel-ai/src/wrapper.ts +49 -0
- package/scripts/bump-version.sh +58 -0
- package/scripts/update-readme-compat.mjs +151 -0
- package/src/__tests__/fingerprint.test.ts +328 -0
- package/src/attachments.ts +88 -0
- package/src/config.ts +164 -0
- package/src/context.ts +258 -0
- package/src/decorators.ts +61 -0
- package/src/deploy.ts +260 -0
- package/src/errors.ts +44 -0
- package/src/eventBuilder.ts +153 -0
- package/src/fingerprint.ts +421 -0
- package/src/governance.ts +156 -0
- package/src/http.ts +241 -0
- package/src/index.ts +57 -0
- package/src/instrumentation.ts +68 -0
- package/src/integrations/mastra.ts +335 -0
- package/src/kpi.ts +112 -0
- package/src/llmDetector.ts +330 -0
- package/src/plugin.ts +384 -0
- package/src/registry.ts +27 -0
- package/src/tracing.ts +39 -0
- package/src/triggerState.ts +27 -0
- package/src/utils.ts +78 -0
- package/tests/compat/anthropic.test.ts +61 -0
- package/tests/compat/cohere.test.ts +57 -0
- package/tests/compat/google-genai.test.ts +61 -0
- package/tests/compat/langchain-openai.test.ts +41 -0
- package/tests/compat/langchain.test.ts +64 -0
- package/tests/compat/mistral.test.ts +58 -0
- package/tests/compat/openai.test.ts +71 -0
- package/tests/compat/vercel-ai.test.ts +56 -0
- package/tests/plugins/anthropic-wrapper.test.ts +120 -0
- package/tests/plugins/langchain-wrapper.test.ts +128 -0
- package/tests/plugins/openai-wrapper.test.ts +165 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Security Scanning Workflow for TypeScript/React Projects
|
|
2
|
+
# Add to: TP-portal, TP-admin-portal, TP-website, TP-sdk-typescript
|
|
3
|
+
name: Security Scan
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main]
|
|
10
|
+
schedule:
|
|
11
|
+
# Run weekly on Monday at 9 AM UTC
|
|
12
|
+
- cron: '0 9 * * 1'
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
security-events: write
|
|
18
|
+
actions: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
# Dependency vulnerability scanning (CVE check)
|
|
22
|
+
dependency-scan:
|
|
23
|
+
name: Dependency CVE Scan
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout code
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Set up Node.js
|
|
30
|
+
uses: actions/setup-node@v4
|
|
31
|
+
with:
|
|
32
|
+
node-version: '20'
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: npm ci --ignore-scripts
|
|
36
|
+
|
|
37
|
+
- name: Run npm audit (CVE scan)
|
|
38
|
+
continue-on-error: true
|
|
39
|
+
run: |
|
|
40
|
+
npm audit --json > npm-audit-report.json || true
|
|
41
|
+
npm audit --audit-level=moderate || true
|
|
42
|
+
|
|
43
|
+
- name: Run Snyk vulnerability scan
|
|
44
|
+
continue-on-error: true
|
|
45
|
+
env:
|
|
46
|
+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
47
|
+
run: |
|
|
48
|
+
if [ -n "$SNYK_TOKEN" ]; then
|
|
49
|
+
npx snyk test --json > snyk-report.json || true
|
|
50
|
+
npx snyk test || true
|
|
51
|
+
else
|
|
52
|
+
echo "SNYK_TOKEN not set, skipping Snyk scan"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
- name: Upload vulnerability reports
|
|
56
|
+
uses: actions/upload-artifact@v4
|
|
57
|
+
if: always()
|
|
58
|
+
with:
|
|
59
|
+
name: dependency-vulnerability-reports
|
|
60
|
+
path: |
|
|
61
|
+
npm-audit-report.json
|
|
62
|
+
snyk-report.json
|
|
63
|
+
retention-days: 30
|
|
64
|
+
|
|
65
|
+
# Static Application Security Testing (SAST)
|
|
66
|
+
sast-scan:
|
|
67
|
+
name: SAST Scan
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
steps:
|
|
70
|
+
- name: Checkout code
|
|
71
|
+
uses: actions/checkout@v4
|
|
72
|
+
|
|
73
|
+
- name: Set up Node.js
|
|
74
|
+
uses: actions/setup-node@v4
|
|
75
|
+
with:
|
|
76
|
+
node-version: '20'
|
|
77
|
+
|
|
78
|
+
- name: Install ESLint security plugins
|
|
79
|
+
run: |
|
|
80
|
+
npm install -g eslint @eslint/js eslint-plugin-security eslint-plugin-no-secrets
|
|
81
|
+
|
|
82
|
+
- name: Run ESLint security scan
|
|
83
|
+
continue-on-error: true
|
|
84
|
+
run: |
|
|
85
|
+
npx eslint . --ext .js,.jsx,.ts,.tsx --format json --output-file eslint-security-report.json \
|
|
86
|
+
--plugin security --plugin no-secrets \
|
|
87
|
+
--rule 'security/detect-object-injection: warn' \
|
|
88
|
+
--rule 'security/detect-non-literal-regexp: warn' \
|
|
89
|
+
--rule 'security/detect-unsafe-regex: warn' \
|
|
90
|
+
--rule 'security/detect-buffer-noassert: warn' \
|
|
91
|
+
--rule 'security/detect-eval-with-expression: error' \
|
|
92
|
+
--rule 'security/detect-no-csrf-before-method-override: warn' \
|
|
93
|
+
--rule 'security/detect-possible-timing-attacks: warn' \
|
|
94
|
+
--rule 'no-secrets/no-secrets: warn' || true
|
|
95
|
+
|
|
96
|
+
- name: Run Semgrep
|
|
97
|
+
continue-on-error: true
|
|
98
|
+
run: |
|
|
99
|
+
pip install semgrep
|
|
100
|
+
semgrep --config=auto --config=p/typescript --json --output=semgrep-report.json . || true
|
|
101
|
+
semgrep --config=auto --config=p/typescript . || true
|
|
102
|
+
|
|
103
|
+
- name: Upload SAST reports
|
|
104
|
+
uses: actions/upload-artifact@v4
|
|
105
|
+
if: always()
|
|
106
|
+
with:
|
|
107
|
+
name: sast-reports
|
|
108
|
+
path: |
|
|
109
|
+
eslint-security-report.json
|
|
110
|
+
semgrep-report.json
|
|
111
|
+
retention-days: 30
|
|
112
|
+
|
|
113
|
+
# Secret scanning
|
|
114
|
+
secret-scan:
|
|
115
|
+
name: Secret Scan
|
|
116
|
+
runs-on: ubuntu-latest
|
|
117
|
+
steps:
|
|
118
|
+
- name: Checkout code
|
|
119
|
+
uses: actions/checkout@v4
|
|
120
|
+
with:
|
|
121
|
+
fetch-depth: 0
|
|
122
|
+
|
|
123
|
+
- name: Run TruffleHog (primary - free)
|
|
124
|
+
id: trufflehog
|
|
125
|
+
run: |
|
|
126
|
+
docker run --rm -v "$PWD:/pwd" trufflesecurity/trufflehog:latest filesystem /pwd --json > trufflehog-report.json 2>&1 || true
|
|
127
|
+
# Check if secrets were found
|
|
128
|
+
if [ -s trufflehog-report.json ]; then
|
|
129
|
+
SECRETS_FOUND=$(cat trufflehog-report.json | grep -c '"SourceMetadata"' || echo "0")
|
|
130
|
+
echo "secrets_found=${SECRETS_FOUND}" >> $GITHUB_OUTPUT
|
|
131
|
+
if [ "$SECRETS_FOUND" -gt 0 ]; then
|
|
132
|
+
echo "::warning::TruffleHog found ${SECRETS_FOUND} potential secrets!"
|
|
133
|
+
cat trufflehog-report.json
|
|
134
|
+
fi
|
|
135
|
+
else
|
|
136
|
+
echo "secrets_found=0" >> $GITHUB_OUTPUT
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
- name: Run Gitleaks (optional - requires license for orgs)
|
|
140
|
+
continue-on-error: true
|
|
141
|
+
uses: gitleaks/gitleaks-action@v2
|
|
142
|
+
env:
|
|
143
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
144
|
+
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
|
|
145
|
+
|
|
146
|
+
- name: Upload secret scan reports
|
|
147
|
+
uses: actions/upload-artifact@v4
|
|
148
|
+
if: always()
|
|
149
|
+
with:
|
|
150
|
+
name: secret-scan-reports
|
|
151
|
+
path: trufflehog-report.json
|
|
152
|
+
retention-days: 30
|
|
153
|
+
if-no-files-found: ignore
|
|
154
|
+
|
|
155
|
+
# Container image scanning (if Dockerfile exists)
|
|
156
|
+
container-scan:
|
|
157
|
+
name: Container CVE Scan
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
steps:
|
|
160
|
+
- name: Checkout code
|
|
161
|
+
uses: actions/checkout@v4
|
|
162
|
+
|
|
163
|
+
- name: Check for Dockerfile
|
|
164
|
+
id: check-dockerfile
|
|
165
|
+
run: |
|
|
166
|
+
if [ -f "Dockerfile" ]; then
|
|
167
|
+
echo "exists=true" >> $GITHUB_OUTPUT
|
|
168
|
+
else
|
|
169
|
+
echo "exists=false" >> $GITHUB_OUTPUT
|
|
170
|
+
echo "No Dockerfile found, skipping container scan"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
- name: Build Docker image
|
|
174
|
+
if: steps.check-dockerfile.outputs.exists == 'true'
|
|
175
|
+
run: docker build -t security-scan:latest .
|
|
176
|
+
|
|
177
|
+
- name: Run Trivy vulnerability scanner
|
|
178
|
+
if: steps.check-dockerfile.outputs.exists == 'true'
|
|
179
|
+
uses: aquasecurity/trivy-action@master
|
|
180
|
+
with:
|
|
181
|
+
image-ref: 'security-scan:latest'
|
|
182
|
+
format: 'sarif'
|
|
183
|
+
output: 'trivy-results.sarif'
|
|
184
|
+
severity: 'CRITICAL,HIGH,MEDIUM'
|
|
185
|
+
|
|
186
|
+
- name: Upload Trivy scan results
|
|
187
|
+
if: steps.check-dockerfile.outputs.exists == 'true'
|
|
188
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
189
|
+
continue-on-error: true # May fail if GitHub Advanced Security not enabled
|
|
190
|
+
with:
|
|
191
|
+
sarif_file: 'trivy-results.sarif'
|
|
192
|
+
|
|
193
|
+
- name: Run Grype scanner
|
|
194
|
+
if: steps.check-dockerfile.outputs.exists == 'true'
|
|
195
|
+
continue-on-error: true
|
|
196
|
+
run: |
|
|
197
|
+
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
|
|
198
|
+
grype security-scan:latest -o json > grype-report.json || true
|
|
199
|
+
|
|
200
|
+
- name: Upload container scan reports
|
|
201
|
+
if: steps.check-dockerfile.outputs.exists == 'true'
|
|
202
|
+
uses: actions/upload-artifact@v4
|
|
203
|
+
with:
|
|
204
|
+
name: container-scan-reports
|
|
205
|
+
path: |
|
|
206
|
+
trivy-results.sarif
|
|
207
|
+
grype-report.json
|
|
208
|
+
retention-days: 30
|
|
209
|
+
|
|
210
|
+
# CodeQL analysis (requires GitHub Advanced Security for private repos)
|
|
211
|
+
codeql-analysis:
|
|
212
|
+
name: CodeQL Analysis
|
|
213
|
+
runs-on: ubuntu-latest
|
|
214
|
+
# Skip if Advanced Security not available
|
|
215
|
+
continue-on-error: true
|
|
216
|
+
steps:
|
|
217
|
+
- name: Checkout repository
|
|
218
|
+
uses: actions/checkout@v4
|
|
219
|
+
|
|
220
|
+
- name: Initialize CodeQL
|
|
221
|
+
uses: github/codeql-action/init@v3
|
|
222
|
+
continue-on-error: true
|
|
223
|
+
with:
|
|
224
|
+
languages: javascript-typescript
|
|
225
|
+
|
|
226
|
+
- name: Autobuild
|
|
227
|
+
uses: github/codeql-action/autobuild@v3
|
|
228
|
+
continue-on-error: true
|
|
229
|
+
|
|
230
|
+
- name: Perform CodeQL Analysis
|
|
231
|
+
uses: github/codeql-action/analyze@v3
|
|
232
|
+
continue-on-error: true
|
|
233
|
+
with:
|
|
234
|
+
category: "/language:javascript-typescript"
|
|
235
|
+
|
|
236
|
+
# License compliance check
|
|
237
|
+
license-scan:
|
|
238
|
+
name: License Compliance
|
|
239
|
+
runs-on: ubuntu-latest
|
|
240
|
+
steps:
|
|
241
|
+
- name: Checkout code
|
|
242
|
+
uses: actions/checkout@v4
|
|
243
|
+
|
|
244
|
+
- name: Set up Node.js
|
|
245
|
+
uses: actions/setup-node@v4
|
|
246
|
+
with:
|
|
247
|
+
node-version: '20'
|
|
248
|
+
|
|
249
|
+
- name: Install dependencies
|
|
250
|
+
run: npm ci --ignore-scripts
|
|
251
|
+
|
|
252
|
+
- name: Run license checker
|
|
253
|
+
continue-on-error: true
|
|
254
|
+
run: |
|
|
255
|
+
npx license-checker --json --out licenses.json || true
|
|
256
|
+
npx license-checker --summary || true
|
|
257
|
+
|
|
258
|
+
- name: Check for problematic licenses
|
|
259
|
+
continue-on-error: true
|
|
260
|
+
run: |
|
|
261
|
+
npx license-checker --failOn 'GPL;AGPL;LGPL;SSPL' || echo "Warning: Found copyleft licenses"
|
|
262
|
+
|
|
263
|
+
- name: Upload license report
|
|
264
|
+
uses: actions/upload-artifact@v4
|
|
265
|
+
if: always()
|
|
266
|
+
with:
|
|
267
|
+
name: license-report
|
|
268
|
+
path: licenses.json
|
|
269
|
+
retention-days: 30
|
|
270
|
+
|
|
271
|
+
# Summary job with email notification
|
|
272
|
+
security-summary:
|
|
273
|
+
name: Security Summary
|
|
274
|
+
runs-on: ubuntu-latest
|
|
275
|
+
needs: [dependency-scan, sast-scan, secret-scan, codeql-analysis, license-scan]
|
|
276
|
+
if: always()
|
|
277
|
+
steps:
|
|
278
|
+
- name: Download all artifacts
|
|
279
|
+
uses: actions/download-artifact@v4
|
|
280
|
+
with:
|
|
281
|
+
merge-multiple: true
|
|
282
|
+
|
|
283
|
+
- name: Generate summary
|
|
284
|
+
id: summary
|
|
285
|
+
run: |
|
|
286
|
+
echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY
|
|
287
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
288
|
+
echo "| Scan Type | Status |" >> $GITHUB_STEP_SUMMARY
|
|
289
|
+
echo "|-----------|--------|" >> $GITHUB_STEP_SUMMARY
|
|
290
|
+
echo "| Dependency CVE | ${{ needs.dependency-scan.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
291
|
+
echo "| SAST | ${{ needs.sast-scan.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
292
|
+
echo "| Secret Scan | ${{ needs.secret-scan.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
293
|
+
echo "| CodeQL | ${{ needs.codeql-analysis.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
294
|
+
echo "| License Check | ${{ needs.license-scan.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
295
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
296
|
+
echo "📊 Check the Security tab for detailed findings." >> $GITHUB_STEP_SUMMARY
|
|
297
|
+
|
|
298
|
+
# Check for failures
|
|
299
|
+
if [[ "${{ needs.dependency-scan.result }}" == "failure" ]] || \
|
|
300
|
+
[[ "${{ needs.sast-scan.result }}" == "failure" ]] || \
|
|
301
|
+
[[ "${{ needs.secret-scan.result }}" == "failure" ]] || \
|
|
302
|
+
[[ "${{ needs.codeql-analysis.result }}" == "failure" ]] || \
|
|
303
|
+
[[ "${{ needs.license-scan.result }}" == "failure" ]]; then
|
|
304
|
+
echo "has_failures=true" >> $GITHUB_OUTPUT
|
|
305
|
+
else
|
|
306
|
+
echo "has_failures=false" >> $GITHUB_OUTPUT
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
- name: Send email notification on critical findings
|
|
310
|
+
if: steps.summary.outputs.has_failures == 'true'
|
|
311
|
+
uses: dawidd6/action-send-mail@v3
|
|
312
|
+
with:
|
|
313
|
+
server_address: smtp.gmail.com
|
|
314
|
+
server_port: 587
|
|
315
|
+
username: ${{ secrets.SMTP_USERNAME }}
|
|
316
|
+
password: ${{ secrets.SMTP_PASSWORD }}
|
|
317
|
+
subject: "🚨 Security Alert: ${{ github.repository }} - Critical Findings Detected"
|
|
318
|
+
to: ${{ secrets.SECURITY_ALERT_EMAIL }}
|
|
319
|
+
from: "TuringPulse Security <security@turingpulse.ai>"
|
|
320
|
+
html_body: |
|
|
321
|
+
<h2>🚨 Security Scan Alert</h2>
|
|
322
|
+
<p><strong>Repository:</strong> ${{ github.repository }}</p>
|
|
323
|
+
<p><strong>Branch:</strong> ${{ github.ref_name }}</p>
|
|
324
|
+
<p><strong>Commit:</strong> ${{ github.sha }}</p>
|
|
325
|
+
<p><strong>Triggered by:</strong> ${{ github.actor }}</p>
|
|
326
|
+
<hr>
|
|
327
|
+
<h3>Scan Results:</h3>
|
|
328
|
+
<ul>
|
|
329
|
+
<li>Dependency CVE: ${{ needs.dependency-scan.result }}</li>
|
|
330
|
+
<li>SAST: ${{ needs.sast-scan.result }}</li>
|
|
331
|
+
<li>Secret Scan: ${{ needs.secret-scan.result }}</li>
|
|
332
|
+
<li>CodeQL: ${{ needs.codeql-analysis.result }}</li>
|
|
333
|
+
<li>License Check: ${{ needs.license-scan.result }}</li>
|
|
334
|
+
</ul>
|
|
335
|
+
<p><a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}">View Full Report</a></p>
|
|
336
|
+
<p><a href="${{ github.server_url }}/${{ github.repository }}/security">View Security Tab</a></p>
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the TuringPulse TypeScript SDK.
|
|
4
|
+
|
|
5
|
+
## [0.2.0] - Unreleased
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `GovernanceBlockedError` and `ConfigurationError` exceptions
|
|
10
|
+
- Pre-execution policy check for HITL governance
|
|
11
|
+
- `hitl` field on `GovernanceDefaults` interface
|
|
12
|
+
- Auto-initialization from `TP_API_KEY` / `TP_WORKFLOW_NAME` env vars
|
|
13
|
+
- New integration packages: LangChain.js, OpenAI, Anthropic, Vercel AI SDK
|
|
14
|
+
- npm workspaces monorepo structure
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `name` in `@instrument()` now takes precedence over `config.workflowName`
|
|
19
|
+
- `context.finish()` sets status to `"blocked"` for `GovernanceBlockedError`
|
|
20
|
+
- `finalize()` skips post-run governance when pre-check already blocked
|
|
21
|
+
- Sync functions return `Promise<T>` when HITL governance is enabled
|
|
22
|
+
|
|
23
|
+
## [0.1.0] - 2025-01-15
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Initial release with core instrumentation, governance, fingerprinting
|
|
28
|
+
- Mastra integration
|
|
29
|
+
- OpenTelemetry tracing support
|
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright (c) 2026 TuringPulse Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
PROPRIETARY AND CONFIDENTIAL
|
|
4
|
+
|
|
5
|
+
This software is proprietary to TuringPulse Inc. Unauthorized copying,
|
|
6
|
+
modification, distribution, or use of this software, in whole or in part,
|
|
7
|
+
is strictly prohibited without a valid license agreement.
|
|
8
|
+
|
|
9
|
+
This software is provided under the terms of a separate license agreement
|
|
10
|
+
between you and TuringPulse Inc. By installing or using this software,
|
|
11
|
+
you agree to be bound by those terms.
|
|
12
|
+
|
|
13
|
+
For licensing inquiries, contact: support@turingpulse.ai
|
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Migration Guide — TypeScript SDK
|
|
2
|
+
|
|
3
|
+
## Migrating to v0.2.0
|
|
4
|
+
|
|
5
|
+
### Governance Changes
|
|
6
|
+
|
|
7
|
+
- New `GovernanceBlockedError` thrown when HITL policy returns `block`
|
|
8
|
+
- `GovernanceDefaults` now supports `hitl: true` for global HITL
|
|
9
|
+
- Pre-execution policy check runs automatically when HITL is enabled
|
|
10
|
+
- Context status is `"blocked"` (not `"error"`) for governance blocks
|
|
11
|
+
|
|
12
|
+
### Important: Sync Function Return Type Change
|
|
13
|
+
|
|
14
|
+
When HITL governance is enabled, **sync functions wrapped with `@instrument`
|
|
15
|
+
will return `Promise<T>` instead of `T`**. This is because the pre-execution
|
|
16
|
+
policy check is async (HTTP call to the backend).
|
|
17
|
+
|
|
18
|
+
If your code relies on synchronous return values, you must either:
|
|
19
|
+
1. Make the calling code async-aware, or
|
|
20
|
+
2. Disable HITL governance for sync-only code paths
|
|
21
|
+
|
|
22
|
+
### Auto-initialization
|
|
23
|
+
|
|
24
|
+
If `TP_API_KEY` and `TP_WORKFLOW_NAME` are set as environment variables,
|
|
25
|
+
the SDK auto-initializes on first use.
|
|
26
|
+
|
|
27
|
+
### workflowName Priority
|
|
28
|
+
|
|
29
|
+
`name` in `@instrument({ name: "..." })` now takes precedence over
|
|
30
|
+
`config.workflowName` set during `init()`.
|
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# TuringPulse TypeScript SDK
|
|
2
|
+
|
|
3
|
+
Decorator-driven instrumentation for Node/TypeScript runtimes. Drop it into any service to publish telemetry to the Agent Observability Service, raise governance workflows (HITL/HATL/HOTL) inside the Agent PM Service, and register hidden entrypoints that can be triggered without an HTTP surface.
|
|
4
|
+
|
|
5
|
+
## Framework Compatibility
|
|
6
|
+
|
|
7
|
+
<!-- COMPAT-BADGES:START -->
|
|
8
|
+

|
|
9
|
+
<!-- COMPAT-BADGES:END -->
|
|
10
|
+
|
|
11
|
+
<details>
|
|
12
|
+
<summary>Full Compatibility Matrix</summary>
|
|
13
|
+
|
|
14
|
+
<!-- COMPAT-MATRIX:START -->
|
|
15
|
+
| Framework | Version | Node 18 | Node 20 | Node 22 |
|
|
16
|
+
|---|---| --- | --- | --- |
|
|
17
|
+
| Mistral | 1.14.1 | pass | pass | pass |
|
|
18
|
+
<!-- COMPAT-MATRIX:END -->
|
|
19
|
+
|
|
20
|
+
</details>
|
|
21
|
+
|
|
22
|
+
## Highlights
|
|
23
|
+
|
|
24
|
+
- `init(config)` bootstraps SDK defaults (base URLs, tenant headers, tracing, governance fallbacks, fetch implementation).
|
|
25
|
+
- `@instrument(...)` works on class methods (NestJS, controllers, workers) while `withInstrumentation(fn, opts)` wraps standalone functions.
|
|
26
|
+
- Decorator options control tracing, custom labels/metadata, manual trigger keys, governance policies, KPI definitions, and hidden entrypoints.
|
|
27
|
+
- Automatic OpenTelemetry spans + rich metadata; emits `AgentEvent` payloads that match the shared `@turingpulse/interfaces` schema.
|
|
28
|
+
- Trigger registry lets you invoke hidden agents via `getInstance().triggerAgent('hidden:sync_rag', args)` even when no endpoint exists.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add @turingpulse/sdk @turingpulse/interfaces
|
|
34
|
+
# or npm/yarn equivalent
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Local workspace dev:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd packages/turingpulse-sdk
|
|
41
|
+
pnpm install
|
|
42
|
+
pnpm build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { init, instrument, GovernanceDirective, KPIConfig } from '@turingpulse/sdk';
|
|
49
|
+
|
|
50
|
+
init({
|
|
51
|
+
apiKey: process.env.TP_API_KEY!,
|
|
52
|
+
workflowName: 'My Workflow',
|
|
53
|
+
redactFields: ['password', 'apiKey', 'secret'],
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const governance = new GovernanceDirective({ hitl: true, reviewers: ['audit@org.com'] });
|
|
57
|
+
const throughputKpi = { kpiId: 'items_processed', fromResultPath: 'count', comparator: 'lt', alertThreshold: 1 };
|
|
58
|
+
|
|
59
|
+
class MarketScanner {
|
|
60
|
+
@instrument({
|
|
61
|
+
agentId: 'agent-research',
|
|
62
|
+
operation: 'market_scan',
|
|
63
|
+
labels: { surface: 'slack' },
|
|
64
|
+
governance,
|
|
65
|
+
kpis: [throughputKpi],
|
|
66
|
+
triggerKey: 'hidden.market_scan',
|
|
67
|
+
hiddenEntrypoint: true,
|
|
68
|
+
})
|
|
69
|
+
async run(query: string) {
|
|
70
|
+
// ... do work ...
|
|
71
|
+
return { count: 3, items: [] };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Manual trigger:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { getInstance } from '@turingpulse/sdk';
|
|
80
|
+
|
|
81
|
+
await getInstance().triggerAgent('hidden.market_scan', 'pricing updates');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Wrap standalone functions:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { withInstrumentation } from '@turingpulse/sdk';
|
|
88
|
+
|
|
89
|
+
const handler = withInstrumentation(
|
|
90
|
+
async (payload: Payload) => {
|
|
91
|
+
return service.process(payload);
|
|
92
|
+
},
|
|
93
|
+
{ agentId: 'agent-worker', operation: 'ingest_payload' },
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Decorator Options
|
|
98
|
+
|
|
99
|
+
| Option | Description |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `agentId` | Required Agent identifier |
|
|
102
|
+
| `operation` | Logical name; defaults to method name |
|
|
103
|
+
| `labels` / `metadata` | Merged with global defaults and sent to traces + AgentEvent metadata |
|
|
104
|
+
| `trace` | Enable/disable tracing at the decorator level |
|
|
105
|
+
| `triggerKey` | Registers the method for manual invocation |
|
|
106
|
+
| `hiddenEntrypoint` | Marks calls as UI-hidden; metadata includes `agent.hidden_entrypoint` |
|
|
107
|
+
| `governance` | `GovernanceDirective` describing HITL/HATL/HOTL behaviour |
|
|
108
|
+
| `kpis` | Array of `KPIConfig` to emit metrics + alert metadata |
|
|
109
|
+
|
|
110
|
+
## Governance
|
|
111
|
+
|
|
112
|
+
`GovernanceDirective` controls reviewer queues, escalation channels, severity, and auto-escalation timers. When enabled, the plugin creates tasks in the Agent PM Service per mode (HITL/HATL/HOTL) and attaches KPI metadata for downstream auditors.
|
|
113
|
+
|
|
114
|
+
## KPI Mapping & Alerts
|
|
115
|
+
|
|
116
|
+
- `useDuration` derives KPI values from observed runtime (ms).
|
|
117
|
+
- `fromResultPath` pulls nested properties from the returned payload.
|
|
118
|
+
- `value` can be a literal number or `(ctx) => number`.
|
|
119
|
+
- When `alertThreshold` + `comparator` trip, metadata includes `metric.alert.<id>=true`.
|
|
120
|
+
|
|
121
|
+
## Security
|
|
122
|
+
|
|
123
|
+
The SDK includes built-in protections to ensure safe operation in customer environments:
|
|
124
|
+
|
|
125
|
+
### Endpoint Validation
|
|
126
|
+
- **SSRF protection**: Private/internal IP ranges (`127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`, `localhost`, `[::1]`) are blocked as endpoints.
|
|
127
|
+
- **CRLF injection prevention**: Newline and null characters are stripped from API keys and endpoint URLs.
|
|
128
|
+
- **TLS enforcement**: The SDK emits a warning if an `http://` endpoint is used instead of `https://`.
|
|
129
|
+
|
|
130
|
+
### Data Protection
|
|
131
|
+
- **Sensitive field redaction**: Use `redactFields` in config to mask sensitive keys before telemetry leaves your environment.
|
|
132
|
+
- **Error sanitization**: Error messages in telemetry do not leak stack traces or internal paths.
|
|
133
|
+
- **No content truncation**: The SDK does not truncate or limit content size — backend handles that.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
init({
|
|
137
|
+
apiKey: 'sk_...',
|
|
138
|
+
workflowName: 'My Workflow',
|
|
139
|
+
redactFields: ['password', 'apiKey', 'secret', 'token', 'authorization'],
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Network Safety
|
|
144
|
+
- **Retry-After compliance**: The SDK respects `Retry-After` headers from 429 responses.
|
|
145
|
+
- **No retry on terminal errors**: 401, 402, 403, 404 responses stop retries immediately.
|
|
146
|
+
- **Timeout cap**: HTTP timeout is capped at 120 seconds.
|
|
147
|
+
|
|
148
|
+
### UUID Generation
|
|
149
|
+
- Uses `crypto.randomUUID()` when available, falls back to `crypto.getRandomValues()` for better entropy than `Math.random()`.
|
|
150
|
+
|
|
151
|
+
## Fingerprinting & Change Detection
|
|
152
|
+
|
|
153
|
+
The SDK automatically captures workflow fingerprints to enable root cause analysis when anomalies or drifts are detected. This works out-of-the-box with zero configuration.
|
|
154
|
+
|
|
155
|
+
### How It Works
|
|
156
|
+
|
|
157
|
+
1. The SDK automatically detects LLM calls (OpenAI, Anthropic, LangChain, etc.)
|
|
158
|
+
2. Prompts and configurations are hashed for change detection
|
|
159
|
+
3. Workflow structure (nodes and edges) is tracked
|
|
160
|
+
4. Fingerprints are sent to the backend after each run
|
|
161
|
+
5. When anomalies occur, changes are correlated for root cause attribution
|
|
162
|
+
|
|
163
|
+
### Configuration
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { init } from '@turingpulse/sdk';
|
|
167
|
+
|
|
168
|
+
init({
|
|
169
|
+
apiKey: 'sk_...',
|
|
170
|
+
workflowName: 'My Workflow',
|
|
171
|
+
fingerprint: {
|
|
172
|
+
enabled: true, // Master switch (default: true)
|
|
173
|
+
capturePrompts: true, // Hash prompts for change detection
|
|
174
|
+
captureConfigs: true, // Hash configs for change detection
|
|
175
|
+
captureStructure: true, // Track DAG structure
|
|
176
|
+
sensitiveConfigKeys: [ // Keys to redact before hashing
|
|
177
|
+
'apiKey', 'password', 'secret', 'token'
|
|
178
|
+
],
|
|
179
|
+
sendAsync: true, // Send fingerprints asynchronously
|
|
180
|
+
sendOnFailure: true, // Send even if run fails
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Deploy Tracking
|
|
186
|
+
|
|
187
|
+
Register deployments to correlate anomalies with code changes:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { registerDeploy } from '@turingpulse/sdk';
|
|
191
|
+
|
|
192
|
+
// Auto-detect from CI/CD environment (GitHub Actions, GitLab CI, etc.)
|
|
193
|
+
await registerDeploy({
|
|
194
|
+
workflowId: 'chat-assistant',
|
|
195
|
+
autoDetect: true,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Or provide explicit values
|
|
199
|
+
await registerDeploy({
|
|
200
|
+
workflowId: 'chat-assistant',
|
|
201
|
+
version: 'v1.2.3',
|
|
202
|
+
gitSha: process.env.GIT_SHA,
|
|
203
|
+
commitMessage: process.env.GIT_COMMIT_MSG,
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Supported CI/CD environments for auto-detection:
|
|
208
|
+
- GitHub Actions
|
|
209
|
+
- GitLab CI
|
|
210
|
+
- CircleCI
|
|
211
|
+
- Jenkins
|
|
212
|
+
- Azure DevOps
|
|
213
|
+
- Bitbucket Pipelines
|
|
214
|
+
- Travis CI
|
|
215
|
+
|
|
216
|
+
## Roadmap
|
|
217
|
+
|
|
218
|
+
- Browser-friendly fetch adapter
|
|
219
|
+
- Extended decorators for parameter injection + custom trace attributes
|
|
220
|
+
- CLI helper for listing/triggering hidden entrypoints
|
|
221
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document attachment support for the TuringPulse TypeScript SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides AttachmentManager for uploading documents to the ingestion service
|
|
5
|
+
* and injecting attachment metadata into the current span.
|
|
6
|
+
*
|
|
7
|
+
* Design principle: NEVER crash customer code. All upload failures are logged
|
|
8
|
+
* and silently ignored.
|
|
9
|
+
*/
|
|
10
|
+
import { TuringPulseConfig } from './config';
|
|
11
|
+
export interface AttachmentResult {
|
|
12
|
+
attachmentId: string;
|
|
13
|
+
filename: string;
|
|
14
|
+
mimeType: string;
|
|
15
|
+
sizeBytes: number;
|
|
16
|
+
storagePath: string;
|
|
17
|
+
direction: string;
|
|
18
|
+
deduplicated: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class AttachmentManager {
|
|
21
|
+
private readonly baseUrl;
|
|
22
|
+
private readonly config;
|
|
23
|
+
private readonly enabled;
|
|
24
|
+
constructor(config: TuringPulseConfig, enabled?: boolean);
|
|
25
|
+
attachBytes(data: Uint8Array | Buffer, filename: string, direction?: 'input' | 'output', mimeType?: string): Promise<AttachmentResult | undefined>;
|
|
26
|
+
attachText(text: string, filename?: string, direction?: 'input' | 'output'): Promise<AttachmentResult | undefined>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../src/attachments.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,MAAM,EAAE,iBAAiB,EAAE,OAAO,UAAO;IAM/C,WAAW,CACf,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,OAAO,GAAG,QAAkB,EACvC,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAyClC,UAAU,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAiB,EACzB,SAAS,GAAE,OAAO,GAAG,QAAkB,GACtC,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;CAIzC"}
|