@atlasent/sdk 1.5.0 → 2.10.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/dist/state.cjs ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/state.ts
21
+ var state_exports = {};
22
+ __export(state_exports, {
23
+ STATE_SOURCES: () => STATE_SOURCES
24
+ });
25
+ module.exports = __toCommonJS(state_exports);
26
+ var STATE_SOURCES = [
27
+ "hiCoach",
28
+ // bettyc925/hicoach (consumer regulation app)
29
+ "CalmState",
30
+ // atlasent/calm-state (org-side regulation app)
31
+ "Echobloom",
32
+ // bettyc925/echobloom (observability — emits from sessions)
33
+ "FutureBloom",
34
+ // atlasent/future-bloom-planner (planner — state inferred from plan execution)
35
+ "LedgersMe",
36
+ // bettyc925/ledgers-me (financial outcomes inform state proxy)
37
+ "AtlaSent",
38
+ // atlasent/atlasent-api (control-plane derived events)
39
+ "manual"
40
+ // operator-entered, no emitter
41
+ ];
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ STATE_SOURCES
45
+ });
46
+ //# sourceMappingURL=state.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/state.ts"],"sourcesContent":["/**\n * Canonical cross-product behavioral state contract.\n *\n * Imported as a sub-export of @atlasent/sdk:\n *\n * ```ts\n * import type { State, StateEvent, StateSource } from \"@atlasent/sdk/state\";\n * ```\n *\n * Defined in `atlasent-docs/docs/STATE_CONTRACT_PROPOSAL.md` (decisions\n * confirmed 2026-05-02). Replaces the ad-hoc per-app definitions\n * previously drifting between hicoach, calm-state, behavior-insights,\n * and ledgers-me.\n *\n * - `State` is the canonical normalized cross-product model.\n * - `StateSnapshot` is the derived latest state at a point in time.\n * - `StateEvent` is what hits the wire.\n * - `StateSource` is a closed enum; new emitters require a contract change.\n */\n\n// ──────────────────────────────────────────────────────────────────\n// 1. StateSource — closed enum, one literal per emitter\n// ──────────────────────────────────────────────────────────────────\nexport const STATE_SOURCES = [\n \"hiCoach\", // bettyc925/hicoach (consumer regulation app)\n \"CalmState\", // atlasent/calm-state (org-side regulation app)\n \"Echobloom\", // bettyc925/echobloom (observability — emits from sessions)\n \"FutureBloom\", // atlasent/future-bloom-planner (planner — state inferred from plan execution)\n \"LedgersMe\", // bettyc925/ledgers-me (financial outcomes inform state proxy)\n \"AtlaSent\", // atlasent/atlasent-api (control-plane derived events)\n \"manual\", // operator-entered, no emitter\n] as const;\n\nexport type StateSource = (typeof STATE_SOURCES)[number];\n\n// ──────────────────────────────────────────────────────────────────\n// 2. State — canonical normalized model\n// Every dimension is OPTIONAL at the type level so partial\n// observations are valid; each axis has a fixed vocabulary.\n// ──────────────────────────────────────────────────────────────────\n\n/** Canonical emotional axis. Superset of calm-state's 8 + hicoach's 5. */\nexport type EmotionalAxis =\n | \"tense\"\n | \"anxious\"\n | \"overwhelmed\"\n | \"flat\"\n | \"frustrated\"\n | \"uncertain\"\n | \"tired\"\n | \"okay\"\n | \"open\"\n | \"grounded\";\n\n/** Canonical body axis. Superset of calm-state's 6 + hicoach's 4. */\nexport type BodyAxis =\n | \"tight\"\n | \"heavy\"\n | \"restless\"\n | \"numb\"\n | \"buzzing\"\n | \"settled\"\n | \"relaxed\"\n | \"exhausted\";\n\nexport type ReadinessLevel = \"low\" | \"medium\" | \"high\";\n\n/**\n * Canonical normalized state. Every dimension is optional; emitters\n * record what they actually captured. Continuous axes are 0..1 normalized\n * — UI layers translate to/from their native scale (e.g. calm-state's\n * 0..10 sliders).\n */\nexport interface State {\n emotional?: EmotionalAxis;\n body?: BodyAxis;\n readiness?: ReadinessLevel;\n\n /** 0..1, 0=baseline, 1=overwhelming. */\n intensity?: number;\n /** 0..1. */\n stress?: number;\n /** 0..1. */\n pressure?: number;\n /** 0..1. */\n cognitive_load?: number;\n /** 0..1, self-rated certainty in the rating itself. */\n confidence?: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// 3. StateSnapshot — derived \"what is the latest state right now\"\n// Built by consumers from the StateEvent stream. Never emitted.\n// ──────────────────────────────────────────────────────────────────\nexport interface StateSnapshot {\n /** UUID of the user / actor. */\n subject_id: string;\n /** Best-known current state. */\n state: State;\n /** ISO-8601 timestamp of derivation. */\n derived_at: string;\n /** StateEvent ids this snapshot folds in. */\n contributing_event_ids: string[];\n /** Age of the newest contributing event, in seconds. */\n freshness_seconds: number;\n /** 0..1, derived from contributing-event confidences. */\n confidence: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// 4. StateEvent — what hits the wire\n// ──────────────────────────────────────────────────────────────────\n\nexport type StateEventKind =\n /** A single point-in-time State capture. */\n | \"observation\"\n /** State before/after a regulation technique, plan step, etc. */\n | \"transition\"\n /** An external outcome (financial, behavioral) bearing on state. */\n | \"outcome\";\n\n/** Envelope shared by every StateEvent variant. */\nexport interface StateEventBase {\n /** UUID. Emitter-generated. Idempotent. */\n event_id: string;\n /** UUID. */\n subject_id: string;\n source: StateSource;\n kind: StateEventKind;\n /** ISO-8601. */\n emitted_at: string;\n\n /** 0..1. */\n confidence: number;\n /** Opaque; validated by behavior-insights. */\n consent_token?: string;\n}\n\nexport interface StateObservationEvent extends StateEventBase {\n kind: \"observation\";\n /** Partial allowed — record what was actually captured. */\n state: State;\n}\n\nexport interface StateTransitionEvent extends StateEventBase {\n kind: \"transition\";\n entry_state: State;\n exit_state: State;\n delta: {\n /** 0..1, magnitude of perceived improvement. */\n relief?: number;\n /** -1..1. */\n intensity_change?: number;\n };\n /** Emitter-side identifier; not constrained by this contract. */\n technique?: string;\n}\n\n/**\n * Per-source `extra` shape on outcome events. Keys must be members\n * of {@link StateSource}. Sources not present in this map carry no\n * `extra` payload. Adding a new emitter adds a new key here.\n */\nexport interface SourceOutcomeExtraMap {\n LedgersMe: {\n transaction_id: string;\n transaction_amount: number | null;\n transaction_currency: string | null;\n /** ISO-8601 — when the transaction cleared. */\n cleared_at: string;\n };\n AtlaSent: {\n permit_id: string;\n execution_status: string;\n };\n Echobloom: {\n session_id: string;\n };\n}\n\n/** Outcome event body, shared across sources. */\ninterface StateOutcomeEventBase extends StateEventBase {\n kind: \"outcome\";\n outcome_description: string;\n linking_mode: \"manual\" | \"time_window\";\n /** Manual mode: explicit StateEvent id to link to. */\n linked_event_id?: string;\n /** time_window mode: ISO-8601. */\n window_start?: string;\n /** time_window mode: ISO-8601. */\n window_end?: string;\n}\n\n/**\n * Outcome event. `extra` is determined by `source` via a mapped type,\n * so the two cannot disagree by construction. Sources without an\n * entry in {@link SourceOutcomeExtraMap} carry `extra?: never`.\n *\n * (An earlier draft used a self-discriminated `extra` union with its\n * own `source` field independent of the outer `source`; TypeScript\n * accepted contradictory pairs. Fixed per Codex P2 review.)\n */\nexport type StateOutcomeEvent = {\n [S in StateSource]: StateOutcomeEventBase & {\n source: S;\n extra?: S extends keyof SourceOutcomeExtraMap\n ? SourceOutcomeExtraMap[S]\n : never;\n };\n}[StateSource];\n\nexport type StateEvent =\n | StateObservationEvent\n | StateTransitionEvent\n | StateOutcomeEvent;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBO,IAAM,gBAAgB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;","names":[]}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Canonical cross-product behavioral state contract.
3
+ *
4
+ * Imported as a sub-export of @atlasent/sdk:
5
+ *
6
+ * ```ts
7
+ * import type { State, StateEvent, StateSource } from "@atlasent/sdk/state";
8
+ * ```
9
+ *
10
+ * Defined in `atlasent-docs/docs/STATE_CONTRACT_PROPOSAL.md` (decisions
11
+ * confirmed 2026-05-02). Replaces the ad-hoc per-app definitions
12
+ * previously drifting between hicoach, calm-state, behavior-insights,
13
+ * and ledgers-me.
14
+ *
15
+ * - `State` is the canonical normalized cross-product model.
16
+ * - `StateSnapshot` is the derived latest state at a point in time.
17
+ * - `StateEvent` is what hits the wire.
18
+ * - `StateSource` is a closed enum; new emitters require a contract change.
19
+ */
20
+ declare const STATE_SOURCES: readonly ["hiCoach", "CalmState", "Echobloom", "FutureBloom", "LedgersMe", "AtlaSent", "manual"];
21
+ type StateSource = (typeof STATE_SOURCES)[number];
22
+ /** Canonical emotional axis. Superset of calm-state's 8 + hicoach's 5. */
23
+ type EmotionalAxis = "tense" | "anxious" | "overwhelmed" | "flat" | "frustrated" | "uncertain" | "tired" | "okay" | "open" | "grounded";
24
+ /** Canonical body axis. Superset of calm-state's 6 + hicoach's 4. */
25
+ type BodyAxis = "tight" | "heavy" | "restless" | "numb" | "buzzing" | "settled" | "relaxed" | "exhausted";
26
+ type ReadinessLevel = "low" | "medium" | "high";
27
+ /**
28
+ * Canonical normalized state. Every dimension is optional; emitters
29
+ * record what they actually captured. Continuous axes are 0..1 normalized
30
+ * — UI layers translate to/from their native scale (e.g. calm-state's
31
+ * 0..10 sliders).
32
+ */
33
+ interface State {
34
+ emotional?: EmotionalAxis;
35
+ body?: BodyAxis;
36
+ readiness?: ReadinessLevel;
37
+ /** 0..1, 0=baseline, 1=overwhelming. */
38
+ intensity?: number;
39
+ /** 0..1. */
40
+ stress?: number;
41
+ /** 0..1. */
42
+ pressure?: number;
43
+ /** 0..1. */
44
+ cognitive_load?: number;
45
+ /** 0..1, self-rated certainty in the rating itself. */
46
+ confidence?: number;
47
+ }
48
+ interface StateSnapshot {
49
+ /** UUID of the user / actor. */
50
+ subject_id: string;
51
+ /** Best-known current state. */
52
+ state: State;
53
+ /** ISO-8601 timestamp of derivation. */
54
+ derived_at: string;
55
+ /** StateEvent ids this snapshot folds in. */
56
+ contributing_event_ids: string[];
57
+ /** Age of the newest contributing event, in seconds. */
58
+ freshness_seconds: number;
59
+ /** 0..1, derived from contributing-event confidences. */
60
+ confidence: number;
61
+ }
62
+ type StateEventKind =
63
+ /** A single point-in-time State capture. */
64
+ "observation"
65
+ /** State before/after a regulation technique, plan step, etc. */
66
+ | "transition"
67
+ /** An external outcome (financial, behavioral) bearing on state. */
68
+ | "outcome";
69
+ /** Envelope shared by every StateEvent variant. */
70
+ interface StateEventBase {
71
+ /** UUID. Emitter-generated. Idempotent. */
72
+ event_id: string;
73
+ /** UUID. */
74
+ subject_id: string;
75
+ source: StateSource;
76
+ kind: StateEventKind;
77
+ /** ISO-8601. */
78
+ emitted_at: string;
79
+ /** 0..1. */
80
+ confidence: number;
81
+ /** Opaque; validated by behavior-insights. */
82
+ consent_token?: string;
83
+ }
84
+ interface StateObservationEvent extends StateEventBase {
85
+ kind: "observation";
86
+ /** Partial allowed — record what was actually captured. */
87
+ state: State;
88
+ }
89
+ interface StateTransitionEvent extends StateEventBase {
90
+ kind: "transition";
91
+ entry_state: State;
92
+ exit_state: State;
93
+ delta: {
94
+ /** 0..1, magnitude of perceived improvement. */
95
+ relief?: number;
96
+ /** -1..1. */
97
+ intensity_change?: number;
98
+ };
99
+ /** Emitter-side identifier; not constrained by this contract. */
100
+ technique?: string;
101
+ }
102
+ /**
103
+ * Per-source `extra` shape on outcome events. Keys must be members
104
+ * of {@link StateSource}. Sources not present in this map carry no
105
+ * `extra` payload. Adding a new emitter adds a new key here.
106
+ */
107
+ interface SourceOutcomeExtraMap {
108
+ LedgersMe: {
109
+ transaction_id: string;
110
+ transaction_amount: number | null;
111
+ transaction_currency: string | null;
112
+ /** ISO-8601 — when the transaction cleared. */
113
+ cleared_at: string;
114
+ };
115
+ AtlaSent: {
116
+ permit_id: string;
117
+ execution_status: string;
118
+ };
119
+ Echobloom: {
120
+ session_id: string;
121
+ };
122
+ }
123
+ /** Outcome event body, shared across sources. */
124
+ interface StateOutcomeEventBase extends StateEventBase {
125
+ kind: "outcome";
126
+ outcome_description: string;
127
+ linking_mode: "manual" | "time_window";
128
+ /** Manual mode: explicit StateEvent id to link to. */
129
+ linked_event_id?: string;
130
+ /** time_window mode: ISO-8601. */
131
+ window_start?: string;
132
+ /** time_window mode: ISO-8601. */
133
+ window_end?: string;
134
+ }
135
+ /**
136
+ * Outcome event. `extra` is determined by `source` via a mapped type,
137
+ * so the two cannot disagree by construction. Sources without an
138
+ * entry in {@link SourceOutcomeExtraMap} carry `extra?: never`.
139
+ *
140
+ * (An earlier draft used a self-discriminated `extra` union with its
141
+ * own `source` field independent of the outer `source`; TypeScript
142
+ * accepted contradictory pairs. Fixed per Codex P2 review.)
143
+ */
144
+ type StateOutcomeEvent = {
145
+ [S in StateSource]: StateOutcomeEventBase & {
146
+ source: S;
147
+ extra?: S extends keyof SourceOutcomeExtraMap ? SourceOutcomeExtraMap[S] : never;
148
+ };
149
+ }[StateSource];
150
+ type StateEvent = StateObservationEvent | StateTransitionEvent | StateOutcomeEvent;
151
+
152
+ export { type BodyAxis, type EmotionalAxis, type ReadinessLevel, STATE_SOURCES, type SourceOutcomeExtraMap, type State, type StateEvent, type StateEventBase, type StateEventKind, type StateObservationEvent, type StateOutcomeEvent, type StateSnapshot, type StateSource, type StateTransitionEvent };
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Canonical cross-product behavioral state contract.
3
+ *
4
+ * Imported as a sub-export of @atlasent/sdk:
5
+ *
6
+ * ```ts
7
+ * import type { State, StateEvent, StateSource } from "@atlasent/sdk/state";
8
+ * ```
9
+ *
10
+ * Defined in `atlasent-docs/docs/STATE_CONTRACT_PROPOSAL.md` (decisions
11
+ * confirmed 2026-05-02). Replaces the ad-hoc per-app definitions
12
+ * previously drifting between hicoach, calm-state, behavior-insights,
13
+ * and ledgers-me.
14
+ *
15
+ * - `State` is the canonical normalized cross-product model.
16
+ * - `StateSnapshot` is the derived latest state at a point in time.
17
+ * - `StateEvent` is what hits the wire.
18
+ * - `StateSource` is a closed enum; new emitters require a contract change.
19
+ */
20
+ declare const STATE_SOURCES: readonly ["hiCoach", "CalmState", "Echobloom", "FutureBloom", "LedgersMe", "AtlaSent", "manual"];
21
+ type StateSource = (typeof STATE_SOURCES)[number];
22
+ /** Canonical emotional axis. Superset of calm-state's 8 + hicoach's 5. */
23
+ type EmotionalAxis = "tense" | "anxious" | "overwhelmed" | "flat" | "frustrated" | "uncertain" | "tired" | "okay" | "open" | "grounded";
24
+ /** Canonical body axis. Superset of calm-state's 6 + hicoach's 4. */
25
+ type BodyAxis = "tight" | "heavy" | "restless" | "numb" | "buzzing" | "settled" | "relaxed" | "exhausted";
26
+ type ReadinessLevel = "low" | "medium" | "high";
27
+ /**
28
+ * Canonical normalized state. Every dimension is optional; emitters
29
+ * record what they actually captured. Continuous axes are 0..1 normalized
30
+ * — UI layers translate to/from their native scale (e.g. calm-state's
31
+ * 0..10 sliders).
32
+ */
33
+ interface State {
34
+ emotional?: EmotionalAxis;
35
+ body?: BodyAxis;
36
+ readiness?: ReadinessLevel;
37
+ /** 0..1, 0=baseline, 1=overwhelming. */
38
+ intensity?: number;
39
+ /** 0..1. */
40
+ stress?: number;
41
+ /** 0..1. */
42
+ pressure?: number;
43
+ /** 0..1. */
44
+ cognitive_load?: number;
45
+ /** 0..1, self-rated certainty in the rating itself. */
46
+ confidence?: number;
47
+ }
48
+ interface StateSnapshot {
49
+ /** UUID of the user / actor. */
50
+ subject_id: string;
51
+ /** Best-known current state. */
52
+ state: State;
53
+ /** ISO-8601 timestamp of derivation. */
54
+ derived_at: string;
55
+ /** StateEvent ids this snapshot folds in. */
56
+ contributing_event_ids: string[];
57
+ /** Age of the newest contributing event, in seconds. */
58
+ freshness_seconds: number;
59
+ /** 0..1, derived from contributing-event confidences. */
60
+ confidence: number;
61
+ }
62
+ type StateEventKind =
63
+ /** A single point-in-time State capture. */
64
+ "observation"
65
+ /** State before/after a regulation technique, plan step, etc. */
66
+ | "transition"
67
+ /** An external outcome (financial, behavioral) bearing on state. */
68
+ | "outcome";
69
+ /** Envelope shared by every StateEvent variant. */
70
+ interface StateEventBase {
71
+ /** UUID. Emitter-generated. Idempotent. */
72
+ event_id: string;
73
+ /** UUID. */
74
+ subject_id: string;
75
+ source: StateSource;
76
+ kind: StateEventKind;
77
+ /** ISO-8601. */
78
+ emitted_at: string;
79
+ /** 0..1. */
80
+ confidence: number;
81
+ /** Opaque; validated by behavior-insights. */
82
+ consent_token?: string;
83
+ }
84
+ interface StateObservationEvent extends StateEventBase {
85
+ kind: "observation";
86
+ /** Partial allowed — record what was actually captured. */
87
+ state: State;
88
+ }
89
+ interface StateTransitionEvent extends StateEventBase {
90
+ kind: "transition";
91
+ entry_state: State;
92
+ exit_state: State;
93
+ delta: {
94
+ /** 0..1, magnitude of perceived improvement. */
95
+ relief?: number;
96
+ /** -1..1. */
97
+ intensity_change?: number;
98
+ };
99
+ /** Emitter-side identifier; not constrained by this contract. */
100
+ technique?: string;
101
+ }
102
+ /**
103
+ * Per-source `extra` shape on outcome events. Keys must be members
104
+ * of {@link StateSource}. Sources not present in this map carry no
105
+ * `extra` payload. Adding a new emitter adds a new key here.
106
+ */
107
+ interface SourceOutcomeExtraMap {
108
+ LedgersMe: {
109
+ transaction_id: string;
110
+ transaction_amount: number | null;
111
+ transaction_currency: string | null;
112
+ /** ISO-8601 — when the transaction cleared. */
113
+ cleared_at: string;
114
+ };
115
+ AtlaSent: {
116
+ permit_id: string;
117
+ execution_status: string;
118
+ };
119
+ Echobloom: {
120
+ session_id: string;
121
+ };
122
+ }
123
+ /** Outcome event body, shared across sources. */
124
+ interface StateOutcomeEventBase extends StateEventBase {
125
+ kind: "outcome";
126
+ outcome_description: string;
127
+ linking_mode: "manual" | "time_window";
128
+ /** Manual mode: explicit StateEvent id to link to. */
129
+ linked_event_id?: string;
130
+ /** time_window mode: ISO-8601. */
131
+ window_start?: string;
132
+ /** time_window mode: ISO-8601. */
133
+ window_end?: string;
134
+ }
135
+ /**
136
+ * Outcome event. `extra` is determined by `source` via a mapped type,
137
+ * so the two cannot disagree by construction. Sources without an
138
+ * entry in {@link SourceOutcomeExtraMap} carry `extra?: never`.
139
+ *
140
+ * (An earlier draft used a self-discriminated `extra` union with its
141
+ * own `source` field independent of the outer `source`; TypeScript
142
+ * accepted contradictory pairs. Fixed per Codex P2 review.)
143
+ */
144
+ type StateOutcomeEvent = {
145
+ [S in StateSource]: StateOutcomeEventBase & {
146
+ source: S;
147
+ extra?: S extends keyof SourceOutcomeExtraMap ? SourceOutcomeExtraMap[S] : never;
148
+ };
149
+ }[StateSource];
150
+ type StateEvent = StateObservationEvent | StateTransitionEvent | StateOutcomeEvent;
151
+
152
+ export { type BodyAxis, type EmotionalAxis, type ReadinessLevel, STATE_SOURCES, type SourceOutcomeExtraMap, type State, type StateEvent, type StateEventBase, type StateEventKind, type StateObservationEvent, type StateOutcomeEvent, type StateSnapshot, type StateSource, type StateTransitionEvent };
package/dist/state.js ADDED
@@ -0,0 +1,21 @@
1
+ // src/state.ts
2
+ var STATE_SOURCES = [
3
+ "hiCoach",
4
+ // bettyc925/hicoach (consumer regulation app)
5
+ "CalmState",
6
+ // atlasent/calm-state (org-side regulation app)
7
+ "Echobloom",
8
+ // bettyc925/echobloom (observability — emits from sessions)
9
+ "FutureBloom",
10
+ // atlasent/future-bloom-planner (planner — state inferred from plan execution)
11
+ "LedgersMe",
12
+ // bettyc925/ledgers-me (financial outcomes inform state proxy)
13
+ "AtlaSent",
14
+ // atlasent/atlasent-api (control-plane derived events)
15
+ "manual"
16
+ // operator-entered, no emitter
17
+ ];
18
+ export {
19
+ STATE_SOURCES
20
+ };
21
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/state.ts"],"sourcesContent":["/**\n * Canonical cross-product behavioral state contract.\n *\n * Imported as a sub-export of @atlasent/sdk:\n *\n * ```ts\n * import type { State, StateEvent, StateSource } from \"@atlasent/sdk/state\";\n * ```\n *\n * Defined in `atlasent-docs/docs/STATE_CONTRACT_PROPOSAL.md` (decisions\n * confirmed 2026-05-02). Replaces the ad-hoc per-app definitions\n * previously drifting between hicoach, calm-state, behavior-insights,\n * and ledgers-me.\n *\n * - `State` is the canonical normalized cross-product model.\n * - `StateSnapshot` is the derived latest state at a point in time.\n * - `StateEvent` is what hits the wire.\n * - `StateSource` is a closed enum; new emitters require a contract change.\n */\n\n// ──────────────────────────────────────────────────────────────────\n// 1. StateSource — closed enum, one literal per emitter\n// ──────────────────────────────────────────────────────────────────\nexport const STATE_SOURCES = [\n \"hiCoach\", // bettyc925/hicoach (consumer regulation app)\n \"CalmState\", // atlasent/calm-state (org-side regulation app)\n \"Echobloom\", // bettyc925/echobloom (observability — emits from sessions)\n \"FutureBloom\", // atlasent/future-bloom-planner (planner — state inferred from plan execution)\n \"LedgersMe\", // bettyc925/ledgers-me (financial outcomes inform state proxy)\n \"AtlaSent\", // atlasent/atlasent-api (control-plane derived events)\n \"manual\", // operator-entered, no emitter\n] as const;\n\nexport type StateSource = (typeof STATE_SOURCES)[number];\n\n// ──────────────────────────────────────────────────────────────────\n// 2. State — canonical normalized model\n// Every dimension is OPTIONAL at the type level so partial\n// observations are valid; each axis has a fixed vocabulary.\n// ──────────────────────────────────────────────────────────────────\n\n/** Canonical emotional axis. Superset of calm-state's 8 + hicoach's 5. */\nexport type EmotionalAxis =\n | \"tense\"\n | \"anxious\"\n | \"overwhelmed\"\n | \"flat\"\n | \"frustrated\"\n | \"uncertain\"\n | \"tired\"\n | \"okay\"\n | \"open\"\n | \"grounded\";\n\n/** Canonical body axis. Superset of calm-state's 6 + hicoach's 4. */\nexport type BodyAxis =\n | \"tight\"\n | \"heavy\"\n | \"restless\"\n | \"numb\"\n | \"buzzing\"\n | \"settled\"\n | \"relaxed\"\n | \"exhausted\";\n\nexport type ReadinessLevel = \"low\" | \"medium\" | \"high\";\n\n/**\n * Canonical normalized state. Every dimension is optional; emitters\n * record what they actually captured. Continuous axes are 0..1 normalized\n * — UI layers translate to/from their native scale (e.g. calm-state's\n * 0..10 sliders).\n */\nexport interface State {\n emotional?: EmotionalAxis;\n body?: BodyAxis;\n readiness?: ReadinessLevel;\n\n /** 0..1, 0=baseline, 1=overwhelming. */\n intensity?: number;\n /** 0..1. */\n stress?: number;\n /** 0..1. */\n pressure?: number;\n /** 0..1. */\n cognitive_load?: number;\n /** 0..1, self-rated certainty in the rating itself. */\n confidence?: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// 3. StateSnapshot — derived \"what is the latest state right now\"\n// Built by consumers from the StateEvent stream. Never emitted.\n// ──────────────────────────────────────────────────────────────────\nexport interface StateSnapshot {\n /** UUID of the user / actor. */\n subject_id: string;\n /** Best-known current state. */\n state: State;\n /** ISO-8601 timestamp of derivation. */\n derived_at: string;\n /** StateEvent ids this snapshot folds in. */\n contributing_event_ids: string[];\n /** Age of the newest contributing event, in seconds. */\n freshness_seconds: number;\n /** 0..1, derived from contributing-event confidences. */\n confidence: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// 4. StateEvent — what hits the wire\n// ──────────────────────────────────────────────────────────────────\n\nexport type StateEventKind =\n /** A single point-in-time State capture. */\n | \"observation\"\n /** State before/after a regulation technique, plan step, etc. */\n | \"transition\"\n /** An external outcome (financial, behavioral) bearing on state. */\n | \"outcome\";\n\n/** Envelope shared by every StateEvent variant. */\nexport interface StateEventBase {\n /** UUID. Emitter-generated. Idempotent. */\n event_id: string;\n /** UUID. */\n subject_id: string;\n source: StateSource;\n kind: StateEventKind;\n /** ISO-8601. */\n emitted_at: string;\n\n /** 0..1. */\n confidence: number;\n /** Opaque; validated by behavior-insights. */\n consent_token?: string;\n}\n\nexport interface StateObservationEvent extends StateEventBase {\n kind: \"observation\";\n /** Partial allowed — record what was actually captured. */\n state: State;\n}\n\nexport interface StateTransitionEvent extends StateEventBase {\n kind: \"transition\";\n entry_state: State;\n exit_state: State;\n delta: {\n /** 0..1, magnitude of perceived improvement. */\n relief?: number;\n /** -1..1. */\n intensity_change?: number;\n };\n /** Emitter-side identifier; not constrained by this contract. */\n technique?: string;\n}\n\n/**\n * Per-source `extra` shape on outcome events. Keys must be members\n * of {@link StateSource}. Sources not present in this map carry no\n * `extra` payload. Adding a new emitter adds a new key here.\n */\nexport interface SourceOutcomeExtraMap {\n LedgersMe: {\n transaction_id: string;\n transaction_amount: number | null;\n transaction_currency: string | null;\n /** ISO-8601 — when the transaction cleared. */\n cleared_at: string;\n };\n AtlaSent: {\n permit_id: string;\n execution_status: string;\n };\n Echobloom: {\n session_id: string;\n };\n}\n\n/** Outcome event body, shared across sources. */\ninterface StateOutcomeEventBase extends StateEventBase {\n kind: \"outcome\";\n outcome_description: string;\n linking_mode: \"manual\" | \"time_window\";\n /** Manual mode: explicit StateEvent id to link to. */\n linked_event_id?: string;\n /** time_window mode: ISO-8601. */\n window_start?: string;\n /** time_window mode: ISO-8601. */\n window_end?: string;\n}\n\n/**\n * Outcome event. `extra` is determined by `source` via a mapped type,\n * so the two cannot disagree by construction. Sources without an\n * entry in {@link SourceOutcomeExtraMap} carry `extra?: never`.\n *\n * (An earlier draft used a self-discriminated `extra` union with its\n * own `source` field independent of the outer `source`; TypeScript\n * accepted contradictory pairs. Fixed per Codex P2 review.)\n */\nexport type StateOutcomeEvent = {\n [S in StateSource]: StateOutcomeEventBase & {\n source: S;\n extra?: S extends keyof SourceOutcomeExtraMap\n ? SourceOutcomeExtraMap[S]\n : never;\n };\n}[StateSource];\n\nexport type StateEvent =\n | StateObservationEvent\n | StateTransitionEvent\n | StateOutcomeEvent;\n"],"mappings":";AAuBO,IAAM,gBAAgB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasent/sdk",
3
- "version": "1.5.0",
3
+ "version": "2.10.0",
4
4
  "description": "TypeScript SDK for the AtlaSent authorization API",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -38,6 +38,16 @@
