@nexalink/carecompass-sdk 0.5.0 → 0.6.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 +10 -7
- package/dist/client.js +3 -0
- package/dist/rcm.d.ts +2 -0
- package/dist/rcm.js +8 -4
- package/dist/telemetry.d.ts +3 -2
- package/dist/telemetry.js +16 -35
- package/dist/version.js +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -185,6 +185,11 @@ field. The hosted runtime authorizes the workflow from the issued embed key and
|
|
|
185
185
|
server-side tenant entitlement. Values in user context do not authorize a
|
|
186
186
|
workflow.
|
|
187
187
|
|
|
188
|
+
Development and staging RCM requests must include `claimContext.stage` set to
|
|
189
|
+
the configured SDK environment (`"development"` or `"staging"`). Production
|
|
190
|
+
may omit the field. The hosted runtime validates any supplied value against the
|
|
191
|
+
authenticated key environment; this marker never grants workflow access.
|
|
192
|
+
|
|
188
193
|
For the hosted RCM path, configure the tenant's RCM policy corpus in the
|
|
189
194
|
CareCompass tenant portal before embedding: an authorized administrator must
|
|
190
195
|
have an executed BAA, enable the RCM entitlement, set up the corpus, upload a
|
|
@@ -210,13 +215,11 @@ import {
|
|
|
210
215
|
/>;
|
|
211
216
|
```
|
|
212
217
|
|
|
213
|
-
The included demo input is synthetic and contains no patient data.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
submitting `CARECOMPASS_RCM_SYNTHETIC_DEMO`. It is deliberately not a real payer
|
|
219
|
-
policy or coding manual.
|
|
218
|
+
The included demo input is synthetic and contains no patient data. Its same-day
|
|
219
|
+
observation scenario is designed to retrieve the official CMS E/M evidence for
|
|
220
|
+
CPT 99236 from the Nexalink base corpus. Tenant policies may supplement the
|
|
221
|
+
base, but the runtime still requires an approved, active corpus and grounded
|
|
222
|
+
citations before returning a candidate.
|
|
220
223
|
|
|
221
224
|
A production tenant must have an executed BAA, an RCM entitlement, and a
|
|
222
225
|
healthy active corpus; otherwise the hosted workflow fails closed with a
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validateCareCompassConfig } from "./schema.js";
|
|
2
2
|
import { CARECOMPASS_TELEMETRY_ERROR_CODES, CARECOMPASS_TELEMETRY_EVENTS, createCareCompassTelemetry, } from "./telemetry.js";
|
|
3
|
+
import { CARECOMPASS_SDK_VERSION } from "./version.js";
|
|
3
4
|
// Internal error metadata keeps telemetry classification separate from messages,
|
|
4
5
|
// which may include user-visible API details that should not be emitted.
|
|
5
6
|
class CareCompassClientError extends Error {
|
|
@@ -185,6 +186,8 @@ export function createCareCompassClient(inputConfig, options = {}) {
|
|
|
185
186
|
requestId: request.requestId,
|
|
186
187
|
workflow: request.workflow,
|
|
187
188
|
sessionId: request.sessionId,
|
|
189
|
+
sdkVersion: CARECOMPASS_SDK_VERSION,
|
|
190
|
+
applicationSurface: config.deploymentTarget,
|
|
188
191
|
userContext: request.userContext,
|
|
189
192
|
promptConfig: config.prompt,
|
|
190
193
|
// Public routing preferences; the hosted runtime validates model
|
package/dist/rcm.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type RcmCodingAssistanceInput = {
|
|
|
10
10
|
serviceDate?: string;
|
|
11
11
|
placeOfService?: string;
|
|
12
12
|
claimContext?: {
|
|
13
|
+
/** Required in development and staging; when supplied, it must match the authenticated SDK environment. */
|
|
14
|
+
stage?: CareCompassConfig["environment"];
|
|
13
15
|
payerName?: string;
|
|
14
16
|
submittedCodes?: string[];
|
|
15
17
|
};
|
package/dist/rcm.js
CHANGED
|
@@ -241,11 +241,15 @@ export function createRcmCodingWorkflow(config, options = {}) {
|
|
|
241
241
|
}
|
|
242
242
|
export const CARECOMPASS_RCM_SYNTHETIC_DEMO = {
|
|
243
243
|
encounterId: "DEMO-ENC-1042",
|
|
244
|
-
diagnosisNarrative: "Synthetic
|
|
245
|
-
procedureNarrative: "Synthetic clinician
|
|
244
|
+
diagnosisNarrative: "Synthetic Medicare hospital observation encounter with same-day admission and discharge.",
|
|
245
|
+
procedureNarrative: "Synthetic clinician documented 110 minutes of qualifying same-day admission and discharge management time.",
|
|
246
246
|
serviceDate: "2026-07-01",
|
|
247
|
-
placeOfService: "
|
|
248
|
-
claimContext: {
|
|
247
|
+
placeOfService: "22",
|
|
248
|
+
claimContext: {
|
|
249
|
+
stage: "development",
|
|
250
|
+
payerName: "Synthetic Medicare demo",
|
|
251
|
+
submittedCodes: ["99236"],
|
|
252
|
+
},
|
|
249
253
|
};
|
|
250
254
|
/** A small branded form suitable for embedding the pilot workflow in a host app. */
|
|
251
255
|
export function RcmCodingAssistant({ config, initialInput = CARECOMPASS_RCM_SYNTHETIC_DEMO, onAuditEvent, onResult, onSafetyEvent, workflowOptions, }) {
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CareCompassConfig } from "./schema.js";
|
|
2
2
|
export declare const CARECOMPASS_TELEMETRY_EVENTS: {
|
|
3
3
|
readonly SDK_INITIALIZED: "carecompass_sdk_initialized";
|
|
4
4
|
readonly SDK_INITIALIZATION_FAILED: "carecompass_sdk_initialization_failed";
|
|
@@ -98,11 +98,12 @@ export type CareCompassTelemetry = {
|
|
|
98
98
|
captureAsync: (event: CareCompassTelemetryEvent, options?: CareCompassTelemetryCaptureOptions) => Promise<void>;
|
|
99
99
|
};
|
|
100
100
|
export declare const careCompassTelemetryDurationBucket: (durationMs: number) => CareCompassTelemetryDurationBucket;
|
|
101
|
-
export declare function createCareCompassTelemetry(config: Pick<CareCompassConfig, "environment" | "payerId">, options?: {
|
|
101
|
+
export declare function createCareCompassTelemetry(config: Pick<CareCompassConfig, "apiBaseUrl" | "environment" | "payerId">, options?: {
|
|
102
102
|
fetcher?: Fetcher;
|
|
103
103
|
now?: () => Date;
|
|
104
104
|
}): CareCompassTelemetry;
|
|
105
105
|
export declare function createCareCompassCliTelemetry(sessionId: string, context?: {
|
|
106
|
+
apiBaseUrl?: string;
|
|
106
107
|
environment?: CareCompassConfig["environment"];
|
|
107
108
|
payerId?: string;
|
|
108
109
|
}, options?: {
|
package/dist/telemetry.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { careCompassApiBaseUrlSchema, } from "./schema.js";
|
|
1
2
|
import { CARECOMPASS_COMPONENT_VERSION, CARECOMPASS_SDK_VERSION, CARECOMPASS_TELEMETRY_CONTRACT_VERSION, } from "./version.js";
|
|
2
3
|
export const CARECOMPASS_TELEMETRY_EVENTS = {
|
|
3
4
|
SDK_INITIALIZED: "carecompass_sdk_initialized",
|
|
@@ -62,12 +63,9 @@ export const CARECOMPASS_TELEMETRY_ERROR_CODES = {
|
|
|
62
63
|
CLI_COMMAND_UNKNOWN: "CLI_COMMAND_UNKNOWN",
|
|
63
64
|
UNKNOWN_ERROR: "UNKNOWN_ERROR",
|
|
64
65
|
};
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const CARECOMPASS_DEFAULT_POSTHOG_API_HOST = "https://us.i.posthog.com";
|
|
68
|
-
const CARECOMPASS_DEFAULT_POSTHOG_PROJECT_TOKEN = "phc_vYl3rpIu6Iz5vCeJUG62BBA3nlPCeF4RSYpCb8FjnOl";
|
|
66
|
+
const CARECOMPASS_DEFAULT_API_BASE_URL = "https://www.nexalink.care";
|
|
67
|
+
const CARECOMPASS_TELEMETRY_PATH = "/api/carecompass/telemetry";
|
|
69
68
|
const TELEMETRY_CAPTURE_TIMEOUT_MS = 1_000;
|
|
70
|
-
const ANONYMOUS_DISTINCT_ID = "carecompass-sdk-anonymous";
|
|
71
69
|
const TELEMETRY_EVENTS = new Set(Object.values(CARECOMPASS_TELEMETRY_EVENTS));
|
|
72
70
|
const TELEMETRY_ERROR_CODES = new Set(Object.values(CARECOMPASS_TELEMETRY_ERROR_CODES));
|
|
73
71
|
const FAILURE_CATEGORIES = new Set([
|
|
@@ -121,28 +119,15 @@ const disabledTelemetry = {
|
|
|
121
119
|
capture: () => undefined,
|
|
122
120
|
captureAsync: async () => undefined,
|
|
123
121
|
};
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (typeof value !== "string")
|
|
122
|
+
const approvedRelayBaseUrl = (value, environment) => {
|
|
123
|
+
const parsed = careCompassApiBaseUrlSchema.safeParse(value);
|
|
124
|
+
if (!parsed.success)
|
|
128
125
|
return null;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
url.hostname === "127.0.0.1" ||
|
|
135
|
-
url.hostname === "[::1]";
|
|
136
|
-
if (isLocalhost) {
|
|
137
|
-
return environment === "development" ? value.replace(/\/+$/, "") : null;
|
|
138
|
-
}
|
|
139
|
-
return url.protocol === "https:" && POSTHOG_HOSTNAMES.has(url.hostname)
|
|
140
|
-
? value.replace(/\/+$/, "")
|
|
141
|
-
: null;
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
126
|
+
const url = new URL(parsed.data);
|
|
127
|
+
const isLocalhost = url.hostname === "localhost" ||
|
|
128
|
+
url.hostname === "127.0.0.1" ||
|
|
129
|
+
url.hostname === "[::1]";
|
|
130
|
+
return isLocalhost && environment !== "development" ? null : parsed.data;
|
|
146
131
|
};
|
|
147
132
|
export const careCompassTelemetryDurationBucket = (durationMs) => {
|
|
148
133
|
if (durationMs < 250)
|
|
@@ -166,14 +151,10 @@ const allowedEnvironment = (value) => value === "development" || value === "stag
|
|
|
166
151
|
? value
|
|
167
152
|
: "unknown";
|
|
168
153
|
function createTelemetry(context, options = {}) {
|
|
169
|
-
const projectToken = CARECOMPASS_DEFAULT_POSTHOG_PROJECT_TOKEN;
|
|
170
|
-
if (!POSTHOG_PROJECT_TOKEN_RE.test(projectToken)) {
|
|
171
|
-
return disabledTelemetry;
|
|
172
|
-
}
|
|
173
154
|
const fetcher = options.fetcher ?? fetch;
|
|
174
155
|
const now = options.now ?? (() => new Date());
|
|
175
|
-
const
|
|
176
|
-
if (!
|
|
156
|
+
const relayBaseUrl = approvedRelayBaseUrl(context.apiBaseUrl, context.environment);
|
|
157
|
+
if (!relayBaseUrl)
|
|
177
158
|
return disabledTelemetry;
|
|
178
159
|
const captureAsync = async (event, captureOptions = {}) => {
|
|
179
160
|
if (!TELEMETRY_EVENTS.has(event))
|
|
@@ -251,12 +232,10 @@ function createTelemetry(context, options = {}) {
|
|
|
251
232
|
const controller = new AbortController();
|
|
252
233
|
const timeout = setTimeout(() => controller.abort(), TELEMETRY_CAPTURE_TIMEOUT_MS);
|
|
253
234
|
try {
|
|
254
|
-
await fetcher(`${
|
|
235
|
+
await fetcher(`${relayBaseUrl}${CARECOMPASS_TELEMETRY_PATH}`, {
|
|
255
236
|
method: "POST",
|
|
256
237
|
headers: { "content-type": "application/json" },
|
|
257
238
|
body: JSON.stringify({
|
|
258
|
-
api_key: projectToken,
|
|
259
|
-
distinct_id: ANONYMOUS_DISTINCT_ID,
|
|
260
239
|
event,
|
|
261
240
|
properties,
|
|
262
241
|
timestamp: eventTimestamp,
|
|
@@ -279,6 +258,7 @@ function createTelemetry(context, options = {}) {
|
|
|
279
258
|
}
|
|
280
259
|
export function createCareCompassTelemetry(config, options = {}) {
|
|
281
260
|
return createTelemetry({
|
|
261
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
282
262
|
environment: config.environment,
|
|
283
263
|
platform: "web",
|
|
284
264
|
}, options);
|
|
@@ -288,6 +268,7 @@ export function createCareCompassCliTelemetry(sessionId, context = {}, options =
|
|
|
288
268
|
void sessionId;
|
|
289
269
|
const environment = context.environment ?? "unknown";
|
|
290
270
|
return createTelemetry({
|
|
271
|
+
apiBaseUrl: context.apiBaseUrl ?? CARECOMPASS_DEFAULT_API_BASE_URL,
|
|
291
272
|
environment,
|
|
292
273
|
platform: "cli",
|
|
293
274
|
}, options);
|
package/dist/version.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const CARECOMPASS_SDK_VERSION = "0.
|
|
1
|
+
export const CARECOMPASS_SDK_VERSION = "0.6.0"; // x-release-please-version
|
|
2
2
|
export const CARECOMPASS_COMPONENT_VERSION = "1.0.0";
|
|
3
3
|
export const CARECOMPASS_TELEMETRY_CONTRACT_VERSION = "1.1.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexalink/carecompass-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Embeddable CareCompass SDK and CLI for healthcare ecosystem integrations with Nexalink onboarding, BAA coverage, and API keys.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.3.9",
|
|
@@ -74,8 +74,9 @@
|
|
|
74
74
|
"tidy": "bun run lint && bun run format",
|
|
75
75
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --watchman=false",
|
|
76
76
|
"audit": "bun audit",
|
|
77
|
-
"release:check": "bun install --frozen-lockfile && bun run lint && bun run test && bun run build && bun run audit && bun run pack:dry-run",
|
|
78
|
-
"pack:dry-run": "bun pm pack --dry-run --ignore-scripts"
|
|
77
|
+
"release:check": "bun install --frozen-lockfile && bun run lint && bun run test && bun run build && bun run audit && bun run verify:package-safety && bun run pack:dry-run",
|
|
78
|
+
"pack:dry-run": "bun pm pack --dry-run --ignore-scripts",
|
|
79
|
+
"verify:package-safety": "node scripts/verify-package-safety.mjs"
|
|
79
80
|
},
|
|
80
81
|
"dependencies": {
|
|
81
82
|
"zod": "^4.4.3"
|
|
@@ -112,7 +113,7 @@
|
|
|
112
113
|
"typescript-eslint": "^8.65.0"
|
|
113
114
|
},
|
|
114
115
|
"overrides": {
|
|
115
|
-
"js-yaml": "4.3.
|
|
116
|
+
"js-yaml": "4.3.1",
|
|
116
117
|
"minimatch": "10.2.5",
|
|
117
118
|
"brace-expansion": "5.0.9"
|
|
118
119
|
},
|