@builder.io/ai-utils 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/ai-utils",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "description": "Builder.io AI utils",
5
5
  "files": [
6
6
  "src"
package/src/claw.d.ts CHANGED
@@ -70,19 +70,14 @@ export declare function parseChannelId(channelId: string): ParsedChannelId;
70
70
  * slack/dm/TEAM_ID/USER_ID
71
71
  * → https://slack.com/app_redirect?team=TEAM_ID&channel=USER_ID
72
72
  *
73
- * Jira:
74
- * Returns null - needs integration.baseUrl from database
75
- * (Future: jira/comment/CLOUD_ID/ISSUE_KEY → {baseUrl}/browse/ISSUE_KEY)
76
- *
77
73
  * Returns null for unsupported platforms or malformed channel IDs.
78
- *
79
- * TODO: Accept optional integration metadata parameter to construct proper
80
- * workspace-specific URLs (Slack teamDomain, Jira baseUrl).
81
74
  */
82
75
  export declare function convertChannelIdToUrl(channelId: string): string | null;
83
76
  export interface WorkerReportOptions {
84
77
  /** The original user's channel that triggered this work. */
85
78
  originChannelId?: string;
79
+ /** Clickable URL for the origin channel, if the integration already has one. */
80
+ channelUrl?: string;
86
81
  /** The report content. */
87
82
  content: string;
88
83
  /** Agent/tool ID (for sub-agent reports). */
@@ -91,6 +86,8 @@ export interface WorkerReportOptions {
91
86
  export interface WorkerMessageOptions {
92
87
  /** The original user's channel that triggered this work. */
93
88
  originChannelId?: string;
89
+ /** Clickable URL for the origin channel, if the integration already has one. */
90
+ channelUrl?: string;
94
91
  /** The report content. */
95
92
  content: string;
96
93
  /** Project ID (for branch reports). */
@@ -129,6 +126,8 @@ export declare function formatSystemMessage(opts: SystemMessageOptions): string;
129
126
  export interface IncomingMessageOptions {
130
127
  /** The source channel (e.g. slack/thread/TEAM/CHANNEL/TS). */
131
128
  channelId: string;
129
+ /** Clickable URL for channelId, if the integration already has one. */
130
+ channelUrl?: string;
132
131
  /** DM channel ID, if the message was a direct message. */
133
132
  dmId?: string;
134
133
  /** Display name of the sender. */
package/src/claw.js CHANGED
@@ -30,14 +30,7 @@ export function parseChannelId(channelId) {
30
30
  * slack/dm/TEAM_ID/USER_ID
31
31
  * → https://slack.com/app_redirect?team=TEAM_ID&channel=USER_ID
32
32
  *
33
- * Jira:
34
- * Returns null - needs integration.baseUrl from database
35
- * (Future: jira/comment/CLOUD_ID/ISSUE_KEY → {baseUrl}/browse/ISSUE_KEY)
36
- *
37
33
  * Returns null for unsupported platforms or malformed channel IDs.
38
- *
39
- * TODO: Accept optional integration metadata parameter to construct proper
40
- * workspace-specific URLs (Slack teamDomain, Jira baseUrl).
41
34
  */
42
35
  export function convertChannelIdToUrl(channelId) {
43
36
  let parsed;
@@ -51,11 +44,6 @@ export function convertChannelIdToUrl(channelId) {
51
44
  if (platform === "slack") {
52
45
  return slackChannelIdToUrl(type, ids);
53
46
  }
54
- // Jira URLs need integration.baseUrl from database - not available here
55
- // TODO: Add integration metadata parameter to support Jira URLs
56
- if (platform === "jira") {
57
- return null;
58
- }
59
47
  return null;
60
48
  }
61
49
  function slackChannelIdToUrl(type, ids) {
@@ -105,10 +93,11 @@ const WORKER_REPORT_TRAILER = "This is a report from a background worker, NOT a
105
93
  * correct user channel.
106
94
  */
107
95
  export function formatWorkerReport(opts) {
96
+ var _a;
108
97
  let xml = `<worker_report>\n`;
109
98
  if (opts.originChannelId) {
110
99
  xml += `<origin_channel_id>${opts.originChannelId}</origin_channel_id>\n`;
111
- const url = convertChannelIdToUrl(opts.originChannelId);
100
+ const url = (_a = opts.channelUrl) !== null && _a !== void 0 ? _a : convertChannelIdToUrl(opts.originChannelId);
112
101
  if (url) {
113
102
  xml += `<origin_channel_url>${url}</origin_channel_url>\n`;
114
103
  }
@@ -120,10 +109,11 @@ export function formatWorkerReport(opts) {
120
109
  return xml;
121
110
  }
122
111
  export function formatWorkerMessage(opts) {
112
+ var _a;
123
113
  let xml = `<worker_message>\n`;
124
114
  if (opts.originChannelId) {
125
115
  xml += `<origin_channel_id>${opts.originChannelId}</origin_channel_id>\n`;
126
- const url = convertChannelIdToUrl(opts.originChannelId);
116
+ const url = (_a = opts.channelUrl) !== null && _a !== void 0 ? _a : convertChannelIdToUrl(opts.originChannelId);
127
117
  if (url) {
128
118
  xml += `<origin_channel_url>${url}</origin_channel_url>\n`;
129
119
  }
@@ -165,13 +155,14 @@ export function formatSystemMessage(opts) {
165
155
  * The org-agent uses `<channel_id>` to reply in the same medium.
166
156
  */
167
157
  export function formatIncomingMessage(opts) {
158
+ var _a;
168
159
  let result = "";
169
160
  if (opts.messageContext) {
170
161
  result += `${opts.messageContext}\n\n`;
171
162
  }
172
163
  result += `<incoming_message>\n`;
173
164
  result += `<channel_id>${opts.channelId}</channel_id>\n`;
174
- const channelUrl = convertChannelIdToUrl(opts.channelId);
165
+ const channelUrl = (_a = opts.channelUrl) !== null && _a !== void 0 ? _a : convertChannelIdToUrl(opts.channelId);
175
166
  if (channelUrl) {
176
167
  result += `<channel_url>${channelUrl}</channel_url>\n`;
177
168
  }
package/src/claw.spec.js CHANGED
@@ -45,10 +45,13 @@ describe("convertChannelIdToUrl", () => {
45
45
  });
46
46
  });
47
47
  describe("jira/comment format", () => {
48
- it("returns null (needs integration.baseUrl from database)", () => {
48
+ it("returns null because Jira URLs are provided by the integration", () => {
49
49
  const url = convertChannelIdToUrl("jira/comment/cloud-id/PROJ-123");
50
50
  expect(url).toBeNull();
51
51
  });
52
+ it("returns null even when the issue key is present", () => {
53
+ expect(convertChannelIdToUrl("jira/comment/cloud-id/PROJ-123")).toBeNull();
54
+ });
52
55
  });
53
56
  describe("unsupported platforms", () => {
54
57
  it("returns null for telegram channel IDs", () => {
@@ -90,14 +93,15 @@ describe("formatIncomingMessage", () => {
90
93
  });
91
94
  expect(result).toContain("<channel_url>https://slack.com/app_redirect?team=TTEAM&channel=CCHAN</channel_url>");
92
95
  });
93
- it("does not include channel_url for Jira (needs integration.baseUrl)", () => {
96
+ it("includes channel_url when provided by the integration", () => {
94
97
  const result = formatIncomingMessage({
95
98
  channelId: "jira/comment/cloud-id/PROJ-123",
99
+ channelUrl: "https://test.atlassian.net/browse/PROJ-123",
96
100
  sender: "Charlie",
97
101
  timestamp: "Wednesday, January 3, 2024 at 12:00 PM PST",
98
102
  content: "Jira comment",
99
103
  });
100
- expect(result).not.toContain("<channel_url>");
104
+ expect(result).toContain("<channel_url>https://test.atlassian.net/browse/PROJ-123</channel_url>");
101
105
  });
102
106
  it("does not include channel_url for unsupported platforms", () => {
103
107
  const result = formatIncomingMessage({
@@ -142,12 +146,13 @@ describe("formatWorkerMessage", () => {
142
146
  });
143
147
  expect(result).toContain("<origin_channel_url>https://slack.com/app_redirect?team=TTEAM&channel=CCHAN&message_ts=1234567890.000100</origin_channel_url>");
144
148
  });
145
- it("does not include origin_channel_url for Jira (needs integration.baseUrl)", () => {
149
+ it("includes origin_channel_url when provided by the integration", () => {
146
150
  const result = formatWorkerMessage({
147
151
  originChannelId: "jira/comment/cloud-id/PROJ-456",
152
+ channelUrl: "https://test.atlassian.net/browse/PROJ-456",
148
153
  content: "Worker result",
149
154
  });
150
- expect(result).not.toContain("<origin_channel_url>");
155
+ expect(result).toContain("<origin_channel_url>https://test.atlassian.net/browse/PROJ-456</origin_channel_url>");
151
156
  });
152
157
  it("does not include origin_channel_url for unsupported platforms", () => {
153
158
  const result = formatWorkerMessage({
@@ -181,13 +186,14 @@ describe("formatWorkerReport", () => {
181
186
  });
182
187
  expect(result).toContain("<origin_channel_url>https://slack.com/app_redirect?team=TTEAM&channel=CCHAN</origin_channel_url>");
183
188
  });
184
- it("does not include origin_channel_url for Jira (needs integration.baseUrl)", () => {
189
+ it("includes origin_channel_url when provided by the integration", () => {
185
190
  const result = formatWorkerReport({
186
191
  originChannelId: "jira/comment/cloud-id/PROJ-789",
192
+ channelUrl: "https://test.atlassian.net/browse/PROJ-789",
187
193
  content: "Report content",
188
194
  agentId: "agent-xyz",
189
195
  });
190
- expect(result).not.toContain("<origin_channel_url>");
196
+ expect(result).toContain("<origin_channel_url>https://test.atlassian.net/browse/PROJ-789</origin_channel_url>");
191
197
  });
192
198
  it("does not include origin_channel_url for unsupported platforms", () => {
193
199
  const result = formatWorkerReport({
package/src/codegen.d.ts CHANGED
@@ -35,6 +35,18 @@ export interface CustomInstruction {
35
35
  isSkill?: boolean;
36
36
  disableModelInvocation?: boolean;
37
37
  userInvocable?: boolean;
38
+ /**
39
+ * Where this instruction was discovered. Drives precedence on name
40
+ * collision: `project` > `user` > `plugin`. Set by the discovery loader,
41
+ * not by the parsed file itself.
42
+ */
43
+ scope?: "project" | "user" | "plugin";
44
+ /**
45
+ * Name of the plugin that contributed this instruction, if any. Set by
46
+ * the plugin loader (Phase 2); always `undefined` for project-level and
47
+ * user-level standalone files (Phase 1).
48
+ */
49
+ pluginName?: string;
38
50
  }
39
51
  /** Reasoning effort level for LLM completions. */
40
52
  export declare const ReasoningEffortSchema: z.ZodEnum<{
@@ -98,13 +110,31 @@ export interface CustomAgentDefinition {
98
110
  maxCompletions?: number;
99
111
  /** Default reasoning effort level for this agent type. Overrides the session default. */
100
112
  reasoning?: ReasoningEffort;
113
+ /**
114
+ * Where this agent was discovered. Drives precedence on name collision:
115
+ * `project` > `user` > `plugin`. Set by the discovery loader, not by the
116
+ * parsed file itself.
117
+ */
118
+ scope?: "project" | "user" | "plugin";
119
+ /**
120
+ * Name of the plugin that contributed this agent, if any. Set by the
121
+ * plugin loader (Phase 2); always `undefined` for project-level and
122
+ * user-level standalone files (Phase 1).
123
+ */
124
+ pluginName?: string;
101
125
  }
102
126
  export type CodeGenFramework = "react" | "html" | "mitosis" | "react-native" | "angular" | "vue" | "svelte" | "qwik" | "solid" | "marko" | "swiftui" | "jetpack-compose" | "flutter";
103
127
  export type CodeGenStyleLibrary = "tailwind" | "tailwind-precise" | "emotion" | "styled-components" | "styled-jsx" | "react-native" | undefined;
104
128
  export type CompletionStopReason = "max_tokens" | "stop_sequence" | "tool_use" | "end_turn" | "content_filter" | "error" | "aborted" | "pause_turn" | "refusal" | "compaction" | "model_context_window_exceeded" | null;
105
129
  export interface ReadToolInput {
130
+ /**
131
+ * Path of the file. Accepts a path relative to the project working directory,
132
+ * an absolute path (e.g. `/Users/.../skill.md`), or a tilde path
133
+ * (e.g. `~/.builder/skills/.../SKILL.md`). User-level Builder state under
134
+ * `~/.builder/**` is allowed by default for plugin operations; other absolute
135
+ * paths require an explicit ACL policy.
136
+ */
106
137
  file_path: string;
107
- view_range?: [number, number];
108
138
  offset?: number | null;
109
139
  limit?: number | null;
110
140
  }
@@ -159,11 +189,23 @@ export interface WebSearchToolInput {
159
189
  }
160
190
  export interface WriteFileInput {
161
191
  title: string;
192
+ /**
193
+ * Path of the file. Accepts a path relative to the project working directory,
194
+ * an absolute path, or a tilde path (e.g. `~/.builder/...`). User-level Builder
195
+ * state under `~/.builder/**` is allowed by default; other absolute paths
196
+ * require an explicit ACL policy.
197
+ */
162
198
  file_path: string;
163
199
  content: string;
164
200
  }
165
201
  export interface SearchReplaceInput {
166
202
  title: string;
203
+ /**
204
+ * Path of the file. Accepts a path relative to the project working directory,
205
+ * an absolute path, or a tilde path (e.g. `~/.builder/...`). User-level Builder
206
+ * state under `~/.builder/**` is allowed by default; other absolute paths
207
+ * require an explicit ACL policy.
208
+ */
167
209
  file_path: string;
168
210
  old_str: string;
169
211
  new_str: string;
@@ -172,6 +214,12 @@ export interface SearchReplaceInput {
172
214
  }
173
215
  export interface MultiSearchReplaceInput {
174
216
  title: string;
217
+ /**
218
+ * Path of the file. Accepts a path relative to the project working directory,
219
+ * an absolute path, or a tilde path (e.g. `~/.builder/...`). User-level Builder
220
+ * state under `~/.builder/**` is allowed by default; other absolute paths
221
+ * require an explicit ACL policy.
222
+ */
175
223
  file_path: string;
176
224
  edits: {
177
225
  old_str: string;
@@ -1006,17 +1054,6 @@ export interface CodeGenInputOptions {
1006
1054
  branchName?: string;
1007
1055
  repoHash?: string;
1008
1056
  repoBranch?: string;
1009
- /**
1010
- * Server-side branch.agentType cached from middleware Firestore lookup.
1011
- * Used to avoid redundant getBranch calls for billing exemption checks.
1012
- * @internal - Set by middleware, not by clients
1013
- */
1014
- branchAgentType?: string | null;
1015
- /**
1016
- * True when middleware performed a Firestore branch lookup; do not use source-based exemption.
1017
- * @internal - Set by middleware, not by clients
1018
- */
1019
- branchAgentTypeChecked?: boolean;
1020
1057
  /** Immediate parent session id when this completion runs inside a sub-agent. */
1021
1058
  parentSessionId?: string;
1022
1059
  /**
@@ -1967,6 +2004,17 @@ export interface MCPServerDefinition {
1967
2004
  env?: Record<string, string>;
1968
2005
  envFile?: string;
1969
2006
  retries?: number;
2007
+ /**
2008
+ * Where this server was discovered. Drives precedence on name collision:
2009
+ * `project` > `user` > `plugin`. Set by the loader, not by the config file.
2010
+ */
2011
+ scope?: "project" | "user" | "plugin";
2012
+ /**
2013
+ * Name of the plugin that contributed this server, if any. Set by the
2014
+ * plugin loader (Phase 2); always `undefined` for project-level and
2015
+ * user-level standalone configs (Phase 1).
2016
+ */
2017
+ pluginName?: string;
1970
2018
  }
1971
2019
  export type MCPServerConfig = Record<string, MCPServerDefinition>;
1972
2020
  export interface FusionConfig {
package/src/events.d.ts CHANGED
@@ -623,6 +623,8 @@ export type ClawMessageSentV1 = FusionEventVariant<"claw.message.sent", {
623
623
  senderId?: string;
624
624
  correlationId?: string;
625
625
  channelId?: string;
626
+ /** Optional clickable URL for channelId. */
627
+ channelUrl?: string;
626
628
  dmId?: string;
627
629
  senderDisplayName?: string;
628
630
  agentBranchName?: string;
@@ -771,6 +773,8 @@ export interface SendMessageToOrgAgentInput {
771
773
  content: string;
772
774
  senderType?: "user" | "sub-agent" | "system";
773
775
  channelId?: string;
776
+ /** Optional clickable URL for channelId. */
777
+ channelUrl?: string;
774
778
  senderDisplayName?: string;
775
779
  messageContext?: string;
776
780
  senderId?: string;