@amalgm/channels 0.1.3 → 0.1.4

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/PURPOSE.md CHANGED
@@ -20,8 +20,16 @@ that no computer has accepted yet. Chat sessions, transcripts, and agent
20
20
  execution stay on the pinned user's computer. The hosted service is its own
21
21
  deployable and does not run inside or depend on Amalgm Gateway.
22
22
 
23
+ Each hosted Channels environment reaches only its declared UI issuer and
24
+ database. Main and preview initially share the database by owner direction;
25
+ their public API and issuer identities remain distinct. Durable delivery leases
26
+ remain authoritative when multiple hosts share data.
27
+
23
28
  ## Axioms
24
29
 
30
+ Managed releases bind to one exact published Core version and build from the
31
+ locked dependency graph on the supported Node toolchain.
32
+
25
33
  1. Every user delivery and every accepted inbound message belongs to exactly
26
34
  one authenticated user.
27
35
  2. A public send input never contains a user id, email address, phone number,
@@ -67,6 +75,9 @@ deployable and does not run inside or depend on Amalgm Gateway.
67
75
  a sent delivery to delivered or failed.
68
76
  19. The global CLI projects the same command definitions as MCP and reaches
69
77
  hosted effects only through Shell's authenticated loopback MCP route.
78
+ 20. The host validates its complete Core binding and every configured endpoint
79
+ before composing clients or workers; an isolated local host uses only
80
+ explicitly supplied loopback authorities.
70
81
 
71
82
  ## Tree
72
83
 
@@ -1,10 +1,14 @@
1
+ import { isLoopbackEndpoint, resolveRuntimeEndpoint, validateRuntimeEndpointEnvironment } from '@amalgm/core/binding';
1
2
  export function channelsHostConfig(env = process.env) {
3
+ const publicOrigin = required(env.AMALGAM_PUBLIC_ORIGIN, 'AMALGAM_PUBLIC_ORIGIN');
4
+ const isolatedOrigin = isLoopbackEndpoint(publicOrigin) ? publicOrigin : undefined;
5
+ const binding = validateRuntimeEndpointEnvironment(env, isolatedOrigin);
2
6
  return Object.freeze({
3
7
  port: integer(env.PORT, 8080, 1, 65_535),
4
- publicOrigin: httpsUrl(env.AMALGAM_PUBLIC_ORIGIN, 'AMALGAM_PUBLIC_ORIGIN'),
5
- supabaseUrl: httpsUrl(env.SUPABASE_URL ?? env.NEXT_PUBLIC_SUPABASE_URL, 'SUPABASE_URL'),
8
+ publicOrigin: resolveRuntimeEndpoint(binding, 'channels', publicOrigin, isolatedOrigin),
9
+ supabaseUrl: resolveRuntimeEndpoint(binding, 'supabase', required(env.SUPABASE_URL ?? env.NEXT_PUBLIC_SUPABASE_URL, 'SUPABASE_URL'), isolatedOrigin),
6
10
  supabaseServiceRoleKey: required(env.SUPABASE_SERVICE_ROLE_KEY, 'SUPABASE_SERVICE_ROLE_KEY'),
7
- authorizationIssuer: httpsUrl(env.AMALGM_AUTHORIZATION_ISSUER, 'AMALGM_AUTHORIZATION_ISSUER'),
11
+ authorizationIssuer: resolveRuntimeEndpoint(binding, 'app', required(env.AMALGM_AUTHORIZATION_ISSUER, 'AMALGM_AUTHORIZATION_ISSUER'), isolatedOrigin),
8
12
  resendApiKey: required(env.RESEND_API_KEY, 'RESEND_API_KEY'),
9
13
  resendWebhookSecret: required(env.RESEND_WEBHOOK_SECRET, 'RESEND_WEBHOOK_SECRET'),
10
14
  emailFrom: required(env.CHANNELS_EMAIL_FROM, 'CHANNELS_EMAIL_FROM'),
@@ -17,14 +21,6 @@ function required(value, name) {
17
21
  throw new Error(`${name} is required`);
18
22
  return value.trim();
19
23
  }
20
- function httpsUrl(value, name) {
21
- const parsed = new URL(required(value, name));
22
- const local = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
23
- if (parsed.protocol !== 'https:' && !(local && parsed.protocol === 'http:')) {
24
- throw new Error(`${name} must use HTTPS`);
25
- }
26
- return parsed.toString().replace(/\/$/, '');
27
- }
28
24
  function integer(value, fallback, minimum, maximum) {
29
25
  const parsed = value === undefined ? fallback : Number(value);
30
26
  if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../host/config.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,kBAAkB,CAChC,MAAoD,OAAO,CAAC,GAAG;IAE/D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC;QACxC,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;QAC1E,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,wBAAwB,EAAE,cAAc,CAAC;QACvF,sBAAsB,EAAE,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;QAC5F,mBAAmB,EAAE,QAAQ,CAAC,GAAG,CAAC,2BAA2B,EAAE,6BAA6B,CAAC;QAC7F,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,gBAAgB,CAAC;QAC5D,mBAAmB,EAAE,QAAQ,CAAC,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;QACjF,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;QACnE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,sBAAsB,CAAC;QACtE,iBAAiB,EAAE,QAAQ,CAAC,GAAG,CAAC,4BAA4B,EAAE,8BAA8B,CAAC;KAC9F,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,IAAY;IACvD,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC;IAC3D,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,IAAY;IACvD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;IACjF,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,OAAO,CACd,KAAyB,EACzB,QAAgB,EAChB,OAAe,EACf,OAAe;IAEf,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,OAAO,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../host/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,sBAAsB,CAAC;AAetH,MAAM,UAAU,kBAAkB,CAChC,MAAoD,OAAO,CAAC,GAAG;IAE/D,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,CAAC;IAClF,MAAM,cAAc,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,MAAM,OAAO,GAAG,kCAAkC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC;QACxC,YAAY,EAAE,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,CAAC;QACvF,WAAW,EAAE,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,wBAAwB,EAAE,cAAc,CAAC,EAAE,cAAc,CAAC;QACpJ,sBAAsB,EAAE,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;QAC5F,mBAAmB,EAAE,sBAAsB,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,2BAA2B,EAAE,6BAA6B,CAAC,EAAE,cAAc,CAAC;QACrJ,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,gBAAgB,CAAC;QAC5D,mBAAmB,EAAE,QAAQ,CAAC,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;QACjF,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;QACnE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,sBAAsB,CAAC;QACtE,iBAAiB,EAAE,QAAQ,CAAC,GAAG,CAAC,4BAA4B,EAAE,8BAA8B,CAAC;KAC9F,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,IAAY;IACvD,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC;IAC3D,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,OAAO,CACd,KAAyB,EACzB,QAAgB,EAChB,OAAe,EACf,OAAe;IAEf,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,OAAO,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amalgm/channels",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Amalgm's SDK and hosted service for durable bidirectional user channels.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -49,10 +49,10 @@
49
49
  "start": "node dist/host/main.js"
50
50
  },
51
51
  "engines": {
52
- "node": ">=20"
52
+ "node": ">=24"
53
53
  },
54
54
  "dependencies": {
55
- "@amalgm/core": "0.4.6",
55
+ "@amalgm/core": "0.4.7",
56
56
  "@modelcontextprotocol/sdk": "^1.30.0",
57
57
  "@supabase/supabase-js": "2.57.4",
58
58
  "jose": "^6.1.0",