@senpi/runtime 1.1.0-dev.runtime-phase-2.20260527113015 → 1.1.1-dev.runtime-phase-2.20260604073249

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.
Files changed (93) hide show
  1. package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
  2. package/dist/actions/close-position/close-position.action.js +19 -1
  3. package/dist/actions/close-position/close-position.action.js.map +1 -1
  4. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  5. package/dist/actions/open-position/open-position.action.js +19 -0
  6. package/dist/actions/open-position/open-position.action.js.map +1 -1
  7. package/dist/actions/position-tracker/position-tracker.action.d.ts +6 -0
  8. package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
  9. package/dist/actions/position-tracker/position-tracker.action.js +35 -0
  10. package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
  11. package/dist/cli/guide-commands.d.ts.map +1 -1
  12. package/dist/cli/guide-commands.js +8 -4
  13. package/dist/cli/guide-commands.js.map +1 -1
  14. package/dist/dsl/engine-client/config-mapping.d.ts +5 -0
  15. package/dist/dsl/engine-client/config-mapping.d.ts.map +1 -1
  16. package/dist/dsl/engine-client/config-mapping.js +14 -2
  17. package/dist/dsl/engine-client/config-mapping.js.map +1 -1
  18. package/dist/dsl/engine-client/event-mapping.d.ts +2 -0
  19. package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
  20. package/dist/dsl/engine-client/event-mapping.js +3 -0
  21. package/dist/dsl/engine-client/event-mapping.js.map +1 -1
  22. package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
  23. package/dist/dsl/events/build-closed-event.js +1 -0
  24. package/dist/dsl/events/build-closed-event.js.map +1 -1
  25. package/dist/dsl/events/guards.d.ts.map +1 -1
  26. package/dist/dsl/events/guards.js +13 -0
  27. package/dist/dsl/events/guards.js.map +1 -1
  28. package/dist/dsl/events/handlers.d.ts.map +1 -1
  29. package/dist/dsl/events/handlers.js +4 -0
  30. package/dist/dsl/events/handlers.js.map +1 -1
  31. package/dist/dsl/events/initial-state.d.ts.map +1 -1
  32. package/dist/dsl/events/initial-state.js +4 -1
  33. package/dist/dsl/events/initial-state.js.map +1 -1
  34. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  35. package/dist/dsl/monitor/process-one-position.js +31 -1
  36. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  37. package/dist/runtime/create-runtime-context.d.ts +2 -0
  38. package/dist/runtime/create-runtime-context.d.ts.map +1 -1
  39. package/dist/runtime/create-runtime-context.js +1 -0
  40. package/dist/runtime/create-runtime-context.js.map +1 -1
  41. package/dist/runtime/runtime.d.ts +7 -0
  42. package/dist/runtime/runtime.d.ts.map +1 -1
  43. package/dist/runtime/runtime.js +29 -1
  44. package/dist/runtime/runtime.js.map +1 -1
  45. package/dist/senpi/client.js +1 -0
  46. package/dist/senpi/client.js.map +1 -1
  47. package/dist/senpi/types.d.ts +5 -1
  48. package/dist/senpi/types.d.ts.map +1 -1
  49. package/dist/state/state-manager.d.ts.map +1 -1
  50. package/dist/state/state-manager.js +5 -0
  51. package/dist/state/state-manager.js.map +1 -1
  52. package/dist/tracking/build-rehydrate-items.d.ts +14 -0
  53. package/dist/tracking/build-rehydrate-items.d.ts.map +1 -0
  54. package/dist/tracking/build-rehydrate-items.js +30 -0
  55. package/dist/tracking/build-rehydrate-items.js.map +1 -0
  56. package/dist/tracking/index.d.ts +4 -0
  57. package/dist/tracking/index.d.ts.map +1 -1
  58. package/dist/tracking/index.js +3 -0
  59. package/dist/tracking/index.js.map +1 -1
  60. package/dist/tracking/pending-open-store.d.ts +19 -0
  61. package/dist/tracking/pending-open-store.d.ts.map +1 -0
  62. package/dist/tracking/pending-open-store.js +27 -0
  63. package/dist/tracking/pending-open-store.js.map +1 -0
  64. package/dist/tracking/position-id-registry.d.ts +91 -0
  65. package/dist/tracking/position-id-registry.d.ts.map +1 -0
  66. package/dist/tracking/position-id-registry.js +149 -0
  67. package/dist/tracking/position-id-registry.js.map +1 -0
  68. package/dist/tracking/spans/plugin-span-tracker.d.ts.map +1 -1
  69. package/dist/tracking/spans/plugin-span-tracker.js +18 -0
  70. package/dist/tracking/spans/plugin-span-tracker.js.map +1 -1
  71. package/dist/tracking/spans/redact-pii.d.ts +115 -0
  72. package/dist/tracking/spans/redact-pii.d.ts.map +1 -0
  73. package/dist/tracking/spans/redact-pii.js +464 -0
  74. package/dist/tracking/spans/redact-pii.js.map +1 -0
  75. package/dist/tracking/spans/span-transport.d.ts +19 -0
  76. package/dist/tracking/spans/span-transport.d.ts.map +1 -1
  77. package/dist/tracking/spans/span-transport.js +28 -2
  78. package/dist/tracking/spans/span-transport.js.map +1 -1
  79. package/dist/tracking/tracker.d.ts +5 -0
  80. package/dist/tracking/tracker.d.ts.map +1 -1
  81. package/dist/tracking/tracker.js +4 -0
  82. package/dist/tracking/tracker.js.map +1 -1
  83. package/dist/tracking/tracking-handler.d.ts.map +1 -1
  84. package/dist/tracking/tracking-handler.js +47 -0
  85. package/dist/tracking/tracking-handler.js.map +1 -1
  86. package/dist/tracking/types.d.ts +12 -0
  87. package/dist/tracking/types.d.ts.map +1 -1
  88. package/dist/types/dsl/index.d.ts +44 -0
  89. package/dist/types/dsl/index.d.ts.map +1 -1
  90. package/dist/types/runtime.d.ts +6 -0
  91. package/dist/types/runtime.d.ts.map +1 -1
  92. package/openclaw.plugin.json +18 -5
  93. package/package.json +3 -1
