@volter/twin-sentry 0.1.37 → 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/README.md +28 -140
- package/api/spec/SOURCE.md +32 -0
- package/api/spec/doc-examples.json +12 -0
- package/api/spec/openapi.json.gz +0 -0
- package/api/spec/patches.json +5350 -0
- package/api/spec/sources.json +122 -0
- package/api/src/fetch.ts +18 -0
- package/api/src/generated/surface.gen.json +1 -0
- package/api/src/generated/ui.gen.json +1 -0
- package/api/src/index.ts +3 -0
- package/api/src/manifest.ts +137 -0
- package/api/src/semantics/api.ts +247 -0
- package/api/src/semantics/around.ts +36 -0
- package/api/src/semantics/doors.ts +76 -0
- package/api/src/semantics/index.ts +19 -0
- package/api/src/semantics/shared.ts +31 -0
- package/api/src/semantics/states.ts +17 -0
- package/dist/api/spec/SOURCE.md +32 -0
- package/dist/api/spec/doc-examples.json +12 -0
- package/dist/api/spec/openapi.json.gz +0 -0
- package/dist/api/spec/patches.json +5350 -0
- package/dist/api/spec/sources.json +122 -0
- package/dist/api/src/fetch.d.ts +2 -0
- package/dist/api/src/fetch.js +17 -0
- package/dist/api/src/fetch.ts +18 -0
- package/dist/api/src/generated/surface.gen.json +1 -0
- package/dist/api/src/generated/ui.gen.json +1 -0
- package/dist/api/src/index.d.ts +2 -0
- package/dist/api/src/index.js +3 -0
- package/dist/api/src/index.ts +3 -0
- package/dist/api/src/manifest.d.ts +2 -0
- package/dist/api/src/manifest.js +136 -0
- package/dist/api/src/manifest.ts +137 -0
- package/dist/api/src/semantics/api.d.ts +13 -0
- package/dist/api/src/semantics/api.js +269 -0
- package/dist/api/src/semantics/api.ts +247 -0
- package/dist/api/src/semantics/around.d.ts +2 -0
- package/dist/api/src/semantics/around.js +41 -0
- package/dist/api/src/semantics/around.ts +36 -0
- package/dist/api/src/semantics/doors.d.ts +5 -0
- package/dist/api/src/semantics/doors.js +71 -0
- package/dist/api/src/semantics/doors.ts +76 -0
- package/dist/api/src/semantics/index.d.ts +2 -0
- package/dist/api/src/semantics/index.js +15 -0
- package/dist/api/src/semantics/index.ts +19 -0
- package/dist/api/src/semantics/shared.d.ts +14 -0
- package/dist/api/src/semantics/shared.js +26 -0
- package/dist/api/src/semantics/shared.ts +31 -0
- package/dist/api/src/semantics/states.d.ts +24 -0
- package/dist/api/src/semantics/states.js +17 -0
- package/dist/api/src/semantics/states.ts +17 -0
- package/dist/ingest/spec/SOURCE.md +30 -0
- package/dist/ingest/spec/authentication.mdx.gz +0 -0
- package/dist/ingest/spec/compression.mdx.gz +0 -0
- package/dist/ingest/spec/doc-examples.json +216 -0
- package/dist/ingest/spec/envelope-items.mdx.gz +0 -0
- package/dist/ingest/spec/envelopes.mdx.gz +0 -0
- package/dist/ingest/spec/openapi.json +178 -0
- package/dist/ingest/spec/rate-limiting.mdx.gz +0 -0
- package/dist/ingest/spec/sources.json +25 -0
- package/dist/ingest/spec/transport.mdx.gz +0 -0
- package/dist/ingest/spec/write-spec.ts +192 -0
- package/dist/ingest/src/fetch.d.ts +2 -0
- package/dist/ingest/src/fetch.js +15 -0
- package/dist/ingest/src/fetch.ts +16 -0
- package/dist/ingest/src/generated/surface.gen.json +1 -0
- package/dist/ingest/src/generated/ui.gen.json +1 -0
- package/dist/ingest/src/index.d.ts +2 -0
- package/dist/ingest/src/index.js +3 -0
- package/dist/ingest/src/index.ts +3 -0
- package/dist/ingest/src/manifest.d.ts +2 -0
- package/dist/ingest/src/manifest.js +37 -0
- package/dist/ingest/src/manifest.ts +42 -0
- package/dist/ingest/src/semantics/api.d.ts +2 -0
- package/dist/ingest/src/semantics/api.js +240 -0
- package/dist/ingest/src/semantics/api.ts +188 -0
- package/dist/ingest/src/semantics/around.d.ts +2 -0
- package/dist/ingest/src/semantics/around.js +6 -0
- package/dist/ingest/src/semantics/around.ts +7 -0
- package/dist/ingest/src/semantics/index.d.ts +2 -0
- package/dist/ingest/src/semantics/index.js +4 -0
- package/dist/ingest/src/semantics/index.ts +8 -0
- package/dist/ingest/src/semantics/shared.d.ts +4 -0
- package/dist/ingest/src/semantics/shared.js +2 -0
- package/dist/ingest/src/semantics/shared.ts +7 -0
- package/dist/ingest/src/semantics/states.d.ts +1 -0
- package/dist/ingest/src/semantics/states.js +2 -0
- package/dist/ingest/src/semantics/states.ts +2 -0
- package/dist/journeys/coverage.json +205 -0
- package/dist/journeys/customer-life.json +921 -0
- package/dist/journeys/customer-life.outline.md +51 -0
- package/dist/journeys/decisions.json +170 -0
- package/dist/journeys/demand.json +92 -0
- package/dist/journeys/first-use.json +22 -0
- package/dist/journeys/score.json +231 -0
- package/dist/journeys/unreachable.json +29 -0
- package/dist/journeys/vendor-examples.json +474 -0
- package/dist/spec/sources.json +76 -0
- package/dist/src/cli.js +12 -27
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +9 -0
- package/dist/src/index.d.ts +5 -15
- package/dist/src/index.js +13 -75
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.js +35 -0
- package/dist/src/semantics/shared.d.ts +88 -0
- package/dist/src/semantics/shared.js +407 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +101 -0
- package/ingest/spec/SOURCE.md +30 -0
- package/ingest/spec/authentication.mdx.gz +0 -0
- package/ingest/spec/compression.mdx.gz +0 -0
- package/ingest/spec/doc-examples.json +216 -0
- package/ingest/spec/envelope-items.mdx.gz +0 -0
- package/ingest/spec/envelopes.mdx.gz +0 -0
- package/ingest/spec/openapi.json +178 -0
- package/ingest/spec/rate-limiting.mdx.gz +0 -0
- package/ingest/spec/sources.json +25 -0
- package/ingest/spec/transport.mdx.gz +0 -0
- package/ingest/spec/write-spec.ts +192 -0
- package/ingest/src/fetch.ts +16 -0
- package/ingest/src/generated/surface.gen.json +1 -0
- package/ingest/src/generated/ui.gen.json +1 -0
- package/ingest/src/index.ts +3 -0
- package/ingest/src/manifest.ts +42 -0
- package/ingest/src/semantics/api.ts +188 -0
- package/ingest/src/semantics/around.ts +7 -0
- package/ingest/src/semantics/index.ts +8 -0
- package/ingest/src/semantics/shared.ts +7 -0
- package/ingest/src/semantics/states.ts +2 -0
- package/journeys/coverage.json +205 -0
- package/journeys/customer-life.json +921 -0
- package/journeys/customer-life.outline.md +51 -0
- package/journeys/decisions.json +170 -0
- package/journeys/demand.json +92 -0
- package/journeys/first-use.json +22 -0
- package/journeys/score.json +231 -0
- package/journeys/unreachable.json +29 -0
- package/journeys/vendor-examples.json +474 -0
- package/package.json +22 -47
- package/spec/sources.json +76 -0
- package/src/cli.ts +12 -24
- package/src/fetch.ts +10 -0
- package/src/index.ts +13 -143
- package/src/manifest.ts +41 -0
- package/src/semantics/shared.ts +439 -0
- package/src/server.ts +8 -0
- package/client/sentry-mirror.css +0 -99
- package/client/sentry-mirror.tsx +0 -352
- package/dist/client/sentry-mirror.bundle.js +0 -388
- package/dist/client/sentry-mirror.css +0 -99
- package/dist/client/sentry-mirror.d.ts +0 -17
- package/dist/client/sentry-mirror.js +0 -156
- package/dist/client/sentry-mirror.tsx +0 -352
- package/dist/src/sentry-budget.d.ts +0 -50
- package/dist/src/sentry-budget.js +0 -145
- package/dist/src/sentry-capabilities.d.ts +0 -3
- package/dist/src/sentry-capabilities.js +0 -1180
- package/dist/src/sentry-conformance.d.ts +0 -22
- package/dist/src/sentry-conformance.js +0 -97
- package/dist/src/sentry-connector.d.ts +0 -77
- package/dist/src/sentry-connector.js +0 -226
- package/dist/src/sentry-events.d.ts +0 -54
- package/dist/src/sentry-events.js +0 -132
- package/dist/src/sentry-ingest.d.ts +0 -137
- package/dist/src/sentry-ingest.js +0 -387
- package/dist/src/sentry-mirror-ui.d.ts +0 -38
- package/dist/src/sentry-mirror-ui.js +0 -162
- package/dist/src/sentry-perform-harness.d.ts +0 -9
- package/dist/src/sentry-perform-harness.js +0 -20
- package/dist/src/sentry-server.d.ts +0 -14
- package/dist/src/sentry-server.js +0 -27
- package/dist/src/sentry-twin.d.ts +0 -17
- package/dist/src/sentry-twin.js +0 -1739
- package/dist/test-fixtures/sentry-openapi-operations.SOURCE.md +0 -24
- package/dist/test-fixtures/sentry-openapi-operations.json +0 -1837
- package/src/sentry-budget.ts +0 -171
- package/src/sentry-capabilities.ts +0 -1222
- package/src/sentry-conformance.ts +0 -110
- package/src/sentry-connector.ts +0 -260
- package/src/sentry-events.ts +0 -172
- package/src/sentry-ingest.ts +0 -471
- package/src/sentry-mirror-ui.ts +0 -162
- package/src/sentry-perform-harness.ts +0 -19
- package/src/sentry-server.ts +0 -35
- package/src/sentry-twin.ts +0 -1615
- package/test-fixtures/sentry-openapi-operations.SOURCE.md +0 -24
- package/test-fixtures/sentry-openapi-operations.json +0 -1837
package/package.json
CHANGED
|
@@ -1,75 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/twin-sentry",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Sentry Protocol 3 twin: demanded SDK envelopes, release/source-map APIs, account project and client-key setup, and derived vendor-backed reads.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
7
|
-
"local",
|
|
8
|
-
"mock",
|
|
9
|
-
"mirror",
|
|
10
|
-
"simulator",
|
|
11
|
-
"fixtures",
|
|
12
|
-
"testing",
|
|
13
|
-
"sdk",
|
|
14
|
-
"api",
|
|
15
|
-
"localstack",
|
|
16
7
|
"sentry",
|
|
17
|
-
"error-
|
|
18
|
-
"
|
|
8
|
+
"error-tracking",
|
|
9
|
+
"envelope",
|
|
10
|
+
"sentry-cli",
|
|
11
|
+
"source-maps"
|
|
19
12
|
],
|
|
20
13
|
"author": "Volter (https://github.com/volter-ai)",
|
|
21
14
|
"license": "Apache-2.0",
|
|
22
15
|
"files": [
|
|
23
16
|
"src",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
17
|
+
"journeys",
|
|
18
|
+
"api",
|
|
19
|
+
"spec",
|
|
20
|
+
"ingest",
|
|
26
21
|
"README.md",
|
|
27
22
|
"LICENSE",
|
|
28
23
|
"!**/*.test.ts",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
24
|
+
"dist",
|
|
25
|
+
"generated"
|
|
31
26
|
],
|
|
32
27
|
"repository": {
|
|
33
28
|
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/volter-ai/twin.git",
|
|
35
|
-
"directory": "
|
|
29
|
+
"url": "git+https://github.com/volter-ai/twin-packs-open.git",
|
|
30
|
+
"directory": "sentry"
|
|
36
31
|
},
|
|
37
|
-
"homepage": "https://
|
|
32
|
+
"homepage": "https://github.com/volter-ai/twin-packs-open/tree/main/sentry#readme",
|
|
38
33
|
"type": "module",
|
|
39
34
|
"exports": {
|
|
40
|
-
".":
|
|
41
|
-
"types": "./dist/src/index.d.ts",
|
|
42
|
-
"default": "./dist/src/index.js"
|
|
43
|
-
}
|
|
35
|
+
".": "./dist/src/index.js"
|
|
44
36
|
},
|
|
45
37
|
"bin": {
|
|
46
|
-
"world-sentry": "dist/src/cli.js"
|
|
47
|
-
},
|
|
48
|
-
"scripts": {
|
|
49
|
-
"test": "bun test src/*.test.ts",
|
|
50
|
-
"typecheck": "tsc --noEmit",
|
|
51
|
-
"build": "node ../../../scripts/publish/build.mjs",
|
|
52
|
-
"prepack": "node ../../../scripts/publish/prepare-publish.mjs prepack",
|
|
53
|
-
"postpack": "node ../../../scripts/publish/prepare-publish.mjs postpack"
|
|
54
|
-
},
|
|
55
|
-
"dependencies": {
|
|
56
|
-
"react": "^19.2.7",
|
|
57
|
-
"react-dom": "^19.2.7"
|
|
38
|
+
"world-sentry": "./dist/src/cli.js"
|
|
58
39
|
},
|
|
59
40
|
"peerDependencies": {
|
|
60
|
-
"@volter/world-core": "
|
|
61
|
-
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@volter/world-core": "2.0.37",
|
|
64
|
-
"@volter/world-tooling": "0.1.0",
|
|
65
|
-
"@sentry/node": "^10.64.0",
|
|
66
|
-
"@types/bun": "^1.2.20",
|
|
67
|
-
"@types/node": "^24.0.0",
|
|
68
|
-
"@types/react": "^19.2.17",
|
|
69
|
-
"@types/react-dom": "^19.2.3",
|
|
70
|
-
"typescript": "^5.9.0"
|
|
41
|
+
"@volter/world-core": ">=3.0.163",
|
|
42
|
+
"@volter/world-runtime": ">=3.0.184"
|
|
71
43
|
},
|
|
72
44
|
"engines": {
|
|
73
45
|
"node": ">=22.3"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/volter-ai/twin-packs-open/issues"
|
|
74
49
|
}
|
|
75
50
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/api/serializers/models/project_key.py": {
|
|
3
|
+
"status": 200,
|
|
4
|
+
"checked": "2026-10-03",
|
|
5
|
+
"quotes": {
|
|
6
|
+
"ProjectKeySerializerResponse": true
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/features/permanent.py": {
|
|
10
|
+
"status": 200,
|
|
11
|
+
"checked": "2026-10-03",
|
|
12
|
+
"quotes": {
|
|
13
|
+
"organizations:advanced-search": true,
|
|
14
|
+
"organizations:change-alerts": true,
|
|
15
|
+
"organizations:crash-rate-alerts": true,
|
|
16
|
+
"organizations:custom-symbol-sources": true,
|
|
17
|
+
"organizations:data-forwarding": true,
|
|
18
|
+
"organizations:discover-basic": true,
|
|
19
|
+
"organizations:discover-query": true,
|
|
20
|
+
"organizations:event-attachments": true,
|
|
21
|
+
"organizations:integrations-alert-rule": true,
|
|
22
|
+
"organizations:integrations-chat-unfurl": true,
|
|
23
|
+
"organizations:integrations-codeowners": true,
|
|
24
|
+
"organizations:integrations-enterprise-alert-rule": true,
|
|
25
|
+
"organizations:integrations-enterprise-incident-management": true,
|
|
26
|
+
"organizations:integrations-event-hooks": true,
|
|
27
|
+
"organizations:integrations-incident-management": true,
|
|
28
|
+
"organizations:integrations-issue-basic": true,
|
|
29
|
+
"organizations:integrations-issue-sync": true,
|
|
30
|
+
"organizations:integrations-scm-multi-org": true,
|
|
31
|
+
"organizations:integrations-stacktrace-link": true,
|
|
32
|
+
"organizations:integrations-ticket-rules": true,
|
|
33
|
+
"organizations:integrations-vercel": true,
|
|
34
|
+
"organizations:performance-view": true,
|
|
35
|
+
"organizations:relay": true,
|
|
36
|
+
"organizations:sso-basic": true,
|
|
37
|
+
"organizations:sso-saml2": true,
|
|
38
|
+
"organizations:team-insights": true,
|
|
39
|
+
"organizations:team-roles": true,
|
|
40
|
+
"organizations:uptime": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/features/temporary.py": {
|
|
44
|
+
"status": 200,
|
|
45
|
+
"checked": "2026-10-03",
|
|
46
|
+
"quotes": {
|
|
47
|
+
"organizations:dashboards-basic": true,
|
|
48
|
+
"organizations:dashboards-edit": true,
|
|
49
|
+
"organizations:insight-modules": true,
|
|
50
|
+
"organizations:invite-members": true,
|
|
51
|
+
"organizations:sentry-app-schema-form-migration": true,
|
|
52
|
+
"organizations:session-replay-ui": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/models/projectkey.py": {
|
|
56
|
+
"status": 200,
|
|
57
|
+
"checked": "2026-10-03",
|
|
58
|
+
"quotes": {
|
|
59
|
+
"secret_key = ProjectKey.generate_api_key()": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/projectoptions/defaults.py": {
|
|
63
|
+
"status": 200,
|
|
64
|
+
"checked": "2026-10-03",
|
|
65
|
+
"quotes": {
|
|
66
|
+
"sentry:default_loader_version": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"https://raw.githubusercontent.com/getsentry/sentry/2efdd4760a75a3d395e3534b7f66a7fbb0c3f22e/src/sentry/utils/numbers.py": {
|
|
70
|
+
"status": 200,
|
|
71
|
+
"checked": "2026-10-03",
|
|
72
|
+
"quotes": {
|
|
73
|
+
"0123456789ABCDEFGHJKMNPQRSTVWXYZ": true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -1,34 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// world-sentry CLI: serve the Sentry API twin (ingestion + Web API), the dashboard mirror
|
|
4
|
-
// UI, or run conformance. (Conformance lives in dev-tooling; cli.ts must not import it, so
|
|
5
|
-
// it's loaded lazily only when the `conformance` command is invoked.)
|
|
2
|
+
// world-sentry: serve the sentry twin.
|
|
6
3
|
import { hasFlag, optionValue } from '@volter/world-core/args';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { defaultDsn } from './sentry-ingest.ts';
|
|
4
|
+
import { keepProcessAlive } from '@volter/world-core/lifecycle';
|
|
5
|
+
import { createSentryTwinServer } from './server.ts';
|
|
10
6
|
|
|
11
7
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
12
8
|
const port = Number(optionValue(rest, '--port', '0')) || undefined;
|
|
13
9
|
const root = optionValue(rest, '--root') || undefined;
|
|
14
|
-
const readOnly = hasFlag(rest, '--read-only');
|
|
10
|
+
const readOnly = hasFlag(rest, '--read-only');
|
|
11
|
+
// the selected twin's private Postgres, which the runtime binds a pack declaring managedDatabase to
|
|
12
|
+
const database = optionValue(rest, '--database') || undefined;
|
|
13
|
+
// the World's scenario file, for a model vendor's turns
|
|
14
|
+
const scenarioPath = optionValue(rest, '--scenario') || undefined;
|
|
15
15
|
|
|
16
|
-
if (cmd === 'serve') {
|
|
17
|
-
const s = await createSentryTwinServer({ readOnly, ...(root ? { root } : {}), ...(port ? { port } : {}) });
|
|
18
|
-
|
|
19
|
-
process.stdout.write(`sentry twin (ingest + Web API)${readOnly ? ' [read-only]' : ''} at ${origin}\n`);
|
|
20
|
-
process.stdout.write(` point @sentry/node at DSN: ${defaultDsn(origin)}\n`);
|
|
21
|
-
await keepProcessAlive();
|
|
22
|
-
} else if (cmd === 'mirror') {
|
|
23
|
-
const s = await createSentryMirrorServer({ ...(root ? { root } : {}), ...(port ? { port } : {}) });
|
|
24
|
-
process.stdout.write(`sentry mirror UI (dashboard) at http://127.0.0.1:${s.port}\n`);
|
|
16
|
+
if (cmd === 'serve' || cmd === undefined) {
|
|
17
|
+
const s = await createSentryTwinServer({ readOnly, ...(root ? { root } : {}), ...(port ? { port } : {}), ...(database ? { database } : {}), ...(scenarioPath ? { scenarioPath } : {}) });
|
|
18
|
+
process.stdout.write(`sentry twin${readOnly ? ' [read-only]' : ''} at http://127.0.0.1:${s.port}\n`);
|
|
25
19
|
await keepProcessAlive();
|
|
26
|
-
} else if (cmd === 'conformance') {
|
|
27
|
-
// dev-only: dynamic import so the conformance module never enters the runtime entrypoints.
|
|
28
|
-
const { checkSentryConformance } = await import('./sentry-conformance.ts');
|
|
29
|
-
const report = await checkSentryConformance({ ...(root ? { root } : {}) });
|
|
30
|
-
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
31
|
-
if (!report.ok) process.exitCode = 1;
|
|
32
20
|
} else {
|
|
33
|
-
process.stdout.write('Usage: world-sentry serve
|
|
21
|
+
process.stdout.write('Usage: world-sentry serve [--port N] [--root DIR] [--read-only] [--database URL] [--scenario FILE]\n');
|
|
34
22
|
}
|
package/src/fetch.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// GENERATED by scripts/create-pack.ts (--init, --index): a fixed file. The kernel serves the vendor's discovery door and
|
|
2
|
+
// sends each request to the lane its manifest's routes name (architecture, "Other wires: lanes").
|
|
3
|
+
import { createVendorFetch, type DerivedFetch, type PackFetchOptions } from '@volter/world-core';
|
|
4
|
+
import { manifest } from './manifest.ts';
|
|
5
|
+
import { createApiLaneFetch, manifest as api_manifest } from '../api/src/index.ts';
|
|
6
|
+
import { createIngestLaneFetch, manifest as ingest_manifest } from '../ingest/src/index.ts';
|
|
7
|
+
|
|
8
|
+
export function createSentryFetch(options: PackFetchOptions = {}): DerivedFetch {
|
|
9
|
+
return createVendorFetch(manifest, { "api": { fetch: createApiLaneFetch(options), manifest: api_manifest }, "ingest": { fetch: createIngestLaneFetch(options), manifest: ingest_manifest } });
|
|
10
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,145 +1,15 @@
|
|
|
1
|
-
// @volter/twin-sentry — the
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
defaultDsn,
|
|
12
|
-
DEFAULT_ORG,
|
|
13
|
-
DEFAULT_PROJECT,
|
|
14
|
-
DEFAULT_PROJECT_ID,
|
|
15
|
-
DEFAULT_PUBLIC_KEY,
|
|
16
|
-
ensureDefaultProject,
|
|
17
|
-
envelopeEvents,
|
|
18
|
-
eventCulprit,
|
|
19
|
-
eventTitle,
|
|
20
|
-
fingerprintText,
|
|
21
|
-
hashFingerprint,
|
|
22
|
-
ingestEvent,
|
|
23
|
-
issueIdFor,
|
|
24
|
-
normalizeFingerprintText,
|
|
25
|
-
parseEnvelope,
|
|
26
|
-
publicKeyFromAuthHeader,
|
|
27
|
-
publicKeyFromDsn,
|
|
28
|
-
resolveProjectKey,
|
|
29
|
-
resolvePublicKey,
|
|
30
|
-
} from './sentry-ingest.ts';
|
|
31
|
-
export type { IngestOutcome, ParsedEnvelope, ResolvedKey, SentryEventPayload, SentryExceptionValue, SentryFrame } from './sentry-ingest.ts';
|
|
32
|
-
export {
|
|
33
|
-
computeSentrySignature,
|
|
34
|
-
constructSentryWebhook,
|
|
35
|
-
emitIssueAlert,
|
|
36
|
-
listAlertRules,
|
|
37
|
-
registerAlertRule,
|
|
38
|
-
SentrySignatureVerificationError,
|
|
39
|
-
verifySentrySignature,
|
|
40
|
-
} from './sentry-events.ts';
|
|
41
|
-
export type { AlertTrigger, SentryWebhook, SentryWebhookAction, SentryWebhookDelivery } from './sentry-events.ts';
|
|
42
|
-
export {
|
|
43
|
-
liveSentryExecute,
|
|
44
|
-
mapIssue,
|
|
45
|
-
mapProject,
|
|
46
|
-
mapRelease,
|
|
47
|
-
pullSentryIssues,
|
|
48
|
-
pullSentryProjects,
|
|
49
|
-
pullSentryReleases,
|
|
50
|
-
pushSentryAction,
|
|
51
|
-
sentryRequestForAction,
|
|
52
|
-
syncSentryFromReal,
|
|
53
|
-
} from './sentry-connector.ts';
|
|
54
|
-
export type { SentryExecute, LiveSentryOptions } from './sentry-connector.ts';
|
|
55
|
-
// The client-side rate budget — the fail-closed backstop `liveSentryExecute` routes every live
|
|
56
|
-
// request through. The MECHANISM is the kernel's shared, vendor-agnostic `RateBudget`; what lives
|
|
57
|
-
// here is Sentry's DECLARATION (window/ceiling/per-endpoint weights) plus the vendor-bound
|
|
58
|
-
// bindings. Exported so an operator can inspect spend (`snapshot`) and so a caller can catch
|
|
59
|
-
// `SentryBudgetError` by type; there is deliberately no export that disables the guard.
|
|
60
|
-
export {
|
|
61
|
-
SENTRY_BUDGET_CEILING,
|
|
62
|
-
SENTRY_BUDGET_MAX_RETRY_AFTER_S,
|
|
63
|
-
SENTRY_BUDGET_WINDOW_MS,
|
|
64
|
-
SENTRY_CALL_WEIGHTS,
|
|
65
|
-
SENTRY_RATE_BUDGET,
|
|
66
|
-
SentryBudget,
|
|
67
|
-
SentryBudgetError,
|
|
68
|
-
sentryBudgetPath,
|
|
69
|
-
sentryCallWeight,
|
|
70
|
-
} from './sentry-budget.ts';
|
|
71
|
-
export type { SentryBudgetErrorKind, SentryBudgetOptions, SentryBudgetReservation, SentryBudgetSnapshot } from './sentry-budget.ts';
|
|
72
|
-
export {
|
|
73
|
-
buildSentryMirrorClient,
|
|
74
|
-
createSentryMirrorServer,
|
|
75
|
-
eventTags,
|
|
76
|
-
formatCount,
|
|
77
|
-
latestStacktrace,
|
|
78
|
-
levelTone,
|
|
79
|
-
sentryMirrorHtml,
|
|
80
|
-
statusTone,
|
|
81
|
-
timeAgo,
|
|
82
|
-
} from './sentry-mirror-ui.ts';
|
|
83
|
-
export type { IssueRow, StackFrame } from './sentry-mirror-ui.ts';
|
|
1
|
+
// @volter/twin-sentry — the sentry twin (Protocol 3). A fixed file (create-pack): the descriptor is the manifest's, and the
|
|
2
|
+
// kernel derives the vendor-backed half from the generated surface, unless the manifest declares none (vendorBacked.none;
|
|
3
|
+
// architecture, "The real-system adapters").
|
|
4
|
+
import { packOf, registerPack, type DerivedSurface } from '@volter/world-core';
|
|
5
|
+
import { manifest } from './manifest.ts';
|
|
6
|
+
import { manifest as apiManifest } from '../api/src/manifest.ts';
|
|
7
|
+
import apiSurface from '../api/src/generated/surface.gen.json' with { type: 'json' };
|
|
8
|
+
import { manifest as ingestManifest } from '../ingest/src/manifest.ts';
|
|
9
|
+
import ingestSurface from '../ingest/src/generated/surface.gen.json' with { type: 'json' };
|
|
84
10
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
import { SENTRY_RATE_BUDGET as RATE_BUDGET } from './sentry-budget.ts';
|
|
89
|
-
import { performSentryAction, syncSentryFromRemote } from './sentry-connector.ts';
|
|
11
|
+
export { createSentryFetch } from './fetch.ts';
|
|
12
|
+
export { createSentryTwinServer } from './server.ts';
|
|
13
|
+
export { manifest };
|
|
90
14
|
|
|
91
|
-
export const pack:
|
|
92
|
-
// PROTOCOL 2 (docs/contributing/architecture.md#protocol-2-the-pack-is-a-plugin): the pack is a plugin — its wire, its tree, and its half of the real
|
|
93
|
-
// state system. Moved 2026-09-08. TRIAGE is what crosses to Sentry — an issue resolved, assigned, muted;
|
|
94
|
-
// everything else this twin holds is something Sentry told it.
|
|
95
|
-
protocol: '2',
|
|
96
|
-
refresh: { every: '2m', webhook: true, onDemand: { atMost: '30s' } },
|
|
97
|
-
stateSystem: { perform: performSentryAction, refresh: syncSentryFromRemote },
|
|
98
|
-
// the round trip: an organization, then a project in it — the two things a Sentry account is made of
|
|
99
|
-
// the round trip: an organization, a team in it, then a project under that team — Sentry's own create
|
|
100
|
-
// path for a project is /teams/:org/:team/projects/, not the organization
|
|
101
|
-
roundTrip: [
|
|
102
|
-
{ method: 'POST', path: '/api/0/organizations/', body: { name: 'Round Trip', slug: 'round-trip' }, headers: { authorization: 'Bearer round-trip' } },
|
|
103
|
-
{ method: 'POST', path: '/api/0/organizations/round-trip/teams/', body: { name: 'Round Trip', slug: 'round-trip' }, headers: { authorization: 'Bearer round-trip' } },
|
|
104
|
-
{ method: 'POST', path: '/api/0/teams/round-trip/round-trip/projects/', body: { name: 'Round Trip', platform: 'node' }, headers: { authorization: 'Bearer round-trip' } },
|
|
105
|
-
// a project's slug is unique inside its org, so the create above rightly refuses a second one on a
|
|
106
|
-
// branch that already has it — the vendor's own truth. The last write is therefore the one a world
|
|
107
|
-
// repeats freely: triage on the project's own issue stream.
|
|
108
|
-
{ method: 'PUT', path: '/api/0/projects/round-trip/round-trip/', body: { platform: 'node', digestsMinDelay: 60 }, headers: { authorization: 'Bearer round-trip' } },
|
|
109
|
-
],
|
|
110
|
-
parityOrigin: 'http://twin',
|
|
111
|
-
vendor: 'sentry',
|
|
112
|
-
// The SAME object sentry-budget.ts declares at module load — one source of truth, so registering
|
|
113
|
-
// the pack and importing the connector can never arm two different ceilings.
|
|
114
|
-
rateBudget: RATE_BUDGET,
|
|
115
|
-
transport: 'rest',
|
|
116
|
-
archetype: 'crud',
|
|
117
|
-
bin: 'world-sentry',
|
|
118
|
-
resources: ['organization', 'team', 'project', 'project_key', 'issue', 'event', 'event_attachment', 'session', 'project_ownership', 'codeowners', 'project_filter', 'release', 'release_file', 'deploy', 'alert_rule', 'metric_alert', 'org_integration'],
|
|
119
|
-
specSource: 'Sentry API reference (https://docs.sentry.io/api/) — ingest store/envelope + Web API /api/0/',
|
|
120
|
-
description: 'Sentry REST twin — SDK ingestion → grouped issues, Web API, signed alert webhooks, dashboard mirror.',
|
|
121
|
-
// Adoption + interception, moved off the central maps unchanged (descriptor-first back-migration, adding-a-twin.md §3,
|
|
122
|
-
// 2026-08-31). The four canonical clients plus the further first-party @sentry
|
|
123
|
-
// framework SDKs of the same ingest surface — battery-observed: sentry was the single
|
|
124
|
-
// most-missed vendor, 13 repos, largely via these — and the whole `@sentry/` scope so a
|
|
125
|
-
// satellite package like `@sentry/cli` still detects.
|
|
126
|
-
adoption: {
|
|
127
|
-
// Sentry's official Python SDK - the one distribution behind every Python integration.
|
|
128
|
-
pypi: ['sentry-sdk'],
|
|
129
|
-
sdks: [
|
|
130
|
-
'@sentry/node', '@sentry/browser', '@sentry/react', '@sentry/nextjs',
|
|
131
|
-
'@sentry/vue', '@sentry/sveltekit', '@sentry/astro', '@sentry/remix',
|
|
132
|
-
'@sentry/electron', '@sentry/react-native',
|
|
133
|
-
],
|
|
134
|
-
scopes: ['@sentry/'],
|
|
135
|
-
// 'APPSMITHSENTRY' — appsmith names its DSN APPSMITH_SENTRY_DSN, an app-prefixed Sentry
|
|
136
|
-
// credential for the same ingest surface (ladder classification 2026-09-02).
|
|
137
|
-
envStems: ['SENTRY', 'APPSMITHSENTRY'],
|
|
138
|
-
},
|
|
139
|
-
// sentry.io (the web/REST API) plus the per-organization DSN ingest hosts
|
|
140
|
-
// (`o<org-id>.ingest.sentry.io`), which need the suffix form.
|
|
141
|
-
hosts: [{ host: 'sentry.io' }, { suffix: '.ingest.sentry.io' }],
|
|
142
|
-
// The @sentry/node SDK POSTs to <dsn-host>/api/:projectId/envelope/; the dashboard hits
|
|
143
|
-
// /api/0/. The dev proxy forwards both prefixes to the twin and strips the sentry.io host.
|
|
144
|
-
browserRouting: { apiPathPrefix: '/api/', loaderHost: 'https://sentry.io' },
|
|
145
|
-
};
|
|
15
|
+
export const pack = registerPack(packOf(manifest, { "api": { manifest: apiManifest, surface: apiSurface as unknown as DerivedSurface }, "ingest": { manifest: ingestManifest, surface: ingestSurface as unknown as DerivedSurface } }));
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Sentry's manifest: a vendor of two APIs, each a lane (architecture, "Other wires: lanes"): the web API that sentry-cli
|
|
2
|
+
// and integrations call (`api`, from Sentry's OpenAPI document), and the ingestion endpoint every SDK sends its envelopes
|
|
3
|
+
// to (`ingest`, written from Sentry's SDK developer documentation). A DSN names its organization's ingest host
|
|
4
|
+
// (`o<id>.ingest[.<region>].sentry.io`); the API is sentry.io's, and a region's (us.sentry.io, de.sentry.io).
|
|
5
|
+
import type { VendorManifest } from '@volter/world-core';
|
|
6
|
+
|
|
7
|
+
export const manifest: VendorManifest = {
|
|
8
|
+
vendor: 'sentry',
|
|
9
|
+
discovery: {
|
|
10
|
+
twinOf: 'Sentry: the envelopes its SDKs send (errors, transactions, sessions, replays, profiles, cron check-ins, feedback, logs, metrics), and its web API for events, issues, releases and source maps',
|
|
11
|
+
stores: 'organizations, projects and client keys, auth tokens (by their SHA-256), events and issues, and every other envelope item; releases and artifact bundles',
|
|
12
|
+
},
|
|
13
|
+
lanes: {
|
|
14
|
+
routes: [
|
|
15
|
+
{ lane: 'ingest', host: '(^|\\.)ingest(\\.[a-z]+)?\\.sentry\\.io$' },
|
|
16
|
+
{ lane: 'api', host: '^([a-z]+\\.)?sentry\\.io$' },
|
|
17
|
+
],
|
|
18
|
+
default: 'api',
|
|
19
|
+
},
|
|
20
|
+
descriptor: {
|
|
21
|
+
protocol: '3',
|
|
22
|
+
transport: 'rest',
|
|
23
|
+
archetype: 'crud',
|
|
24
|
+
bin: 'world-sentry',
|
|
25
|
+
resources: ['organization', 'project', 'project_key', 'event', 'issue', 'release', 'monitor', 'check_in'],
|
|
26
|
+
specSource: "Sentry's OpenAPI document (api/spec, sentry-api-schema 98ec014, patched with evidence) and its SDK developer documentation's envelope endpoint (ingest/spec)",
|
|
27
|
+
description: 'Sentry twin — the envelope endpoint every SDK sends to (events grouped into issues, transactions, sessions, replays, profiles, check-ins, feedback, logs, metrics), and release and source-map APIs used by Cal.com and Rallly, account project/key setup, and core vendor-backed reads.',
|
|
28
|
+
adoption: { sdks: ['@sentry/astro', '@sentry/browser', '@sentry/electron', '@sentry/nextjs', '@sentry/node', '@sentry/nestjs', '@sentry/react', '@sentry/react-native', '@sentry/remix', '@sentry/sveltekit', '@sentry/vue', '@sentry/cli'], pypi: ['sentry-sdk'], envStems: ['APPSMITHSENTRY', 'SENTRY'] },
|
|
29
|
+
hosts: [{ host: 'sentry.io' }, { host: 'us.sentry.io' }, { host: 'de.sentry.io' }, { suffix: '.ingest.sentry.io' }, { suffix: '.ingest.us.sentry.io' }, { suffix: '.ingest.de.sentry.io' }],
|
|
30
|
+
endpointEnvNone: "an SDK sends to its DSN's host and sentry-cli to SENTRY_URL (sentry.io by default); the DSN the World issues names the World's ingest host, claimed by the host rules",
|
|
31
|
+
// Bootstrap: account sign-up, first credential and the project/key named by this env, stable at every boot.
|
|
32
|
+
credentialDoor: { account: { field: 'account', tenancy: 'organization', source: 'https://docs.sentry.io/api/permissions/' },
|
|
33
|
+
deployment: { field: 'deployment', object: 'project and client key', source: 'https://docs.sentry.io/product/sentry-basics/environments/', organizationOutputs: ['SENTRY_ORG', 'SENTRY_ORGANIZATION'] },
|
|
34
|
+
path: '/_twin/app-credentials', body: {},
|
|
35
|
+
fill: {
|
|
36
|
+
SENTRY_DSN: 'dsn', NEXT_PUBLIC_SENTRY_DSN: 'dsn', NEXT_PUBLIC_SENTRY_DSN_CLIENT: 'dsn', SENTRY_FRONT_DSN: 'dsn', SENTRY_DSN_API: 'dsn', VITE_SENTRY_DSN: 'dsn', EXPO_PUBLIC_SENTRY_DSN: 'dsn',
|
|
37
|
+
SENTRY_AUTH_TOKEN: 'auth_token', SENTRY_ORG: 'org', SENTRY_ORGANIZATION: 'org', SENTRY_PROJECT: 'project',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|