@m8t-stack/api-contract 0.1.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.
Files changed (75) hide show
  1. package/README.md +9 -0
  2. package/dist/cjs/a2a-card.js +33 -0
  3. package/dist/cjs/a2a-card.js.map +1 -0
  4. package/dist/cjs/binding.js +45 -0
  5. package/dist/cjs/binding.js.map +1 -0
  6. package/dist/cjs/brain-eval.js +58 -0
  7. package/dist/cjs/brain-eval.js.map +1 -0
  8. package/dist/cjs/brain-link.js +52 -0
  9. package/dist/cjs/brain-link.js.map +1 -0
  10. package/dist/cjs/errors.js +57 -0
  11. package/dist/cjs/errors.js.map +1 -0
  12. package/dist/cjs/inbound-envelope.js +3 -0
  13. package/dist/cjs/inbound-envelope.js.map +1 -0
  14. package/dist/cjs/index.js +37 -0
  15. package/dist/cjs/index.js.map +1 -0
  16. package/dist/cjs/me.js +3 -0
  17. package/dist/cjs/me.js.map +1 -0
  18. package/dist/cjs/package.json +1 -0
  19. package/dist/cjs/reasons.js +8 -0
  20. package/dist/cjs/reasons.js.map +1 -0
  21. package/dist/cjs/response.js +19 -0
  22. package/dist/cjs/response.js.map +1 -0
  23. package/dist/cjs/service-bus.js +3 -0
  24. package/dist/cjs/service-bus.js.map +1 -0
  25. package/dist/cjs/team.js +13 -0
  26. package/dist/cjs/team.js.map +1 -0
  27. package/dist/esm/a2a-card.d.ts +23 -0
  28. package/dist/esm/a2a-card.d.ts.map +1 -0
  29. package/dist/esm/a2a-card.js +28 -0
  30. package/dist/esm/a2a-card.js.map +1 -0
  31. package/dist/esm/binding.d.ts +106 -0
  32. package/dist/esm/binding.d.ts.map +1 -0
  33. package/dist/esm/binding.js +40 -0
  34. package/dist/esm/binding.js.map +1 -0
  35. package/dist/esm/brain-eval.d.ts +295 -0
  36. package/dist/esm/brain-eval.d.ts.map +1 -0
  37. package/dist/esm/brain-eval.js +54 -0
  38. package/dist/esm/brain-eval.js.map +1 -0
  39. package/dist/esm/brain-link.d.ts +49 -0
  40. package/dist/esm/brain-link.d.ts.map +1 -0
  41. package/dist/esm/brain-link.js +45 -0
  42. package/dist/esm/brain-link.js.map +1 -0
  43. package/dist/esm/errors.d.ts +39 -0
  44. package/dist/esm/errors.d.ts.map +1 -0
  45. package/dist/esm/errors.js +45 -0
  46. package/dist/esm/errors.js.map +1 -0
  47. package/dist/esm/inbound-envelope.d.ts +43 -0
  48. package/dist/esm/inbound-envelope.d.ts.map +1 -0
  49. package/dist/esm/inbound-envelope.js +2 -0
  50. package/dist/esm/inbound-envelope.js.map +1 -0
  51. package/dist/esm/index.d.ts +14 -0
  52. package/dist/esm/index.d.ts.map +1 -0
  53. package/dist/esm/index.js +12 -0
  54. package/dist/esm/index.js.map +1 -0
  55. package/dist/esm/me.d.ts +25 -0
  56. package/dist/esm/me.d.ts.map +1 -0
  57. package/dist/esm/me.js +2 -0
  58. package/dist/esm/me.js.map +1 -0
  59. package/dist/esm/reasons.d.ts +12 -0
  60. package/dist/esm/reasons.d.ts.map +1 -0
  61. package/dist/esm/reasons.js +7 -0
  62. package/dist/esm/reasons.js.map +1 -0
  63. package/dist/esm/response.d.ts +27 -0
  64. package/dist/esm/response.d.ts.map +1 -0
  65. package/dist/esm/response.js +16 -0
  66. package/dist/esm/response.js.map +1 -0
  67. package/dist/esm/service-bus.d.ts +15 -0
  68. package/dist/esm/service-bus.d.ts.map +1 -0
  69. package/dist/esm/service-bus.js +2 -0
  70. package/dist/esm/service-bus.js.map +1 -0
  71. package/dist/esm/team.d.ts +57 -0
  72. package/dist/esm/team.d.ts.map +1 -0
  73. package/dist/esm/team.js +9 -0
  74. package/dist/esm/team.js.map +1 -0
  75. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # `@m8t-stack/api-contract`
