@volter-ai-dev/supercode-ui 0.1.65 → 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/README.md +5 -0
- package/activity.mjs +136 -2
- package/components.mjs +136 -2
- package/composer.mjs +6 -1
- package/controller.mjs +5 -0
- package/conversation.mjs +6 -1
- package/core.d.ts +7 -0
- package/core.mjs +175 -0
- package/embed.mjs +136 -2
- package/host.d.ts +29 -0
- package/host.mjs +128 -5
- package/index.d.ts +56 -0
- package/messenger.mjs +136 -2
- package/package.json +1 -1
- package/react/activity.mjs +136 -2
- package/react/components.mjs +136 -2
- package/react/composer.mjs +6 -1
- package/react/conversation.mjs +6 -1
- package/react/messenger.mjs +136 -2
- package/react/sessions.mjs +6 -1
- package/react/settings.mjs +6 -1
- package/react/subagents.mjs +6 -1
- package/sessions.mjs +6 -1
- package/settings.mjs +6 -1
- package/subagents.mjs +6 -1
package/README.md
CHANGED
|
@@ -243,6 +243,11 @@ heartbeat churn, treats compaction as a new baseline, and returns the delay for
|
|
|
243
243
|
settlement timer. This keeps unread and finished semantics identical in an editor, extension,
|
|
244
244
|
desktop app, or mobile companion without moving file persistence into the UI package.
|
|
245
245
|
|
|
246
|
+
`createNativeMessengerState` wraps that ledger with bounded per-conversation drafts and per-harness
|
|
247
|
+
Terminal/Headless preferences. It emits one serializable snapshot, so native hosts do not need to
|
|
248
|
+
duplicate state parsing or coordinate several independent maps. The host still owns where that
|
|
249
|
+
snapshot is stored, its debounce and encryption policy, and any multi-device synchronization.
|
|
250
|
+
|
|
246
251
|
Native continuation exposes one action and a quiet execution-transport selector. A host with a real
|
|
247
252
|
terminal provider can add `terminal` to `continuationModes` and handle `onResumeTerminal`; Terminal
|
|
248
253
|
is then the initial choice and Headless remains available from the selector. The UI never infers
|
package/activity.mjs
CHANGED
|
@@ -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) {
|
package/components.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/composer.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
|
function harnessDisplayName(id) {
|
|
75
80
|
return HARNESS_NAMES[id] ?? id;
|
package/controller.mjs
CHANGED
|
@@ -608,6 +608,11 @@ function projectClientSnapshotInternal(snapshot, options, imageRegistry) {
|
|
|
608
608
|
reductionReceipt: options.reductionReceipt ?? snapshot.reductionReceipt ?? null,
|
|
609
609
|
interopSettings: snapshot.interopSettings ?? null,
|
|
610
610
|
interopSettingsError: snapshot.interopSettingsError ?? null,
|
|
611
|
+
agentPackage: snapshot.agentPackage ?? null,
|
|
612
|
+
contributions: snapshot.agentPackage?.contributions ?? [],
|
|
613
|
+
agentPackageError: snapshot.agentPackageError ?? null,
|
|
614
|
+
agentPackageCapabilityState: snapshot.agentPackageCapabilityState ?? null,
|
|
615
|
+
agentPackageCapabilityError: snapshot.agentPackageCapabilityError ?? null,
|
|
611
616
|
error: snapshot.error?.message ?? null,
|
|
612
617
|
recoverable: snapshot.error?.recoverable === true,
|
|
613
618
|
harnesses: (snapshot.harnesses ?? []).map((harness) => ({
|
package/conversation.mjs
CHANGED
|
@@ -70,7 +70,12 @@ var EMPTY_UI_STATE = Object.freeze({
|
|
|
70
70
|
subagentInspector: null,
|
|
71
71
|
attached: null,
|
|
72
72
|
owned: null,
|
|
73
|
-
attachError: null
|
|
73
|
+
attachError: null,
|
|
74
|
+
agentPackage: null,
|
|
75
|
+
contributions: Object.freeze([]),
|
|
76
|
+
agentPackageError: null,
|
|
77
|
+
agentPackageCapabilityState: null,
|
|
78
|
+
agentPackageCapabilityError: null
|
|
74
79
|
});
|
|
75
80
|
var TOOL_CATEGORIES = /* @__PURE__ */ new Set(["read", "search", "edit", "command", "test", "web", "agent", "plan", "other"]);
|
|
76
81
|
var MAX_TOOL_FIELDS = 8;
|
package/core.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
AttachedSessionModel,
|
|
3
3
|
AgentActivityModel,
|
|
4
|
+
AgentContributionModel,
|
|
5
|
+
AgentPackageModel,
|
|
6
|
+
AgentPackageResourceModel,
|
|
7
|
+
AgentPackageResourceStateModel,
|
|
8
|
+
AgentPackageCapabilityStateModel,
|
|
4
9
|
ContinuationMode,
|
|
5
10
|
ControlStrategy,
|
|
6
11
|
HarnessId,
|
|
@@ -36,6 +41,7 @@ export {
|
|
|
36
41
|
groupConversation,
|
|
37
42
|
harnessDisplayName,
|
|
38
43
|
isSendKey,
|
|
44
|
+
normalizeContributions,
|
|
39
45
|
normalizeUiState,
|
|
40
46
|
operationLabel,
|
|
41
47
|
projectAgentActivity,
|
|
@@ -43,6 +49,7 @@ export {
|
|
|
43
49
|
relativeAge,
|
|
44
50
|
sessionActivity,
|
|
45
51
|
sessionDisplayName,
|
|
52
|
+
selectContributions,
|
|
46
53
|
terminalCommand,
|
|
47
54
|
toolCategory,
|
|
48
55
|
toolTarget,
|
package/core.mjs
CHANGED
|
@@ -68,6 +68,11 @@ export const EMPTY_UI_STATE = Object.freeze({
|
|
|
68
68
|
attached: null,
|
|
69
69
|
owned: null,
|
|
70
70
|
attachError: null,
|
|
71
|
+
agentPackage: null,
|
|
72
|
+
contributions: Object.freeze([]),
|
|
73
|
+
agentPackageError: null,
|
|
74
|
+
agentPackageCapabilityState: null,
|
|
75
|
+
agentPackageCapabilityError: null,
|
|
71
76
|
});
|
|
72
77
|
|
|
73
78
|
const ROLES = new Set(['system', 'user', 'assistant', 'tool', 'reasoning', 'request', 'notice']);
|
|
@@ -81,6 +86,10 @@ const AUTHENTICATION_PHASES = new Set(['idle', 'checking', 'required', 'configur
|
|
|
81
86
|
const MAX_TOOL_FIELDS = 8;
|
|
82
87
|
const MAX_TOOL_FIELD_CHARS = 800;
|
|
83
88
|
const MAX_TOOL_PREVIEW_CHARS = 4_000;
|
|
89
|
+
const MAX_CONTRIBUTIONS = 64;
|
|
90
|
+
const MAX_CONTRIBUTION_JSON_DEPTH = 12;
|
|
91
|
+
const MAX_CONTRIBUTION_COLLECTION = 100;
|
|
92
|
+
const MAX_CONTRIBUTION_STRING_CHARS = 16_000;
|
|
84
93
|
|
|
85
94
|
function record(value) {
|
|
86
95
|
return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
@@ -121,6 +130,165 @@ function nullableNumber(value) {
|
|
|
121
130
|
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
122
131
|
}
|
|
123
132
|
|
|
133
|
+
function relativeContributionPath(value) {
|
|
134
|
+
if (typeof value !== 'string' || value.startsWith('/') || /^[a-z]:[\\/]/i.test(value)) return null;
|
|
135
|
+
return value.replaceAll('\\', '/').split('/').some((segment) => segment === '..')
|
|
136
|
+
? null
|
|
137
|
+
: boundedString(value, 1_000);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function contributionJson(value, depth = 0, seen = new WeakSet()) {
|
|
141
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'string') {
|
|
142
|
+
return typeof value === 'string' ? boundedString(value, MAX_CONTRIBUTION_STRING_CHARS) : value;
|
|
143
|
+
}
|
|
144
|
+
if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;
|
|
145
|
+
if (depth >= MAX_CONTRIBUTION_JSON_DEPTH || !value || typeof value !== 'object' || seen.has(value)) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
seen.add(value);
|
|
149
|
+
if (Array.isArray(value)) {
|
|
150
|
+
const result = [];
|
|
151
|
+
for (const item of value.slice(0, MAX_CONTRIBUTION_COLLECTION)) {
|
|
152
|
+
const normalized = contributionJson(item, depth + 1, seen);
|
|
153
|
+
if (normalized !== undefined) result.push(normalized);
|
|
154
|
+
}
|
|
155
|
+
seen.delete(value);
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
const source = record(value);
|
|
159
|
+
if (!source) return undefined;
|
|
160
|
+
const result = {};
|
|
161
|
+
for (const [key, item] of Object.entries(source).slice(0, MAX_CONTRIBUTION_COLLECTION)) {
|
|
162
|
+
const normalized = contributionJson(item, depth + 1, seen);
|
|
163
|
+
if (normalized !== undefined) result[boundedString(key, 200)] = normalized;
|
|
164
|
+
}
|
|
165
|
+
seen.delete(value);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function normalizeContributions(value) {
|
|
170
|
+
if (!Array.isArray(value)) return [];
|
|
171
|
+
return value.slice(0, MAX_CONTRIBUTIONS).flatMap((candidate) => {
|
|
172
|
+
const item = record(candidate);
|
|
173
|
+
const placement = record(item?.placement);
|
|
174
|
+
const source = relativeContributionPath(item?.source);
|
|
175
|
+
if (
|
|
176
|
+
item?.schema !== 'supercode/contribution-v1' ||
|
|
177
|
+
typeof item.id !== 'string' || !item.id.trim() ||
|
|
178
|
+
typeof item.kind !== 'string' || !item.kind.trim() ||
|
|
179
|
+
source === null
|
|
180
|
+
) return [];
|
|
181
|
+
const data = contributionJson(item.data);
|
|
182
|
+
if (data === undefined) return [];
|
|
183
|
+
return [{
|
|
184
|
+
schema: 'supercode/contribution-v1',
|
|
185
|
+
id: boundedString(item.id, 200),
|
|
186
|
+
kind: boundedString(item.kind, 100),
|
|
187
|
+
...(typeof item.title === 'string' ? { title: boundedString(item.title, 500) } : {}),
|
|
188
|
+
...(placement ? { placement: {
|
|
189
|
+
...(typeof placement.surface === 'string' ? { surface: boundedString(placement.surface, 100) } : {}),
|
|
190
|
+
...(typeof placement.region === 'string' ? { region: boundedString(placement.region, 100) } : {}),
|
|
191
|
+
} } : {}),
|
|
192
|
+
data,
|
|
193
|
+
source,
|
|
194
|
+
}];
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function selectContributions(contributions, query = {}) {
|
|
199
|
+
return normalizeContributions(contributions).filter((contribution) => (
|
|
200
|
+
(query.kind === undefined || contribution.kind === query.kind) &&
|
|
201
|
+
(query.surface === undefined || contribution.placement?.surface === query.surface) &&
|
|
202
|
+
(query.region === undefined || contribution.placement?.region === query.region)
|
|
203
|
+
));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function readAgentPackage(value) {
|
|
207
|
+
const agentPackage = record(value);
|
|
208
|
+
const capabilities = record(agentPackage?.capabilities);
|
|
209
|
+
const storage = record(agentPackage?.storage);
|
|
210
|
+
const relativePath = relativeContributionPath(storage?.relativePath);
|
|
211
|
+
if (
|
|
212
|
+
agentPackage?.schemaVersion !== 1 ||
|
|
213
|
+
typeof agentPackage.id !== 'string' ||
|
|
214
|
+
typeof agentPackage.name !== 'string' ||
|
|
215
|
+
typeof agentPackage.version !== 'string' ||
|
|
216
|
+
!capabilities ||
|
|
217
|
+
!Array.isArray(capabilities.required) ||
|
|
218
|
+
!Array.isArray(capabilities.optional) ||
|
|
219
|
+
!storage ||
|
|
220
|
+
relativePath === null
|
|
221
|
+
) return null;
|
|
222
|
+
const resources = record(agentPackage.resources);
|
|
223
|
+
return {
|
|
224
|
+
id: boundedString(agentPackage.id, 200),
|
|
225
|
+
name: boundedString(agentPackage.name, 500),
|
|
226
|
+
version: boundedString(agentPackage.version, 100),
|
|
227
|
+
description: typeof agentPackage.description === 'string'
|
|
228
|
+
? boundedString(agentPackage.description, 2_000)
|
|
229
|
+
: null,
|
|
230
|
+
capabilities: {
|
|
231
|
+
required: capabilities.required.filter((item) => typeof item === 'string').slice(0, 100).map((item) => boundedString(item, 200)),
|
|
232
|
+
optional: capabilities.optional.filter((item) => typeof item === 'string').slice(0, 100).map((item) => boundedString(item, 200)),
|
|
233
|
+
},
|
|
234
|
+
storage: { relativePath },
|
|
235
|
+
resources: resources ? Object.fromEntries(Object.entries(resources).flatMap(([id, candidate]) => {
|
|
236
|
+
const state = record(candidate);
|
|
237
|
+
if (state?.schema !== 'supercode/package-resource-state-v1') return [];
|
|
238
|
+
if (state.status === 'absent' && typeof state.contributionId === 'string') {
|
|
239
|
+
return [[boundedString(id, 200), {
|
|
240
|
+
schema: 'supercode/package-resource-state-v1',
|
|
241
|
+
status: 'absent',
|
|
242
|
+
contributionId: boundedString(state.contributionId, 200),
|
|
243
|
+
}]];
|
|
244
|
+
}
|
|
245
|
+
if (state.status === 'error' && typeof state.contributionId === 'string' && typeof state.message === 'string') {
|
|
246
|
+
return [[boundedString(id, 200), {
|
|
247
|
+
schema: 'supercode/package-resource-state-v1',
|
|
248
|
+
status: 'error',
|
|
249
|
+
contributionId: boundedString(state.contributionId, 200),
|
|
250
|
+
message: boundedString(state.message),
|
|
251
|
+
}]];
|
|
252
|
+
}
|
|
253
|
+
const resource = record(state?.resource);
|
|
254
|
+
const data = contributionJson(resource?.data);
|
|
255
|
+
if (
|
|
256
|
+
state?.status !== 'ready' ||
|
|
257
|
+
resource?.schema !== 'supercode/package-resource-v1' ||
|
|
258
|
+
typeof resource.contributionId !== 'string' ||
|
|
259
|
+
!['json', 'text'].includes(resource.format) ||
|
|
260
|
+
typeof resource.mediaType !== 'string' ||
|
|
261
|
+
data === undefined
|
|
262
|
+
) return [];
|
|
263
|
+
return [[boundedString(id, 200), {
|
|
264
|
+
schema: 'supercode/package-resource-state-v1',
|
|
265
|
+
status: 'ready',
|
|
266
|
+
resource: {
|
|
267
|
+
schema: 'supercode/package-resource-v1',
|
|
268
|
+
contributionId: boundedString(resource.contributionId, 200),
|
|
269
|
+
format: resource.format,
|
|
270
|
+
mediaType: boundedString(resource.mediaType, 200),
|
|
271
|
+
data,
|
|
272
|
+
},
|
|
273
|
+
}]];
|
|
274
|
+
})) : {},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function readAgentPackageCapabilityState(value) {
|
|
279
|
+
const state = record(value);
|
|
280
|
+
if (!state) return null;
|
|
281
|
+
const fields = ['availableRequired', 'missingRequired', 'enabledOptional', 'unavailableOptional'];
|
|
282
|
+
if (!fields.every((field) => Array.isArray(state[field]))) return null;
|
|
283
|
+
return {
|
|
284
|
+
ready: state.ready === true,
|
|
285
|
+
...Object.fromEntries(fields.map((field) => [
|
|
286
|
+
field,
|
|
287
|
+
state[field].filter((item) => typeof item === 'string').slice(0, 100).map((item) => boundedString(item, 200)),
|
|
288
|
+
])),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
124
292
|
export function relativeAge(updatedAt, now = Date.now()) {
|
|
125
293
|
if (typeof updatedAt !== 'number' || !Number.isFinite(updatedAt) || updatedAt <= 0) return '';
|
|
126
294
|
const delta = Math.max(0, now - updatedAt);
|
|
@@ -896,6 +1064,13 @@ export function normalizeUiState(value) {
|
|
|
896
1064
|
attached: readAttached(raw.attached),
|
|
897
1065
|
owned: readAttached(raw.owned),
|
|
898
1066
|
attachError: attachError && typeof attachError.key === 'string' && typeof attachError.message === 'string' ? { key: attachError.key, message: attachError.message } : null,
|
|
1067
|
+
agentPackage: readAgentPackage(raw.agentPackage),
|
|
1068
|
+
contributions: normalizeContributions(raw.contributions),
|
|
1069
|
+
agentPackageError: typeof raw.agentPackageError === 'string' ? boundedString(raw.agentPackageError) : null,
|
|
1070
|
+
agentPackageCapabilityState: readAgentPackageCapabilityState(raw.agentPackageCapabilityState),
|
|
1071
|
+
agentPackageCapabilityError: typeof raw.agentPackageCapabilityError === 'string'
|
|
1072
|
+
? boundedString(raw.agentPackageCapabilityError)
|
|
1073
|
+
: null,
|
|
899
1074
|
};
|
|
900
1075
|
}
|
|
901
1076
|
|