@cotal-ai/connector-core 0.49.0 → 0.50.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.
@@ -1 +1 @@
1
- {"version":3,"file":"docs-bundle.generated.js","sourceRoot":"","sources":["../src/docs-bundle.generated.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC,SAAS,EAAE,QAAQ;IACnB,eAAe,EAAE,mEAAmE;IACpF,OAAO,EAAE;QACP;YACE,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,0BAA0B;YAClC,SAAS,EAAE,+FAA+F;YAC1G,MAAM,EAAE,k5IAAk5I;SAC35I;QACD;YACE,MAAM,EAAE,iBAAiB;YACzB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,0BAA0B;YAClC,SAAS,EAAE,gHAAgH;YAC3H,MAAM,EAAE,ohWAAohW;SAC7hW;QACD;YACE,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,8njBAA8njB;SACvojB;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,kBAAkB;YAC3B,MAAM,EAAE,mEAAmE;YAC3E,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,+n/BAA+n/B;SACxo/B;QACD;YACE,MAAM,EAAE,0BAA0B;YAClC,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,mCAAmC;YAC3C,SAAS,EAAE,gGAAgG;YAC3G,MAAM,EAAE,iyLAAiyL;SAC1yL;QACD;YACE,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,oDAAoD;YAC/D,MAAM,EAAE,s97BAAs97B;SAC/97B;QACD;YACE,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE,yFAAyF;YACjG,SAAS,EAAE,gJAAgJ;YAC3J,MAAM,EAAE,mxTAAmxT;SAC5xT;QACD;YACE,MAAM,EAAE,uBAAuB;YAC/B,OAAO,EAAE,uBAAuB;YAChC,MAAM,EAAE,sFAAsF;YAC9F,SAAS,EAAE,6GAA6G;YACxH,MAAM,EAAE,+7KAA+7K;SACx8K;QACD;YACE,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,sMAAsM;YACjN,MAAM,EAAE,wtSAAwtS;SACjuS;QACD;YACE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,uBAAuB;YAChC,MAAM,EAAE,wGAAwG;YAChH,SAAS,EAAE,iKAAiK;YAC5K,MAAM,EAAE,0+0GAA0+0G;SACn/0G;QACD;YACE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,uHAAuH;YAC/H,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,u5wBAAu5wB;SACh6wB;QACD;YACE,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,gBAAgB;YACzB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,+EAA+E;YAC1F,MAAM,EAAE,kz6BAAkz6B;SAC3z6B;QACD;YACE,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,y8qBAAy8qB;SACl9qB;QACD;YACE,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,wBAAwB;YACjC,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,kJAAkJ;YAC7J,MAAM,EAAE,uyJAAuyJ;SAChzJ;QACD;YACE,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,6CAA6C;YACxD,MAAM,EAAE,uknBAAuknB;SAChlnB;QACD;YACE,MAAM,EAAE,kBAAkB;YAC1B,OAAO,EAAE,yBAAyB;YAClC,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,wJAAwJ;YACnK,MAAM,EAAE,u6QAAu6Q;SACh7Q;QACD;YACE,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,oBAAoB;YAC7B,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,8DAA8D;YACzE,MAAM,EAAE,wxLAAwxL;SACjyL;QACD;YACE,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,4HAA4H;YACvI,MAAM,EAAE,spKAAspK;SAC/pK;QACD;YACE,MAAM,EAAE,iBAAiB;YACzB,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,oIAAoI;YAC/I,MAAM,EAAE,6yrBAA6yrB;SACtzrB;QACD;YACE,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,uMAAuM;YAClN,MAAM,EAAE,6kQAA6kQ;SACtlQ;QACD;YACE,MAAM,EAAE,iBAAiB;YACzB,OAAO,EAAE,+BAA+B;YACxC,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,6HAA6H;YACxI,MAAM,EAAE,m8NAAm8N;SAC58N;QACD;YACE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,uBAAuB;YAChC,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,6GAA6G;YACxH,MAAM,EAAE,o0MAAo0M;SAC70M;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,iBAAiB;YAC1B,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,yEAAyE;YACpF,MAAM,EAAE,05+BAA05+B;SACn6+B;QACD;YACE,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,6DAA6D;YACxE,MAAM,EAAE,sjGAAsjG;SAC/jG;QACD;YACE,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,yBAAyB;YACjC,SAAS,EAAE,wEAAwE;YACnF,MAAM,EAAE,q5PAAq5P;SAC95P;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,yBAAyB;YACjC,SAAS,EAAE,+CAA+C;YAC1D,MAAM,EAAE,4sMAA4sM;SACrtM;QACD;YACE,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,8BAA8B;YACvC,MAAM,EAAE,8CAA8C;YACtD,SAAS,EAAE,qIAAqI;YAChJ,MAAM,EAAE,i3OAAi3O;SAC13O;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,sDAAsD;YAC9D,SAAS,EAAE,uJAAuJ;YAClK,MAAM,EAAE,i3SAAi3S;SAC13S;QACD;YACE,MAAM,EAAE,uBAAuB;YAC/B,OAAO,EAAE,cAAc;YACvB,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,0IAA0I;YACrJ,MAAM,EAAE,6oTAA6oT;SACtpT;QACD;YACE,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,0CAA0C;YAClD,SAAS,EAAE,gIAAgI;YAC3I,MAAM,EAAE,q3QAAq3Q;SAC93Q;QACD;YACE,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,yBAAyB;YACjC,SAAS,EAAE,mLAAmL;YAC9L,MAAM,EAAE,y7KAAy7K;SACl8K;QACD;YACE,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,09kCAA09kC;SACn+kC;QACD;YACE,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,gBAAgB;YACzB,MAAM,EAAE,oCAAoC;YAC5C,SAAS,EAAE,kGAAkG;YAC7G,MAAM,EAAE,yxXAAyxX;SAClyX;QACD;YACE,MAAM,EAAE,iBAAiB;YACzB,OAAO,EAAE,oCAAoC;YAC7C,MAAM,EAAE,0CAA0C;YAClD,SAAS,EAAE,wMAAwM;YACnN,MAAM,EAAE,o8jBAAo8jB;SAC78jB;QACD;YACE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,2DAA2D;YACtE,MAAM,EAAE,swKAAswK;SAC/wK;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,kGAAkG;YAC7G,MAAM,EAAE,8uPAA8uP;SACvvP;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,uBAAuB;YAChC,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,kGAAkG;YAC7G,MAAM,EAAE,6kNAA6kN;SACtlN;QACD;YACE,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,MAAM,EAAE,qBAAqB;YAC7B,SAAS,EAAE,uHAAuH;YAClI,MAAM,EAAE,2rdAA2rd;SACpsd;QACD;YACE,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,uBAAuB;YAC/B,SAAS,EAAE,kHAAkH;YAC7H,MAAM,EAAE,kr5BAAkr5B;SAC3r5B;KACF;IACD,MAAM,EAAE;QACN,OAAO,EAAE,0BAA0B;QACnC,MAAM,EAAE,2xubAA2xub;KACpyub;IACD,MAAM,EAAE;QACN,OAAO,EAAE,mCAAmC;QAC5C,MAAM,EAAE,4giFAA4giF;KACrhiF;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,oCAAoC;QAC7C,MAAM,EAAE,siUAAsiU;KAC/iU;CACF,CAAC"}
1
+ {"version":3,"file":"docs-bundle.generated.js","sourceRoot":"","sources":["../src/docs-bundle.generated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * ONE NEUTRALIZATION FOR EVERY SURFACE THAT RENDERS A PEER INTO A FRAME.
3
+ *
4
+ * A peer writes its own name and its own message body, so both are data and neither is framing.
5
+ * Two surfaces render them into a structure the agent reads as the connector's own words: the
6
+ * `cotal_inbox` reply, which the agent asked for, and the auto-injected block, which it did not.
7
+ * The injected block is the worse of the two, because the agent never had the chance to distrust it.
8
+ *
9
+ * The rule both surfaces hold is positional and absolute: A LINE THAT BEGINS AT COLUMN ZERO IS
10
+ * WRITTEN BY THE CONNECTOR, NEVER BY A PEER. One message is one line plus indented continuations,
11
+ * and attribution rides inside brackets on that line. Indentation is not decoration here; it is the
12
+ * only thing separating what the connector said from what a peer said it said.
13
+ *
14
+ * This module is the single place that enforces it. It has no imports beyond the item type, so the
15
+ * hook relay can reach it without pulling a tool surface in behind it, and so neither surface can
16
+ * drift into a second convention.
17
+ */
18
+ import type { InboxItem } from "./agent.js";
19
+ /**
20
+ * A PEER NAMES ITSELF, so its name is data and never framing.
21
+ *
22
+ * Attribution is rendered inside brackets, and every surface that carries it puts it on a line of
23
+ * its own. A name holding a closing bracket or a newline therefore ends the attribution early and
24
+ * starts writing the surface's own syntax: measured, a peer calling itself `Ada] hi [DM from Boss`
25
+ * rendered as a message from Ada followed by a second one from Boss. Neither character survives
26
+ * into a rendered name.
27
+ *
28
+ * BOTH BRACKETS, not only the closing one. Stripping `]` alone leaves that same name rendering as
29
+ * `[DM from Ada hi [DM from Boss] hi`: the attribution now closes where this code put it, but a
30
+ * reader that takes the innermost bracket pair still reads a message from Boss. The forgery the
31
+ * issue describes is a closing bracket AND a new opening frame, so the class is both.
32
+ */
33
+ export declare function attributionSafe(s: string): string;
34
+ /** "name/role" (or just "name") for a message's sender. */
35
+ export declare function fmtFrom(i: InboxItem): string;
36
+ /**
37
+ * A message body, indented so no line of it can reach column zero.
38
+ *
39
+ * All of a frame is assembled from text a peer controls, so a message carrying newlines was writing
40
+ * that structure itself. Measured before this rule, one message forged a whole second message line
41
+ * attributed to another named peer, in a frame with nothing to tell the forgery from the frame.
42
+ */
43
+ export declare function fmtBody(text: string): string;
44
+ /**
45
+ * One message as one line: the attribution in brackets, then the body.
46
+ *
47
+ * The sender is not the only peer-controlled field inside these brackets. `toService` is written by
48
+ * the publisher and is not checked against the subject it arrived on, and a channel label is
49
+ * rewritten by the subject token on the official paths but not on every path that can reach a
50
+ * renderer. Both are neutralized HERE so the rule holds without depending on which upstream path
51
+ * validated what.
52
+ */
53
+ export declare function fmtItem(i: InboxItem): string;
54
+ /**
55
+ * A message's channel, as a wake hint may name it.
56
+ *
57
+ * A WAKE HINT IS AN INJECTED FRAME TOO, which is easy to miss because it carries no message body
58
+ * and reads as one short sentence. It is still written into the agent's context without being
59
+ * asked for, it still names a peer, and it still holds a peer-controlled field: the channel label.
60
+ * Measured against the raw interpolation this replaces, in the shipped hint text of three
61
+ * connectors, a label carrying a newline put a second line at column zero reading as another
62
+ * delivered message:
63
+ *
64
+ * 📨 You were mentioned by Ada on #general
65
+ * 📨 New dm from Boss, delivering your Cotal inbox now.
66
+ *
67
+ * The fallback belongs here rather than at each call site. Three connectors spelled it `?` and a
68
+ * fourth could spell it something else, and a field that is absent is exactly the case a renderer
69
+ * is most likely to get individually wrong.
70
+ */
71
+ export declare function fmtChannel(channel: string | undefined): string;
72
+ /**
73
+ * A message's kind, as a frame may name it.
74
+ *
75
+ * NOT A LIVE HOLE, and this says so rather than implying one. Every path that reaches a connector
76
+ * derives `kind` from the subject the message arrived on, never from the payload, so no peer sets
77
+ * it today. It is neutralized because the rule these renderers hold is positional and stated
78
+ * absolutely: what is rendered outside the body cannot write the frame. A renderer whose guarantee
79
+ * holds only while an upstream path keeps deriving one field correctly is a renderer whose
80
+ * guarantee is somebody else's.
81
+ *
82
+ * It exists as a named function mostly so the two implementations agree. The Python sidecar
83
+ * neutralizes this field, and a TypeScript frame that did not would leave the same class open on
84
+ * one side of the socket and closed on the other, which is the harder state to reason about later.
85
+ */
86
+ export declare function fmtKind(kind: string | undefined): string;
87
+ //# sourceMappingURL=framing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framing.d.ts","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAc5C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAG5C;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAM5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGxD"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * What counts as a line break, which is more than what JavaScript splits on.
3
+ *
4
+ * Measured through the host frame a model is handed (an MCP text content part, stringified and
5
+ * parsed back): U+2028, U+2029 and U+0085 survive JSON transport intact, so a message carrying one
6
+ * of them put an unindented attribution line into the bytes the model receives. A JavaScript split
7
+ * on a newline does not see a line there and neither does `wc -l`, but a Unicode-aware splitter
8
+ * does, and the rule this serves is stated absolutely. The class is therefore every code point a
9
+ * line splitter may honour, not the two this repo used to know.
10
+ */
11
+ const LINE_BREAK = /\r\n?|[\n\v\f\u0085\u2028\u2029]/g;
12
+ /**
13
+ * A PEER NAMES ITSELF, so its name is data and never framing.
14
+ *
15
+ * Attribution is rendered inside brackets, and every surface that carries it puts it on a line of
16
+ * its own. A name holding a closing bracket or a newline therefore ends the attribution early and
17
+ * starts writing the surface's own syntax: measured, a peer calling itself `Ada] hi [DM from Boss`
18
+ * rendered as a message from Ada followed by a second one from Boss. Neither character survives
19
+ * into a rendered name.
20
+ *
21
+ * BOTH BRACKETS, not only the closing one. Stripping `]` alone leaves that same name rendering as
22
+ * `[DM from Ada hi [DM from Boss] hi`: the attribution now closes where this code put it, but a
23
+ * reader that takes the innermost bracket pair still reads a message from Boss. The forgery the
24
+ * issue describes is a closing bracket AND a new opening frame, so the class is both.
25
+ */
26
+ export function attributionSafe(s) {
27
+ return s.replace(/[\r\n\v\f\u0085\u2028\u2029[\]]+/g, " ");
28
+ }
29
+ /** "name/role" (or just "name") for a message's sender. */
30
+ export function fmtFrom(i) {
31
+ const name = attributionSafe(i.fromName);
32
+ return i.fromRole ? `${name}/${attributionSafe(i.fromRole)}` : name;
33
+ }
34
+ /**
35
+ * A message body, indented so no line of it can reach column zero.
36
+ *
37
+ * All of a frame is assembled from text a peer controls, so a message carrying newlines was writing
38
+ * that structure itself. Measured before this rule, one message forged a whole second message line
39
+ * attributed to another named peer, in a frame with nothing to tell the forgery from the frame.
40
+ */
41
+ export function fmtBody(text) {
42
+ return text.replace(LINE_BREAK, "\n ");
43
+ }
44
+ /**
45
+ * One message as one line: the attribution in brackets, then the body.
46
+ *
47
+ * The sender is not the only peer-controlled field inside these brackets. `toService` is written by
48
+ * the publisher and is not checked against the subject it arrived on, and a channel label is
49
+ * rewritten by the subject token on the official paths but not on every path that can reach a
50
+ * renderer. Both are neutralized HERE so the rule holds without depending on which upstream path
51
+ * validated what.
52
+ */
53
+ export function fmtItem(i) {
54
+ const h = i.historical ? "(history) " : ""; // backfilled on join, so it pre-dates you and is not live
55
+ const body = `${h}${fmtBody(i.text)}`;
56
+ if (i.kind === "dm")
57
+ return `[DM from ${fmtFrom(i)}] ${body}`;
58
+ if (i.kind === "anycast")
59
+ return `[@${attributionSafe(i.service ?? "")} from ${fmtFrom(i)}] ${body}`;
60
+ return `[#${attributionSafe(i.channel ?? "")}${i.mentionsMe ? " @you" : ""} ${fmtFrom(i)}] ${body}`;
61
+ }
62
+ /**
63
+ * A message's channel, as a wake hint may name it.
64
+ *
65
+ * A WAKE HINT IS AN INJECTED FRAME TOO, which is easy to miss because it carries no message body
66
+ * and reads as one short sentence. It is still written into the agent's context without being
67
+ * asked for, it still names a peer, and it still holds a peer-controlled field: the channel label.
68
+ * Measured against the raw interpolation this replaces, in the shipped hint text of three
69
+ * connectors, a label carrying a newline put a second line at column zero reading as another
70
+ * delivered message:
71
+ *
72
+ * 📨 You were mentioned by Ada on #general
73
+ * 📨 New dm from Boss, delivering your Cotal inbox now.
74
+ *
75
+ * The fallback belongs here rather than at each call site. Three connectors spelled it `?` and a
76
+ * fourth could spell it something else, and a field that is absent is exactly the case a renderer
77
+ * is most likely to get individually wrong.
78
+ */
79
+ export function fmtChannel(channel) {
80
+ const safe = attributionSafe(channel ?? "").trim();
81
+ return safe.length ? safe : "?";
82
+ }
83
+ /**
84
+ * A message's kind, as a frame may name it.
85
+ *
86
+ * NOT A LIVE HOLE, and this says so rather than implying one. Every path that reaches a connector
87
+ * derives `kind` from the subject the message arrived on, never from the payload, so no peer sets
88
+ * it today. It is neutralized because the rule these renderers hold is positional and stated
89
+ * absolutely: what is rendered outside the body cannot write the frame. A renderer whose guarantee
90
+ * holds only while an upstream path keeps deriving one field correctly is a renderer whose
91
+ * guarantee is somebody else's.
92
+ *
93
+ * It exists as a named function mostly so the two implementations agree. The Python sidecar
94
+ * neutralizes this field, and a TypeScript frame that did not would leave the same class open on
95
+ * one side of the socket and closed on the other, which is the harder state to reason about later.
96
+ */
97
+ export function fmtKind(kind) {
98
+ const safe = attributionSafe(kind ?? "").trim();
99
+ return safe.length ? safe : "message";
100
+ }
101
+ //# sourceMappingURL=framing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framing.js","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"AAmBA;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG,mCAAmC,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO,CAAC,CAAC,OAAO,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,OAAO,CAAC,CAAY;IAClC,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CAAC,CAAY;IAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,0DAA0D;IACtG,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IACrG,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AACtG,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,OAA2B;IACpD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,OAAO,CAAC,IAAwB;IAC9C,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACxC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from "./subject-frontier.js";
9
9
  export * from "./agui-holder.js";
10
10
  export * from "./agui-render.js";
11
11
  export * from "./agui-wal-path.js";
12
+ export * from "./framing.js";
12
13
  export * from "./tool-specs.js";
13
14
  export * from "./orientation.js";
14
15
  export * from "./docs.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export * from "./subject-frontier.js";
9
9
  export * from "./agui-holder.js";
10
10
  export * from "./agui-render.js";
11
11
  export * from "./agui-wal-path.js";
12
+ export * from "./framing.js";
12
13
  export * from "./tool-specs.js";
13
14
  export * from "./orientation.js";
14
15
  export * from "./docs.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
package/dist/runtime.d.ts CHANGED
@@ -1,22 +1,3 @@
1
- /**
2
- * A connector's local control endpoint: the OS path its lifecycle hooks (and the manager's
3
- * cooperative-shutdown call) connect to, plus the shared secret that authenticates the first frame.
4
- *
5
- * The path id is `sha256(space\0name\0pid\0token)` (base64url, ≤32) — unguessable and
6
- * collision-free without leaking identity; the 256-bit `token` is the actual auth boundary (the
7
- * server validates it with a constant-time compare before doing anything — see `control.ts`).
8
- *
9
- * Transport is per-platform but the same `node:net` path string drives both: win32 has no
10
- * filesystem AF_UNIX socket Node can bind, so the path is a named pipe (`\\.\pipe\…`) whose default
11
- * DACL lets ANY local process connect — which is exactly why the token, not the path, is the
12
- * security boundary there. POSIX uses a per-user `tmpdir` socket.
13
- *
14
- * Minted ONCE at launch (in the manager's process, via the connector's `buildLaunch`). Both ends —
15
- * the in-agent server that LISTENS and the short-lived hooks that CONNECT — then read `path`+`token`
16
- * from the child env (`COTAL_CONTROL_SOCKET`/`COTAL_CONTROL_TOKEN`), never recompute them from
17
- * public identity; the manager keeps them in memory for the cooperative shutdown. (`process.pid` is
18
- * just generation-time entropy — the value flows by env, so it never has to match across processes.)
19
- */
20
1
  export declare function controlEndpoint(space: string, name: string, token?: string): {
21
2
  path: string;
22
3
  token: string;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAA8C,GACpD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAQjC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAqCA,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAA8C,GACpD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAwBjC"}
package/dist/runtime.js CHANGED
@@ -20,12 +20,39 @@ import { createHash, randomBytes } from "node:crypto";
20
20
  * public identity; the manager keeps them in memory for the cooperative shutdown. (`process.pid` is
21
21
  * just generation-time entropy — the value flows by env, so it never has to match across processes.)
22
22
  */
23
+ /**
24
+ * The longest control-socket path the kernel will actually bind, in BYTES.
25
+ *
26
+ * `sockaddr_un.sun_path` is 108 bytes on Linux and 104 on macOS, and overrunning it fails at the
27
+ * bind with a bare `EINVAL` — an errno that names neither paths, nor lengths, nor sockets. The
28
+ * connector then reads as broken when what is actually wrong is the directory it was handed.
29
+ *
30
+ * MEASURED, not assumed: on this Linux 6.12 box a 108-byte path binds and a 109-byte path fails
31
+ * `EINVAL`, so the limit is INCLUSIVE and the whole 108 is usable. The darwin figure is the
32
+ * documented `sun_path` size and is NOT measured here; it is the smaller of the two, so taking it
33
+ * as the cap fails closed.
34
+ */
35
+ const SUN_PATH_MAX_BYTES = process.platform === "darwin" ? 104 : 108;
23
36
  export function controlEndpoint(space, name, token = randomBytes(32).toString("base64url")) {
24
37
  const id = createHash("sha256")
25
38
  .update(`${space}\0${name}\0${process.pid}\0${token}`)
26
39
  .digest("base64url")
27
40
  .slice(0, 32);
28
41
  const path = process.platform === "win32" ? `\\\\.\\pipe\\cotal-${id}` : join(tmpdir(), `cotal-${id}.sock`);
42
+ // `id` is a fixed 32 chars, so `tmpdir()` is the ONLY variable in this path: the tail
43
+ // `/cotal-<id>.sock` is a constant 44 bytes, leaving 64 for the temp root on Linux. A TMPDIR
44
+ // pointed inside a deep working copy spends that budget silently, and the overrun then surfaces
45
+ // as an `EINVAL` from a bind that cannot say why. Refuse HERE, where the path, its length and the
46
+ // limit are all in hand. win32 named pipes are not `sun_path` and carry no such limit.
47
+ const bytes = Buffer.byteLength(path);
48
+ if (process.platform !== "win32" && bytes > SUN_PATH_MAX_BYTES) {
49
+ const tail = `/cotal-${id}.sock`.length;
50
+ throw new Error(`control socket path is ${bytes} bytes, over the ${SUN_PATH_MAX_BYTES}-byte sun_path limit on ` +
51
+ `${process.platform}, so it cannot be bound and the kernel would report only EINVAL: ${path}. ` +
52
+ `The socket name is a fixed ${tail} bytes, so the temp root must be at most ` +
53
+ `${SUN_PATH_MAX_BYTES - tail} bytes — TMPDIR is ${Buffer.byteLength(tmpdir())} bytes ` +
54
+ `(${tmpdir()}). Point TMPDIR at a shorter directory.`);
55
+ }
29
56
  return { path, token };
30
57
  }
31
58
  //# sourceMappingURL=runtime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,IAAY,EACZ,QAAgB,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;IAErD,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC5B,MAAM,CAAC,GAAG,KAAK,KAAK,IAAI,KAAK,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;SACrD,MAAM,CAAC,WAAW,CAAC;SACnB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACjG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;;;;;;GAWG;AACH,MAAM,kBAAkB,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAErE,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,IAAY,EACZ,QAAgB,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;IAErD,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC5B,MAAM,CAAC,GAAG,KAAK,KAAK,IAAI,KAAK,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;SACrD,MAAM,CAAC,WAAW,CAAC;SACnB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACjG,sFAAsF;IACtF,6FAA6F;IAC7F,gGAAgG;IAChG,kGAAkG;IAClG,uFAAuF;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,GAAG,kBAAkB,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,0BAA0B,KAAK,oBAAoB,kBAAkB,0BAA0B;YAC7F,GAAG,OAAO,CAAC,QAAQ,oEAAoE,IAAI,IAAI;YAC/F,8BAA8B,IAAI,2CAA2C;YAC7E,GAAG,kBAAkB,GAAG,IAAI,sBAAsB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,SAAS;YACtF,IAAI,MAAM,EAAE,yCAAyC,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
@@ -54,8 +54,8 @@ export declare function parseToolArgs(spec: CotalToolSpec, args: unknown): Recor
54
54
  * A host given this refuses extras itself; a host given no `inputSchema` at all forwards them. */
55
55
  export declare const NO_TOOL_ARGS: CotalToolInput;
56
56
  export declare function refuseAnyArgs(name: string, args: unknown): string | undefined;
57
- /** "name/role" (or just "name") for a message's sender. */
58
- export declare function fmtFrom(i: InboxItem): string;
57
+ /** The neutralization and the per-item rendering live in `framing.ts`, one convention shared with
58
+ * the auto-injected block, and are used here rather than restated. See that file for the rule. */
59
59
  /**
60
60
  * HOW MUCH OF THE INBOX ONE RESPONSE MAY CARRY, in characters.
61
61
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tool-specs.d.ts","sourceRoot":"","sources":["../src/tool-specs.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAI5F;yDACyD;AACzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAgDD;;;;;;;sGAOsG;AACtG,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAExD,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB;;;;8FAI0F;IAC1F,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;CACzF;AAUD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzF;AAED;;;;;;;;;GASG;AACH;mGACmG;AACnG,eAAO,MAAM,YAAY,EAAE,cAAmC,CAAC;AAE/D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7E;AAeD,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAG5C;AAeD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,oCAAoC;IACpC,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,uEAAuE;IACvE,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,KAAK,MAAM,CAAC;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC,GAAG,aAAa,CAyFhB;AA8LD,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhE;AAED;+DAC+D;AAC/D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,SAAc,GAAG,aAAa,EAAE,CA+8BzF"}
1
+ {"version":3,"file":"tool-specs.d.ts","sourceRoot":"","sources":["../src/tool-specs.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAI5F;yDACyD;AACzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAgDD;;;;;;;sGAOsG;AACtG,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAExD,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB;;;;8FAI0F;IAC1F,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;CACzF;AAUD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzF;AAED;;;;;;;;;GASG;AACH;mGACmG;AACnG,eAAO,MAAM,YAAY,EAAE,cAAmC,CAAC;AAE/D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7E;AAeD;mGACmG;AACnG;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,oCAAoC;IACpC,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,uEAAuE;IACvE,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,KAAK,MAAM,CAAC;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC,GAAG,aAAa,CAyFhB;AAyJD,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhE;AAED;+DAC+D;AAC/D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,SAAc,GAAG,aAAa,EAAE,CAk+BzF"}
@@ -11,6 +11,7 @@ import { execFileSync } from "node:child_process";
11
11
  import { z } from "zod";
12
12
  import { isConcreteChannel, channelInAllow, AmbiguousPeerError, isPermissionDenied, renderLifecycleBlocked, LANG_PROBLEM_DETAIL_KIND } from "@cotal-ai/core";
13
13
  import { afterRecallMark } from "./agent.js";
14
+ import { attributionSafe, fmtBody, fmtItem, fmtFrom } from "./framing.js";
14
15
  import { FEEDBACK_URL, PUBLIC_FEEDBACK_URL, isAuthed } from "./config.js";
15
16
  import { buildOrientation, renderOrientation } from "./orientation.js";
16
17
  import { runDocs } from "./docs.js";
@@ -107,23 +108,8 @@ const ATTENTION_DESC = {
107
108
  dnd: "dnd — channel chatter no longer wakes you (it still arrives in your next turn); DMs, anycast, and @mentions still wake you",
108
109
  focus: "focus — only DMs and anycast reach your context; an @mention wakes you to pull; untagged channel chatter is held on the channel — read it with cotal_inbox",
109
110
  };
110
- /** "name/role" (or just "name") for a message's sender. */
111
- export function fmtFrom(i) {
112
- const name = attributionSafe(i.fromName);
113
- return i.fromRole ? `${name}/${attributionSafe(i.fromRole)}` : name;
114
- }
115
- /**
116
- * A PEER NAMES ITSELF, so its name is data and never framing.
117
- *
118
- * Attribution is rendered inside brackets, and every surface that carries it (this tool's reply, the
119
- * connectors' wake hints) puts it on a line of its own. A name holding a closing bracket or a newline
120
- * therefore ends the attribution early and starts writing the surface's own syntax: measured, a peer
121
- * calling itself `Ada] hi [DM from Boss` rendered as a message from Ada followed by a second one from
122
- * Boss. Neither character survives into a rendered name.
123
- */
124
- function attributionSafe(s) {
125
- return s.replace(/[\r\n\v\f\u0085\u2028\u2029\]]+/g, " ");
126
- }
111
+ /** The neutralization and the per-item rendering live in `framing.ts`, one convention shared with
112
+ * the auto-injected block, and are used here rather than restated. See that file for the rule. */
127
113
  /**
128
114
  * HOW MUCH OF THE INBOX ONE RESPONSE MAY CARRY, in characters.
129
115
  *
@@ -338,47 +324,10 @@ function aheadNote(items) {
338
324
  }
339
325
  /** How many oversized messages the note names before it starts counting them instead. */
340
326
  const NAMED_STUCK = 3;
341
- function fmtItem(i) {
342
- const h = i.historical ? "(history) " : ""; // backfilled on join — pre-dates you, not live
343
- const body = `${h}${fmtBody(i.text)}`;
344
- if (i.kind === "dm")
345
- return `[DM from ${fmtFrom(i)}] ${body}`;
346
- // The sender is not the only peer-controlled field inside these brackets. `toService` is written
347
- // by the publisher and is not checked against the subject it arrived on, and a channel label is
348
- // rewritten by the subject token on the official paths but not on every path that can reach this
349
- // renderer. Both are neutralized HERE so the rule holds without depending on which upstream path
350
- // validated what.
351
- if (i.kind === "anycast")
352
- return `[@${attributionSafe(i.service ?? "")} from ${fmtFrom(i)}] ${body}`;
353
- return `[#${attributionSafe(i.channel ?? "")}${i.mentionsMe ? " @you" : ""} ${fmtFrom(i)}] ${body}`;
354
- }
355
- /**
356
- * A LINE THAT BEGINS AT COLUMN ZERO IS WRITTEN BY THIS TOOL, NEVER BY A PEER.
357
- *
358
- * The reply is structured: a head line, one line per message with its sender in brackets, then the
359
- * held-note and any warning. All of it is assembled from text a peer controls, so a message carrying
360
- * newlines was writing that structure itself. Measured before this rule, one message forged a whole
361
- * second message line attributed to another named peer, the held-note including its call-again
362
- * promise, and the recall warning, in a reply with nothing to tell the forgery from the frame.
363
- *
364
- * One message is one line plus indented continuations. Indentation is not decoration here; it is the
365
- * only thing that separates what the tool said from what a peer said it said.
366
- */
367
- function fmtBody(text) {
368
- return text.replace(LINE_BREAK, "\n ");
369
- }
370
- /**
371
- * What counts as a line break, which is more than what JavaScript splits on.
372
- *
373
- * Measured through the host frame a model is handed (an MCP text content part, stringified and
374
- * parsed back): U+2028, U+2029 and U+0085 survive JSON transport intact, so a message carrying one
375
- * of them put an unindented attribution line into the bytes the model receives. A JavaScript split
376
- * on a newline does not see a line there and neither does `wc -l`, but a Unicode-aware splitter
377
- * does, and the rule this serves is stated absolutely: a line at column zero is written by this
378
- * tool. A rule whose truth depends on which splitter the consumer happens to use is not that rule,
379
- * so the class is every code point a line splitter may honour, not the two this file used to know.
380
- */
381
- const LINE_BREAK = /\r\n?|[\n\v\f\u0085\u2028\u2029]/g;
327
+ /** A LINE THAT BEGINS AT COLUMN ZERO IS WRITTEN BY THIS TOOL, NEVER BY A PEER. The reply is a head
328
+ * line, one line per message with its sender in brackets, then the held-note and any warning, all
329
+ * of it assembled from peer-controlled text. `fmtItem` and `fmtBody` in `framing.ts` are what hold
330
+ * that rule, and the auto-injected block holds it through the same two functions. */
382
331
  /** Render a channel's registry text as ATTRIBUTED, ADVISORY data — never as instructions to
383
332
  * obey. The registry is privileged-write but still untrusted from the model's seat (a write
384
333
  * reaches every joiner's context), so the fence — advisory framing plus the caveat travelling
@@ -475,8 +424,13 @@ export function cotalToolSpecs(config, source = "connector") {
475
424
  {
476
425
  name: "cotal_connection_status",
477
426
  title: "Cotal: connection status",
478
- description: "Report this session's mesh connection as one of five states, plus the raw facts it is " +
479
- "derived from. `ready` is bound with a live transport. `degraded` is bound while the " +
427
+ description: "Report this session's mesh connection as one of six states, plus the raw facts it is " +
428
+ "derived from. `ready` is bound with a live transport AND consuming its queue. `stalled` is " +
429
+ "bound with a live transport while automatic deliveries have been queued with no progress " +
430
+ "for over ten minutes: the connection is fine and the seat is not consuming, so peer " +
431
+ "messages are piling up behind it. Progress is measured at the HEAD of the queue, so a seat " +
432
+ "that keeps committing fresh arrivals while its oldest deliveries never come off reports " +
433
+ "`stalled` rather than `ready`. `degraded` is bound while the " +
480
434
  "transport underneath is DOWN, so sends queue or fail until the client reconnects; this is " +
481
435
  "the state that needs attention. `connecting` is a live transport whose Cotal bind has not " +
482
436
  "finished. `disconnected` is neither. `stopped` means this session was shut down " +
@@ -484,10 +438,10 @@ export function cotalToolSpecs(config, source = "connector") {
484
438
  "and the time of the latest successful non-empty inbox drain when one has occurred. A " +
485
439
  "retained failure is reported as `connectionIssue` while it is the CURRENT reason, and as " +
486
440
  "`lastConnectionIssue` on a stopped session, where it is a post-mortem rather than a live " +
487
- "problem. Also reports how many automatic (connector-managed) deliveries are still queued " +
488
- "and the local receive time of the oldest of those, so a seat that cannot be steered can " +
489
- "say so. Read-only and local: it reads this session's MeshAgent directly and does not call " +
490
- "the manager or the broker.",
441
+ "problem. Also reports how many automatic (connector-managed) deliveries are still queued, " +
442
+ "the local receive time of the oldest of those, and how long that queue has gone without " +
443
+ "committing anything, so a seat that cannot be steered can say so. Read-only and local: it " +
444
+ "reads this session's MeshAgent directly and does not call the manager or the broker.",
491
445
  run(agent) {
492
446
  const state = agent.connectionState;
493
447
  const issue = agent.connectionIssue;
@@ -519,6 +473,17 @@ export function cotalToolSpecs(config, source = "connector") {
519
473
  note: "presence writes are the first thing to fail here, not necessarily the only thing - a broker can refuse writes far more widely while this connection stays up",
520
474
  },
521
475
  };
476
+ // #1233: the queue's own progress, reported whenever there IS a queue rather than only once
477
+ // it crosses the bound. A caller watching a seat needs to see the number climbing before it
478
+ // becomes a verdict, and a reader who disagrees with our threshold can apply their own -
479
+ // the same reason the three liveness facts are reported next to the state they derive.
480
+ const stalledForMs = agent.automaticQueueStalledForMs();
481
+ const lastAutomaticAt = agent.lastAutomaticDrainedAt;
482
+ // #1526: the two automatic marks are reported SEPARATELY because the gap between them is the
483
+ // fault. A seat committing fresh arrivals over a head it cannot deliver has a moving
484
+ // `lastAutomaticDrainedAt` and a frozen `lastAutomaticHeadDrainedAt`, and reporting only the
485
+ // first describes that seat as busy and healthy while its oldest messages never arrive.
486
+ const lastHeadAt = agent.lastAutomaticHeadDrainedAt;
522
487
  return ok(JSON.stringify({
523
488
  state,
524
489
  // The facts the state is derived from, so a caller that reads the combination
@@ -534,7 +499,10 @@ export function cotalToolSpecs(config, source = "connector") {
534
499
  ...issueField,
535
500
  ...presenceField,
536
501
  ...(lastDrainedAt !== undefined ? { lastDrainedAt: new Date(lastDrainedAt).toISOString() } : {}),
502
+ ...(lastAutomaticAt !== undefined ? { lastAutomaticDrainedAt: new Date(lastAutomaticAt).toISOString() } : {}),
503
+ ...(lastHeadAt !== undefined ? { lastAutomaticHeadDrainedAt: new Date(lastHeadAt).toISOString() } : {}),
537
504
  ...(oldestAutomaticAt !== undefined ? { oldestAutomaticAt: new Date(oldestAutomaticAt).toISOString() } : {}),
505
+ ...(stalledForMs !== undefined ? { automaticQueueStalledForMs: stalledForMs } : {}),
538
506
  }, null, 2));
539
507
  },
540
508
  },
@@ -1127,12 +1095,12 @@ export function cotalToolSpecs(config, source = "connector") {
1127
1095
  {
1128
1096
  name: "cotal_yield",
1129
1097
  title: "Cotal: yield a run turn",
1130
- description: "Yield the run turn you were handed (the 🎯 context block) back to its workflow. You rarely need this: simply ending your session turn yields `done` automatically. Call it only when you are BLOCKED (can't make progress; say why in `note`) or HANDING OFF the turn to another agent (`status: handoff` with `to`). Applies to the oldest turn you were handed; pass `turn` (its goal id, shown in the block) only when you hold several.",
1098
+ description: "Report the outcome of a workflow turn assigned to you. Use this only when your context contains a pending run turn; it does not start a workflow or resolve a checkpoint/ask.\n\nUsually finish your session turn normally: that yields `done` automatically. If you cannot progress, call `{\"status\":\"blocked\",\"note\":\"<what prevents progress>\"}`. To hand the assigned turn to another agent, call `{\"status\":\"handoff\",\"to\":\"<agent-name>\",\"note\":\"<handoff context>\"}`.\n\nWhen you hold several assigned turns, pass `turn` with the exact goal id from the relevant run-turn context block. Without `turn`, the oldest turn already shown to your session is selected. A turn that has not been shown cannot be yielded. A successful reply confirms the turn was yielded, not that the whole workflow completed; the run's coordinator can inspect progress with `cotal_run` status.",
1131
1099
  schema: {
1132
1100
  status: z
1133
1101
  .enum(["done", "blocked", "handoff"])
1134
1102
  .describe("done = finished (usually implicit: just end your turn instead); blocked = can't proceed; handoff = another agent should take it."),
1135
- to: z.string().optional().describe("handoff only: the agent name the turn should pass to."),
1103
+ to: z.string().optional().describe("Required for handoff: the agent name the assigned turn should pass to."),
1136
1104
  note: z.string().max(4096).optional().describe("Short free-text for the run: what blocked you, or what the next agent should know."),
1137
1105
  turn: z.string().optional().describe("The turn's goal id, from the 🎯 block. Omit when you hold only one."),
1138
1106
  },
@@ -1151,15 +1119,15 @@ export function cotalToolSpecs(config, source = "connector") {
1151
1119
  {
1152
1120
  name: "cotal_run",
1153
1121
  title: "Cotal: run a workflow program",
1154
- description: "Write a cotal-lang program and run it durably on the mesh's manager. `start` takes the program SOURCE inline: the manager validates it (a refusal lists every problem with its line, cause and fix), mints a run id, and drives it from its own process, so the run outlives your session, survives a manager restart, and can be answered from anywhere. It returns the run id at once; the run keeps going. The run is admitted under YOUR channel scope: it may read and post in the channels your credential may and no others, and a `wait` on a channel outside that scope is refused at the effect. Use it for coordination that must survive restarts: multi-step plans, human checkpoints, timed waits, fan-out over agents. Read the `workflows` and `lang-card` docs (cotal_docs) before writing a program. `status` returns a run's record and its step journal (an open pause shows what it asks under the step key an answer takes back); `ps` lists the runs; `answer` resolves an open checkpoint or ask by its step key; `resume` takes a released or held run over from its recorded program.",
1122
+ description: "Use Cotal Lang to program multi-step coordination between agents: sequence work, run tasks in parallel, branch on results, wait for events, and request human decisions. Agents own their reasoning and conversations; the workflow specifies when they act and which outcomes determine the next step.\n\nBefore writing a program, read cotal_docs pages `workflows` and `lang-card`. Hosted execution requires a running manager, the `run` capability, and static authentication with issued caller authority; open and user-auth meshes refuse hosted runs. `@cotal-ai/lang` provides validation and simulation separately; those are not verbs of this tool.\n\nSTART: pass `verb: \"start\"` and the program text in `source`. Example: `{\"verb\":\"start\",\"source\":\"await sleep(\\\"1s\\\", { name: \\\"first-run\\\" });\"}`. Optional `file` labels diagnostics only; it reads nothing from disk. The manager validates before recording the run and returns a runId. Acceptance is not completion.\n\nINSPECT: use `verb: \"status\"` with that `runId` for state and step journal, or `verb: \"ps\"` to list runs. Both are read-only. Report completion only after observing state `completed`; surface failures or unresolved steps.\n\nANSWER: first inspect status, then pass `verb: \"answer\"`, `runId`, the exact open `stepKey`, and, when requested, `value` matching the answer shape. An ask requires its requested record; a checkpoint can resolve without a value. `artifact` may name the evidence reviewed. Answer only with authority to make that decision; never invent an approval.\n\nRESUME: pass `verb: \"resume\"` and `runId` to continue a run from its recorded source. A held run appears as `released` in status. Do not start a duplicate run to continue it or resume one the manager is already driving.\n\nRuns continue independently of your session and can recover after a manager restart. Their channel effects are bounded by the starting credential's issued channel scope. To report that your assigned agent turn is blocked or handed off, use `cotal_yield` instead.",
1155
1123
  schema: {
1156
1124
  verb: z.enum(["start", "status", "ps", "answer", "resume"]).describe("start = validate and drive a new program; status = one run's record + journal; ps = list runs; answer = resolve an open checkpoint/ask; resume = take a released or held run over."),
1157
1125
  source: z.string().min(1).optional().describe("start only: the cotal-lang program source, inline. Required for start."),
1158
1126
  file: z.string().min(1).optional().describe("start only: a file name to attribute the source to in error messages. Diagnostic only; nothing is read from disk."),
1159
1127
  timeout: z.string().min(1).optional().describe("start/resume: the default checkpoint timeout for the drive, as a duration (e.g. `1h`, `30m`). Default 1h."),
1160
- runId: z.string().min(1).optional().describe("status/answer/resume: the run id (`run-<32 hex>`), as `start` or `ps` returned it."),
1161
- stepKey: z.string().min(1).optional().describe("answer only: the open step's key as `status` prints it, e.g. `/checkpoint:approve#0`."),
1162
- value: z.unknown().optional().describe("answer only: the answer payload; its shape is the program's (a checkpoint takes what its schema says)."),
1128
+ runId: z.string().min(1).optional().describe("Required for status, answer and resume: the run id (`run-<32 hex>`) returned by start or ps."),
1129
+ stepKey: z.string().min(1).optional().describe("Required for answer: copy the exact open step key from status, e.g. `/checkpoint:approve#0`."),
1130
+ value: z.unknown().optional().describe("answer only: supply the value requested by the open checkpoint or ask and match its answer shape. A checkpoint may resolve without a value; an ask must receive its requested record. Use null only when that is the intended answer."),
1163
1131
  artifact: z.string().min(1).optional().describe("answer only: a reference to what you reviewed before answering, recorded beside the answer."),
1164
1132
  endpoint: z.string().min(1).optional().describe("status/ps/answer: the endpoint the run record lives under. Omit for runs the manager hosts."),
1165
1133
  },