@rasputin-ai/node 0.3.0 → 0.4.0
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 +18 -4
- package/dist/auto-instrumentation/collect-instrumentation-delta.d.ts +6 -0
- package/dist/auto-instrumentation/collect-instrumentation-delta.d.ts.map +1 -1
- package/dist/auto-instrumentation/format-configuration-report.d.ts +14 -0
- package/dist/auto-instrumentation/format-configuration-report.d.ts.map +1 -0
- package/dist/auto-instrumentation/instrumentation-manifest-registry.d.ts +9 -3
- package/dist/auto-instrumentation/instrumentation-manifest-registry.d.ts.map +1 -1
- package/dist/auto-instrumentation/schedule-instrumentation-manifest-upload.d.ts +11 -1
- package/dist/auto-instrumentation/schedule-instrumentation-manifest-upload.d.ts.map +1 -1
- package/dist/execution-recorder/automatic-runtime.d.ts +11 -8
- package/dist/execution-recorder/automatic-runtime.d.ts.map +1 -1
- package/dist/execution-recorder/execution-recorder-types.d.ts +7 -3
- package/dist/execution-recorder/execution-recorder-types.d.ts.map +1 -1
- package/dist/execution-recorder/execution-recorder.d.ts.map +1 -1
- package/dist/execution-recorder/index.d.ts +1 -1
- package/dist/execution-recorder/index.d.ts.map +1 -1
- package/dist/execution-recorder/source-exclusions.d.ts +2 -1
- package/dist/execution-recorder/source-exclusions.d.ts.map +1 -1
- package/dist/index.js +307 -111
- package/dist/instrument/bun.js +33 -21
- package/dist/instrument/node.js +32 -20
- package/dist/rasputin-init.d.ts +3 -2
- package/dist/rasputin-init.d.ts.map +1 -1
- package/dist/sdk-meta.d.ts +2 -2
- package/dist/sdk-meta.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,6 @@ export const rasputin = RasputinInit({
|
|
|
14
14
|
release: process.env.RASPUTIN_RELEASE!,
|
|
15
15
|
environment: process.env.NODE_ENV ?? 'development',
|
|
16
16
|
enabled: ['staging', 'production'].includes(process.env.NODE_ENV ?? 'development'),
|
|
17
|
-
moduleUrl: import.meta.url,
|
|
18
17
|
});
|
|
19
18
|
```
|
|
20
19
|
|
|
@@ -38,8 +37,23 @@ try {
|
|
|
38
37
|
| `environment` | yes | Environment such as `production`, `staging`, or `preview` |
|
|
39
38
|
| `release` | yes | Git commit SHA for the deployed version |
|
|
40
39
|
| `enabled` | no | Enables or disables the SDK; defaults to `true` |
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
40
|
+
| `logSuccess` | no | Prints a configuration summary when setup succeeds; defaults to `true`. Failures always log. |
|
|
41
|
+
| `moduleUrl` | no | `import.meta.url` from the initialization file; helps normalize local stack paths |
|
|
42
|
+
| `sourceRoot` | no | Git repository folder for a single-package service, such as `apps/api` |
|
|
43
|
+
| `sourceRoots` | no | Package-name to Git-folder mappings for ambiguous monorepos |
|
|
44
|
+
| `repoRoot` | no | Local filesystem display root; it does not control instrumentation or Git identity |
|
|
45
|
+
|
|
46
|
+
Rasputin normally identifies source from the nearest `package.json` and verifies it against the exact release on the server. Filesystem paths such as `/container` are never used as source identity.
|
|
47
|
+
|
|
48
|
+
For deployment checks, call:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const verification = await rasputin.verifyConfiguration();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`verified` means every instrumented source file maps uniquely to the configured Git release. If a monorepo is ambiguous, set `sourceRoot` or `sourceRoots` using repository-relative folders, never Docker paths.
|
|
55
|
+
|
|
56
|
+
Rasputin also prints a configuration summary after the instrumentation manifest is uploaded. Set `logSuccess: false` if you do not want that banner in production logs. Mapping failures still warn.
|
|
43
57
|
|
|
44
58
|
## Shutdown
|
|
45
59
|
|
|
@@ -124,7 +138,7 @@ Defaults work for most apps. Customize to exclude noisy sources, redact fields,
|
|
|
124
138
|
| `maxStringLength` | `500` | Maximum characters retained from one string |
|
|
125
139
|
| `maxSerializedValueBytes` | `8 KiB` | Maximum retained size of one captured value |
|
|
126
140
|
| `redactKeys` | `[]` | Additional case-insensitive property names to redact |
|
|
127
|
-
| `excludeSources` | `[]` | Source globs or function-
|
|
141
|
+
| `excludeSources` | `[]` | Source globs or function-name patterns to exclude |
|
|
128
142
|
|
|
129
143
|
```ts
|
|
130
144
|
const rasputin = RasputinInit({
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks the TypeScript AST while a module is being transformed and records the static facts
|
|
3
|
+
* Rasputin needs for replay: instrumented functions, call sites, and parameter destructuring
|
|
4
|
+
* bindings. transform-source calls these collectors and passes the delta to the manifest
|
|
5
|
+
* registry so the server can map runtime locations back to Git.
|
|
6
|
+
*/
|
|
1
7
|
import type { InstrumentationArgIdentifier, InstrumentationParamBinding } from '@rasputin-ai/core';
|
|
2
8
|
import ts from 'typescript';
|
|
3
9
|
type SourceLocation = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-instrumentation-delta.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/collect-instrumentation-delta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,KAAK,cAAc,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,oBAAoB,GAAG,CAAC,QAAQ,EAAE,cAAc,KAAK,cAAc,GAAG,SAAS,CAAC;AAErF,KAAK,mBAAmB,GAAG;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,4BAA4B,EAAE,CAAC;CAC/C,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,2BAA2B,CAAC;CACrC,CAAC;AAEF,KAAK,cAAc,GAAG;IACrB,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC;IAC1B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IAC1C,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,YAAY,EAAE,sBAAsB,EAAE,CAAC;CACvC,CAAC;AAqCF,eAAO,MAAM,qBAAqB,GACjC,MAAM,EAAE,CAAC,uBAAuB,EAChC,YAAY,EAAE,CAAC,UAAU,KACvB;IAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAQlE,CAAC;AA2BF,eAAO,MAAM,cAAc,GAC1B,YAAY,EAAE,CAAC,UAAU,EACzB,UAAU,MAAM,EAChB,cAAc,MAAM,EACpB,cAAc,oBAAoB,+BASlC,CAAC;AAuEF,eAAO,MAAM,eAAe,GAC3B,MAAM,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC,aAAa,EAC1C,QAAQ,mBAAmB,EAC3B,SAAS,cAAc,KACrB,mBAAmB,GAAG,IA4BxB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GACnC,aAAa,EAAE,CAAC,mBAAmB,EACnC,QAAQ,mBAAmB,EAC3B,SAAS,cAAc,KACrB,sBAAsB,GAAG,IAsB3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"collect-instrumentation-delta.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/collect-instrumentation-delta.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,KAAK,cAAc,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,oBAAoB,GAAG,CAAC,QAAQ,EAAE,cAAc,KAAK,cAAc,GAAG,SAAS,CAAC;AAErF,KAAK,mBAAmB,GAAG;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,4BAA4B,EAAE,CAAC;CAC/C,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,2BAA2B,CAAC;CACrC,CAAC;AAEF,KAAK,cAAc,GAAG;IACrB,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC;IAC1B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IAC1C,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,YAAY,EAAE,sBAAsB,EAAE,CAAC;CACvC,CAAC;AAqCF,eAAO,MAAM,qBAAqB,GACjC,MAAM,EAAE,CAAC,uBAAuB,EAChC,YAAY,EAAE,CAAC,UAAU,KACvB;IAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAQlE,CAAC;AA2BF,eAAO,MAAM,cAAc,GAC1B,YAAY,EAAE,CAAC,UAAU,EACzB,UAAU,MAAM,EAChB,cAAc,MAAM,EACpB,cAAc,oBAAoB,+BASlC,CAAC;AAuEF,eAAO,MAAM,eAAe,GAC3B,MAAM,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC,aAAa,EAC1C,QAAQ,mBAAmB,EAC3B,SAAS,cAAc,KACrB,mBAAmB,GAAG,IA4BxB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GACnC,aAAa,EAAE,CAAC,mBAAmB,EACnC,QAAQ,mBAAmB,EAC3B,SAAS,cAAc,KACrB,sBAAsB,GAAG,IAsB3B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SourceVerification } from '@rasputin-ai/core';
|
|
2
|
+
type ConfigurationReportInput = {
|
|
3
|
+
release: string;
|
|
4
|
+
runtime: string;
|
|
5
|
+
modules: number;
|
|
6
|
+
functions: number;
|
|
7
|
+
packageNames: string[];
|
|
8
|
+
verification: SourceVerification;
|
|
9
|
+
uploaded: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const formatConfigurationReport: (input: ConfigurationReportInput) => string;
|
|
12
|
+
export declare const runtimeLabel: () => string;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=format-configuration-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-configuration-report.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/format-configuration-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,KAAK,wBAAwB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,kBAAkB,CAAC;IACjC,QAAQ,EAAE,OAAO,CAAC;CAClB,CAAC;AA2CF,eAAO,MAAM,yBAAyB,GAAI,OAAO,wBAAwB,KAAG,MAkE3E,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,MAI/B,CAAC"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type InstrumentationManifestContent } from '@rasputin-ai/core';
|
|
2
2
|
import type { InstrumentationManifestDelta } from './collect-instrumentation-delta';
|
|
3
|
-
export declare const INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.
|
|
3
|
+
export declare const INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.v2";
|
|
4
|
+
type SnapshotOptions = {
|
|
5
|
+
sourceRoot?: string;
|
|
6
|
+
sourceRoots?: Record<string, string>;
|
|
7
|
+
};
|
|
4
8
|
export declare const recordInstrumentationManifestDelta: (filePath: string, delta: InstrumentationManifestDelta) => void;
|
|
5
9
|
export declare const isInstrumentationManifestDirty: () => boolean;
|
|
6
10
|
export declare const instrumentationManifestGeneration: () => number;
|
|
7
|
-
export declare const
|
|
11
|
+
export declare const instrumentationManifestModuleCount: () => number;
|
|
12
|
+
export declare const snapshotInstrumentationManifest: (options?: SnapshotOptions) => InstrumentationManifestContent | undefined;
|
|
8
13
|
export declare const markInstrumentationManifestUploaded: (generation: number) => void;
|
|
9
14
|
export declare const setInstrumentationManifestOnDirty: (onDirty?: () => void) => void;
|
|
10
15
|
export declare const resetInstrumentationManifestRegistry: () => void;
|
|
16
|
+
export {};
|
|
11
17
|
//# sourceMappingURL=instrumentation-manifest-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation-manifest-registry.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/instrumentation-manifest-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrumentation-manifest-registry.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/instrumentation-manifest-registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAGN,KAAK,8BAA8B,EAKnC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAEpF,eAAO,MAAM,+BAA+B,yCAAyC,CAAC;AAYtF,KAAK,eAAe,GAAG;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AAiCF,eAAO,MAAM,kCAAkC,GAC9C,UAAU,MAAM,EAChB,OAAO,4BAA4B,KACjC,IAKF,CAAC;AAEF,eAAO,MAAM,8BAA8B,QAAO,OAGjD,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAO,MAAkC,CAAC;AAExF,eAAO,MAAM,kCAAkC,QAAO,MAAkC,CAAC;AAEzF,eAAO,MAAM,+BAA+B,GAC3C,UAAS,eAAoB,KAC3B,8BAA8B,GAAG,SAiFnC,CAAC;AAEF,eAAO,MAAM,mCAAmC,GAAI,YAAY,MAAM,KAAG,IAGxE,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAAI,UAAU,MAAM,IAAI,KAAG,IAExE,CAAC;AAEF,eAAO,MAAM,oCAAoC,QAAO,IAEvD,CAAC"}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The manifest registry accumulates instrumentation facts as modules load, but Rasputin only
|
|
3
|
+
* learns about them after an upload. This schedules that upload after startup without blocking
|
|
4
|
+
* the process, debounces on registry changes, prints the configuration report once, and exposes
|
|
5
|
+
* verifyConfiguration().
|
|
6
|
+
*/
|
|
7
|
+
import { type SourceVerification } from '@rasputin-ai/core';
|
|
1
8
|
type ScheduleInstrumentationManifestUploadOptions = {
|
|
2
9
|
projectApiKey: string;
|
|
3
10
|
release?: string;
|
|
4
11
|
apiUrl?: string;
|
|
5
|
-
|
|
12
|
+
sourceRoot?: string;
|
|
13
|
+
sourceRoots?: Record<string, string>;
|
|
14
|
+
logSuccess?: boolean;
|
|
6
15
|
fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
7
16
|
enabled: boolean;
|
|
8
17
|
};
|
|
@@ -10,6 +19,7 @@ type InstrumentationManifestUploadHandle = {
|
|
|
10
19
|
flushSoon: () => void;
|
|
11
20
|
wait: () => Promise<void>;
|
|
12
21
|
disconnect: () => void;
|
|
22
|
+
verify: () => Promise<SourceVerification>;
|
|
13
23
|
};
|
|
14
24
|
export declare const scheduleInstrumentationManifestUpload: (options: ScheduleInstrumentationManifestUploadOptions) => InstrumentationManifestUploadHandle;
|
|
15
25
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-instrumentation-manifest-upload.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/schedule-instrumentation-manifest-upload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schedule-instrumentation-manifest-upload.d.ts","sourceRoot":"","sources":["../../src/auto-instrumentation/schedule-instrumentation-manifest-upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGN,KAAK,kBAAkB,EAEvB,MAAM,mBAAmB,CAAC;AAW3B,KAAK,4CAA4C,GAAG;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjF,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,mCAAmC,GAAG;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC1C,CAAC;AAkBF,eAAO,MAAM,qCAAqC,GACjD,SAAS,4CAA4C,KACnD,mCAwGF,CAAC"}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler-instrumented functions and the initialized SDK can live in separate bundles. This
|
|
3
|
+
* versioned global registry joins them without generated code importing a physical SDK file. Source
|
|
4
|
+
* tokens contain only package-relative identity, so Docker paths never leak into runtime events.
|
|
5
|
+
*/
|
|
6
|
+
import { type RuntimeFunctionDefinition } from '@rasputin-ai/core';
|
|
1
7
|
import type { RasputinExecution } from './execution-recorder-types';
|
|
2
|
-
export declare const AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.
|
|
8
|
+
export declare const AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v2";
|
|
3
9
|
type AutomaticFunctionSource = {
|
|
4
10
|
filePath: string;
|
|
5
11
|
name: string;
|
|
6
12
|
line: number;
|
|
7
13
|
column: number;
|
|
8
14
|
};
|
|
9
|
-
|
|
10
|
-
repoRoot?: string;
|
|
11
|
-
};
|
|
12
|
-
/** Encode source metadata once at transform time without allocating an object per function call. */
|
|
15
|
+
/** Resolve package ownership at transform time, never on the user's request hot path. */
|
|
13
16
|
export declare const encodeAutomaticFunctionSource: (source: AutomaticFunctionSource) => string;
|
|
14
|
-
export declare const
|
|
15
|
-
/** Connect
|
|
16
|
-
export declare const installAutomaticExecutionRuntime: (execution: RasputinExecution
|
|
17
|
+
export declare const decodeAutomaticFunctionSource: (sourceToken: string) => RuntimeFunctionDefinition | undefined;
|
|
18
|
+
/** Connect transformed application functions to this SDK instance. */
|
|
19
|
+
export declare const installAutomaticExecutionRuntime: (execution: RasputinExecution) => (() => void);
|
|
17
20
|
export {};
|
|
18
21
|
//# sourceMappingURL=automatic-runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automatic-runtime.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/automatic-runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"automatic-runtime.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/automatic-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACN,KAAK,yBAAyB,EAG9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,eAAO,MAAM,wBAAwB,kCAAkC,CAAC;AAKxE,KAAK,uBAAuB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAaF,yFAAyF;AACzF,eAAO,MAAM,6BAA6B,GAAI,QAAQ,uBAAuB,KAAG,MAO/E,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACzC,aAAa,MAAM,KACjB,yBAAyB,GAAG,SAe9B,CAAC;AAuBF,sEAAsE;AACtE,eAAO,MAAM,gCAAgC,GAAI,WAAW,iBAAiB,KAAG,CAAC,MAAM,IAAI,CAkB1F,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* event model explicit allows the same bounded state to represent HTTP requests, jobs, scheduled
|
|
4
4
|
* work, and future serverless invocations without coupling the recorder to one framework lifecycle.
|
|
5
5
|
*/
|
|
6
|
-
import type { RuntimeExecutionEvent, RuntimeExecutionKind, RuntimeExecutionMetadata, RuntimeExecutionState, RuntimeFunctionCallsSuppressedEvent, RuntimeFunctionEnterEvent } from '@rasputin-ai/core';
|
|
6
|
+
import type { RuntimeExecutionEvent, RuntimeExecutionKind, RuntimeExecutionMetadata, RuntimeExecutionState, RuntimeFunctionCallsSuppressedEvent, RuntimeFunctionDefinition, RuntimeFunctionEnterEvent, SourcePosition } from '@rasputin-ai/core';
|
|
7
7
|
export type ExecutionSourceExclusion = string | RegExp;
|
|
8
8
|
export type ExecutionRecorderOptions = {
|
|
9
9
|
/** Disable runtime-state capture explicitly. It is enabled by SDK initializers by default. */
|
|
@@ -37,6 +37,10 @@ export type ExecutionFunctionEnterEvent = RuntimeFunctionEnterEvent;
|
|
|
37
37
|
export type ExecutionFunctionCallsSuppressedEvent = RuntimeFunctionCallsSuppressedEvent;
|
|
38
38
|
export type ExecutionEvent = RuntimeExecutionEvent;
|
|
39
39
|
export type ExecutionState = RuntimeExecutionState;
|
|
40
|
+
export type ExecutionFunctionDescriptor = {
|
|
41
|
+
name: string;
|
|
42
|
+
source?: SourcePosition;
|
|
43
|
+
};
|
|
40
44
|
export type ExecutionRecorderStats = {
|
|
41
45
|
errorSnapshots: number;
|
|
42
46
|
successfulExecutionsDiscarded: number;
|
|
@@ -63,9 +67,9 @@ export type RasputinExecution = {
|
|
|
63
67
|
run: <T>(metadata: ExecutionMetadata, callback: () => T) => T;
|
|
64
68
|
getErrorState: (error: unknown, metadata?: Partial<ExecutionMetadata>) => ExecutionState | undefined;
|
|
65
69
|
/** Internal primitive used by SDK-owned source instrumentation. */
|
|
66
|
-
runFunction: <T>(
|
|
70
|
+
runFunction: <T>(definition: RuntimeFunctionDefinition | string, args: ArrayLike<unknown>, callback: () => T) => T;
|
|
67
71
|
/** Manual fallback for runtimes/build systems without automatic instrumentation. */
|
|
68
|
-
trace: <TThis, TArgs extends unknown[], TResult>(
|
|
72
|
+
trace: <TThis, TArgs extends unknown[], TResult>(definition: string | ExecutionFunctionDescriptor, fn: (this: TThis, ...args: TArgs) => TResult) => (this: TThis, ...args: TArgs) => TResult;
|
|
69
73
|
getStats: () => ExecutionRecorderStats;
|
|
70
74
|
};
|
|
71
75
|
//# sourceMappingURL=execution-recorder-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-recorder-types.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/execution-recorder-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,wBAAwB,GAAG;IACtC,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uGAAuG;IACvG,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,oBAAoB,CAAC;AACjD,MAAM,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AACpE,MAAM,MAAM,qCAAqC,GAAG,mCAAmC,CAAC;AACxF,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B,EAAE,MAAM,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,0BAA0B,EAAE,MAAM,CAAC;IACnC,2BAA2B,EAAE,MAAM,CAAC;IACpC,2BAA2B,EAAE,MAAM,CAAC;IACpC,qBAAqB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,aAAa,EAAE,CACd,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KACjC,cAAc,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,cAAc,CAAC;IAC7D,0FAA0F;IAC1F,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,aAAa,EAAE,CACd,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KACjC,cAAc,GAAG,SAAS,CAAC;IAChC,mEAAmE;IACnE,WAAW,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"execution-recorder-types.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/execution-recorder-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,wBAAwB,GAAG;IACtC,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uGAAuG;IACvG,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,oBAAoB,CAAC;AACjD,MAAM,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AACpE,MAAM,MAAM,qCAAqC,GAAG,mCAAmC,CAAC;AACxF,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAEnD,MAAM,MAAM,2BAA2B,GAAG;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B,EAAE,MAAM,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,0BAA0B,EAAE,MAAM,CAAC;IACnC,2BAA2B,EAAE,MAAM,CAAC;IACpC,2BAA2B,EAAE,MAAM,CAAC;IACpC,qBAAqB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,aAAa,EAAE,CACd,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KACjC,cAAc,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,cAAc,CAAC;IAC7D,0FAA0F;IAC1F,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,aAAa,EAAE,CACd,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KACjC,cAAc,GAAG,SAAS,CAAC;IAChC,mEAAmE;IACnE,WAAW,EAAE,CAAC,CAAC,EACd,UAAU,EAAE,yBAAyB,GAAG,MAAM,EAC9C,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,EACxB,QAAQ,EAAE,MAAM,CAAC,KACb,CAAC,CAAC;IACP,oFAAoF;IACpF,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EAC9C,UAAU,EAAE,MAAM,GAAG,2BAA2B,EAChD,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,KACxC,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;IAC9C,QAAQ,EAAE,MAAM,sBAAsB,CAAC;CACvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-recorder.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/execution-recorder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"execution-recorder.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/execution-recorder.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAKX,wBAAwB,EAExB,iBAAiB,EACjB,MAAM,4BAA4B,CAAC;AA8LpC,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,GACnC,SAAS,wBAAwB,GAAG,SAAS,KAC3C,iBAkdF,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createExecutionRecorder } from './execution-recorder';
|
|
2
|
-
export type { ExecutionKind, ExecutionMetadata, ExecutionRecorderOptions, ExecutionRecorderStats, ExecutionScope, ExecutionSourceExclusion, ExecutionState, RasputinExecution, } from './execution-recorder-types';
|
|
2
|
+
export type { ExecutionFunctionDescriptor, ExecutionKind, ExecutionMetadata, ExecutionRecorderOptions, ExecutionRecorderStats, ExecutionScope, ExecutionSourceExclusion, ExecutionState, RasputinExecution, } from './execution-recorder-types';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EACX,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,iBAAiB,GACjB,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EACX,2BAA2B,EAC3B,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,iBAAiB,GACjB,MAAM,4BAA4B,CAAC"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* capture time avoids both CPU work and accidental retention of redundant logger/framework state,
|
|
4
4
|
* while compiling patterns once keeps the exclusion feature off the hot path.
|
|
5
5
|
*/
|
|
6
|
+
import type { RuntimeFunctionDefinition } from '@rasputin-ai/core';
|
|
6
7
|
import type { ExecutionSourceExclusion } from './execution-recorder-types';
|
|
7
8
|
/** Compile exclusions once so skipped calls avoid serialization and repeated pattern work. */
|
|
8
|
-
export declare const createSourceExclusionMatcher: (exclusions: ExecutionSourceExclusion[] | undefined) => ((
|
|
9
|
+
export declare const createSourceExclusionMatcher: (exclusions: ExecutionSourceExclusion[] | undefined) => ((definition: RuntimeFunctionDefinition) => boolean);
|
|
9
10
|
//# sourceMappingURL=source-exclusions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-exclusions.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/source-exclusions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"source-exclusions.d.ts","sourceRoot":"","sources":["../../src/execution-recorder/source-exclusions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AA2C3E,8FAA8F;AAC9F,eAAO,MAAM,4BAA4B,GACxC,YAAY,wBAAwB,EAAE,GAAG,SAAS,KAChD,CAAC,CAAC,UAAU,EAAE,yBAAyB,KAAK,OAAO,CAgCrD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,23 +5,133 @@ import {
|
|
|
5
5
|
uploadInstrumentationManifest
|
|
6
6
|
} from "@rasputin-ai/core";
|
|
7
7
|
|
|
8
|
+
// src/auto-instrumentation/format-configuration-report.ts
|
|
9
|
+
var RULE = "-".repeat(64);
|
|
10
|
+
var BANNER = [
|
|
11
|
+
RULE,
|
|
12
|
+
" ____ _ ____ ____ _ _ _____ ___ _ _",
|
|
13
|
+
"| _ \\ / \\ / ___| | _ \\ | | | | |_ _| |_ _| | \\ | |",
|
|
14
|
+
"| |_) | / _ \\ \\___ \\ | |_) | | | | | | | | | | \\| |",
|
|
15
|
+
"| _ < / ___ \\ ___) | | __/ | |_| | | | | | | |\\ |",
|
|
16
|
+
"|_| \\_\\ /_/ \\_\\ |____/ |_| \\___/ |_| |___| |_| \\_|",
|
|
17
|
+
"",
|
|
18
|
+
"",
|
|
19
|
+
"CONFIGURATION:"
|
|
20
|
+
];
|
|
21
|
+
var counted = (n, singular, plural) => `${n} ${n === 1 ? singular : plural}`;
|
|
22
|
+
var issueHeadline = (issue) => {
|
|
23
|
+
const target = issue.packageName ? `package ${issue.packageName}` : issue.packageRelativePath;
|
|
24
|
+
if (issue.reason === "ambiguous") return `Could not uniquely locate ${target}.`;
|
|
25
|
+
if (issue.reason === "not_found") return `Could not find ${target} in this Git release.`;
|
|
26
|
+
if (issue.reason === "invalid_mapping") {
|
|
27
|
+
return `The configured package root for ${target} does not match this Git release.`;
|
|
28
|
+
}
|
|
29
|
+
return `GitHub could not be reached while locating ${target}.`;
|
|
30
|
+
};
|
|
31
|
+
var formatIssue = (issue) => {
|
|
32
|
+
const lines = [
|
|
33
|
+
`! ${issueHeadline(issue)}`,
|
|
34
|
+
"",
|
|
35
|
+
" Captured:",
|
|
36
|
+
` ${issue.packageRelativePath}`
|
|
37
|
+
];
|
|
38
|
+
if (issue.candidates?.length) {
|
|
39
|
+
lines.push("", " Possible repository locations:");
|
|
40
|
+
for (const candidate of issue.candidates) lines.push(` ${candidate}`);
|
|
41
|
+
}
|
|
42
|
+
return lines;
|
|
43
|
+
};
|
|
44
|
+
var formatConfigurationReport = (input) => {
|
|
45
|
+
const packages = input.verification.packages ?? [];
|
|
46
|
+
const unresolved = input.verification.unresolved;
|
|
47
|
+
const mappingIssues = unresolved.filter((issue) => issue.reason !== "github_unavailable");
|
|
48
|
+
const githubUnavailable = input.verification.status === "unavailable" || unresolved.some((issue) => issue.reason === "github_unavailable");
|
|
49
|
+
const verified = input.uploaded && input.verification.status === "verified";
|
|
50
|
+
const lines = [
|
|
51
|
+
...BANNER,
|
|
52
|
+
"",
|
|
53
|
+
"Release",
|
|
54
|
+
`\u2713 ${input.release}`,
|
|
55
|
+
"",
|
|
56
|
+
"Runtime",
|
|
57
|
+
`\u2713 ${input.runtime}`,
|
|
58
|
+
"",
|
|
59
|
+
"Instrumentation",
|
|
60
|
+
`\u2713 ${counted(input.modules, "application module", "application modules")} observed`,
|
|
61
|
+
`\u2713 ${counted(input.functions, "function", "functions")} instrumented`,
|
|
62
|
+
`\u2713 ${counted(input.packageNames.length, "workspace package", "workspace packages")} detected`
|
|
63
|
+
];
|
|
64
|
+
if (packages.length > 0 || mappingIssues.length > 0) {
|
|
65
|
+
lines.push("", "Package roots");
|
|
66
|
+
for (const mapping of packages) {
|
|
67
|
+
lines.push(
|
|
68
|
+
mapping.packageName ? `\u2713 ${mapping.packageName} \u2192 ${mapping.repositoryRoot}` : `\u2713 ${mapping.repositoryRoot}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
for (const [index, issue] of mappingIssues.entries()) {
|
|
72
|
+
if (packages.length > 0 || index > 0) lines.push("");
|
|
73
|
+
lines.push(...formatIssue(issue));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
lines.push("", "Manifest");
|
|
77
|
+
if (!input.uploaded) {
|
|
78
|
+
lines.push("! upload failed");
|
|
79
|
+
} else {
|
|
80
|
+
lines.push("\u2713 uploaded");
|
|
81
|
+
lines.push(
|
|
82
|
+
verified ? "\u2713 verified against GitHub" : "! some source files could not be mapped to this Git release"
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
lines.push("", "GitHub");
|
|
86
|
+
if (!input.uploaded) {
|
|
87
|
+
lines.push("! not verified");
|
|
88
|
+
} else if (githubUnavailable) {
|
|
89
|
+
lines.push("! repository is not connected, or this release could not be read");
|
|
90
|
+
} else {
|
|
91
|
+
lines.push("\u2713 repository connected");
|
|
92
|
+
}
|
|
93
|
+
if (input.uploaded && input.verification.status !== "verified") {
|
|
94
|
+
lines.push("", "Runtime recording is unaffected.");
|
|
95
|
+
}
|
|
96
|
+
lines.push(RULE);
|
|
97
|
+
return lines.join("\n");
|
|
98
|
+
};
|
|
99
|
+
var runtimeLabel = () => {
|
|
100
|
+
const bun = globalThis.Bun;
|
|
101
|
+
if (typeof bun?.version === "string" && bun.version) return `Bun ${bun.version}`;
|
|
102
|
+
return `Node ${process.versions.node}`;
|
|
103
|
+
};
|
|
104
|
+
|
|
8
105
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
9
|
-
import {
|
|
106
|
+
import { createHash } from "node:crypto";
|
|
107
|
+
import {
|
|
108
|
+
INSTRUMENTATION_MANIFEST_SCHEMA_VERSION,
|
|
109
|
+
sourceLocatorFromFile as sourceLocatorFromFile2
|
|
110
|
+
} from "@rasputin-ai/core";
|
|
10
111
|
|
|
11
112
|
// src/execution-recorder/automatic-runtime.ts
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
113
|
+
import {
|
|
114
|
+
runtimeFunctionId,
|
|
115
|
+
sourceLocatorFromFile
|
|
116
|
+
} from "@rasputin-ai/core";
|
|
117
|
+
var AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v2";
|
|
118
|
+
var AUTOMATIC_SOURCE_PREFIX = "rasputin-source-v2:";
|
|
15
119
|
var runtimeSymbol = Symbol.for(AUTOMATIC_RUNTIME_SYMBOL);
|
|
16
|
-
var
|
|
17
|
-
if (!sourceToken.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
120
|
+
var decodeAutomaticFunctionSource = (sourceToken) => {
|
|
121
|
+
if (!sourceToken.startsWith(AUTOMATIC_SOURCE_PREFIX)) return void 0;
|
|
122
|
+
try {
|
|
123
|
+
const parsed = JSON.parse(
|
|
124
|
+
sourceToken.slice(AUTOMATIC_SOURCE_PREFIX.length)
|
|
125
|
+
);
|
|
126
|
+
if (typeof parsed.name !== "string" || !parsed.name) return void 0;
|
|
127
|
+
const definition = {
|
|
128
|
+
name: parsed.name,
|
|
129
|
+
...parsed.source ? { source: parsed.source } : {}
|
|
130
|
+
};
|
|
131
|
+
return { ...definition, functionId: runtimeFunctionId(definition) };
|
|
132
|
+
} catch {
|
|
22
133
|
return void 0;
|
|
23
134
|
}
|
|
24
|
-
return `${fromRoot.replaceAll("\\", "/")}:${name}@${line}:${column}`;
|
|
25
135
|
};
|
|
26
136
|
var getRegistry = () => {
|
|
27
137
|
const existing = Reflect.get(globalThis, runtimeSymbol);
|
|
@@ -32,30 +142,25 @@ var getRegistry = () => {
|
|
|
32
142
|
const registry = {
|
|
33
143
|
__rasputinRuntimeRegistry: true,
|
|
34
144
|
runtimes,
|
|
35
|
-
run: (
|
|
145
|
+
run: (sourceToken, args, callback) => {
|
|
36
146
|
const runtime = runtimes.at(-1);
|
|
37
|
-
return runtime ? runtime.run(
|
|
147
|
+
return runtime ? runtime.run(sourceToken, args, callback) : callback();
|
|
38
148
|
}
|
|
39
149
|
};
|
|
40
150
|
Reflect.set(globalThis, runtimeSymbol, registry);
|
|
41
151
|
return registry;
|
|
42
152
|
};
|
|
43
|
-
var installAutomaticExecutionRuntime = (execution
|
|
153
|
+
var installAutomaticExecutionRuntime = (execution) => {
|
|
44
154
|
const registry = getRegistry();
|
|
45
|
-
const
|
|
46
|
-
const normalizedIds = /* @__PURE__ */ new Map();
|
|
155
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
47
156
|
const runtime = {
|
|
48
157
|
run: (sourceToken, args, callback) => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
let functionId = normalizedIds.get(sourceToken);
|
|
54
|
-
if (!normalizedIds.has(sourceToken)) {
|
|
55
|
-
functionId = normalizeAutomaticFunctionId(sourceToken, repoRoot);
|
|
56
|
-
normalizedIds.set(sourceToken, functionId);
|
|
158
|
+
let definition = definitions.get(sourceToken);
|
|
159
|
+
if (!definitions.has(sourceToken)) {
|
|
160
|
+
definition = decodeAutomaticFunctionSource(sourceToken);
|
|
161
|
+
definitions.set(sourceToken, definition);
|
|
57
162
|
}
|
|
58
|
-
return
|
|
163
|
+
return definition ? execution.runFunction(definition, args, callback) : callback();
|
|
59
164
|
}
|
|
60
165
|
};
|
|
61
166
|
registry.runtimes.push(runtime);
|
|
@@ -66,7 +171,7 @@ var installAutomaticExecutionRuntime = (execution, options = {}) => {
|
|
|
66
171
|
};
|
|
67
172
|
|
|
68
173
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
69
|
-
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.
|
|
174
|
+
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.v2";
|
|
70
175
|
var registrySymbol = Symbol.for(INSTRUMENTATION_MANIFEST_SYMBOL);
|
|
71
176
|
var getRegistry2 = () => {
|
|
72
177
|
const existing = Reflect.get(globalThis, registrySymbol);
|
|
@@ -82,31 +187,28 @@ var getRegistry2 = () => {
|
|
|
82
187
|
Reflect.set(globalThis, registrySymbol, registry);
|
|
83
188
|
return registry;
|
|
84
189
|
};
|
|
85
|
-
var
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
return void 0;
|
|
89
|
-
}
|
|
90
|
-
return fromRoot.replaceAll("\\", "/");
|
|
190
|
+
var sourceAt = (filePath, line, column) => {
|
|
191
|
+
const source = sourceLocatorFromFile2(filePath);
|
|
192
|
+
return source ? { ...source, line, column } : void 0;
|
|
91
193
|
};
|
|
194
|
+
var stableId = (kind, ...parts) => `${kind}_${createHash("sha256").update(parts.join("\0")).digest("base64url").slice(0, 24)}`;
|
|
92
195
|
var isInstrumentationManifestDirty = () => {
|
|
93
196
|
const registry = getRegistry2();
|
|
94
197
|
return registry.generation !== registry.uploadedGeneration && registry.files.size > 0;
|
|
95
198
|
};
|
|
96
199
|
var instrumentationManifestGeneration = () => getRegistry2().generation;
|
|
97
|
-
var
|
|
200
|
+
var instrumentationManifestModuleCount = () => getRegistry2().files.size;
|
|
201
|
+
var snapshotInstrumentationManifest = (options = {}) => {
|
|
98
202
|
const functions = [];
|
|
99
203
|
const callSites = [];
|
|
100
204
|
const destructures = [];
|
|
101
|
-
const root = resolve2(repoRoot);
|
|
102
205
|
for (const delta of getRegistry2().files.values()) {
|
|
103
206
|
for (const fn of delta.functions) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
if (!functionId || !path) continue;
|
|
207
|
+
const definition = decodeAutomaticFunctionSource(fn.sourceToken);
|
|
208
|
+
if (!definition?.source) continue;
|
|
107
209
|
functions.push({
|
|
108
|
-
functionId,
|
|
109
|
-
|
|
210
|
+
functionId: definition.functionId,
|
|
211
|
+
source: definition.source,
|
|
110
212
|
name: fn.name,
|
|
111
213
|
startLine: fn.startLine,
|
|
112
214
|
startColumn: fn.startColumn,
|
|
@@ -116,15 +218,22 @@ var snapshotInstrumentationManifest = (repoRoot) => {
|
|
|
116
218
|
});
|
|
117
219
|
}
|
|
118
220
|
for (const site of delta.callSites) {
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
if (!
|
|
221
|
+
const caller = decodeAutomaticFunctionSource(site.callerSourceToken);
|
|
222
|
+
const source = sourceAt(site.filePath, site.line, site.column);
|
|
223
|
+
if (!caller || !source) continue;
|
|
122
224
|
callSites.push({
|
|
123
|
-
id:
|
|
124
|
-
|
|
225
|
+
id: stableId(
|
|
226
|
+
"cs",
|
|
227
|
+
caller.functionId,
|
|
228
|
+
source.packageName ?? "",
|
|
229
|
+
source.packageRelativePath,
|
|
230
|
+
site.line,
|
|
231
|
+
site.column
|
|
232
|
+
),
|
|
233
|
+
callerFunctionId: caller.functionId,
|
|
125
234
|
calleeName: site.calleeName,
|
|
126
235
|
calleeText: site.calleeText,
|
|
127
|
-
|
|
236
|
+
source,
|
|
128
237
|
line: site.line,
|
|
129
238
|
column: site.column,
|
|
130
239
|
endLine: site.endLine,
|
|
@@ -134,13 +243,13 @@ var snapshotInstrumentationManifest = (repoRoot) => {
|
|
|
134
243
|
});
|
|
135
244
|
}
|
|
136
245
|
for (const destructure of delta.destructures) {
|
|
137
|
-
const
|
|
138
|
-
const
|
|
139
|
-
if (!
|
|
246
|
+
const caller = decodeAutomaticFunctionSource(destructure.callerSourceToken);
|
|
247
|
+
const source = sourceAt(destructure.filePath, destructure.line, destructure.column);
|
|
248
|
+
if (!caller || !source) continue;
|
|
140
249
|
destructures.push({
|
|
141
|
-
callerFunctionId,
|
|
250
|
+
callerFunctionId: caller.functionId,
|
|
142
251
|
sourceParam: destructure.sourceParam,
|
|
143
|
-
|
|
252
|
+
source,
|
|
144
253
|
line: destructure.line,
|
|
145
254
|
column: destructure.column,
|
|
146
255
|
binding: destructure.binding
|
|
@@ -150,8 +259,15 @@ var snapshotInstrumentationManifest = (repoRoot) => {
|
|
|
150
259
|
if (functions.length === 0 && callSites.length === 0 && destructures.length === 0) {
|
|
151
260
|
return void 0;
|
|
152
261
|
}
|
|
262
|
+
const packages = { ...options.sourceRoots ?? {} };
|
|
153
263
|
return {
|
|
154
|
-
schema_version:
|
|
264
|
+
schema_version: INSTRUMENTATION_MANIFEST_SCHEMA_VERSION,
|
|
265
|
+
...options.sourceRoot || Object.keys(packages).length > 0 ? {
|
|
266
|
+
sourceRoots: {
|
|
267
|
+
...options.sourceRoot ? { default: options.sourceRoot } : {},
|
|
268
|
+
packages
|
|
269
|
+
}
|
|
270
|
+
} : {},
|
|
155
271
|
functions,
|
|
156
272
|
callSites,
|
|
157
273
|
destructures
|
|
@@ -159,35 +275,63 @@ var snapshotInstrumentationManifest = (repoRoot) => {
|
|
|
159
275
|
};
|
|
160
276
|
var markInstrumentationManifestUploaded = (generation) => {
|
|
161
277
|
const registry = getRegistry2();
|
|
162
|
-
if (registry.generation === generation)
|
|
163
|
-
registry.uploadedGeneration = generation;
|
|
164
|
-
}
|
|
278
|
+
if (registry.generation === generation) registry.uploadedGeneration = generation;
|
|
165
279
|
};
|
|
166
280
|
var setInstrumentationManifestOnDirty = (onDirty) => {
|
|
167
281
|
getRegistry2().onDirty = onDirty;
|
|
168
282
|
};
|
|
169
283
|
|
|
170
284
|
// src/auto-instrumentation/schedule-instrumentation-manifest-upload.ts
|
|
285
|
+
var unavailable = () => ({
|
|
286
|
+
status: "unavailable",
|
|
287
|
+
verified: 0,
|
|
288
|
+
unresolved: [],
|
|
289
|
+
packages: []
|
|
290
|
+
});
|
|
171
291
|
var noopHandle = {
|
|
172
292
|
flushSoon() {
|
|
173
293
|
},
|
|
174
294
|
async wait() {
|
|
175
295
|
},
|
|
176
296
|
disconnect() {
|
|
297
|
+
},
|
|
298
|
+
async verify() {
|
|
299
|
+
return unavailable();
|
|
177
300
|
}
|
|
178
301
|
};
|
|
179
302
|
var scheduleInstrumentationManifestUpload = (options) => {
|
|
180
303
|
const release = detectRelease({ release: options.release });
|
|
181
|
-
|
|
182
|
-
if (!options.enabled || !release || !repoRoot || !options.projectApiKey.trim()) {
|
|
304
|
+
if (!options.enabled || !release || !options.projectApiKey.trim()) {
|
|
183
305
|
return noopHandle;
|
|
184
306
|
}
|
|
185
307
|
const { instrumentationManifestUrl } = resolveEndpointUrls(options.apiUrl);
|
|
186
308
|
let inflight;
|
|
309
|
+
let verification = unavailable();
|
|
310
|
+
let loggedSuccess = false;
|
|
311
|
+
let loggedFailure = false;
|
|
312
|
+
const packageNamesOf = (manifest) => [
|
|
313
|
+
...new Set(
|
|
314
|
+
manifest.functions.map((fn) => fn.source.packageName).filter((name) => Boolean(name))
|
|
315
|
+
)
|
|
316
|
+
].sort();
|
|
317
|
+
const report = (manifest, uploaded, next) => {
|
|
318
|
+
return formatConfigurationReport({
|
|
319
|
+
release,
|
|
320
|
+
runtime: runtimeLabel(),
|
|
321
|
+
modules: instrumentationManifestModuleCount(),
|
|
322
|
+
functions: manifest.functions.length,
|
|
323
|
+
packageNames: packageNamesOf(manifest),
|
|
324
|
+
verification: next,
|
|
325
|
+
uploaded
|
|
326
|
+
});
|
|
327
|
+
};
|
|
187
328
|
const flushSoon = () => {
|
|
188
329
|
if (!isInstrumentationManifestDirty()) return;
|
|
189
330
|
const generation = instrumentationManifestGeneration();
|
|
190
|
-
const manifest = snapshotInstrumentationManifest(
|
|
331
|
+
const manifest = snapshotInstrumentationManifest({
|
|
332
|
+
sourceRoot: options.sourceRoot,
|
|
333
|
+
sourceRoots: options.sourceRoots
|
|
334
|
+
});
|
|
191
335
|
if (!manifest) {
|
|
192
336
|
markInstrumentationManifestUploaded(generation);
|
|
193
337
|
return;
|
|
@@ -199,7 +343,26 @@ var scheduleInstrumentationManifestUpload = (options) => {
|
|
|
199
343
|
manifest,
|
|
200
344
|
fetch: options.fetch
|
|
201
345
|
}).then((result) => {
|
|
202
|
-
if (result
|
|
346
|
+
if (result.ok) {
|
|
347
|
+
verification = result.verification;
|
|
348
|
+
markInstrumentationManifestUploaded(generation);
|
|
349
|
+
if (verification.status === "verified") {
|
|
350
|
+
if (!loggedSuccess && options.logSuccess !== false) {
|
|
351
|
+
loggedSuccess = true;
|
|
352
|
+
console.info(report(manifest, true, verification));
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (!loggedFailure) {
|
|
357
|
+
loggedFailure = true;
|
|
358
|
+
console.warn(report(manifest, true, verification));
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (!loggedFailure) {
|
|
363
|
+
loggedFailure = true;
|
|
364
|
+
console.warn(report(manifest, false, unavailable()));
|
|
365
|
+
}
|
|
203
366
|
});
|
|
204
367
|
inflight = inflight ? inflight.then(() => work) : work;
|
|
205
368
|
};
|
|
@@ -212,12 +375,18 @@ var scheduleInstrumentationManifestUpload = (options) => {
|
|
|
212
375
|
},
|
|
213
376
|
disconnect: () => {
|
|
214
377
|
setInstrumentationManifestOnDirty(void 0);
|
|
378
|
+
},
|
|
379
|
+
verify: async () => {
|
|
380
|
+
flushSoon();
|
|
381
|
+
await inflight;
|
|
382
|
+
return verification;
|
|
215
383
|
}
|
|
216
384
|
};
|
|
217
385
|
};
|
|
218
386
|
|
|
219
387
|
// src/execution-recorder/execution-recorder.ts
|
|
220
388
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
389
|
+
import { runtimeFunctionId as runtimeFunctionId2 } from "@rasputin-ai/core";
|
|
221
390
|
|
|
222
391
|
// src/execution-recorder/call-aware-event-buffer.ts
|
|
223
392
|
var CallAwareEventBuffer = class {
|
|
@@ -577,9 +746,10 @@ var safeSerializeWithBytes = (value, options = {}) => {
|
|
|
577
746
|
var safeSerialize = (value, options = {}) => safeSerializeWithBytes(value, options).value;
|
|
578
747
|
|
|
579
748
|
// src/execution-recorder/source-exclusions.ts
|
|
580
|
-
var sourcePathFrom = (
|
|
581
|
-
|
|
582
|
-
|
|
749
|
+
var sourcePathFrom = (definition) => definition.source?.packageRelativePath.replaceAll("\\", "/") ?? definition.name;
|
|
750
|
+
var searchableIdentity = (definition) => {
|
|
751
|
+
const source = definition.source;
|
|
752
|
+
return source ? `${source.packageName ? `${source.packageName}:` : ""}${source.packageRelativePath}:${definition.name}@${source.line ?? ""}:${source.column ?? ""}` : definition.name;
|
|
583
753
|
};
|
|
584
754
|
var normalizePattern = (pattern) => pattern.trim().replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
585
755
|
var globRegex = (pattern) => {
|
|
@@ -610,35 +780,51 @@ var globRegex = (pattern) => {
|
|
|
610
780
|
return new RegExp(`^${expression}$`);
|
|
611
781
|
};
|
|
612
782
|
var createSourceExclusionMatcher = (exclusions) => {
|
|
613
|
-
const matchers = (exclusions ?? []).flatMap(
|
|
614
|
-
|
|
783
|
+
const matchers = (exclusions ?? []).flatMap(
|
|
784
|
+
(exclusion) => {
|
|
785
|
+
if (exclusion instanceof RegExp) {
|
|
786
|
+
return [
|
|
787
|
+
(definition) => {
|
|
788
|
+
exclusion.lastIndex = 0;
|
|
789
|
+
const matched = exclusion.test(searchableIdentity(definition));
|
|
790
|
+
exclusion.lastIndex = 0;
|
|
791
|
+
return matched;
|
|
792
|
+
}
|
|
793
|
+
];
|
|
794
|
+
}
|
|
795
|
+
const pattern = normalizePattern(exclusion);
|
|
796
|
+
if (!pattern) return [];
|
|
797
|
+
if (pattern.includes("*") || pattern.includes("?")) {
|
|
798
|
+
const regex = globRegex(pattern);
|
|
799
|
+
return [(definition) => regex.test(sourcePathFrom(definition))];
|
|
800
|
+
}
|
|
615
801
|
return [
|
|
616
|
-
(
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
exclusion.lastIndex = 0;
|
|
620
|
-
return matched;
|
|
802
|
+
(definition) => {
|
|
803
|
+
const sourcePath = sourcePathFrom(definition);
|
|
804
|
+
return sourcePath === pattern || sourcePath.startsWith(`${pattern}/`);
|
|
621
805
|
}
|
|
622
806
|
];
|
|
623
807
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if (pattern.includes("*") || pattern.includes("?")) {
|
|
627
|
-
const regex = globRegex(pattern);
|
|
628
|
-
return [(functionId) => regex.test(sourcePathFrom(functionId))];
|
|
629
|
-
}
|
|
630
|
-
return [
|
|
631
|
-
(functionId) => {
|
|
632
|
-
const sourcePath = sourcePathFrom(functionId);
|
|
633
|
-
return sourcePath === pattern || sourcePath.startsWith(`${pattern}/`);
|
|
634
|
-
}
|
|
635
|
-
];
|
|
636
|
-
});
|
|
637
|
-
return matchers.length === 0 ? () => false : (functionId) => matchers.some((matcher) => matcher(functionId));
|
|
808
|
+
);
|
|
809
|
+
return matchers.length === 0 ? () => false : (definition) => matchers.some((matcher) => matcher(definition));
|
|
638
810
|
};
|
|
639
811
|
|
|
640
812
|
// src/execution-recorder/execution-recorder.ts
|
|
641
813
|
var DEFAULT_MAX_ACTIVE_MEMORY_BYTES = 64 * 1024 * 1024;
|
|
814
|
+
var manualFunctionDefinition = (value) => {
|
|
815
|
+
const located = /^(.+):([^:@]+)@(\d+):(\d+)$/.exec(value);
|
|
816
|
+
const named = located ? void 0 : /^(.+):([^:@]+)$/.exec(value);
|
|
817
|
+
const path = located?.[1] ?? named?.[1];
|
|
818
|
+
const name = located?.[2] ?? named?.[2] ?? value;
|
|
819
|
+
const source = path ? {
|
|
820
|
+
packageRelativePath: path.replaceAll("\\", "/").replace(/^\.\//, ""),
|
|
821
|
+
...located?.[3] ? { line: Number(located[3]) } : {},
|
|
822
|
+
...located?.[4] ? { column: Number(located[4]) } : {}
|
|
823
|
+
} : void 0;
|
|
824
|
+
const definition = { name, ...source ? { source } : {} };
|
|
825
|
+
return { ...definition, functionId: runtimeFunctionId2(definition) };
|
|
826
|
+
};
|
|
827
|
+
var normalizeFunctionDefinition = (value) => typeof value === "string" ? manualFunctionDefinition(value) : value;
|
|
642
828
|
var elapsedMs = (startedAtNs, endedAtNs = process.hrtime.bigint()) => Number(endedAtNs - startedAtNs) / 1e6;
|
|
643
829
|
var roundedMilliseconds = (nanoseconds) => Math.round(Number(nanoseconds) / 1e6 * 1e4) / 1e4;
|
|
644
830
|
var addRecorderTime = (recording, nanoseconds) => {
|
|
@@ -773,8 +959,14 @@ var createExecutionRecorder = (options) => {
|
|
|
773
959
|
const captureValue = (recording, value) => memoryBudget.captureValue(recording.memory, () => safeSerializeWithBytes(value, options));
|
|
774
960
|
const stateFrom = (recording, endedAtNs = process.hrtime.bigint()) => {
|
|
775
961
|
const recorderStartedAtNs = process.hrtime.bigint();
|
|
962
|
+
const events = recording.events.values().map((event) => event.type === "function_calls_suppressed" ? { ...event } : event);
|
|
963
|
+
const referencedFunctionIds = new Set(
|
|
964
|
+
events.flatMap(
|
|
965
|
+
(event) => event.type === "function_enter" || event.type === "function_calls_suppressed" ? [event.functionId] : []
|
|
966
|
+
)
|
|
967
|
+
);
|
|
776
968
|
const state = {
|
|
777
|
-
version:
|
|
969
|
+
version: 2,
|
|
778
970
|
executionId: recording.executionId,
|
|
779
971
|
startedAt: recording.startedAt,
|
|
780
972
|
durationMs: elapsedMs(recording.startedAtNs, endedAtNs),
|
|
@@ -783,7 +975,10 @@ var createExecutionRecorder = (options) => {
|
|
|
783
975
|
...recording.execution,
|
|
784
976
|
...recording.execution.request ? { request: { ...recording.execution.request } } : {}
|
|
785
977
|
},
|
|
786
|
-
|
|
978
|
+
functions: [...recording.functions.values()].filter(
|
|
979
|
+
(definition) => referencedFunctionIds.has(definition.functionId)
|
|
980
|
+
),
|
|
981
|
+
events,
|
|
787
982
|
...recording.events.dropped > 0 ? { truncated: { eventsDropped: recording.events.dropped } } : {},
|
|
788
983
|
...recording.memory.underPressure ? {
|
|
789
984
|
capture: {
|
|
@@ -925,6 +1120,7 @@ var createExecutionRecorder = (options) => {
|
|
|
925
1120
|
...metadata.request ? { request: { ...metadata.request } } : {}
|
|
926
1121
|
},
|
|
927
1122
|
events: new CallAwareEventBuffer(maxEventsPerExecution),
|
|
1123
|
+
functions: /* @__PURE__ */ new Map(),
|
|
928
1124
|
repeatedCalls: /* @__PURE__ */ new Map(),
|
|
929
1125
|
capturedErrors: /* @__PURE__ */ new WeakMap(),
|
|
930
1126
|
nextCallId: 0,
|
|
@@ -993,16 +1189,19 @@ var createExecutionRecorder = (options) => {
|
|
|
993
1189
|
return void 0;
|
|
994
1190
|
}
|
|
995
1191
|
};
|
|
996
|
-
const runFunction = (
|
|
1192
|
+
const runFunction = (input, args, callback) => {
|
|
997
1193
|
const store = storage.getStore();
|
|
998
1194
|
if (!store || store.recording.finished) return callback();
|
|
1195
|
+
const definition = normalizeFunctionDefinition(input);
|
|
1196
|
+
const functionId = definition.functionId;
|
|
999
1197
|
const recorderStartedAtNs = process.hrtime.bigint();
|
|
1000
|
-
if (store.suppressCapture || excludesSource(
|
|
1198
|
+
if (store.suppressCapture || excludesSource(definition)) {
|
|
1001
1199
|
return storage.run({ ...store, suppressCapture: true }, () => {
|
|
1002
1200
|
addRecorderTime(store.recording, process.hrtime.bigint() - recorderStartedAtNs);
|
|
1003
1201
|
return callback();
|
|
1004
1202
|
});
|
|
1005
1203
|
}
|
|
1204
|
+
store.recording.functions.set(functionId, definition);
|
|
1006
1205
|
const parentCallId = store.currentCallId;
|
|
1007
1206
|
const group = repeatedCallGroup(store.recording, functionId, parentCallId);
|
|
1008
1207
|
group.observedCalls++;
|
|
@@ -1111,9 +1310,10 @@ var createExecutionRecorder = (options) => {
|
|
|
1111
1310
|
)
|
|
1112
1311
|
);
|
|
1113
1312
|
};
|
|
1114
|
-
function trace(
|
|
1313
|
+
function trace(input, fn) {
|
|
1314
|
+
const definition = typeof input === "string" ? manualFunctionDefinition(input) : { ...input, functionId: runtimeFunctionId2(input) };
|
|
1115
1315
|
return function traced(...args) {
|
|
1116
|
-
return runFunction(
|
|
1316
|
+
return runFunction(definition, args, () => fn.apply(this, args));
|
|
1117
1317
|
};
|
|
1118
1318
|
}
|
|
1119
1319
|
return {
|
|
@@ -1177,26 +1377,23 @@ var installGlobalHandlers = (client, options = {}) => {
|
|
|
1177
1377
|
// src/rasputin-init.ts
|
|
1178
1378
|
import {
|
|
1179
1379
|
createClient,
|
|
1180
|
-
isClientEnabled
|
|
1181
|
-
resolveRepoRoot
|
|
1380
|
+
isClientEnabled
|
|
1182
1381
|
} from "@rasputin-ai/core";
|
|
1183
1382
|
|
|
1184
1383
|
// src/sdk-meta.ts
|
|
1185
1384
|
var SDK_NAME = "@rasputin-ai/node";
|
|
1186
|
-
var SDK_VERSION = "0.
|
|
1385
|
+
var SDK_VERSION = "0.4.0";
|
|
1187
1386
|
|
|
1188
1387
|
// src/rasputin-init.ts
|
|
1189
|
-
var withExecution = (client, execution, installRuntime,
|
|
1190
|
-
const uninstallRuntime = installRuntime ? installAutomaticExecutionRuntime(execution
|
|
1388
|
+
var withExecution = (client, execution, installRuntime, manifest) => {
|
|
1389
|
+
const uninstallRuntime = installRuntime ? installAutomaticExecutionRuntime(execution) : () => {
|
|
1191
1390
|
};
|
|
1192
|
-
const manifestUpload = scheduleInstrumentationManifestUpload(
|
|
1193
|
-
...manifest,
|
|
1194
|
-
repoRoot
|
|
1195
|
-
});
|
|
1391
|
+
const manifestUpload = scheduleInstrumentationManifestUpload(manifest);
|
|
1196
1392
|
return {
|
|
1197
1393
|
...client,
|
|
1198
1394
|
execution,
|
|
1199
1395
|
getStats: () => ({ ...client.getStats(), recorder: execution.getStats() }),
|
|
1396
|
+
verifyConfiguration: manifestUpload.verify,
|
|
1200
1397
|
captureException: (error, context) => {
|
|
1201
1398
|
const runtimeState = context?.runtimeState ?? execution.getErrorState(
|
|
1202
1399
|
error,
|
|
@@ -1226,18 +1423,15 @@ var RasputinInit = (options) => {
|
|
|
1226
1423
|
...options.executionRecorder,
|
|
1227
1424
|
enabled: recorderEnabled
|
|
1228
1425
|
});
|
|
1229
|
-
const wrappedClient = withExecution(
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
enabled: isClientEnabled(options)
|
|
1239
|
-
}
|
|
1240
|
-
);
|
|
1426
|
+
const wrappedClient = withExecution(client, execution, recorderEnabled, {
|
|
1427
|
+
projectApiKey: options.projectApiKey,
|
|
1428
|
+
release: options.release,
|
|
1429
|
+
apiUrl: options.apiUrl,
|
|
1430
|
+
enabled: isClientEnabled(options),
|
|
1431
|
+
sourceRoot: options.sourceRoot,
|
|
1432
|
+
sourceRoots: options.sourceRoots,
|
|
1433
|
+
logSuccess: options.logSuccess
|
|
1434
|
+
});
|
|
1241
1435
|
if (isClientEnabled(options)) {
|
|
1242
1436
|
installGlobalHandlers(wrappedClient);
|
|
1243
1437
|
}
|
|
@@ -1247,12 +1441,14 @@ var RasputinInit = (options) => {
|
|
|
1247
1441
|
createClient({ ...options, enabled: false }),
|
|
1248
1442
|
createExecutionRecorder({ enabled: false }),
|
|
1249
1443
|
false,
|
|
1250
|
-
void 0,
|
|
1251
1444
|
{
|
|
1252
1445
|
projectApiKey: options.projectApiKey,
|
|
1253
1446
|
release: options.release,
|
|
1254
1447
|
apiUrl: options.apiUrl,
|
|
1255
|
-
enabled: false
|
|
1448
|
+
enabled: false,
|
|
1449
|
+
sourceRoot: options.sourceRoot,
|
|
1450
|
+
sourceRoots: options.sourceRoots,
|
|
1451
|
+
logSuccess: options.logSuccess
|
|
1256
1452
|
}
|
|
1257
1453
|
);
|
|
1258
1454
|
}
|
package/dist/instrument/bun.js
CHANGED
|
@@ -3,22 +3,34 @@ import { plugin } from "bun";
|
|
|
3
3
|
|
|
4
4
|
// src/auto-instrumentation/bun-plugin.ts
|
|
5
5
|
import { readFile } from "node:fs/promises";
|
|
6
|
-
import { resolve as
|
|
6
|
+
import { resolve as resolve4 } from "node:path";
|
|
7
7
|
|
|
8
8
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
9
|
-
import {
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import {
|
|
11
|
+
INSTRUMENTATION_MANIFEST_SCHEMA_VERSION,
|
|
12
|
+
sourceLocatorFromFile as sourceLocatorFromFile2
|
|
13
|
+
} from "@rasputin-ai/core";
|
|
10
14
|
|
|
11
15
|
// src/execution-recorder/automatic-runtime.ts
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
import {
|
|
17
|
+
runtimeFunctionId,
|
|
18
|
+
sourceLocatorFromFile
|
|
19
|
+
} from "@rasputin-ai/core";
|
|
20
|
+
var AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v2";
|
|
21
|
+
var AUTOMATIC_SOURCE_PREFIX = "rasputin-source-v2:";
|
|
15
22
|
var runtimeSymbol = Symbol.for(AUTOMATIC_RUNTIME_SYMBOL);
|
|
16
|
-
var encodeAutomaticFunctionSource = (source) =>
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
var encodeAutomaticFunctionSource = (source) => {
|
|
24
|
+
const locator = sourceLocatorFromFile(source.filePath);
|
|
25
|
+
const value = {
|
|
26
|
+
name: source.name,
|
|
27
|
+
...locator ? { source: { ...locator, line: source.line, column: source.column } } : {}
|
|
28
|
+
};
|
|
29
|
+
return `${AUTOMATIC_SOURCE_PREFIX}${JSON.stringify(value)}`;
|
|
30
|
+
};
|
|
19
31
|
|
|
20
32
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
21
|
-
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.
|
|
33
|
+
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.v2";
|
|
22
34
|
var registrySymbol = Symbol.for(INSTRUMENTATION_MANIFEST_SYMBOL);
|
|
23
35
|
var getRegistry = () => {
|
|
24
36
|
const existing = Reflect.get(globalThis, registrySymbol);
|
|
@@ -36,13 +48,13 @@ var getRegistry = () => {
|
|
|
36
48
|
};
|
|
37
49
|
var recordInstrumentationManifestDelta = (filePath, delta) => {
|
|
38
50
|
const registry = getRegistry();
|
|
39
|
-
registry.files.set(
|
|
51
|
+
registry.files.set(resolve(filePath), delta);
|
|
40
52
|
registry.generation += 1;
|
|
41
53
|
registry.onDirty?.();
|
|
42
54
|
};
|
|
43
55
|
|
|
44
56
|
// src/auto-instrumentation/source-classification.ts
|
|
45
|
-
import { isAbsolute
|
|
57
|
+
import { isAbsolute, relative, resolve as resolve2, sep } from "node:path";
|
|
46
58
|
var sourceExtension = /\.[cm]?[jt]sx?$/i;
|
|
47
59
|
var alwaysExcludedDirectory = /(^|[\\/])(node_modules|coverage|generated|\.git|\.next|\.svelte-kit|\.output|\.vercel|\.rasputin|\.turbo|\.yarn|\.pnpm|\.bun)([\\/]|$)/;
|
|
48
60
|
var buildOutputDirectory = /(^|[\\/])(dist|build|out)([\\/]|$)/;
|
|
@@ -53,11 +65,11 @@ var matches = (pattern, value) => {
|
|
|
53
65
|
return result;
|
|
54
66
|
};
|
|
55
67
|
var isWithinRoot = (filePath, root) => {
|
|
56
|
-
const fromRoot =
|
|
57
|
-
return fromRoot === "" || !fromRoot.startsWith(`..${
|
|
68
|
+
const fromRoot = relative(resolve2(root), filePath);
|
|
69
|
+
return fromRoot === "" || !fromRoot.startsWith(`..${sep}`) && fromRoot !== ".." && !isAbsolute(fromRoot);
|
|
58
70
|
};
|
|
59
71
|
var isApplicationSource = (filePath, options = {}) => {
|
|
60
|
-
const absolutePath =
|
|
72
|
+
const absolutePath = resolve2(filePath);
|
|
61
73
|
if (!sourceExtension.test(absolutePath) || alwaysExcludedDirectory.test(absolutePath))
|
|
62
74
|
return false;
|
|
63
75
|
if (options.includeBuildOutput !== true && buildOutputDirectory.test(absolutePath)) return false;
|
|
@@ -71,7 +83,7 @@ var isApplicationSource = (filePath, options = {}) => {
|
|
|
71
83
|
};
|
|
72
84
|
|
|
73
85
|
// src/auto-instrumentation/transform-source.ts
|
|
74
|
-
import { resolve as
|
|
86
|
+
import { resolve as resolve3 } from "node:path";
|
|
75
87
|
import ts2 from "typescript";
|
|
76
88
|
|
|
77
89
|
// src/auto-instrumentation/collect-instrumentation-delta.ts
|
|
@@ -348,7 +360,7 @@ var transformSource = (source, options) => {
|
|
|
348
360
|
);
|
|
349
361
|
let helperName = "__rasputinAutoRun__";
|
|
350
362
|
while (source.includes(helperName)) helperName += "_";
|
|
351
|
-
const absolutePath =
|
|
363
|
+
const absolutePath = resolve3(options.filePath);
|
|
352
364
|
const edits = [];
|
|
353
365
|
let order = 0;
|
|
354
366
|
const delta = {
|
|
@@ -423,7 +435,7 @@ var loaderFor = (filePath) => {
|
|
|
423
435
|
var loadedSourceFilter = /^(?!.*[\\/](?:node_modules|dist|build|out|coverage|generated|\.git|\.next|\.svelte-kit|\.output|\.vercel|\.rasputin|\.turbo|\.yarn|\.pnpm|\.bun)[\\/]).*\.[cm]?[jt]sx?$/i;
|
|
424
436
|
var isLoadedApplicationSource = (filePath, options = {}) => isApplicationSource(filePath, { ...options, includeBuildOutput: false });
|
|
425
437
|
var loadSourceForInstrumentation = async (filePath, options = {}) => {
|
|
426
|
-
const absolutePath =
|
|
438
|
+
const absolutePath = resolve4(filePath);
|
|
427
439
|
const source = await readFile(absolutePath, "utf8");
|
|
428
440
|
if (!isLoadedApplicationSource(absolutePath, options)) {
|
|
429
441
|
return { contents: source, loader: loaderFor(absolutePath), transformed: false };
|
|
@@ -449,11 +461,11 @@ var createRasputinBunPlugin = (options = {}) => {
|
|
|
449
461
|
setup(build) {
|
|
450
462
|
if (debug) {
|
|
451
463
|
console.info(
|
|
452
|
-
options.rootDir ? `[rasputin] automatic instrumentation active (source root: ${
|
|
464
|
+
options.rootDir ? `[rasputin] automatic instrumentation active (source root: ${resolve4(options.rootDir)})` : "[rasputin] automatic instrumentation active (loaded local source)"
|
|
453
465
|
);
|
|
454
466
|
}
|
|
455
467
|
build.onLoad({ filter: loadedSourceFilter }, async ({ path }) => {
|
|
456
|
-
const absolutePath =
|
|
468
|
+
const absolutePath = resolve4(path);
|
|
457
469
|
const result = await loadSourceForInstrumentation(absolutePath, options);
|
|
458
470
|
if (debug && result.transformed) {
|
|
459
471
|
console.info(`[rasputin] instrumented ${absolutePath}`);
|
|
@@ -465,9 +477,9 @@ var createRasputinBunPlugin = (options = {}) => {
|
|
|
465
477
|
};
|
|
466
478
|
|
|
467
479
|
// src/auto-instrumentation/sdk-source-boundary.ts
|
|
468
|
-
import { dirname, resolve as
|
|
480
|
+
import { dirname, resolve as resolve5 } from "node:path";
|
|
469
481
|
import { fileURLToPath } from "node:url";
|
|
470
|
-
var sdkPackageScopeRootFrom = (instrumentEntryUrl) =>
|
|
482
|
+
var sdkPackageScopeRootFrom = (instrumentEntryUrl) => resolve5(dirname(fileURLToPath(instrumentEntryUrl)), "../../..");
|
|
471
483
|
|
|
472
484
|
// src/instrument/bun.ts
|
|
473
485
|
plugin(
|
package/dist/instrument/node.js
CHANGED
|
@@ -3,19 +3,31 @@ import * as nodeModule from "node:module";
|
|
|
3
3
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4
4
|
|
|
5
5
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
6
|
-
import {
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import {
|
|
8
|
+
INSTRUMENTATION_MANIFEST_SCHEMA_VERSION,
|
|
9
|
+
sourceLocatorFromFile as sourceLocatorFromFile2
|
|
10
|
+
} from "@rasputin-ai/core";
|
|
7
11
|
|
|
8
12
|
// src/execution-recorder/automatic-runtime.ts
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
import {
|
|
14
|
+
runtimeFunctionId,
|
|
15
|
+
sourceLocatorFromFile
|
|
16
|
+
} from "@rasputin-ai/core";
|
|
17
|
+
var AUTOMATIC_RUNTIME_SYMBOL = "rasputin.execution.runtime.v2";
|
|
18
|
+
var AUTOMATIC_SOURCE_PREFIX = "rasputin-source-v2:";
|
|
12
19
|
var runtimeSymbol = Symbol.for(AUTOMATIC_RUNTIME_SYMBOL);
|
|
13
|
-
var encodeAutomaticFunctionSource = (source) =>
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
var encodeAutomaticFunctionSource = (source) => {
|
|
21
|
+
const locator = sourceLocatorFromFile(source.filePath);
|
|
22
|
+
const value = {
|
|
23
|
+
name: source.name,
|
|
24
|
+
...locator ? { source: { ...locator, line: source.line, column: source.column } } : {}
|
|
25
|
+
};
|
|
26
|
+
return `${AUTOMATIC_SOURCE_PREFIX}${JSON.stringify(value)}`;
|
|
27
|
+
};
|
|
16
28
|
|
|
17
29
|
// src/auto-instrumentation/instrumentation-manifest-registry.ts
|
|
18
|
-
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.
|
|
30
|
+
var INSTRUMENTATION_MANIFEST_SYMBOL = "rasputin.instrumentation.manifest.v2";
|
|
19
31
|
var registrySymbol = Symbol.for(INSTRUMENTATION_MANIFEST_SYMBOL);
|
|
20
32
|
var getRegistry = () => {
|
|
21
33
|
const existing = Reflect.get(globalThis, registrySymbol);
|
|
@@ -33,13 +45,13 @@ var getRegistry = () => {
|
|
|
33
45
|
};
|
|
34
46
|
var recordInstrumentationManifestDelta = (filePath, delta) => {
|
|
35
47
|
const registry = getRegistry();
|
|
36
|
-
registry.files.set(
|
|
48
|
+
registry.files.set(resolve(filePath), delta);
|
|
37
49
|
registry.generation += 1;
|
|
38
50
|
registry.onDirty?.();
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
// src/auto-instrumentation/source-classification.ts
|
|
42
|
-
import { isAbsolute
|
|
54
|
+
import { isAbsolute, relative, resolve as resolve2, sep } from "node:path";
|
|
43
55
|
var sourceExtension = /\.[cm]?[jt]sx?$/i;
|
|
44
56
|
var alwaysExcludedDirectory = /(^|[\\/])(node_modules|coverage|generated|\.git|\.next|\.svelte-kit|\.output|\.vercel|\.rasputin|\.turbo|\.yarn|\.pnpm|\.bun)([\\/]|$)/;
|
|
45
57
|
var buildOutputDirectory = /(^|[\\/])(dist|build|out)([\\/]|$)/;
|
|
@@ -50,11 +62,11 @@ var matches = (pattern, value) => {
|
|
|
50
62
|
return result;
|
|
51
63
|
};
|
|
52
64
|
var isWithinRoot = (filePath, root) => {
|
|
53
|
-
const fromRoot =
|
|
54
|
-
return fromRoot === "" || !fromRoot.startsWith(`..${
|
|
65
|
+
const fromRoot = relative(resolve2(root), filePath);
|
|
66
|
+
return fromRoot === "" || !fromRoot.startsWith(`..${sep}`) && fromRoot !== ".." && !isAbsolute(fromRoot);
|
|
55
67
|
};
|
|
56
68
|
var isApplicationSource = (filePath, options = {}) => {
|
|
57
|
-
const absolutePath =
|
|
69
|
+
const absolutePath = resolve2(filePath);
|
|
58
70
|
if (!sourceExtension.test(absolutePath) || alwaysExcludedDirectory.test(absolutePath))
|
|
59
71
|
return false;
|
|
60
72
|
if (options.includeBuildOutput !== true && buildOutputDirectory.test(absolutePath)) return false;
|
|
@@ -69,7 +81,7 @@ var isApplicationSource = (filePath, options = {}) => {
|
|
|
69
81
|
|
|
70
82
|
// src/auto-instrumentation/source-map-locations.ts
|
|
71
83
|
import { readFileSync } from "node:fs";
|
|
72
|
-
import { dirname, isAbsolute as
|
|
84
|
+
import { dirname, isAbsolute as isAbsolute2, join, resolve as resolve3 } from "node:path";
|
|
73
85
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
74
86
|
import { LEAST_UPPER_BOUND, originalPositionFor, TraceMap } from "@jridgewell/trace-mapping";
|
|
75
87
|
var sourceMapComment = /(?:\/\/[#@][ \t]*sourceMappingURL=([^\s'"]+)|\/\*[#@][ \t]*sourceMappingURL=([^\s*'"]+)[ \t]*\*\/)\s*$/;
|
|
@@ -86,7 +98,7 @@ var sourceMapFor = (generatedPath, source) => {
|
|
|
86
98
|
const payload = decodeDataUrl(reference);
|
|
87
99
|
return payload ? { payload, mapUrl: pathToFileURL(generatedPath).href } : void 0;
|
|
88
100
|
}
|
|
89
|
-
const mapPath = reference ?
|
|
101
|
+
const mapPath = reference ? resolve3(dirname(generatedPath), reference) : `${generatedPath}.map`;
|
|
90
102
|
return {
|
|
91
103
|
payload: readFileSync(mapPath, "utf8"),
|
|
92
104
|
mapUrl: pathToFileURL(mapPath).href
|
|
@@ -94,7 +106,7 @@ var sourceMapFor = (generatedPath, source) => {
|
|
|
94
106
|
};
|
|
95
107
|
var toFilePath = (source, generatedPath) => {
|
|
96
108
|
if (source.startsWith("file:")) return fileURLToPath(source);
|
|
97
|
-
return
|
|
109
|
+
return isAbsolute2(source) ? source : join(dirname(generatedPath), source);
|
|
98
110
|
};
|
|
99
111
|
var createSourceMapLocationMapper = (generatedPath, source) => {
|
|
100
112
|
try {
|
|
@@ -126,7 +138,7 @@ var createSourceMapLocationMapper = (generatedPath, source) => {
|
|
|
126
138
|
};
|
|
127
139
|
|
|
128
140
|
// src/auto-instrumentation/transform-source.ts
|
|
129
|
-
import { resolve as
|
|
141
|
+
import { resolve as resolve4 } from "node:path";
|
|
130
142
|
import ts2 from "typescript";
|
|
131
143
|
|
|
132
144
|
// src/auto-instrumentation/collect-instrumentation-delta.ts
|
|
@@ -403,7 +415,7 @@ var transformSource = (source, options) => {
|
|
|
403
415
|
);
|
|
404
416
|
let helperName = "__rasputinAutoRun__";
|
|
405
417
|
while (source.includes(helperName)) helperName += "_";
|
|
406
|
-
const absolutePath =
|
|
418
|
+
const absolutePath = resolve4(options.filePath);
|
|
407
419
|
const edits = [];
|
|
408
420
|
let order = 0;
|
|
409
421
|
const delta = {
|
|
@@ -522,9 +534,9 @@ var registerRasputinNodeHooks = (options = {}) => {
|
|
|
522
534
|
};
|
|
523
535
|
|
|
524
536
|
// src/auto-instrumentation/sdk-source-boundary.ts
|
|
525
|
-
import { dirname as dirname2, resolve as
|
|
537
|
+
import { dirname as dirname2, resolve as resolve5 } from "node:path";
|
|
526
538
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
527
|
-
var sdkPackageScopeRootFrom = (instrumentEntryUrl) =>
|
|
539
|
+
var sdkPackageScopeRootFrom = (instrumentEntryUrl) => resolve5(dirname2(fileURLToPath3(instrumentEntryUrl)), "../../..");
|
|
528
540
|
|
|
529
541
|
// src/instrument/node.ts
|
|
530
542
|
registerRasputinNodeHooks({
|
package/dist/rasputin-init.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* recorder. Centralizing this wiring keeps initialization fail-safe and ensures every capture path
|
|
4
4
|
* attaches runtime state using the same limits and lifecycle rules.
|
|
5
5
|
*/
|
|
6
|
-
import { type RasputinClient, type RasputinClientStats, type RasputinOptions } from '@rasputin-ai/core';
|
|
6
|
+
import { type RasputinClient, type RasputinClientStats, type RasputinOptions, type SourceVerification } from '@rasputin-ai/core';
|
|
7
7
|
import { type ExecutionRecorderOptions, type ExecutionRecorderStats, type RasputinExecution } from './execution-recorder';
|
|
8
8
|
export type RasputinNodeOptions = RasputinOptions & {
|
|
9
9
|
/** Bounded runtime-state capture. Enabled by default; successful executions are discarded. */
|
|
@@ -16,6 +16,8 @@ export type RasputinNodeClientStats = RasputinClientStats & {
|
|
|
16
16
|
export type RasputinNodeClient = Omit<RasputinClient, 'getStats'> & {
|
|
17
17
|
execution: RasputinExecution;
|
|
18
18
|
getStats: () => RasputinNodeClientStats;
|
|
19
|
+
/** Verify package source locators against the configured Git repository and exact release. */
|
|
20
|
+
verifyConfiguration: () => Promise<SourceVerification>;
|
|
19
21
|
};
|
|
20
22
|
/**
|
|
21
23
|
* Boot the Node/Bun SDK: client + process global handlers.
|
|
@@ -27,7 +29,6 @@ export type RasputinNodeClient = Omit<RasputinClient, 'getStats'> & {
|
|
|
27
29
|
* release: process.env.RASPUTIN_RELEASE!,
|
|
28
30
|
* environment: process.env.NODE_ENV ?? 'development',
|
|
29
31
|
* enabled: ['staging', 'production'].includes(process.env.NODE_ENV ?? 'development'),
|
|
30
|
-
* moduleUrl: import.meta.url,
|
|
31
32
|
* });
|
|
32
33
|
*/
|
|
33
34
|
export declare const RasputinInit: (options: RasputinNodeOptions) => RasputinNodeClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rasputin-init.d.ts","sourceRoot":"","sources":["../src/rasputin-init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"rasputin-init.d.ts","sourceRoot":"","sources":["../src/rasputin-init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEN,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG;IACnD,8FAA8F;IAC9F,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,GAAG;IAC3D,+EAA+E;IAC/E,QAAQ,EAAE,sBAAsB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG;IACnE,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,MAAM,uBAAuB,CAAC;IACxC,8FAA8F;IAC9F,mBAAmB,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvD,CAAC;AAgDF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,mBAAmB,KAAG,kBA2C3D,CAAC"}
|
package/dist/sdk-meta.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Generated by
|
|
1
|
+
/** Generated by scripts/generate-sdk-meta.ts — do not edit. */
|
|
2
2
|
export declare const SDK_NAME = "@rasputin-ai/node";
|
|
3
|
-
export declare const SDK_VERSION = "0.
|
|
3
|
+
export declare const SDK_VERSION = "0.4.0";
|
|
4
4
|
//# sourceMappingURL=sdk-meta.d.ts.map
|
package/dist/sdk-meta.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-meta.d.ts","sourceRoot":"","sources":["../src/sdk-meta.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sdk-meta.d.ts","sourceRoot":"","sources":["../src/sdk-meta.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAC5C,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rasputin-ai/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Official Rasputin AI SDK for Node and Bun.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
39
|
-
"@rasputin-ai/core": "0.
|
|
39
|
+
"@rasputin-ai/core": "0.4.0",
|
|
40
40
|
"typescript": "5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|