2
+
3
+ > 📦 Published on npm: `npm i @m8t-stack/api-contract`
4
+
5
+ **What:** Shared gateway HTTP request/response types + error reasons (response envelope, errors, reason codes, team, me, binding, inbound-envelope, service-bus). Re-exported in full by [`@m8t-stack/platform-sdk`](../platform-sdk) — most consumers import the SDK rather than this package directly.
6
+
7
+ **Used by:** the m8t gateway (apps/web), the `@m8t-stack/cli`, and `@m8t-stack/platform-sdk`.
8
+
9
+ See [the package index](../README.md) for the full map.
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.A2A_CARD_MAX_CHARS = void 0;
4
+ exports.serializeA2aCard = serializeA2aCard;
5
+ exports.parseA2aCard = parseA2aCard;
6
+ /** Foundry agent metadata value max length (REST API project/agents). */
7
+ exports.A2A_CARD_MAX_CHARS = 512;
8
+ function serializeA2aCard(card) {
9
+ return JSON.stringify(card);
10
+ }
11
+ /** Defensive parse (mirrors parseBrainLink): null on missing/malformed; never throws. */
12
+ function parseA2aCard(raw) {
13
+ if (!raw)
14
+ return null;
15
+ let o;
16
+ try {
17
+ o = JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ if (typeof o !== "object" || o === null)
23
+ return null;
24
+ const c = o;
25
+ return {
26
+ role: typeof c.role === "string" ? c.role : "",
27
+ summary: typeof c.summary === "string" ? c.summary : "",
28
+ whenToDelegate: typeof c.whenToDelegate === "string" ? c.whenToDelegate : "",
29
+ accepts: typeof c.accepts === "string" ? c.accepts : "",
30
+ returns: typeof c.returns === "string" ? c.returns : "",
31
+ };
32
+ }
33
+ //# sourceMappingURL=a2a-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a-card.js","sourceRoot":"","sources":["../../src/a2a-card.ts"],"names":[],"mappings":";;;AAqBA,4CAEC;AAGD,oCAiBC;AAzBD,yEAAyE;AAC5D,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC,SAAgB,gBAAgB,CAAC,IAAa;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,yFAAyF;AACzF,SAAgB,YAAY,CAAC,GAAuB;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAU,CAAC;IACf,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,CAAC,GAAG,CAAqB,CAAC;IAChC,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QAC9C,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACvD,cAAc,EAAE,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;QAC5E,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACvD,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Wire DTOs for the binding-management API surface.
4
+ * `/api/bindings` GET/POST, `/api/bindings/[bindingId]` GET/DELETE,
5
+ * `/api/bindings/cleanup-orphaned` POST.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.BINDING_STATUSES = void 0;
9
+ exports.isBindingStatus = isBindingStatus;
10
+ exports.isBindingSecretPayload = isBindingSecretPayload;
11
+ exports.BINDING_STATUSES = ["active", "orphaned"];
12
+ function isBindingStatus(v) {
13
+ return v === "active" || v === "orphaned";
14
+ }
15
+ /**
16
+ * Runtime guard for BindingSecretPayload. Used by `lib/gateway/secrets.ts`
17
+ * to validate JSON.parse output before treating it as a typed payload.
18
+ *
19
+ * Strict on `version: 1` and `channel` discriminator; rejects unknown channel
20
+ * variants so a future schema rename can't silently misroute. Field validation
21
+ * within each variant is structural (key presence + string type) only — the
22
+ * caller decides what to do with malformed contents.
23
+ */
24
+ function isBindingSecretPayload(v) {
25
+ if (v === null || typeof v !== "object")
26
+ return false;
27
+ const obj = v;
28
+ if (obj.version !== 1)
29
+ return false;
30
+ if (typeof obj.channel !== "string")
31
+ return false;
32
+ if (obj.channel === "telegram") {
33
+ return typeof obj.botToken === "string" && typeof obj.webhookSecret === "string";
34
+ }
35
+ if (obj.channel === "slack") {
36
+ return (typeof obj.botToken === "string" &&
37
+ typeof obj.signingSecret === "string" &&
38
+ (obj.appLevelToken === undefined || typeof obj.appLevelToken === "string"));
39
+ }
40
+ if (obj.channel === "teams") {
41
+ return typeof obj.appId === "string" && typeof obj.appPassword === "string";
42
+ }
43
+ return false;
44
+ }
45
+ //# sourceMappingURL=binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/binding.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAQH,0CAEC;AAuHD,wDAoBC;AA/IY,QAAA,gBAAgB,GAA6B,CAAC,QAAQ,EAAE,UAAU,CAAU,CAAC;AAE1F,SAAgB,eAAe,CAAC,CAAU;IACxC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,UAAU,CAAC;AAC5C,CAAC;AA8GD;;;;;;;;GAQG;AACH,SAAgB,sBAAsB,CAAC,CAAU;IAC/C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,CAA4B,CAAC;IACzC,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAElD,IAAI,GAAG,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC;IACnF,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAChC,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;YACrC,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAC3E,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ // Brain Faculties Evaluation — wire shapes emitted by the Python brain-eval core (camelCase JSON).
3
+ // Mirror of the Brain Faculties Evaluation EPIC §6. The Python dataclasses are authoritative for the
4
+ // running core; these are the typed view consumers (the brain-F3 librarian, future sinks) read.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EXAM_EVAL_VERSION = void 0;
7
+ exports.redactForFeed = redactForFeed;
8
+ /** The single exam grader-prose constant (DESIGN §7.6). Distinct from the gate's `f1.x` line.
9
+ * Bump on ANY grader-prose change (criteria text, input builders, suite-critique prompt,
10
+ * parser semantics); a bump resets the exam-side validation window. Pinned into
11
+ * ExamVerdict.evalVersion on every verdict. */
12
+ exports.EXAM_EVAL_VERSION = "exam-f2.0";
13
+ /**
14
+ * The ONLY permitted producer of an E1-facing feed from a full ExamVerdict (DESIGN §7.6 #1).
15
+ * Pure + total. Sealed-task runs collapse to aggregates; dev-only verdicts pass through
16
+ * UNCHANGED (identity). Strips ALL sealed-task TEXT (assertions, evidence, raw turns,
17
+ * implicitClaims, the runs[] array) AND drops any suiteCritique entry attributed to a
18
+ * sealed taskId — BY ID, not by substring-matching the taskId inside the text. A grader
19
+ * FEEDBACK line quotes the sealed assertion TEXT and may name no taskId at all, so a
20
+ * substring scan leaks it; id-based attribution (set on the entry at the source) closes
21
+ * the leak (the Law-1 sealed-text fix). KEEPS the version provenance
22
+ * (rubricVersion / evalVersion / loaderSha / judgeDeployment) — they name THAT something
23
+ * changed, not WHAT, and are public-safe (§7.6 #2). comparisons[].flips keep
24
+ * direction + taskId so per-task flip counts survive for the sign test.
25
+ * Returns RedactedExamVerdict iff ANY arm contains a sealed task, else the verdict unchanged.
26
+ */
27
+ function redactForFeed(verdict, sealedTaskIds) {
28
+ // Redact if ANY sealed reference exists — a sealed run in an arm OR a sealed-attributed suiteCritique
29
+ // entry. The latter guard means a sealed critique can never slip through via the identity path.
30
+ const hasSealedRun = verdict.arms.some((a) => a.runs.some((r) => sealedTaskIds.has(r.taskId)));
31
+ const hasSealedCritique = verdict.suiteCritique.some((c) => sealedTaskIds.has(c.taskId));
32
+ if (!hasSealedRun && !hasSealedCritique)
33
+ return verdict; // dev-only -> identity pass-through (total + cheap)
34
+ const redactedArms = verdict.arms.map((a) => {
35
+ const ra = {
36
+ arm: a.arm,
37
+ passRate: a.passRate,
38
+ stddev: a.stddev,
39
+ n: a.n,
40
+ runsRedacted: true,
41
+ };
42
+ if (a.recallMetrics !== undefined)
43
+ ra.recallMetrics = a.recallMetrics; // F3 §5.4: aggregate → feed-safe
44
+ return ra;
45
+ });
46
+ // Drop any suiteCritique entry attributed to a sealed task — BY ID (not substring): the entry's
47
+ // `text` may quote the sealed assertion verbatim and name no taskId, so id attribution is the
48
+ // only sound drop (the Law-1 sealed-text leak fix).
49
+ const cleanedCritique = verdict.suiteCritique.filter((c) => !sealedTaskIds.has(c.taskId));
50
+ const { arms: _arms, suiteCritique: _sc, ...rest } = verdict;
51
+ return {
52
+ ...rest,
53
+ arms: redactedArms,
54
+ suiteCritique: cleanedCritique,
55
+ redacted: true,
56
+ };
57
+ }
58
+ //# sourceMappingURL=brain-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-eval.js","sourceRoot":"","sources":["../../src/brain-eval.ts"],"names":[],"mappings":";AAAA,mGAAmG;AACnG,qGAAqG;AACrG,gGAAgG;;;AAoRhG,sCAkCC;AAtDD;;;gDAGgD;AACnC,QAAA,iBAAiB,GAAG,WAAW,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,SAAgB,aAAa,CAC3B,OAAoB,EACpB,aAA0B;IAE1B,sGAAsG;IACtG,gGAAgG;IAChG,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,IAAI,CAAC,YAAY,IAAI,CAAC,iBAAiB;QAAE,OAAO,OAAO,CAAC,CAAC,oDAAoD;IAE7G,MAAM,YAAY,GAA2B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAClE,MAAM,EAAE,GAAyB;YAC/B,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,YAAY,EAAE,IAAI;SACnB,CAAC;QACF,IAAI,CAAC,CAAC,aAAa,KAAK,SAAS;YAAE,EAAE,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC,CAAE,iCAAiC;QACzG,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,gGAAgG;IAChG,8FAA8F;IAC9F,oDAAoD;IACpD,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE1F,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAC7D,OAAO;QACL,GAAG,IAAI;QACP,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,eAAe;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IN_CONTAINER_CREDENTIAL_REF = void 0;
4
+ exports.parseBrainLink = parseBrainLink;
5
+ exports.isAppMode = isAppMode;
6
+ exports.isInContainer = isInContainer;
7
+ exports.serializeBrainLink = serializeBrainLink;
8
+ /**
9
+ * Parse the brain link from Foundry agent metadata. Defensive: absent or
10
+ * malformed returns undefined and never throws — discovery must not break on
11
+ * a hand-written or partial `metadata.brain`.
12
+ */
13
+ function parseBrainLink(metadata) {
14
+ const raw = metadata?.brain;
15
+ if (!raw)
16
+ return undefined;
17
+ try {
18
+ const obj = JSON.parse(raw);
19
+ if (!obj || typeof obj.repo !== "string" || obj.repo.length === 0)
20
+ return undefined;
21
+ return {
22
+ repo: obj.repo,
23
+ branch: typeof obj.branch === "string" && obj.branch ? obj.branch : "main",
24
+ topology: obj.topology === "shared" ? "shared" : "per-worker",
25
+ schemaVersion: typeof obj.schemaVersion === "string" && obj.schemaVersion ? obj.schemaVersion : "1",
26
+ credentialRef: typeof obj.credentialRef === "string" ? obj.credentialRef : "",
27
+ ...(typeof obj.installationId === "string" ? { installationId: obj.installationId } : {}),
28
+ ...(typeof obj.instanceFolder === "string" ? { instanceFolder: obj.instanceFolder } : {}),
29
+ };
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ }
35
+ /** True when the link uses GitHub App authentication (F2 mode). A type guard so
36
+ * callers that mint with the installation id narrow it to a present string. */
37
+ function isAppMode(link) {
38
+ return typeof link.installationId === "string" && link.installationId.length > 0;
39
+ }
40
+ /** Sentinel credentialRef for hosted workers: the token is minted INSIDE the
41
+ * container (no Foundry connection). Invoke-path rotation must skip these. */
42
+ exports.IN_CONTAINER_CREDENTIAL_REF = "in-container";
43
+ /** True when the link is a hosted/in-container brain (token minted in-sandbox;
44
+ * there is NO Foundry connection to rotate). */
45
+ function isInContainer(link) {
46
+ return link.credentialRef === exports.IN_CONTAINER_CREDENTIAL_REF;
47
+ }
48
+ /** Serialize a BrainLink to the Foundry-metadata JSON string. */
49
+ function serializeBrainLink(link) {
50
+ return JSON.stringify(link);
51
+ }
52
+ //# sourceMappingURL=brain-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-link.js","sourceRoot":"","sources":["../../src/brain-link.ts"],"names":[],"mappings":";;;AAmCA,wCAqBC;AAID,8BAEC;AAQD,sCAEC;AAGD,gDAEC;AA/CD;;;;GAIG;AACH,SAAgB,cAAc,CAC5B,QAA4C;IAE5C,MAAM,GAAG,GAAG,QAAQ,EAAE,KAAK,CAAC;IAC5B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,GAA8B,IAAI,CAAC,KAAK,CAAC,GAAG,CAA8B,CAAC;QACpF,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACpF,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC1E,QAAQ,EAAE,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY;YAC7D,aAAa,EACX,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG;YACtF,aAAa,EAAE,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;YAC7E,GAAG,CAAC,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1F,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;gFACgF;AAChF,SAAgB,SAAS,CAAC,IAAe;IACvC,OAAO,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;AACnF,CAAC;AAED;+EAC+E;AAClE,QAAA,2BAA2B,GAAG,cAAc,CAAC;AAE1D;iDACiD;AACjD,SAAgB,aAAa,CAAC,IAAe;IAC3C,OAAO,IAAI,CAAC,aAAa,KAAK,mCAA2B,CAAC;AAC5D,CAAC;AAED,iEAAiE;AACjE,SAAgB,kBAAkB,CAAC,IAAe;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InternalError = exports.UpstreamError = exports.RateLimitedError = exports.ConflictError = exports.NotFoundError = exports.BadRequestError = exports.ForbiddenError = exports.UnauthenticatedError = exports.ApiError = void 0;
4
+ class ApiError extends Error {
5
+ details;
6
+ constructor(message, details) {
7
+ super(message);
8
+ this.name = this.constructor.name;
9
+ this.details = details;
10
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- V8-specific API absent in non-Node environments; typed as always-present in @types/node but runtime presence is not guaranteed
11
+ if (Error.captureStackTrace) {
12
+ Error.captureStackTrace(this, this.constructor);
13
+ }
14
+ }
15
+ }
16
+ exports.ApiError = ApiError;
17
+ class UnauthenticatedError extends ApiError {
18
+ code = "UNAUTHENTICATED";
19
+ status = 401;
20
+ }
21
+ exports.UnauthenticatedError = UnauthenticatedError;
22
+ class ForbiddenError extends ApiError {
23
+ code = "FORBIDDEN";
24
+ status = 403;
25
+ }
26
+ exports.ForbiddenError = ForbiddenError;
27
+ class BadRequestError extends ApiError {
28
+ code = "BAD_REQUEST";
29
+ status = 400;
30
+ }
31
+ exports.BadRequestError = BadRequestError;
32
+ class NotFoundError extends ApiError {
33
+ code = "NOT_FOUND";
34
+ status = 404;
35
+ }
36
+ exports.NotFoundError = NotFoundError;
37
+ class ConflictError extends ApiError {
38
+ code = "CONFLICT";
39
+ status = 409;
40
+ }
41
+ exports.ConflictError = ConflictError;
42
+ class RateLimitedError extends ApiError {
43
+ code = "RATE_LIMITED";
44
+ status = 429;
45
+ }
46
+ exports.RateLimitedError = RateLimitedError;
47
+ class UpstreamError extends ApiError {
48
+ code = "UPSTREAM_FAILED";
49
+ status = 502;
50
+ }
51
+ exports.UpstreamError = UpstreamError;
52
+ class InternalError extends ApiError {
53
+ code = "INTERNAL";
54
+ status = 500;
55
+ }
56
+ exports.InternalError = InternalError;
57
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAsB,QAAS,SAAQ,KAAK;IAGjC,OAAO,CAAW;IAE3B,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,yMAAyM;QACzM,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF;AAdD,4BAcC;AAED,MAAa,oBAAqB,SAAQ,QAAQ;IACvC,IAAI,GAAG,iBAAiB,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,oDAGC;AAED,MAAa,cAAe,SAAQ,QAAQ;IACjC,IAAI,GAAG,WAAW,CAAC;IACnB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,wCAGC;AAED,MAAa,eAAgB,SAAQ,QAAQ;IAClC,IAAI,GAAG,aAAa,CAAC;IACrB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,0CAGC;AAED,MAAa,aAAc,SAAQ,QAAQ;IAChC,IAAI,GAAG,WAAW,CAAC;IACnB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,sCAGC;AAED,MAAa,aAAc,SAAQ,QAAQ;IAChC,IAAI,GAAG,UAAU,CAAC;IAClB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,sCAGC;AAED,MAAa,gBAAiB,SAAQ,QAAQ;IACnC,IAAI,GAAG,cAAc,CAAC;IACtB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,4CAGC;AAED,MAAa,aAAc,SAAQ,QAAQ;IAChC,IAAI,GAAG,iBAAiB,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,sCAGC;AAED,MAAa,aAAc,SAAQ,QAAQ;IAChC,IAAI,GAAG,UAAU,CAAC;IAClB,MAAM,GAAG,GAAG,CAAC;CACvB;AAHD,sCAGC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=inbound-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound-envelope.js","sourceRoot":"","sources":["../../src/inbound-envelope.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.A2A_CARD_MAX_CHARS = exports.parseA2aCard = exports.serializeA2aCard = exports.IN_CONTAINER_CREDENTIAL_REF = exports.isInContainer = exports.serializeBrainLink = exports.isAppMode = exports.parseBrainLink = void 0;
18
+ __exportStar(require("./response.js"), exports);
19
+ __exportStar(require("./errors.js"), exports);
20
+ __exportStar(require("./reasons.js"), exports);
21
+ __exportStar(require("./team.js"), exports);
22
+ __exportStar(require("./me.js"), exports);
23
+ __exportStar(require("./binding.js"), exports);
24
+ __exportStar(require("./inbound-envelope.js"), exports);
25
+ __exportStar(require("./service-bus.js"), exports);
26
+ var brain_link_js_1 = require("./brain-link.js");
27
+ Object.defineProperty(exports, "parseBrainLink", { enumerable: true, get: function () { return brain_link_js_1.parseBrainLink; } });
28
+ Object.defineProperty(exports, "isAppMode", { enumerable: true, get: function () { return brain_link_js_1.isAppMode; } });
29
+ Object.defineProperty(exports, "serializeBrainLink", { enumerable: true, get: function () { return brain_link_js_1.serializeBrainLink; } });
30
+ Object.defineProperty(exports, "isInContainer", { enumerable: true, get: function () { return brain_link_js_1.isInContainer; } });
31
+ Object.defineProperty(exports, "IN_CONTAINER_CREDENTIAL_REF", { enumerable: true, get: function () { return brain_link_js_1.IN_CONTAINER_CREDENTIAL_REF; } });
32
+ var a2a_card_js_1 = require("./a2a-card.js");
33
+ Object.defineProperty(exports, "serializeA2aCard", { enumerable: true, get: function () { return a2a_card_js_1.serializeA2aCard; } });
34
+ Object.defineProperty(exports, "parseA2aCard", { enumerable: true, get: function () { return a2a_card_js_1.parseA2aCard; } });
35
+ Object.defineProperty(exports, "A2A_CARD_MAX_CHARS", { enumerable: true, get: function () { return a2a_card_js_1.A2A_CARD_MAX_CHARS; } });
36
+ __exportStar(require("./brain-eval.js"), exports);
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,8CAA4B;AAC5B,+CAA6B;AAC7B,4CAA0B;AAC1B,0CAAwB;AACxB,+CAA6B;AAC7B,wDAAsC;AACtC,mDAAiC;AAEjC,iDAA4H;AAAnH,+GAAA,cAAc,OAAA;AAAE,0GAAA,SAAS,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAAE,8GAAA,aAAa,OAAA;AAAE,4HAAA,2BAA2B,OAAA;AAElG,6CAAmF;AAA1E,+GAAA,gBAAgB,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,iHAAA,kBAAkB,OAAA;AAC3D,kDAAgC"}
package/dist/cjs/me.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=me.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/me.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * String-literal union types for the `details.reason` field carried in
4
+ * `ApiResponse.error.details`. Centralizing these prevents drift between
5
+ * the backend's throws and the CLI's hint-lookup table.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ //# sourceMappingURL=reasons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reasons.js","sourceRoot":"","sources":["../../src/reasons.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isApiResponse = isApiResponse;
4
+ /**
5
+ * Type guard for callers that received a parsed JSON of unknown shape.
6
+ */
7
+ function isApiResponse(value) {
8
+ if (typeof value !== "object" || value === null)
9
+ return false;
10
+ const v = value;
11
+ if (v.ok === true && "data" in v)
12
+ return true;
13
+ if (v.ok === false && typeof v.error === "object" && v.error !== null) {
14
+ const e = v.error;
15
+ return typeof e.code === "string" && typeof e.message === "string";
16
+ }
17
+ return false;
18
+ }
19
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/response.ts"],"names":[],"mappings":";;AAwBA,sCASC;AAZD;;GAEG;AACH,SAAgB,aAAa,CAAc,KAAc;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACtE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAgC,CAAC;QAC7C,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=service-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-bus.js","sourceRoot":"","sources":["../../src/service-bus.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Wire DTOs for the team-management API surface.
4
+ * `/api/team` GET/POST, `/api/team/[handle]` GET/PATCH/DELETE.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CHANNELS = void 0;
8
+ exports.isChannel = isChannel;
9
+ exports.CHANNELS = ["telegram", "slack", "teams"];
10
+ function isChannel(v) {
11
+ return v === "telegram" || v === "slack" || v === "teams";
12
+ }
13
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/team.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH,8BAEC;AAJY,QAAA,QAAQ,GAAuB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAEpF,SAAgB,SAAS,CAAC,CAAU;IAClC,OAAO,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The A2A capability card — authored in a persona's targets.foundry.a2a-card
3
+ * block, projected into Foundry agent metadata as the `a2aCard` JSON string
4
+ * (mirrors metadata.brain), and returned by the bridge's discover_workers.
5
+ *
6
+ * Foundry agent metadata values are capped at 512 chars, so the serialized
7
+ * card must fit one value. Maps onto the A2A AgentCard for the future
8
+ * graduation: summary→description, whenToDelegate→skill description/tags,
9
+ * accepts/returns→skill I/O modes, role→skill name.
10
+ */
11
+ export interface A2aCard {
12
+ role: string;
13
+ summary: string;
14
+ whenToDelegate: string;
15
+ accepts: string;
16
+ returns: string;
17
+ }
18
+ /** Foundry agent metadata value max length (REST API project/agents). */
19
+ export declare const A2A_CARD_MAX_CHARS = 512;
20
+ export declare function serializeA2aCard(card: A2aCard): string;
21
+ /** Defensive parse (mirrors parseBrainLink): null on missing/malformed; never throws. */
22
+ export declare function parseA2aCard(raw: string | undefined): A2aCard | null;
23
+ //# sourceMappingURL=a2a-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a-card.d.ts","sourceRoot":"","sources":["../../src/a2a-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEtD;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAiBpE"}
@@ -0,0 +1,28 @@
1
+ /** Foundry agent metadata value max length (REST API project/agents). */
2
+ export const A2A_CARD_MAX_CHARS = 512;
3
+ export function serializeA2aCard(card) {
4
+ return JSON.stringify(card);
5
+ }
6
+ /** Defensive parse (mirrors parseBrainLink): null on missing/malformed; never throws. */
7
+ export function parseA2aCard(raw) {
8
+ if (!raw)
9
+ return null;
10
+ let o;
11
+ try {
12
+ o = JSON.parse(raw);
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ if (typeof o !== "object" || o === null)
18
+ return null;
19
+ const c = o;
20
+ return {
21
+ role: typeof c.role === "string" ? c.role : "",
22
+ summary: typeof c.summary === "string" ? c.summary : "",
23
+ whenToDelegate: typeof c.whenToDelegate === "string" ? c.whenToDelegate : "",
24
+ accepts: typeof c.accepts === "string" ? c.accepts : "",
25
+ returns: typeof c.returns === "string" ? c.returns : "",
26
+ };
27
+ }
28
+ //# sourceMappingURL=a2a-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a-card.js","sourceRoot":"","sources":["../../src/a2a-card.ts"],"names":[],"mappings":"AAkBA,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEtC,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,GAAuB;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAU,CAAC;IACf,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,CAAC,GAAG,CAAqB,CAAC;IAChC,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QAC9C,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACvD,cAAc,EAAE,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;QAC5E,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACvD,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Wire DTOs for the binding-management API surface.
3
+ * `/api/bindings` GET/POST, `/api/bindings/[bindingId]` GET/DELETE,
4
+ * `/api/bindings/cleanup-orphaned` POST.
5
+ */
6
+ import type { Channel } from "./team.js";
7
+ export type BindingStatus = "active" | "orphaned";
8
+ export declare const BINDING_STATUSES: readonly BindingStatus[];
9
+ export declare function isBindingStatus(v: unknown): v is BindingStatus;
10
+ export interface Binding {
11
+ channel: Channel;
12
+ bindingId: string;
13
+ agentName: string;
14
+ /** Key Vault URI for the secret blob (versioned). NEVER the token itself. */
15
+ botTokenSecretRef: string;
16
+ botUsername?: string;
17
+ status: BindingStatus;
18
+ /** ISO 8601 */
19
+ createdAt: string;
20
+ /** Admin UPN who created the binding */
21
+ createdBy: string;
22
+ }
23
+ export interface ListBindingsResponse {
24
+ bindings: Binding[];
25
+ }
26
+ export interface CreateBindingRequest {
27
+ channel: Channel;
28
+ bindingId: string;
29
+ agentName: string;
30
+ /** Plaintext bot token — sent on the wire (HTTPS), never persisted in the row. */
31
+ botToken: string;
32
+ botUsername?: string;
33
+ }
34
+ export interface CreateBindingResponse {
35
+ binding: Binding;
36
+ /** Constructed from GATEWAY_PUBLIC_URL + channel + bindingId. */
37
+ webhookUrl: string;
38
+ }
39
+ export interface GetBindingResponse {
40
+ binding: Binding;
41
+ }
42
+ export interface DeleteBindingResponse {
43
+ deleted: {
44
+ bindingId: string;
45
+ channel: Channel;
46
+ conversationsCleared: number;
47
+ };
48
+ }
49
+ export interface CleanupOrphanedResponse {
50
+ cleaned: {
51
+ bindingId: string;
52
+ channel: Channel;
53
+ }[];
54
+ failed: {
55
+ bindingId: string;
56
+ channel: Channel;
57
+ originalMessage: string;
58
+ }[];
59
+ }
60
+ export type CascadeStep = "unregisterWebhook" | "kvSecret" | "conversations" | "bindingsRow";
61
+ /**
62
+ * Carried in UpstreamError.details.partial when DELETE cascade fails mid-flow.
63
+ * The CLI's `bind remove` command renders this inline for a structured retry hint.
64
+ */
65
+ export interface CascadeFailureDetails {
66
+ bindingId: string;
67
+ channel: Channel;
68
+ completedSteps: CascadeStep[];
69
+ failedStep: CascadeStep;
70
+ originalMessage: string;
71
+ }
72
+ export interface TelegramSecretPayload {
73
+ version: 1;
74
+ channel: "telegram";
75
+ botToken: string;
76
+ /** 64 hex chars; set on Telegram's `setWebhook` via the `secret_token` param. */
77
+ webhookSecret: string;
78
+ }
79
+ export interface SlackSecretPayload {
80
+ version: 1;
81
+ channel: "slack";
82
+ /** `xoxb-...` bot user OAuth token */
83
+ botToken: string;
84
+ /** App-level signing secret used to verify Slack request HMACs */
85
+ signingSecret: string;
86
+ /** `xapp-...` app-level token, optional, for future Socket Mode */
87
+ appLevelToken?: string;
88
+ }
89
+ export interface TeamsSecretPayload {
90
+ version: 1;
91
+ channel: "teams";
92
+ appId: string;
93
+ appPassword: string;
94
+ }
95
+ export type BindingSecretPayload = TelegramSecretPayload | SlackSecretPayload | TeamsSecretPayload;
96
+ /**
97
+ * Runtime guard for BindingSecretPayload. Used by `lib/gateway/secrets.ts`
98
+ * to validate JSON.parse output before treating it as a typed payload.
99
+ *
100
+ * Strict on `version: 1` and `channel` discriminator; rejects unknown channel
101
+ * variants so a future schema rename can't silently misroute. Field validation
102
+ * within each variant is structural (key presence + string type) only — the
103
+ * caller decides what to do with malformed contents.
104
+ */
105
+ export declare function isBindingSecretPayload(v: unknown): v is BindingSecretPayload;
106
+ //# sourceMappingURL=binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Wire DTOs for the binding-management API surface.
3
+ * `/api/bindings` GET/POST, `/api/bindings/[bindingId]` GET/DELETE,
4
+ * `/api/bindings/cleanup-orphaned` POST.
5
+ */
6
+ export const BINDING_STATUSES = ["active", "orphaned"];
7
+ export function isBindingStatus(v) {
8
+ return v === "active" || v === "orphaned";
9
+ }
10
+ /**
11
+ * Runtime guard for BindingSecretPayload. Used by `lib/gateway/secrets.ts`
12
+ * to validate JSON.parse output before treating it as a typed payload.
13
+ *
14
+ * Strict on `version: 1` and `channel` discriminator; rejects unknown channel
15
+ * variants so a future schema rename can't silently misroute. Field validation
16
+ * within each variant is structural (key presence + string type) only — the
17
+ * caller decides what to do with malformed contents.
18
+ */
19
+ export function isBindingSecretPayload(v) {
20
+ if (v === null || typeof v !== "object")
21
+ return false;
22
+ const obj = v;
23
+ if (obj.version !== 1)
24
+ return false;
25
+ if (typeof obj.channel !== "string")
26
+ return false;
27
+ if (obj.channel === "telegram") {
28
+ return typeof obj.botToken === "string" && typeof obj.webhookSecret === "string";
29
+ }
30
+ if (obj.channel === "slack") {
31
+ return (typeof obj.botToken === "string" &&
32
+ typeof obj.signingSecret === "string" &&
33
+ (obj.appLevelToken === undefined || typeof obj.appLevelToken === "string"));
34
+ }
35
+ if (obj.channel === "teams") {
36
+ return typeof obj.appId === "string" && typeof obj.appPassword === "string";
37
+ }
38
+ return false;
39
+ }
40
+ //# sourceMappingURL=binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/binding.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,CAAC,MAAM,gBAAgB,GAA6B,CAAC,QAAQ,EAAE,UAAU,CAAU,CAAC;AAE1F,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,UAAU,CAAC;AAC5C,CAAC;AA8GD;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,CAAU;IAC/C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,CAA4B,CAAC;IACzC,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAElD,IAAI,GAAG,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC;IACnF,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAChC,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;YACrC,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAC3E,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}