38
38
  "default": "./dist/behavior.cjs"
39
39
  }
40
40
  },
41
+ "./state": {
42
+ "import": {
43
+ "types": "./dist/state.d.ts",
44
+ "default": "./dist/state.js"
45
+ },
46
+ "require": {
47
+ "types": "./dist/state.d.cts",
48
+ "default": "./dist/state.cjs"
49
+ }
50
+ },
41
51
  "./package.json": "./package.json"
42
52
  },
43
53
  "files": [
@@ -47,14 +57,21 @@
47
57
  ],
48
58
  "sideEffects": false,
49
59
  "engines": {
50
- "node": ">=20"
60
+ "node": ">=18"
51
61
  },
62
+ "browserslist": [
63
+ "Chrome >= 103",
64
+ "Firefox >= 100",
65
+ "Safari >= 16"
66
+ ],
52
67
  "scripts": {
53
68
  "build": "tsup",
54
69
  "clean": "rm -rf dist",
55
70
  "prepublishOnly": "npm run clean && npm run typecheck && npm test && npm run build",
71
+ "size": "size-limit",
56
72
  "test": "vitest run",
57
73
  "test:coverage": "vitest run --coverage",
74
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
58
75
  "test:integration": "vitest run --config vitest.integration.config.ts",
59
76
  "test:watch": "vitest",
60
77
  "typecheck": "tsc --noEmit",
@@ -82,18 +99,28 @@
82
99
  "access": "public"
83
100
  },