@@ -0,0 +1,27 @@
1
+ /** State key (→ `{baseDir}/pending-opens.json`). */
2
+ const PENDING_KEY = "pending-opens";
3
+ export class StateManagerPendingStore {
4
+ state;
5
+ constructor(state) {
6
+ this.state = state;
7
+ }
8
+ async load() {
9
+ return (await this.state.getOrLoad(PENDING_KEY)) ?? {};
10
+ }
11
+ async put(record) {
12
+ const map = await this.load();
13
+ map[record.key] = record;
14
+ await this.state.set(PENDING_KEY, map);
15
+ }
16
+ async delete(key) {
17
+ const map = await this.load();
18
+ if (key in map) {
19
+ delete map[key];
20
+ await this.state.set(PENDING_KEY, map);
21
+ }
22
+ }
23
+ async list() {
24
+ return Object.values(await this.load());
25
+ }
26
+ }
27
+ //# sourceMappingURL=pending-open-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-open-store.js","sourceRoot":"","sources":["../../src/tracking/pending-open-store.ts"],"names":[],"mappings":"AAWA,oDAAoD;AACpD,MAAM,WAAW,GAAG,eAAe,CAAC;AAIpC,MAAM,OAAO,wBAAwB;IACN;IAA7B,YAA6B,KAAmB;QAAnB,UAAK,GAAL,KAAK,CAAc;IAAG,CAAC;IAE5C,KAAK,CAAC,IAAI;QAChB,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAa,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAqB;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACzB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACf,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Build the registry key for a position. Normalizes dex the same way the
3
+ * position-tracker scanner's buildPositionKey does (empty/whitespace → "main"),
4
+ * scoped by wallet so the map is correct under multi-wallet deployment.
5
+ */
6
+ export declare function positionRegistryKey(wallet: string, dex: string, asset: string): string;
7
+ /** A client-order-id role. Entry/SL/TP are set at open; close accrues over the position's life. */
8
+ export type CloidRole = "entry" | "sl" | "tp" | "close";
9
+ /** The set of cloids associated with one position. */
10
+ export interface Cloids {
11
+ entry?: string;
12
+ sl?: string;
13
+ tp?: string;
14
+ close?: string[];
15
+ }
16
+ export interface Entry {
17
+ positionId: string;
18
+ cloids: Cloids;
19
+ }
20
+ /** A pending-open record persisted between intent-mint and confirmed open. */
21
+ export interface PendingRecord {
22
+ key: string;
23
+ /** The position.id minted at intent; reused (not re-minted) on confirmed open. */
24
+ positionId: string;
25
+ cloids: Cloids;
26
+ ts: number;
27
+ }
28
+ /** Durable store for pending-open records (so a restart in the open window keeps the cloids). */
29
+ export interface PendingStore {
30
+ put(record: PendingRecord): Promise<void>;
31
+ delete(key: string): Promise<void>;
32
+ list(): Promise<PendingRecord[]>;
33
+ }
34
+ /** One unit of boot-time state to restore: a minted entry, a pending record, or both. */
35
+ export interface RehydrateItem {
36
+ key: string;
37
+ entry?: Entry;
38
+ pending?: {
39
+ positionId: string;
40
+ cloids: Cloids;
41
+ ts: number;
42
+ };
43
+ }
44
+ export interface PositionIdRegistryOptions {
45
+ store?: PendingStore;
46
+ now?: () => number;
47
+ }
48
+ export declare class PositionIdRegistry {
49
+ private readonly entries;
50
+ /** Positions minted at intent, awaiting a confirmed open. */
51
+ private readonly pending;
52
+ private readonly store?;
53
+ private readonly now;
54
+ constructor(opts?: PositionIdRegistryOptions);
55
+ /**
56
+ * Mint a position.id at the moment the runtime decides to open, before the position
57
+ * is confirmed open. The id is returned immediately so callers can stamp it on the
58
+ * `action.open` emit. Idempotent: a re-submit (or an already-confirmed entry) reuses
59
+ * the existing id rather than minting a new one. Persisted so a restart in the
60
+ * submit→observe window keeps the id; promoted by the next {@link mintOnOpened}.
61
+ *
62
+ * If the open was already confirmed (e.g. the position tracker observed it before
63
+ * createPosition called this), the newly-supplied cloids are still merged into the
64
+ * confirmed entry — otherwise the exchange-returned entry cloid would be dropped and
65
+ * ON_OPEN_ORDER_SUBMITTED would omit __cloids.entry. New keys win; absent keys leave
66
+ * any existing confirmed cloid intact.
67
+ */
68
+ mintOnIntent(key: string, cloids?: Cloids): Promise<Entry>;
69
+ /**
70
+ * Confirm the open. Idempotent: if a confirmed entry already exists it is returned.
71
+ * If the position was minted at intent, that id is promoted (reused, never re-minted)
72
+ * and the pending record dropped. Otherwise — an externally-opened position with no
73
+ * prior runtime intent — a fresh id is minted.
74
+ */
75
+ mintOnOpened(key: string): Promise<Entry>;
76
+ /** Associate another cloid with a position (e.g. a DSL/runtime close order). */
77
+ addCloid(key: string, role: CloidRole, cloid: string): Promise<void>;
78
+ /**
79
+ * Read the current entry for a key (INCREASED/DECREASED/FLIPPED, DSL start). Surfaces
80
+ * an intent-mint that has not yet been confirmed open, so reads in the open window
81
+ * still resolve the position.id.
82
+ */
83
+ get(key: string): Entry | undefined;
84
+ /** Clear on confirmed close. The next open on this key mints a fresh id. */
85
+ clearOnClosed(key: string): Promise<void>;
86
+ /** Repopulate in-memory state at boot from persisted DSL entries + pending records. */
87
+ rehydrate(items: RehydrateItem[]): void;
88
+ /** Drop pending records older than maxAgeMs (orders that were submitted but never filled). */
89
+ sweepStalePendings(maxAgeMs: number): Promise<void>;
90
+ }
91
+ //# sourceMappingURL=position-id-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-id-registry.d.ts","sourceRoot":"","sources":["../../src/tracking/position-id-registry.ts"],"names":[],"mappings":"AAuBA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED,mGAAmG;AACnG,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC;AAExD,sDAAsD;AACtD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CAClC;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyE;IACjG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,GAAE,yBAA8B;IAKhD;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IAgBpE;;;;;OAKG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAa/C,gFAAgF;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1E;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAOnC,4EAA4E;IACtE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,uFAAuF;IACvF,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI;IAavC,8FAA8F;IACxF,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAS1D"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * PositionIdRegistry: cross-flow position.id state machine.
3
+ *
4
+ * Sibling of the intra-flow correlation_id in src/tracking/context.ts. Keyed on
5
+ * (wallet, dex, asset).
6
+ *
7
+ * **Mint-at-intent.** A stable position.id is minted the moment the runtime decides to
8
+ * open ({@link mintOnIntent}), so it is already on the `action.open` emit — the open
9
+ * trace correlates by position.id directly, with no read-side cloid bridge, and even a
10
+ * sub-minute open+close (which the tracker poll never observes) still has a lifecycle.
11
+ *
12
+ * Two internal phases:
13
+ * - `pending` — minted at intent, awaiting a confirmed open. Stale-swept if the order
14
+ * never fills ({@link sweepStalePendings}), persisted so a restart in the
15
+ * submit→observe window keeps the id.
16
+ * - `entries` — confirmed open. Reused for INCREASED/DECREASED/FLIPPED and DSL reads;
17
+ * cleared on POSITION_CLOSED. Never stale-swept.
18
+ *
19
+ * {@link mintOnOpened} promotes a pending intent-mint to a confirmed entry (reusing the
20
+ * id), or mints fresh for an externally-opened position with no prior intent.
21
+ */
22
+ import { randomUUID } from "node:crypto";
23
+ /**
24
+ * Build the registry key for a position. Normalizes dex the same way the
25
+ * position-tracker scanner's buildPositionKey does (empty/whitespace → "main"),
26
+ * scoped by wallet so the map is correct under multi-wallet deployment.
27
+ */
28
+ export function positionRegistryKey(wallet, dex, asset) {
29
+ const normalizedDex = dex.trim() || "main";
30
+ return `${wallet}|${normalizedDex}:${asset}`;
31
+ }
32
+ export class PositionIdRegistry {
33
+ entries = new Map();
34
+ /** Positions minted at intent, awaiting a confirmed open. */
35
+ pending = new Map();
36
+ store;
37
+ now;
38
+ constructor(opts = {}) {
39
+ this.store = opts.store;
40
+ this.now = opts.now ?? Date.now;
41
+ }
42
+ /**
43
+ * Mint a position.id at the moment the runtime decides to open, before the position
44
+ * is confirmed open. The id is returned immediately so callers can stamp it on the
45
+ * `action.open` emit. Idempotent: a re-submit (or an already-confirmed entry) reuses
46
+ * the existing id rather than minting a new one. Persisted so a restart in the
47
+ * submit→observe window keeps the id; promoted by the next {@link mintOnOpened}.
48
+ *
49
+ * If the open was already confirmed (e.g. the position tracker observed it before
50
+ * createPosition called this), the newly-supplied cloids are still merged into the
51
+ * confirmed entry — otherwise the exchange-returned entry cloid would be dropped and
52
+ * ON_OPEN_ORDER_SUBMITTED would omit __cloids.entry. New keys win; absent keys leave
53
+ * any existing confirmed cloid intact.
54
+ */
55
+ async mintOnIntent(key, cloids = {}) {
56
+ const confirmed = this.entries.get(key);
57
+ if (confirmed) {
58
+ confirmed.cloids = { ...confirmed.cloids, ...cloids };
59
+ return confirmed;
60
+ }
61
+ const ts = this.now();
62
+ const existing = this.pending.get(key);
63
+ const positionId = existing?.positionId ?? randomUUID();
64
+ const merged = { ...existing?.cloids, ...cloids };
65
+ this.pending.set(key, { positionId, cloids: merged, ts });
66
+ await this.store?.put({ key, positionId, cloids: { ...merged }, ts });
67
+ return { positionId, cloids: merged };
68
+ }
69
+ /**
70
+ * Confirm the open. Idempotent: if a confirmed entry already exists it is returned.
71
+ * If the position was minted at intent, that id is promoted (reused, never re-minted)
72
+ * and the pending record dropped. Otherwise — an externally-opened position with no
73
+ * prior runtime intent — a fresh id is minted.
74
+ */
75
+ async mintOnOpened(key) {
76
+ const existing = this.entries.get(key);
77
+ if (existing)
78
+ return existing;
79
+ const pending = this.pending.get(key);
80
+ const entry = pending
81
+ ? { positionId: pending.positionId, cloids: pending.cloids }
82
+ : { positionId: randomUUID(), cloids: {} };
83
+ this.entries.set(key, entry);
84
+ this.pending.delete(key);
85
+ await this.store?.delete(key);
86
+ return entry;
87
+ }
88
+ /** Associate another cloid with a position (e.g. a DSL/runtime close order). */
89
+ async addCloid(key, role, cloid) {
90
+ const confirmed = this.entries.get(key);
91
+ const cloids = confirmed?.cloids ?? this.pending.get(key)?.cloids;
92
+ if (!cloids)
93
+ return;
94
+ if (role === "close") {
95
+ (cloids.close ??= []).push(cloid);
96
+ }
97
+ else {
98
+ cloids[role] = cloid;
99
+ }
100
+ // Re-persist while still pending so a restart keeps the added cloid.
101
+ if (!confirmed) {
102
+ const p = this.pending.get(key);
103
+ await this.store?.put({ key, positionId: p.positionId, cloids: { ...p.cloids }, ts: p.ts });
104
+ }
105
+ }
106
+ /**
107
+ * Read the current entry for a key (INCREASED/DECREASED/FLIPPED, DSL start). Surfaces
108
+ * an intent-mint that has not yet been confirmed open, so reads in the open window
109
+ * still resolve the position.id.
110
+ */
111
+ get(key) {
112
+ const confirmed = this.entries.get(key);
113
+ if (confirmed)
114
+ return confirmed;
115
+ const pending = this.pending.get(key);
116
+ return pending ? { positionId: pending.positionId, cloids: pending.cloids } : undefined;
117
+ }
118
+ /** Clear on confirmed close. The next open on this key mints a fresh id. */
119
+ async clearOnClosed(key) {
120
+ this.entries.delete(key);
121
+ this.pending.delete(key);
122
+ await this.store?.delete(key);
123
+ }
124
+ /** Repopulate in-memory state at boot from persisted DSL entries + pending records. */
125
+ rehydrate(items) {
126
+ for (const item of items) {
127
+ if (item.entry)
128
+ this.entries.set(item.key, item.entry);
129
+ if (item.pending) {
130
+ this.pending.set(item.key, {
131
+ positionId: item.pending.positionId,
132
+ cloids: item.pending.cloids,
133
+ ts: item.pending.ts,
134
+ });
135
+ }
136
+ }
137
+ }
138
+ /** Drop pending records older than maxAgeMs (orders that were submitted but never filled). */
139
+ async sweepStalePendings(maxAgeMs) {
140
+ const cutoff = this.now() - maxAgeMs;
141
+ for (const [key, rec] of this.pending) {
142
+ if (rec.ts < cutoff) {
143
+ this.pending.delete(key);
144
+ await this.store?.delete(key);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ //# sourceMappingURL=position-id-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-id-registry.js","sourceRoot":"","sources":["../../src/tracking/position-id-registry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-span-tracker.d.ts","sourceRoot":"","sources":["../../../src/tracking/spans/plugin-span-tracker.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,WAAW,CAWb"}
1
+ {"version":3,"file":"plugin-span-tracker.d.ts","sourceRoot":"","sources":["../../../src/tracking/spans/plugin-span-tracker.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA8BhD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,WAAW,CAYb"}
@@ -10,8 +10,26 @@ import { createLogger } from "../../utils/logger.js";
10
10
  import { TRACKING_API_BASE_URL } from "../constants.js";
11
11
  import { BatchingSpanTransport, NoOpSpanTransport } from "./span-transport.js";
12
12
  import { SpanTracker } from "./span-tracker.js";
13
+ import { createOpenRedactionAdapter, setDefaultPiiRedactor, } from "./redact-pii.js";
13
14
  const logger = createLogger("[senpi-core][plugin-span-tracker]");
15
+ /**
16
+ * Initialize the process-wide default PII redactor at plugin startup.
17
+ *
18
+ * Fire-and-forget. Failures are logged; spans continue flowing unredacted
19
+ * rather than blocking startup.
20
+ */
21
+ function initPiiRedactor() {
22
+ createOpenRedactionAdapter()
23
+ .then((redactor) => {
24
+ setDefaultPiiRedactor(redactor);
25
+ logger.info("PII redaction enabled — spans will be scrubbed for emails, international phones (US/IN/CN/KR/JP/UK/BR/+intl), vendor API keys, EVM private keys, and BIP39 mnemonics before transport");
26
+ })
27
+ .catch((err) => {
28
+ logger.warn("PII redaction init failed — spans will flow UNredacted; check openredaction install", { err: err instanceof Error ? err.message : String(err) });
29
+ });
30
+ }
14
31
  export function createPluginSpanTracker(apiKey) {
32
+ initPiiRedactor();
15
33
  const trackingBaseUrl = process.env.SENPI_TRACKING_URL ?? TRACKING_API_BASE_URL;
16
34
  const transport = apiKey
17
35
  ? new BatchingSpanTransport({ baseUrl: trackingBaseUrl, apiKey })
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-span-tracker.js","sourceRoot":"","sources":["../../../src/tracking/spans/plugin-span-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,MAAM,GAAG,YAAY,CAAC,mCAAmC,CAAC,CAAC;AAEjE,MAAM,UAAU,uBAAuB,CACrC,MAA0B;IAE1B,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,qBAAqB,CAAC;IAChF,MAAM,SAAS,GAAG,MAAM;QACtB,CAAC,CAAC,IAAI,qBAAqB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,CAAC,IAAI,CACT,iIAAiI,CAClI,CAAC;YACF,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACjC,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,IAAI,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"plugin-span-tracker.js","sourceRoot":"","sources":["../../../src/tracking/spans/plugin-span-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,GAAG,YAAY,CAAC,mCAAmC,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,SAAS,eAAe;IACtB,0BAA0B,EAAE;SACzB,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;QACjB,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CACT,uLAAuL,CACxL,CAAC;IACJ,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,CAAC,IAAI,CACT,qFAAqF,EACrF,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAA0B;IAE1B,eAAe,EAAE,CAAC;IAClB,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,qBAAqB,CAAC;IAChF,MAAM,SAAS,GAAG,MAAM;QACtB,CAAC,CAAC,IAAI,qBAAqB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,CAAC,IAAI,CACT,iIAAiI,CAClI,CAAC;YACF,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACjC,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,IAAI,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * PII + secret redaction for span payloads.
3
+ *
4
+ * Walks the `data` field of each span and replaces matches in string values
5
+ * before the batch hits the wire. Runs at flush time (async) — the underlying
6
+ * redactor is async, and the producer is fire-and-forget, so we pay the
7
+ * latency on the network-bound path rather than on the caller's enqueue call.
8
+ *
9
+ * Scope (see createOpenRedactionAdapter): emails, phones (US, international,
10
+ * India, China, South Korea, Japan, UK mobile, Brazil), ~28 vendor API keys
11
+ * / tokens (AWS, GitHub, Stripe, OpenAI, etc.), EVM private keys, Anthropic
12
+ * `sk-ant-*` keys, generic `sk-*` keys, and BIP39 mnemonic phrases.
13
+ *
14
+ * Integration point: BatchingSpanTransport.flush() applies this to every
15
+ * span in the batch before JSON.stringify. Only `span.data` is walked;
16
+ * top-level columns (`address`, `correlationId`, etc.) are non-PII identifiers
17
+ * and stay as-is.
18
+ *
19
+ * Always on — the plugin initializes a default redactor at startup.
20
+ */
21
+ import type { TrackingSpan } from "./types.js";
22
+ /** Minimal interface so tests can inject a synchronous stub. */
23
+ export interface PiiRedactor {
24
+ redact(text: string): Promise<string>;
25
+ }
26
+ /**
27
+ * Walks a JSON-shaped value. Strings are run through the redactor; arrays
28
+ * and plain objects are recursed; everything else (number, boolean, null,
29
+ * non-plain objects) is returned unchanged. Preserves reference identity
30
+ * when nothing changes — useful for short-circuit downstream comparisons.
31
+ */
32
+ export declare function redactStringsDeep(value: unknown, redactor: PiiRedactor): Promise<unknown>;
33
+ /**
34
+ * Redact PII inside `span.data` only. Top-level structural fields (address,
35
+ * correlationId, runId, etc.) are non-PII identifiers and skipped.
36
+ *
37
+ * Returns the same span if nothing changed (avoids object allocation when no
38
+ * PII was found).
39
+ */
40
+ export declare function redactSpanData(span: TrackingSpan, redactor: PiiRedactor): Promise<TrackingSpan>;
41
+ export declare function setDefaultPiiRedactor(r: PiiRedactor | null): void;
42
+ export declare function getDefaultPiiRedactor(): PiiRedactor | null;
43
+ /**
44
+ * Find BIP39-mnemonic spans in `text` using a true sliding window — not
45
+ * a greedy regex with a post-hoc validator.
46
+ *
47
+ * Why this and not a regex+validator:
48
+ * - OpenRedaction calls the validator on whatever the regex captured. JS
49
+ * regex matching is left-to-right with no backtracking across `lastIndex`
50
+ * advances; once a (greedy) match is rejected, the engine moves past it
51
+ * entirely. So a 17-word lowercase run like "my secret is <12 BIP39>
52
+ * so keep safe" gets captured whole, fails validation on word count,
53
+ * and the engine doesn't retry the 12-word window starting 3 tokens in.
54
+ *
55
+ * Algorithm:
56
+ * 1. Tokenize lowercase-only words and their offsets (skips capitalized
57
+ * words and punctuation — real mnemonics from wallet exports are
58
+ * always all-lowercase space-separated).
59
+ * 2. Walk left to right. At each token position, try valid mnemonic
60
+ * counts largest-first (24, 21, 18, 15, 12) so a 24-word phrase
61
+ * inside a longer prose run isn't missed by a premature 12-match.
62
+ * 3. A window is valid only when every word is BIP39 AND the gap between
63
+ * consecutive tokens in the source is whitespace-only (rejects forms
64
+ * with commas or other punctuation between words, which real wallet
65
+ * exports don't use).
66
+ * 4. On match, record the source span and advance past it; otherwise step
67
+ * forward one token.
68
+ */
69
+ export declare function findMnemonicSpans(text: string, bip39: Set<string>): Array<{
70
+ start: number;
71
+ end: number;
72
+ }>;
73
+ /**
74
+ * Pre-redact BIP39 mnemonics in `text` before handing the result to
75
+ * OpenRedaction. Returns the original string when no mnemonics are present
76
+ * (cheap path — only the tokenizer runs and finds nothing).
77
+ */
78
+ export declare function redactMnemonicsPreRedaction(text: string): Promise<string>;
79
+ /**
80
+ * Build an OpenRedaction-backed PiiRedactor.
81
+ *
82
+ * Detects:
83
+ * - Contact PII: emails.
84
+ * - Phones (all custom — upstream phone patterns are unreliable, see
85
+ * ALLOWLISTED_PATTERN_TYPES docstring): US, international (`+` prefix),
86
+ * India, China, South Korea, Japan, UK mobile, Brazil. Each requires
87
+ * either an explicit country code OR a country-specific mobile prefix
88
+ * plus separators, so bare numeric IDs (timestamps, span IDs, UUIDs)
89
+ * survive untouched.
90
+ * - Credentials (upstream): cloud / vendor API keys + tokens (AWS, Azure,
91
+ * GCP, GitHub, Slack, Stripe, OpenAI, Twilio, …), bearer + JWT tokens,
92
+ * OAuth secrets, generic API keys, SSH/PEM private keys, URLs with
93
+ * embedded auth.
94
+ * - Crypto secrets (custom patterns): EVM private keys (0x + 64 hex),
95
+ * Anthropic `sk-ant-*` keys, generic `sk-*` keys (OpenAI/OpenRouter).
96
+ * - BIP39 mnemonic phrases (out-of-band sliding-window pre-pass — see
97
+ * `redactMnemonicsPreRedaction`): 12/15/18/21/24 BIP39 words, found and
98
+ * redacted before the OpenRedaction pass so embedded phrases like
99
+ * "my key is <12 words> keep safe" are caught.
100
+ *
101
+ * Tuning:
102
+ * - `enableFalsePositiveFilter: false` — explicit; the library defaults
103
+ * this to truthy in practice and suppresses valid international-phone
104
+ * matches in some contexts.
105
+ * - `enableContextAnalysis: false` — saves CPU; context rules add
106
+ * latency and aren't load-bearing for the patterns we keep.
107
+ * - `enableCache: true` — chat history repeats; cache skips re-scan.
108
+ * - `confidenceThreshold: 0.5` — kept conservative; custom patterns score
109
+ * 1.0 so this only affects built-ins.
110
+ *
111
+ * Lazy-imports `openredaction` and `bip39` — both deps stay cold for builds
112
+ * / tests that don't enable redaction.
113
+ */
114
+ export declare function createOpenRedactionAdapter(): Promise<PiiRedactor>;
115
+ //# sourceMappingURL=redact-pii.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact-pii.d.ts","sourceRoot":"","sources":["../../../src/tracking/spans/redact-pii.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvC;AAQD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,OAAO,CAAC,CAgClB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,YAAY,CAAC,CAKvB;AASD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAEjE;AAED,wBAAgB,qBAAqB,IAAI,WAAW,GAAG,IAAI,CAE1D;AAqOD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GACjB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA0CvC;AAsBD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,WAAW,CAAC,CAkCvE"}