@volter-ai-dev/supercode-ui 0.1.66 → 0.1.67

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/embed.mjs CHANGED
@@ -72,7 +72,12 @@ var EMPTY_UI_STATE = Object.freeze({
72
72
  subagentInspector: null,
73
73
  attached: null,
74
74
  owned: null,
75
- attachError: null
75
+ attachError: null,
76
+ agentPackage: null,
77
+ contributions: Object.freeze([]),
78
+ agentPackageError: null,
79
+ agentPackageCapabilityState: null,
80
+ agentPackageCapabilityError: null
76
81
  });
77
82
  var ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool", "reasoning", "request", "notice"]);
78
83
  var MODES = /* @__PURE__ */ new Set(["none", "control", "mirror"]);
@@ -85,6 +90,10 @@ var AUTHENTICATION_PHASES = /* @__PURE__ */ new Set(["idle", "checking", "requir
85
90
  var MAX_TOOL_FIELDS = 8;
86
91
  var MAX_TOOL_FIELD_CHARS = 800;
87
92
  var MAX_TOOL_PREVIEW_CHARS = 4e3;
93
+ var MAX_CONTRIBUTIONS = 64;
94
+ var MAX_CONTRIBUTION_JSON_DEPTH = 12;
95
+ var MAX_CONTRIBUTION_COLLECTION = 100;
96
+ var MAX_CONTRIBUTION_STRING_CHARS = 16e3;
88
97
  function record(value) {
89
98
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
90
99
  }
@@ -117,6 +126,126 @@ function number(value, fallback = 0) {
117
126
  function nullableNumber(value) {
118
127
  return typeof value === "number" && Number.isFinite(value) ? value : null;
119
128
  }
129
+ function relativeContributionPath(value) {
130
+ if (typeof value !== "string" || value.startsWith("/") || /^[a-z]:[\\/]/i.test(value)) return null;
131
+ return value.replaceAll("\\", "/").split("/").some((segment) => segment === "..") ? null : boundedString(value, 1e3);
132
+ }
133
+ function contributionJson(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
134
+ if (value === null || typeof value === "boolean" || typeof value === "string") {
135
+ return typeof value === "string" ? boundedString(value, MAX_CONTRIBUTION_STRING_CHARS) : value;
136
+ }
137
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
138
+ if (depth >= MAX_CONTRIBUTION_JSON_DEPTH || !value || typeof value !== "object" || seen.has(value)) {
139
+ return void 0;
140
+ }
141
+ seen.add(value);
142
+ if (Array.isArray(value)) {
143
+ const result2 = [];
144
+ for (const item of value.slice(0, MAX_CONTRIBUTION_COLLECTION)) {
145
+ const normalized = contributionJson(item, depth + 1, seen);
146
+ if (normalized !== void 0) result2.push(normalized);
147
+ }
148
+ seen.delete(value);
149
+ return result2;
150
+ }
151
+ const source = record(value);
152
+ if (!source) return void 0;
153
+ const result = {};
154
+ for (const [key, item] of Object.entries(source).slice(0, MAX_CONTRIBUTION_COLLECTION)) {
155
+ const normalized = contributionJson(item, depth + 1, seen);
156
+ if (normalized !== void 0) result[boundedString(key, 200)] = normalized;
157
+ }
158
+ seen.delete(value);
159
+ return result;
160
+ }
161
+ function normalizeContributions(value) {
162
+ if (!Array.isArray(value)) return [];
163
+ return value.slice(0, MAX_CONTRIBUTIONS).flatMap((candidate) => {
164
+ const item = record(candidate);
165
+ const placement = record(item?.placement);
166
+ const source = relativeContributionPath(item?.source);
167
+ if (item?.schema !== "supercode/contribution-v1" || typeof item.id !== "string" || !item.id.trim() || typeof item.kind !== "string" || !item.kind.trim() || source === null) return [];
168
+ const data = contributionJson(item.data);
169
+ if (data === void 0) return [];
170
+ return [{
171
+ schema: "supercode/contribution-v1",
172
+ id: boundedString(item.id, 200),
173
+ kind: boundedString(item.kind, 100),
174
+ ...typeof item.title === "string" ? { title: boundedString(item.title, 500) } : {},
175
+ ...placement ? { placement: {
176
+ ...typeof placement.surface === "string" ? { surface: boundedString(placement.surface, 100) } : {},
177
+ ...typeof placement.region === "string" ? { region: boundedString(placement.region, 100) } : {}
178
+ } } : {},
179
+ data,
180
+ source
181
+ }];
182
+ });
183
+ }
184
+ function readAgentPackage(value) {
185
+ const agentPackage = record(value);
186
+ const capabilities = record(agentPackage?.capabilities);
187
+ const storage = record(agentPackage?.storage);
188
+ const relativePath = relativeContributionPath(storage?.relativePath);
189
+ if (agentPackage?.schemaVersion !== 1 || typeof agentPackage.id !== "string" || typeof agentPackage.name !== "string" || typeof agentPackage.version !== "string" || !capabilities || !Array.isArray(capabilities.required) || !Array.isArray(capabilities.optional) || !storage || relativePath === null) return null;
190
+ const resources = record(agentPackage.resources);
191
+ return {
192
+ id: boundedString(agentPackage.id, 200),
193
+ name: boundedString(agentPackage.name, 500),
194
+ version: boundedString(agentPackage.version, 100),
195
+ description: typeof agentPackage.description === "string" ? boundedString(agentPackage.description, 2e3) : null,
196
+ capabilities: {
197
+ required: capabilities.required.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200)),
198
+ optional: capabilities.optional.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
199
+ },
200
+ storage: { relativePath },
201
+ resources: resources ? Object.fromEntries(Object.entries(resources).flatMap(([id, candidate]) => {
202
+ const state = record(candidate);
203
+ if (state?.schema !== "supercode/package-resource-state-v1") return [];
204
+ if (state.status === "absent" && typeof state.contributionId === "string") {
205
+ return [[boundedString(id, 200), {
206
+ schema: "supercode/package-resource-state-v1",
207
+ status: "absent",
208
+ contributionId: boundedString(state.contributionId, 200)
209
+ }]];
210
+ }
211
+ if (state.status === "error" && typeof state.contributionId === "string" && typeof state.message === "string") {
212
+ return [[boundedString(id, 200), {
213
+ schema: "supercode/package-resource-state-v1",
214
+ status: "error",
215
+ contributionId: boundedString(state.contributionId, 200),
216
+ message: boundedString(state.message)
217
+ }]];
218
+ }
219
+ const resource = record(state?.resource);
220
+ const data = contributionJson(resource?.data);
221
+ if (state?.status !== "ready" || resource?.schema !== "supercode/package-resource-v1" || typeof resource.contributionId !== "string" || !["json", "text"].includes(resource.format) || typeof resource.mediaType !== "string" || data === void 0) return [];
222
+ return [[boundedString(id, 200), {
223
+ schema: "supercode/package-resource-state-v1",
224
+ status: "ready",
225
+ resource: {
226
+ schema: "supercode/package-resource-v1",
227
+ contributionId: boundedString(resource.contributionId, 200),
228
+ format: resource.format,
229
+ mediaType: boundedString(resource.mediaType, 200),
230
+ data
231
+ }
232
+ }]];
233
+ })) : {}
234
+ };
235
+ }
236
+ function readAgentPackageCapabilityState(value) {
237
+ const state = record(value);
238
+ if (!state) return null;
239
+ const fields = ["availableRequired", "missingRequired", "enabledOptional", "unavailableOptional"];
240
+ if (!fields.every((field) => Array.isArray(state[field]))) return null;
241
+ return {
242
+ ready: state.ready === true,
243
+ ...Object.fromEntries(fields.map((field) => [
244
+ field,
245
+ state[field].filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
246
+ ]))
247
+ };
248
+ }
120
249
  function relativeAge(updatedAt, now = Date.now()) {
121
250
  if (typeof updatedAt !== "number" || !Number.isFinite(updatedAt) || updatedAt <= 0) return "";
122
251
  const delta = Math.max(0, now - updatedAt);
@@ -834,7 +963,12 @@ function normalizeUiState(value) {
834
963
  subagentInspector: readSubagentInspector(raw.subagentInspector),
835
964
  attached: readAttached(raw.attached),
836
965
  owned: readAttached(raw.owned),
837
- attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null
966
+ attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null,
967
+ agentPackage: readAgentPackage(raw.agentPackage),
968
+ contributions: normalizeContributions(raw.contributions),
969
+ agentPackageError: typeof raw.agentPackageError === "string" ? boundedString(raw.agentPackageError) : null,
970
+ agentPackageCapabilityState: readAgentPackageCapabilityState(raw.agentPackageCapabilityState),
971
+ agentPackageCapabilityError: typeof raw.agentPackageCapabilityError === "string" ? boundedString(raw.agentPackageCapabilityError) : null
838
972
  };
839
973
  }
840
974
  function harnessDisplayName(id) {
package/index.d.ts CHANGED
@@ -10,6 +10,51 @@ export type ExecutionMode = 'headless' | 'terminal';
10
10
  export type ContinuationMode = ExecutionMode;
11
11
  export type SessionActivity = 'idle' | 'recent' | 'running' | 'working' | 'needs-input' | 'finished' | 'failed' | 'unseen';
12
12
 
13
+ export type ContributionJson = null | boolean | number | string | ContributionJson[] | { [key: string]: ContributionJson };
14
+
15
+ export interface AgentContributionModel {
16
+ schema: 'supercode/contribution-v1';
17
+ id: string;
18
+ kind: string;
19
+ title?: string;
20
+ placement?: { surface?: string; region?: string };
21
+ data: ContributionJson;
22
+ /** Workspace-relative declaration path; never an absolute host path. */
23
+ source: string;
24
+ }
25
+
26
+ export interface AgentPackageModel {
27
+ id: string;
28
+ name: string;
29
+ version: string;
30
+ description: string | null;
31
+ capabilities: { required: string[]; optional: string[] };
32
+ /** Workspace-relative durable data location. */
33
+ storage: { relativePath: string };
34
+ resources: Record<string, AgentPackageResourceStateModel>;
35
+ }
36
+
37
+ export interface AgentPackageResourceModel {
38
+ schema: 'supercode/package-resource-v1';
39
+ contributionId: string;
40
+ format: 'json' | 'text';
41
+ mediaType: string;
42
+ data: ContributionJson;
43
+ }
44
+
45
+ export type AgentPackageResourceStateModel =
46
+ | { schema: 'supercode/package-resource-state-v1'; status: 'ready'; resource: AgentPackageResourceModel }
47
+ | { schema: 'supercode/package-resource-state-v1'; status: 'absent'; contributionId: string }
48
+ | { schema: 'supercode/package-resource-state-v1'; status: 'error'; contributionId: string; message: string };
49
+
50
+ export interface AgentPackageCapabilityStateModel {
51
+ ready: boolean;
52
+ availableRequired: string[];
53
+ missingRequired: string[];
54
+ enabledOptional: string[];
55
+ unavailableOptional: string[];
56
+ }
57
+
13
58
  export interface AgentActivityModel {
14
59
  harness: HarnessId | '';
15
60
  sessionKey: string | null;
@@ -347,6 +392,12 @@ export interface SupercodeUiState {
347
392
  attached: AttachedSessionModel | null;
348
393
  owned: AttachedSessionModel | null;
349
394
  attachError: { key: string; message: string } | null;
395
+ /** Browser-safe package metadata; host filesystem paths are deliberately omitted. */
396
+ agentPackage: AgentPackageModel | null;
397
+ contributions: AgentContributionModel[];
398
+ agentPackageError: string | null;
399
+ agentPackageCapabilityState: AgentPackageCapabilityStateModel | null;
400
+ agentPackageCapabilityError: string | null;
350
401
  }
351
402
 
352
403
  export type SupercodeUiIntent =
@@ -561,6 +612,11 @@ export interface MessengerProps {
561
612
  export const EMPTY_UI_STATE: Readonly<SupercodeUiState>;
562
613
  export const DEFAULT_LABELS: Readonly<MessengerLabels>;
563
614
  export function normalizeUiState(value: unknown): SupercodeUiState;
615
+ export function normalizeContributions(value: unknown): AgentContributionModel[];
616
+ export function selectContributions(
617
+ contributions: unknown,
618
+ query?: { kind?: string; surface?: string; region?: string },
619
+ ): AgentContributionModel[];
564
620
  export function harnessDisplayName(id: string): string;
565
621
  export function sessionDisplayName(session: Pick<SessionRowModel, 'name' | 'title'>): string;
566
622
  export function relativeAge(updatedAt: number | null | undefined, now?: number): string;
package/messenger.mjs CHANGED
@@ -69,7 +69,12 @@ var EMPTY_UI_STATE = Object.freeze({
69
69
  subagentInspector: null,
70
70
  attached: null,
71
71
  owned: null,
72
- attachError: null
72
+ attachError: null,
73
+ agentPackage: null,
74
+ contributions: Object.freeze([]),
75
+ agentPackageError: null,
76
+ agentPackageCapabilityState: null,
77
+ agentPackageCapabilityError: null
73
78
  });
74
79
  var ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool", "reasoning", "request", "notice"]);
75
80
  var MODES = /* @__PURE__ */ new Set(["none", "control", "mirror"]);
@@ -82,6 +87,10 @@ var AUTHENTICATION_PHASES = /* @__PURE__ */ new Set(["idle", "checking", "requir
82
87
  var MAX_TOOL_FIELDS = 8;
83
88
  var MAX_TOOL_FIELD_CHARS = 800;
84
89
  var MAX_TOOL_PREVIEW_CHARS = 4e3;
90
+ var MAX_CONTRIBUTIONS = 64;
91
+ var MAX_CONTRIBUTION_JSON_DEPTH = 12;
92
+ var MAX_CONTRIBUTION_COLLECTION = 100;
93
+ var MAX_CONTRIBUTION_STRING_CHARS = 16e3;
85
94
  function record(value) {
86
95
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
87
96
  }
@@ -114,6 +123,126 @@ function number(value, fallback = 0) {
114
123
  function nullableNumber(value) {
115
124
  return typeof value === "number" && Number.isFinite(value) ? value : null;
116
125
  }
126
+ function relativeContributionPath(value) {
127
+ if (typeof value !== "string" || value.startsWith("/") || /^[a-z]:[\\/]/i.test(value)) return null;
128
+ return value.replaceAll("\\", "/").split("/").some((segment) => segment === "..") ? null : boundedString(value, 1e3);
129
+ }
130
+ function contributionJson(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
131
+ if (value === null || typeof value === "boolean" || typeof value === "string") {
132
+ return typeof value === "string" ? boundedString(value, MAX_CONTRIBUTION_STRING_CHARS) : value;
133
+ }
134
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
135
+ if (depth >= MAX_CONTRIBUTION_JSON_DEPTH || !value || typeof value !== "object" || seen.has(value)) {
136
+ return void 0;
137
+ }
138
+ seen.add(value);
139
+ if (Array.isArray(value)) {
140
+ const result2 = [];
141
+ for (const item of value.slice(0, MAX_CONTRIBUTION_COLLECTION)) {
142
+ const normalized = contributionJson(item, depth + 1, seen);
143
+ if (normalized !== void 0) result2.push(normalized);
144
+ }
145
+ seen.delete(value);
146
+ return result2;
147
+ }
148
+ const source = record(value);
149
+ if (!source) return void 0;
150
+ const result = {};
151
+ for (const [key, item] of Object.entries(source).slice(0, MAX_CONTRIBUTION_COLLECTION)) {
152
+ const normalized = contributionJson(item, depth + 1, seen);
153
+ if (normalized !== void 0) result[boundedString(key, 200)] = normalized;
154
+ }
155
+ seen.delete(value);
156
+ return result;
157
+ }
158
+ function normalizeContributions(value) {
159
+ if (!Array.isArray(value)) return [];
160
+ return value.slice(0, MAX_CONTRIBUTIONS).flatMap((candidate) => {
161
+ const item = record(candidate);
162
+ const placement = record(item?.placement);
163
+ const source = relativeContributionPath(item?.source);
164
+ if (item?.schema !== "supercode/contribution-v1" || typeof item.id !== "string" || !item.id.trim() || typeof item.kind !== "string" || !item.kind.trim() || source === null) return [];
165
+ const data = contributionJson(item.data);
166
+ if (data === void 0) return [];
167
+ return [{
168
+ schema: "supercode/contribution-v1",
169
+ id: boundedString(item.id, 200),
170
+ kind: boundedString(item.kind, 100),
171
+ ...typeof item.title === "string" ? { title: boundedString(item.title, 500) } : {},
172
+ ...placement ? { placement: {
173
+ ...typeof placement.surface === "string" ? { surface: boundedString(placement.surface, 100) } : {},
174
+ ...typeof placement.region === "string" ? { region: boundedString(placement.region, 100) } : {}
175
+ } } : {},
176
+ data,
177
+ source
178
+ }];
179
+ });
180
+ }
181
+ function readAgentPackage(value) {
182
+ const agentPackage = record(value);
183
+ const capabilities = record(agentPackage?.capabilities);
184
+ const storage = record(agentPackage?.storage);
185
+ const relativePath = relativeContributionPath(storage?.relativePath);
186
+ if (agentPackage?.schemaVersion !== 1 || typeof agentPackage.id !== "string" || typeof agentPackage.name !== "string" || typeof agentPackage.version !== "string" || !capabilities || !Array.isArray(capabilities.required) || !Array.isArray(capabilities.optional) || !storage || relativePath === null) return null;
187
+ const resources = record(agentPackage.resources);
188
+ return {
189
+ id: boundedString(agentPackage.id, 200),
190
+ name: boundedString(agentPackage.name, 500),
191
+ version: boundedString(agentPackage.version, 100),
192
+ description: typeof agentPackage.description === "string" ? boundedString(agentPackage.description, 2e3) : null,
193
+ capabilities: {
194
+ required: capabilities.required.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200)),
195
+ optional: capabilities.optional.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
196
+ },
197
+ storage: { relativePath },
198
+ resources: resources ? Object.fromEntries(Object.entries(resources).flatMap(([id, candidate]) => {
199
+ const state = record(candidate);
200
+ if (state?.schema !== "supercode/package-resource-state-v1") return [];
201
+ if (state.status === "absent" && typeof state.contributionId === "string") {
202
+ return [[boundedString(id, 200), {
203
+ schema: "supercode/package-resource-state-v1",
204
+ status: "absent",
205
+ contributionId: boundedString(state.contributionId, 200)
206
+ }]];
207
+ }
208
+ if (state.status === "error" && typeof state.contributionId === "string" && typeof state.message === "string") {
209
+ return [[boundedString(id, 200), {
210
+ schema: "supercode/package-resource-state-v1",
211
+ status: "error",
212
+ contributionId: boundedString(state.contributionId, 200),
213
+ message: boundedString(state.message)
214
+ }]];
215
+ }
216
+ const resource = record(state?.resource);
217
+ const data = contributionJson(resource?.data);
218
+ if (state?.status !== "ready" || resource?.schema !== "supercode/package-resource-v1" || typeof resource.contributionId !== "string" || !["json", "text"].includes(resource.format) || typeof resource.mediaType !== "string" || data === void 0) return [];
219
+ return [[boundedString(id, 200), {
220
+ schema: "supercode/package-resource-state-v1",
221
+ status: "ready",
222
+ resource: {
223
+ schema: "supercode/package-resource-v1",
224
+ contributionId: boundedString(resource.contributionId, 200),
225
+ format: resource.format,
226
+ mediaType: boundedString(resource.mediaType, 200),
227
+ data
228
+ }
229
+ }]];
230
+ })) : {}
231
+ };
232
+ }
233
+ function readAgentPackageCapabilityState(value) {
234
+ const state = record(value);
235
+ if (!state) return null;
236
+ const fields = ["availableRequired", "missingRequired", "enabledOptional", "unavailableOptional"];
237
+ if (!fields.every((field) => Array.isArray(state[field]))) return null;
238
+ return {
239
+ ready: state.ready === true,
240
+ ...Object.fromEntries(fields.map((field) => [
241
+ field,
242
+ state[field].filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
243
+ ]))
244
+ };
245
+ }
117
246
  function relativeAge(updatedAt, now = Date.now()) {
118
247
  if (typeof updatedAt !== "number" || !Number.isFinite(updatedAt) || updatedAt <= 0) return "";
119
248
  const delta = Math.max(0, now - updatedAt);
@@ -831,7 +960,12 @@ function normalizeUiState(value) {
831
960
  subagentInspector: readSubagentInspector(raw.subagentInspector),
832
961
  attached: readAttached(raw.attached),
833
962
  owned: readAttached(raw.owned),
834
- attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null
963
+ attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null,
964
+ agentPackage: readAgentPackage(raw.agentPackage),
965
+ contributions: normalizeContributions(raw.contributions),
966
+ agentPackageError: typeof raw.agentPackageError === "string" ? boundedString(raw.agentPackageError) : null,
967
+ agentPackageCapabilityState: readAgentPackageCapabilityState(raw.agentPackageCapabilityState),
968
+ agentPackageCapabilityError: typeof raw.agentPackageCapabilityError === "string" ? boundedString(raw.agentPackageCapabilityError) : null
835
969
  };
836
970
  }
837
971
  function harnessDisplayName(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter-ai-dev/supercode-ui",
3
- "version": "0.1.66",
3
+ "version": "0.1.67",
4
4
  "type": "module",
5
5
  "description": "Composable default UI kit for Supercode-powered coding-agent experiences",
6
6
  "exports": {
@@ -66,7 +66,12 @@ var EMPTY_UI_STATE = Object.freeze({
66
66
  subagentInspector: null,
67
67
  attached: null,
68
68
  owned: null,
69
- attachError: null
69
+ attachError: null,
70
+ agentPackage: null,
71
+ contributions: Object.freeze([]),
72
+ agentPackageError: null,
73
+ agentPackageCapabilityState: null,
74
+ agentPackageCapabilityError: null
70
75
  });
71
76
  var ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool", "reasoning", "request", "notice"]);
72
77
  var MODES = /* @__PURE__ */ new Set(["none", "control", "mirror"]);
@@ -79,6 +84,10 @@ var AUTHENTICATION_PHASES = /* @__PURE__ */ new Set(["idle", "checking", "requir
79
84
  var MAX_TOOL_FIELDS = 8;
80
85
  var MAX_TOOL_FIELD_CHARS = 800;
81
86
  var MAX_TOOL_PREVIEW_CHARS = 4e3;
87
+ var MAX_CONTRIBUTIONS = 64;
88
+ var MAX_CONTRIBUTION_JSON_DEPTH = 12;
89
+ var MAX_CONTRIBUTION_COLLECTION = 100;
90
+ var MAX_CONTRIBUTION_STRING_CHARS = 16e3;
82
91
  function record(value) {
83
92
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
84
93
  }
@@ -111,6 +120,126 @@ function number(value, fallback = 0) {
111
120
  function nullableNumber(value) {
112
121
  return typeof value === "number" && Number.isFinite(value) ? value : null;
113
122
  }
123
+ function relativeContributionPath(value) {
124
+ if (typeof value !== "string" || value.startsWith("/") || /^[a-z]:[\\/]/i.test(value)) return null;
125
+ return value.replaceAll("\\", "/").split("/").some((segment) => segment === "..") ? null : boundedString(value, 1e3);
126
+ }
127
+ function contributionJson(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
128
+ if (value === null || typeof value === "boolean" || typeof value === "string") {
129
+ return typeof value === "string" ? boundedString(value, MAX_CONTRIBUTION_STRING_CHARS) : value;
130
+ }
131
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
132
+ if (depth >= MAX_CONTRIBUTION_JSON_DEPTH || !value || typeof value !== "object" || seen.has(value)) {
133
+ return void 0;
134
+ }
135
+ seen.add(value);
136
+ if (Array.isArray(value)) {
137
+ const result2 = [];
138
+ for (const item of value.slice(0, MAX_CONTRIBUTION_COLLECTION)) {
139
+ const normalized = contributionJson(item, depth + 1, seen);
140
+ if (normalized !== void 0) result2.push(normalized);
141
+ }
142
+ seen.delete(value);
143
+ return result2;
144
+ }
145
+ const source = record(value);
146
+ if (!source) return void 0;
147
+ const result = {};
148
+ for (const [key, item] of Object.entries(source).slice(0, MAX_CONTRIBUTION_COLLECTION)) {
149
+ const normalized = contributionJson(item, depth + 1, seen);
150
+ if (normalized !== void 0) result[boundedString(key, 200)] = normalized;
151
+ }
152
+ seen.delete(value);
153
+ return result;
154
+ }
155
+ function normalizeContributions(value) {
156
+ if (!Array.isArray(value)) return [];
157
+ return value.slice(0, MAX_CONTRIBUTIONS).flatMap((candidate) => {
158
+ const item = record(candidate);
159
+ const placement = record(item?.placement);
160
+ const source = relativeContributionPath(item?.source);
161
+ if (item?.schema !== "supercode/contribution-v1" || typeof item.id !== "string" || !item.id.trim() || typeof item.kind !== "string" || !item.kind.trim() || source === null) return [];
162
+ const data = contributionJson(item.data);
163
+ if (data === void 0) return [];
164
+ return [{
165
+ schema: "supercode/contribution-v1",
166
+ id: boundedString(item.id, 200),
167
+ kind: boundedString(item.kind, 100),
168
+ ...typeof item.title === "string" ? { title: boundedString(item.title, 500) } : {},
169
+ ...placement ? { placement: {
170
+ ...typeof placement.surface === "string" ? { surface: boundedString(placement.surface, 100) } : {},
171
+ ...typeof placement.region === "string" ? { region: boundedString(placement.region, 100) } : {}
172
+ } } : {},
173
+ data,
174
+ source
175
+ }];
176
+ });
177
+ }
178
+ function readAgentPackage(value) {
179
+ const agentPackage = record(value);
180
+ const capabilities = record(agentPackage?.capabilities);
181
+ const storage = record(agentPackage?.storage);
182
+ const relativePath = relativeContributionPath(storage?.relativePath);
183
+ if (agentPackage?.schemaVersion !== 1 || typeof agentPackage.id !== "string" || typeof agentPackage.name !== "string" || typeof agentPackage.version !== "string" || !capabilities || !Array.isArray(capabilities.required) || !Array.isArray(capabilities.optional) || !storage || relativePath === null) return null;
184
+ const resources = record(agentPackage.resources);
185
+ return {
186
+ id: boundedString(agentPackage.id, 200),
187
+ name: boundedString(agentPackage.name, 500),
188
+ version: boundedString(agentPackage.version, 100),
189
+ description: typeof agentPackage.description === "string" ? boundedString(agentPackage.description, 2e3) : null,
190
+ capabilities: {
191
+ required: capabilities.required.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200)),
192
+ optional: capabilities.optional.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
193
+ },
194
+ storage: { relativePath },
195
+ resources: resources ? Object.fromEntries(Object.entries(resources).flatMap(([id, candidate]) => {
196
+ const state = record(candidate);
197
+ if (state?.schema !== "supercode/package-resource-state-v1") return [];
198
+ if (state.status === "absent" && typeof state.contributionId === "string") {
199
+ return [[boundedString(id, 200), {
200
+ schema: "supercode/package-resource-state-v1",
201
+ status: "absent",
202
+ contributionId: boundedString(state.contributionId, 200)
203
+ }]];
204
+ }
205
+ if (state.status === "error" && typeof state.contributionId === "string" && typeof state.message === "string") {
206
+ return [[boundedString(id, 200), {
207
+ schema: "supercode/package-resource-state-v1",
208
+ status: "error",
209
+ contributionId: boundedString(state.contributionId, 200),
210
+ message: boundedString(state.message)
211
+ }]];
212
+ }
213
+ const resource = record(state?.resource);
214
+ const data = contributionJson(resource?.data);
215
+ if (state?.status !== "ready" || resource?.schema !== "supercode/package-resource-v1" || typeof resource.contributionId !== "string" || !["json", "text"].includes(resource.format) || typeof resource.mediaType !== "string" || data === void 0) return [];
216
+ return [[boundedString(id, 200), {
217
+ schema: "supercode/package-resource-state-v1",
218
+ status: "ready",
219
+ resource: {
220
+ schema: "supercode/package-resource-v1",
221
+ contributionId: boundedString(resource.contributionId, 200),
222
+ format: resource.format,
223
+ mediaType: boundedString(resource.mediaType, 200),
224
+ data
225
+ }
226
+ }]];
227
+ })) : {}
228
+ };
229
+ }
230
+ function readAgentPackageCapabilityState(value) {
231
+ const state = record(value);
232
+ if (!state) return null;
233
+ const fields = ["availableRequired", "missingRequired", "enabledOptional", "unavailableOptional"];
234
+ if (!fields.every((field) => Array.isArray(state[field]))) return null;
235
+ return {
236
+ ready: state.ready === true,
237
+ ...Object.fromEntries(fields.map((field) => [
238
+ field,
239
+ state[field].filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
240
+ ]))
241
+ };
242
+ }
114
243
  function boundedString(value, max = 2e3) {
115
244
  if (typeof value !== "string") return "";
116
245
  return value.length <= max ? value : `${value.slice(0, max)}\u2026`;
@@ -819,7 +948,12 @@ function normalizeUiState(value) {
819
948
  subagentInspector: readSubagentInspector(raw.subagentInspector),
820
949
  attached: readAttached(raw.attached),
821
950
  owned: readAttached(raw.owned),
822
- attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null
951
+ attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null,
952
+ agentPackage: readAgentPackage(raw.agentPackage),
953
+ contributions: normalizeContributions(raw.contributions),
954
+ agentPackageError: typeof raw.agentPackageError === "string" ? boundedString(raw.agentPackageError) : null,
955
+ agentPackageCapabilityState: readAgentPackageCapabilityState(raw.agentPackageCapabilityState),
956
+ agentPackageCapabilityError: typeof raw.agentPackageCapabilityError === "string" ? boundedString(raw.agentPackageCapabilityError) : null
823
957
  };
824
958
  }
825
959
  function harnessDisplayName(id) {