84
101
  "devDependencies": {
102
+ "@size-limit/esbuild": "^12.1.0",
103
+ "@size-limit/file": "^12.1.0",
104
+ "@types/express": "^5.0.6",
105
+ "@types/jsdom": "^28.0.1",
85
106
  "@types/node": "^25.6.0",
86
107
  "@vitest/coverage-v8": "^4.1.5",
87
108
  "hono": "^4.12.15",
109
+ "jsdom": "^29.1.0",
110
+ "size-limit": "^12.1.0",
88
111
  "tsup": "^8.0.2",
89
112
  "tsx": "^4.7.2",
90
113
  "typescript": "^6.0.3",
91
114
  "vitest": "^4.1.5"
92
115
  },
93
116
  "peerDependencies": {
117
+ "express": "^4.0.0 || ^5.0.0",
94
118
  "hono": "^4.0.0"
95
119
  },
96
120
  "peerDependenciesMeta": {
121
+ "express": {
122
+ "optional": true
123
+ },
97
124
  "hono": {
98
125
  "optional": true
99
126
  }
@@ -1,159 +0,0 @@
1
- /**
2
- * Error types for the AtlaSent TypeScript SDK.
3
- *
4
- * The SDK follows a fail-closed design: a clean policy DENY is
5
- * returned as `EvaluateResponse.decision === "DENY"` (not thrown),
6
- * but any failure to confirm authorization — network, timeout,
7
- * bad response, invalid key, rate limit — throws an
8
- * {@link AtlaSentError}.
9
- */
10
- /** Discriminator for {@link AtlaSentError.code}. */
11
- type AtlaSentErrorCode = "invalid_api_key" | "forbidden" | "rate_limited" | "timeout" | "network" | "bad_response" | "bad_request" | "server_error";
12
- /** Initialization options for {@link AtlaSentError}. */
13
- interface AtlaSentErrorInit {
14
- status?: number;
15
- code?: AtlaSentErrorCode;
16
- requestId?: string;
17
- retryAfterMs?: number;
18
- cause?: unknown;
19
- }
20
- /**
21
- * The only error type this SDK throws.
22
- *
23
- * Flat top-level properties mirror the convention used by Stripe,
24
- * Octokit, and Supabase. `cause` is forwarded to the standard
25
- * ES2022 `Error` constructor.
26
- */
27
- declare class AtlaSentError extends Error {
28
- name: string;
29
- /** HTTP status code, when the error originated from an API response. */
30
- readonly status: number | undefined;
31
- /** Coarse category — useful for `switch` statements at call sites. */
32
- readonly code: AtlaSentErrorCode | undefined;
33
- /** Correlation ID echoed from the `X-Request-ID` header the SDK sent. */
34
- readonly requestId: string | undefined;
35
- /** Parsed `Retry-After` header value, in milliseconds. Only set for 429. */
36
- readonly retryAfterMs: number | undefined;
37
- constructor(message: string, init?: AtlaSentErrorInit);
38
- }
39
- /**
40
- * Outcome of a denied decision.
41
- *
42
- * `"deny"` is what the current `/v1-evaluate` API returns. `"hold"`
43
- * and `"escalate"` are reserved for forthcoming API decisions that
44
- * put a permit into a pending state requiring human review; the
45
- * union is declared now so call sites can `switch` exhaustively
46
- * from the start and adopt new decisions without a breaking change.
47
- */
48
- type AtlaSentDecision = "deny" | "hold" | "escalate";
49
- /** Initialization options for {@link AtlaSentDeniedError}. */
50
- interface AtlaSentDeniedErrorInit {
51
- decision: AtlaSentDecision;
52
- evaluationId: string;
53
- reason?: string;
54
- requestId?: string;
55
- auditHash?: string;
56
- }
57
- /**
58
- * Thrown by {@link atlasent.protect} when the policy engine refuses
59
- * the action, or when a permit fails end-to-end verification.
60
- *
61
- * This is the **fail-closed boundary** of the SDK: every code path
62
- * that short-circuits an action because authorization was not
63
- * confirmed raises an `AtlaSentDeniedError`. Callers cannot silently
64
- * proceed on a denial by forgetting to branch on a return value.
65
- *
66
- * Extends {@link AtlaSentError} so `instanceof AtlaSentError`
67
- * catches denials as part of the SDK's single exception family;
68
- * use `instanceof AtlaSentDeniedError` to distinguish a policy
69
- * denial from a transport/auth error.
70
- */
71
- declare class AtlaSentDeniedError extends AtlaSentError {
72
- name: string;
73
- /** Policy decision — `"deny"` today; `"hold"` / `"escalate"` reserved. */
74
- readonly decision: AtlaSentDecision;
75
- /** Opaque permit/decision id from `/v1-evaluate`. */
76
- readonly evaluationId: string;
77
- /** Human-readable explanation from the policy engine, if provided. */
78
- readonly reason: string | undefined;
79
- /** Hash-chained audit-trail entry associated with the decision. */
80
- readonly auditHash: string | undefined;
81
- constructor(init: AtlaSentDeniedErrorInit);
82
- }
83
-
84
- /**
85
- * `atlasent.protect(...)` — the one-call, fail-closed execution-time
86
- * authorization boundary.
87
- *
88
- * ```ts
89
- * import atlasent from "@atlasent/sdk";
90
- *
91
- * const permit = await atlasent.protect({
92
- * agent: "deploy-bot",
93
- * action: "deploy_to_production",
94
- * context: { commit, approver },
95
- * });
96
- * // …run the action. If we got here, AtlaSent authorized it
97
- * // end-to-end (evaluate + verifyPermit).
98
- * ```
99
- *
100
- * Unlike {@link AtlaSentClient.evaluate}, `protect` never returns a
101
- * denied decision. On deny, it throws {@link AtlaSentDeniedError};
102
- * on transport / auth / server failure it throws
103
- * {@link AtlaSentError}. The action cannot execute unless a valid
104
- * {@link Permit} is returned — this is the SDK's category boundary,
105
- * not a helper.
106
- */
107
- /** Input to {@link protect}. Same shape as `EvaluateRequest`. */
108
- interface ProtectRequest {
109
- agent: string;
110
- action: string;
111
- context?: Record<string, unknown>;
112
- }
113
- /**
114
- * Success return from {@link protect}. The action is authorized
115
- * end-to-end — evaluation allowed AND the resulting permit verified.
116
- */
117
- interface Permit {
118
- /** Opaque permit / decision identifier. */
119
- permitId: string;
120
- /** Verification hash bound to the permit. */
121
- permitHash: string;
122
- /** Audit-trail entry associated with the decision (hash-chained). */
123
- auditHash: string;
124
- /** Human-readable reason from the policy engine. */
125
- reason: string;
126
- /** ISO 8601 timestamp of the verification. */
127
- timestamp: string;
128
- }
129
- /** Configuration for the process-wide singleton used by {@link protect}. */
130
- interface ConfigureOptions {
131
- /** Overrides `ATLASENT_API_KEY` env var. */
132
- apiKey?: string;
133
- /** Overrides the default `https://api.atlasent.io`. */
134
- baseUrl?: string;
135
- /** Per-request timeout in ms. */
136
- timeoutMs?: number;
137
- /** Inject a custom fetch (primarily for tests). */
138
- fetch?: typeof fetch;
139
- }
140
- /**
141
- * Configure the singleton client used by {@link protect}. Optional —
142
- * if `ATLASENT_API_KEY` is set in the environment, `protect` works
143
- * without any configuration. Calling `configure` again replaces the
144
- * singleton; subsequent `protect` calls use the new settings.
145
- */
146
- declare function configure(options: ConfigureOptions): void;
147
- /**
148
- * Authorize an action end-to-end. On allow, returns a verified
149
- * {@link Permit}. On anything else, throws:
150
- *
151
- * - {@link AtlaSentDeniedError} — policy denied, or the permit
152
- * failed verification. Fail-closed: if this throws, the action
153
- * MUST NOT proceed.
154
- * - {@link AtlaSentError} — transport, timeout, auth, rate-limit,
155
- * or server error. Same fail-closed contract: do not proceed.
156
- */
157
- declare function protect(request: ProtectRequest): Promise<Permit>;
158
-
159
- export { AtlaSentDeniedError as A, type ConfigureOptions as C, type Permit as P, AtlaSentError as a, type ProtectRequest as b, configure as c, type AtlaSentDecision as d, type AtlaSentDeniedErrorInit as e, type AtlaSentErrorCode as f, type AtlaSentErrorInit as g, protect as p };