@ariobarin/glossa 0.2.2 → 0.2.3-beta.1
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/dist/app.js +122 -22
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -39380,6 +39380,7 @@ function containsRestrictedAuthenticationData(value) {
|
|
|
39380
39380
|
|
|
39381
39381
|
// ../protocol/dist/index.js
|
|
39382
39382
|
var MAX_TEXT_BYTES = 1024 * 1024;
|
|
39383
|
+
var MAX_IMAGE_BYTES = 4 * 1024 * 1024;
|
|
39383
39384
|
var MAX_EDIT_DIFF_BYTES = 128 * 1024;
|
|
39384
39385
|
var MAX_EDIT_OPERATIONS = 100;
|
|
39385
39386
|
var MAX_COMMAND_OUTPUT_BYTES = 12 * 1024;
|
|
@@ -39428,6 +39429,13 @@ var readFileJobSchema = readFileRequestSchema.extend({
|
|
|
39428
39429
|
type: external_exports.literal("read_file"),
|
|
39429
39430
|
requestId: external_exports.string().uuid()
|
|
39430
39431
|
});
|
|
39432
|
+
var viewImageRequestSchema = external_exports.object({
|
|
39433
|
+
path: relativePathSchema
|
|
39434
|
+
}).strict();
|
|
39435
|
+
var viewImageJobSchema = viewImageRequestSchema.extend({
|
|
39436
|
+
type: external_exports.literal("view_image"),
|
|
39437
|
+
requestId: external_exports.string().uuid()
|
|
39438
|
+
});
|
|
39431
39439
|
var structuredReadTimeoutSchema = external_exports.number().int().min(1).max(MAX_STRUCTURED_READ_TIMEOUT_MS);
|
|
39432
39440
|
var listFilesCursorSchema = external_exports.string().max(4096).describe("Opaque cursor returned by an earlier list_files result.");
|
|
39433
39441
|
var listFilesRequestSchema = external_exports.object({
|
|
@@ -39570,6 +39578,7 @@ var cancelCommandJobSchema = cancelCommandRequestSchema.extend({
|
|
|
39570
39578
|
});
|
|
39571
39579
|
var workerJobSchema = external_exports.discriminatedUnion("type", [
|
|
39572
39580
|
readFileJobSchema,
|
|
39581
|
+
viewImageJobSchema,
|
|
39573
39582
|
listFilesJobSchema,
|
|
39574
39583
|
searchTextJobSchema,
|
|
39575
39584
|
readFileRangeJobSchema,
|
|
@@ -50491,6 +50500,18 @@ var PathPolicy = class _PathPolicy {
|
|
|
50491
50500
|
function sha256(content) {
|
|
50492
50501
|
return createHash("sha256").update(content).digest("hex");
|
|
50493
50502
|
}
|
|
50503
|
+
function imageMimeType(content) {
|
|
50504
|
+
if (content.byteLength >= 8 && content[0] === 137 && content[1] === 80 && content[2] === 78 && content[3] === 71 && content[4] === 13 && content[5] === 10 && content[6] === 26 && content[7] === 10) {
|
|
50505
|
+
return "image/png";
|
|
50506
|
+
}
|
|
50507
|
+
if (content.byteLength >= 3 && content[0] === 255 && content[1] === 216 && content[2] === 255) {
|
|
50508
|
+
return "image/jpeg";
|
|
50509
|
+
}
|
|
50510
|
+
if (content.byteLength >= 12 && content[0] === 82 && content[1] === 73 && content[2] === 70 && content[3] === 70 && content[8] === 87 && content[9] === 69 && content[10] === 66 && content[11] === 80) {
|
|
50511
|
+
return "image/webp";
|
|
50512
|
+
}
|
|
50513
|
+
return void 0;
|
|
50514
|
+
}
|
|
50494
50515
|
function isPathWithin(root, candidate) {
|
|
50495
50516
|
const relative = path7.relative(root, candidate);
|
|
50496
50517
|
return relative === "" || !relative.startsWith(`..${path7.sep}`) && relative !== ".." && !path7.isAbsolute(relative);
|
|
@@ -50898,6 +50919,43 @@ var FileService = class {
|
|
|
50898
50919
|
const target = await this.policy.resolveExisting(relativePath);
|
|
50899
50920
|
return await this.#readResolvedText(target);
|
|
50900
50921
|
}
|
|
50922
|
+
async readImage(relativePath) {
|
|
50923
|
+
const target = await this.policy.resolveExisting(relativePath);
|
|
50924
|
+
const targetStat = await stat3(target);
|
|
50925
|
+
if (!targetStat.isFile()) {
|
|
50926
|
+
throw new WorkerError("not_file", "The requested path is not a file.");
|
|
50927
|
+
}
|
|
50928
|
+
if (targetStat.size > MAX_IMAGE_BYTES) {
|
|
50929
|
+
throw new WorkerError(
|
|
50930
|
+
"image_too_large",
|
|
50931
|
+
"The image exceeds the 4 MiB image limit."
|
|
50932
|
+
);
|
|
50933
|
+
}
|
|
50934
|
+
const content = await this.#readFileBytes(
|
|
50935
|
+
target,
|
|
50936
|
+
MAX_IMAGE_BYTES,
|
|
50937
|
+
targetStat.size
|
|
50938
|
+
);
|
|
50939
|
+
if (content.byteLength > MAX_IMAGE_BYTES) {
|
|
50940
|
+
throw new WorkerError(
|
|
50941
|
+
"image_too_large",
|
|
50942
|
+
"The image exceeds the 4 MiB image limit."
|
|
50943
|
+
);
|
|
50944
|
+
}
|
|
50945
|
+
const mimeType = imageMimeType(content);
|
|
50946
|
+
if (!mimeType) {
|
|
50947
|
+
throw new WorkerError(
|
|
50948
|
+
"unsupported_image",
|
|
50949
|
+
"Only PNG, JPEG, and WebP images are supported."
|
|
50950
|
+
);
|
|
50951
|
+
}
|
|
50952
|
+
return {
|
|
50953
|
+
data: content.toString("base64"),
|
|
50954
|
+
mimeType,
|
|
50955
|
+
sha256: sha256(content),
|
|
50956
|
+
bytes: content.byteLength
|
|
50957
|
+
};
|
|
50958
|
+
}
|
|
50901
50959
|
async listFiles(options = {}) {
|
|
50902
50960
|
const deadlineAt = this.#scanDeadline(options.timeoutMs);
|
|
50903
50961
|
const startPath = options.path ?? ".";
|
|
@@ -51589,6 +51647,7 @@ function restrictedDataError2() {
|
|
|
51589
51647
|
function jobInputContainsRestrictedData(job) {
|
|
51590
51648
|
switch (job.type) {
|
|
51591
51649
|
case "read_file":
|
|
51650
|
+
case "view_image":
|
|
51592
51651
|
return containsRestrictedAuthenticationData(job.path);
|
|
51593
51652
|
case "list_files":
|
|
51594
51653
|
return containsRestrictedAuthenticationData({
|
|
@@ -51679,6 +51738,9 @@ var LocalWorker = class _LocalWorker {
|
|
|
51679
51738
|
case "read_file":
|
|
51680
51739
|
value = await this.files.readText(job.path);
|
|
51681
51740
|
break;
|
|
51741
|
+
case "view_image":
|
|
51742
|
+
value = await this.files.readImage(job.path);
|
|
51743
|
+
break;
|
|
51682
51744
|
case "list_files":
|
|
51683
51745
|
value = await this.files.listFiles({
|
|
51684
51746
|
...job.path ? { path: job.path } : {},
|
|
@@ -51792,13 +51854,17 @@ var DEFAULT_HEARTBEAT_MS = 15e3;
|
|
|
51792
51854
|
var CAPACITY_REFRESH_POLL_MS = 1;
|
|
51793
51855
|
var MAX_CONCURRENT_JOBS = 5;
|
|
51794
51856
|
var WORKER_TOKEN_PATTERN = /^glw_[A-Za-z0-9_-]{43}$/;
|
|
51795
|
-
var
|
|
51857
|
+
var LEGACY_WORKER_CAPABILITIES = {
|
|
51796
51858
|
commandProgress: true,
|
|
51797
51859
|
concurrentJobs: true,
|
|
51798
51860
|
structuredReads: true,
|
|
51799
51861
|
structuredMutations: true,
|
|
51800
51862
|
commandOutputRanges: true
|
|
51801
51863
|
};
|
|
51864
|
+
var WORKER_CAPABILITIES = {
|
|
51865
|
+
...LEGACY_WORKER_CAPABILITIES,
|
|
51866
|
+
imageReads: true
|
|
51867
|
+
};
|
|
51802
51868
|
var DeviceRejectedError = class extends Error {
|
|
51803
51869
|
constructor() {
|
|
51804
51870
|
super("The relay rejected the device credential.");
|
|
@@ -51827,14 +51893,18 @@ function requiredWorkerToken(value) {
|
|
|
51827
51893
|
}
|
|
51828
51894
|
return value;
|
|
51829
51895
|
}
|
|
51830
|
-
function
|
|
51896
|
+
function acceptsCapabilities(value, requireImageReads) {
|
|
51831
51897
|
if (typeof value !== "object" || value === null) return false;
|
|
51832
51898
|
if (!("capabilities" in value)) return false;
|
|
51833
51899
|
const capabilities = value.capabilities;
|
|
51834
51900
|
if (typeof capabilities !== "object" || capabilities === null) return false;
|
|
51835
|
-
|
|
51901
|
+
const required2 = Object.keys(LEGACY_WORKER_CAPABILITIES);
|
|
51902
|
+
if (!required2.every(
|
|
51836
51903
|
(capability) => capabilities[capability] === true
|
|
51837
|
-
)
|
|
51904
|
+
)) {
|
|
51905
|
+
return false;
|
|
51906
|
+
}
|
|
51907
|
+
return !requireImageReads || capabilities.imageReads === true;
|
|
51838
51908
|
}
|
|
51839
51909
|
function jobLane(job) {
|
|
51840
51910
|
switch (job.type) {
|
|
@@ -51844,6 +51914,7 @@ function jobLane(job) {
|
|
|
51844
51914
|
case "cancel_command":
|
|
51845
51915
|
return "cancel";
|
|
51846
51916
|
case "read_file":
|
|
51917
|
+
case "view_image":
|
|
51847
51918
|
case "list_files":
|
|
51848
51919
|
case "search_text":
|
|
51849
51920
|
case "read_file_range":
|
|
@@ -51857,7 +51928,7 @@ function jobLane(job) {
|
|
|
51857
51928
|
return "mutation";
|
|
51858
51929
|
}
|
|
51859
51930
|
}
|
|
51860
|
-
function acceptedJobTypes(counts, total) {
|
|
51931
|
+
function acceptedJobTypes(counts, total, imageReads) {
|
|
51861
51932
|
if (total >= MAX_CONCURRENT_JOBS) return [];
|
|
51862
51933
|
const accepted = [];
|
|
51863
51934
|
if (counts.status < 1) {
|
|
@@ -51865,7 +51936,9 @@ function acceptedJobTypes(counts, total) {
|
|
|
51865
51936
|
}
|
|
51866
51937
|
if (counts.cancel < 1) accepted.push("cancel_command");
|
|
51867
51938
|
if (counts.read < 2) {
|
|
51868
|
-
accepted.push("read_file"
|
|
51939
|
+
accepted.push("read_file");
|
|
51940
|
+
if (imageReads) accepted.push("view_image");
|
|
51941
|
+
accepted.push("list_files", "search_text", "read_file_range");
|
|
51869
51942
|
}
|
|
51870
51943
|
if (counts.mutation < 1) {
|
|
51871
51944
|
accepted.push(
|
|
@@ -51979,28 +52052,45 @@ var RemoteWorker = class {
|
|
|
51979
52052
|
}
|
|
51980
52053
|
}
|
|
51981
52054
|
async #register() {
|
|
52055
|
+
const registrationBody = (capabilities) => ({
|
|
52056
|
+
workerId: this.#workerId,
|
|
52057
|
+
accessProfile: this.#accessProfile,
|
|
52058
|
+
...this.#workerVersion ? { workerVersion: this.#workerVersion } : {},
|
|
52059
|
+
...this.#workspaceLabel ? { workspaceLabel: this.#workspaceLabel } : {},
|
|
52060
|
+
capabilities
|
|
52061
|
+
});
|
|
51982
52062
|
let response;
|
|
52063
|
+
let imageReads = true;
|
|
51983
52064
|
try {
|
|
51984
|
-
response = await this.#post(
|
|
51985
|
-
|
|
51986
|
-
|
|
51987
|
-
|
|
51988
|
-
...this.#workspaceLabel ? { workspaceLabel: this.#workspaceLabel } : {},
|
|
51989
|
-
capabilities: WORKER_CAPABILITIES
|
|
51990
|
-
});
|
|
52065
|
+
response = await this.#post(
|
|
52066
|
+
"/device/register",
|
|
52067
|
+
registrationBody(WORKER_CAPABILITIES)
|
|
52068
|
+
);
|
|
51991
52069
|
} catch (error46) {
|
|
51992
|
-
if (error46 instanceof RelayResponseError
|
|
51993
|
-
throw
|
|
52070
|
+
if (!(error46 instanceof RelayResponseError) || error46.status !== 400) {
|
|
52071
|
+
throw error46;
|
|
52072
|
+
}
|
|
52073
|
+
imageReads = false;
|
|
52074
|
+
try {
|
|
52075
|
+
response = await this.#post(
|
|
52076
|
+
"/device/register",
|
|
52077
|
+
registrationBody(LEGACY_WORKER_CAPABILITIES)
|
|
52078
|
+
);
|
|
52079
|
+
} catch (legacyError) {
|
|
52080
|
+
if (legacyError instanceof RelayResponseError && legacyError.status === 400) {
|
|
52081
|
+
throw new RelayProtocolUnsupportedError();
|
|
52082
|
+
}
|
|
52083
|
+
throw legacyError;
|
|
51994
52084
|
}
|
|
51995
|
-
throw error46;
|
|
51996
52085
|
}
|
|
51997
52086
|
const value = await response.json();
|
|
51998
|
-
if (typeof value !== "object" || value === null || !("generation" in value) || typeof value.generation !== "string" || !("workerId" in value) || value.workerId !== this.#workerId || !("workerToken" in value) || !("accessProfile" in value) || value.accessProfile !== this.#accessProfile || !
|
|
52087
|
+
if (typeof value !== "object" || value === null || !("generation" in value) || typeof value.generation !== "string" || !("workerId" in value) || value.workerId !== this.#workerId || !("workerToken" in value) || !("accessProfile" in value) || value.accessProfile !== this.#accessProfile || !acceptsCapabilities(value, imageReads) || this.#workspaceLabel !== void 0 && (!("workspaceLabel" in value) || value.workspaceLabel !== this.#workspaceLabel)) {
|
|
51999
52088
|
throw new RelayProtocolUnsupportedError();
|
|
52000
52089
|
}
|
|
52001
52090
|
return {
|
|
52002
52091
|
generation: value.generation,
|
|
52003
|
-
workerToken: requiredWorkerToken(value.workerToken)
|
|
52092
|
+
workerToken: requiredWorkerToken(value.workerToken),
|
|
52093
|
+
imageReads
|
|
52004
52094
|
};
|
|
52005
52095
|
}
|
|
52006
52096
|
async #pollGeneration(session) {
|
|
@@ -52076,7 +52166,11 @@ var RemoteWorker = class {
|
|
|
52076
52166
|
try {
|
|
52077
52167
|
while (!this.#signal.aborted) {
|
|
52078
52168
|
if (failure !== void 0) throw failure;
|
|
52079
|
-
const acceptedTypes = acceptedJobTypes(
|
|
52169
|
+
const acceptedTypes = acceptedJobTypes(
|
|
52170
|
+
counts,
|
|
52171
|
+
inFlight.size,
|
|
52172
|
+
session.imageReads
|
|
52173
|
+
);
|
|
52080
52174
|
if (acceptedTypes.length === 0) {
|
|
52081
52175
|
await Promise.race(inFlight);
|
|
52082
52176
|
continue;
|
|
@@ -52102,7 +52196,11 @@ var RemoteWorker = class {
|
|
|
52102
52196
|
}
|
|
52103
52197
|
if (failure !== void 0) throw failure;
|
|
52104
52198
|
observedCapacityVersion = capacityVersion;
|
|
52105
|
-
const refreshedTypes = acceptedJobTypes(
|
|
52199
|
+
const refreshedTypes = acceptedJobTypes(
|
|
52200
|
+
counts,
|
|
52201
|
+
inFlight.size,
|
|
52202
|
+
session.imageReads
|
|
52203
|
+
);
|
|
52106
52204
|
const newlyAcceptedTypes = refreshedTypes.filter(
|
|
52107
52205
|
(type) => !acceptedTypes.includes(type)
|
|
52108
52206
|
);
|
|
@@ -52221,6 +52319,7 @@ function activitySafeJob(job) {
|
|
|
52221
52319
|
if (!containsRestrictedAuthenticationData(job)) return job;
|
|
52222
52320
|
switch (job.type) {
|
|
52223
52321
|
case "read_file":
|
|
52322
|
+
case "view_image":
|
|
52224
52323
|
return { ...job, path: "[restricted input blocked]" };
|
|
52225
52324
|
case "list_files":
|
|
52226
52325
|
return {
|
|
@@ -52484,7 +52583,7 @@ function initialHudState(workspace) {
|
|
|
52484
52583
|
notice: void 0
|
|
52485
52584
|
};
|
|
52486
52585
|
}
|
|
52487
|
-
var MAX_STORED_ACTIVITIES =
|
|
52586
|
+
var MAX_STORED_ACTIVITIES = 9999;
|
|
52488
52587
|
var MAX_STORED_ACTIVITY_TARGET_CHARS = 512;
|
|
52489
52588
|
function truncate(value, width) {
|
|
52490
52589
|
if (width <= 0) return "";
|
|
@@ -52561,6 +52660,7 @@ function assertNever2(_value) {
|
|
|
52561
52660
|
function summarizeJob(job) {
|
|
52562
52661
|
switch (job.type) {
|
|
52563
52662
|
case "read_file":
|
|
52663
|
+
case "view_image":
|
|
52564
52664
|
return pathSummary(job.path);
|
|
52565
52665
|
case "list_files":
|
|
52566
52666
|
return pathSummary(workspacePath(job.path), [
|
|
@@ -54127,7 +54227,7 @@ async function acquireWorkspaceLease(root, options = {}) {
|
|
|
54127
54227
|
}
|
|
54128
54228
|
|
|
54129
54229
|
// src/main.ts
|
|
54130
|
-
var VERSION = "0.2.
|
|
54230
|
+
var VERSION = "0.2.3-beta.1";
|
|
54131
54231
|
var DISTRIBUTION = "npm";
|
|
54132
54232
|
var HELP = `Glossa ${VERSION}
|
|
54133
54233
|
|