@clawos-dev/clawd 0.2.102-beta.197.08025e2 → 0.2.103-beta.198.c756b33
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/cli.cjs +69 -22
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -5367,6 +5367,20 @@ var init_received_capability = __esm({
|
|
|
5367
5367
|
});
|
|
5368
5368
|
|
|
5369
5369
|
// ../protocol/src/extension.ts
|
|
5370
|
+
function isAllowedHostedUrl(raw) {
|
|
5371
|
+
let u;
|
|
5372
|
+
try {
|
|
5373
|
+
u = new URL(raw);
|
|
5374
|
+
} catch {
|
|
5375
|
+
return false;
|
|
5376
|
+
}
|
|
5377
|
+
if (u.protocol === "https:") return true;
|
|
5378
|
+
if (u.protocol === "http:" && LOCALHOST_HOSTS.has(u.hostname)) return true;
|
|
5379
|
+
return false;
|
|
5380
|
+
}
|
|
5381
|
+
function manifestMode(m2) {
|
|
5382
|
+
return m2.entry?.url ? "hosted" : "local";
|
|
5383
|
+
}
|
|
5370
5384
|
function ownerNamespace(ownerPrincipalId) {
|
|
5371
5385
|
let h = 2166136261;
|
|
5372
5386
|
for (let i = 0; i < ownerPrincipalId.length; i++) {
|
|
@@ -5408,7 +5422,7 @@ function parseOrThrow(v2) {
|
|
|
5408
5422
|
const [a, b2, c] = v2.split(".").map((p2) => parseInt(p2, 10));
|
|
5409
5423
|
return [a, b2, c];
|
|
5410
5424
|
}
|
|
5411
|
-
var EXT_ID_REGEX, ExtensionStateSchema, ExtensionManifestSchema, ExtensionRecordSchema, PublishedSnapshotSchema, ChannelRefSchema, SourceRefSchema, PublishedExtensionRecordSchema, PublishCheckSchema, PublishStatusResultSchema;
|
|
5425
|
+
var EXT_ID_REGEX, ExtensionStateSchema, LOCALHOST_HOSTS, ExtensionManifestSchema, ExtensionTargetSchema, ExtensionRecordSchema, PublishedSnapshotSchema, ChannelRefSchema, SourceRefSchema, PublishedExtensionRecordSchema, PublishCheckSchema, PublishStatusResultSchema;
|
|
5412
5426
|
var init_extension = __esm({
|
|
5413
5427
|
"../protocol/src/extension.ts"() {
|
|
5414
5428
|
"use strict";
|
|
@@ -5421,18 +5435,38 @@ var init_extension = __esm({
|
|
|
5421
5435
|
"crashed",
|
|
5422
5436
|
"invalid"
|
|
5423
5437
|
]);
|
|
5438
|
+
LOCALHOST_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
5424
5439
|
ExtensionManifestSchema = external_exports.object({
|
|
5425
5440
|
id: external_exports.string().regex(EXT_ID_REGEX),
|
|
5426
5441
|
name: external_exports.string().min(1),
|
|
5427
5442
|
version: external_exports.string().min(1),
|
|
5428
5443
|
apiVersion: external_exports.literal("1"),
|
|
5444
|
+
runtime: external_exports.object({ startCommand: external_exports.string().min(1) }).passthrough().optional(),
|
|
5429
5445
|
entry: external_exports.object({
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5446
|
+
url: external_exports.string().url().refine(isAllowedHostedUrl, {
|
|
5447
|
+
message: "INVALID_URL_SCHEME: only https or http://localhost is allowed"
|
|
5448
|
+
})
|
|
5449
|
+
}).strict().optional()
|
|
5450
|
+
}).passthrough().superRefine((m2, ctx) => {
|
|
5451
|
+
const hasRuntime = !!m2.runtime;
|
|
5452
|
+
const hasUrl = !!m2.entry?.url;
|
|
5453
|
+
if (hasRuntime && hasUrl) {
|
|
5454
|
+
ctx.addIssue({
|
|
5455
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5456
|
+
message: "INVALID_MANIFEST: entry.url and runtime cannot coexist"
|
|
5457
|
+
});
|
|
5458
|
+
}
|
|
5459
|
+
if (!hasRuntime && !hasUrl) {
|
|
5460
|
+
ctx.addIssue({
|
|
5461
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5462
|
+
message: "INVALID_MANIFEST: must have either entry.url or runtime"
|
|
5463
|
+
});
|
|
5464
|
+
}
|
|
5465
|
+
});
|
|
5466
|
+
ExtensionTargetSchema = external_exports.discriminatedUnion("kind", [
|
|
5467
|
+
external_exports.object({ kind: external_exports.literal("local"), port: external_exports.number().int().min(1).max(65535) }),
|
|
5468
|
+
external_exports.object({ kind: external_exports.literal("hosted"), url: external_exports.string().url() })
|
|
5469
|
+
]);
|
|
5436
5470
|
ExtensionRecordSchema = external_exports.discriminatedUnion("state", [
|
|
5437
5471
|
external_exports.object({
|
|
5438
5472
|
extId: external_exports.string(),
|
|
@@ -5448,7 +5482,7 @@ var init_extension = __esm({
|
|
|
5448
5482
|
extId: external_exports.string(),
|
|
5449
5483
|
manifest: ExtensionManifestSchema,
|
|
5450
5484
|
state: external_exports.literal("running"),
|
|
5451
|
-
|
|
5485
|
+
target: ExtensionTargetSchema
|
|
5452
5486
|
}),
|
|
5453
5487
|
external_exports.object({
|
|
5454
5488
|
extId: external_exports.string(),
|
|
@@ -37766,12 +37800,6 @@ async function importZip(buf, root) {
|
|
|
37766
37800
|
} catch (e) {
|
|
37767
37801
|
throw new ImportError("INVALID_MANIFEST", `manifest.json: ${e.message}`);
|
|
37768
37802
|
}
|
|
37769
|
-
if (manifestJson && typeof manifestJson === "object" && "entry" in manifestJson && manifestJson.entry?.url !== void 0) {
|
|
37770
|
-
throw new ImportError(
|
|
37771
|
-
"REMOTE_NOT_SUPPORTED",
|
|
37772
|
-
"entry.url (remote mode) is not supported in v1"
|
|
37773
|
-
);
|
|
37774
|
-
}
|
|
37775
37803
|
const result = ExtensionManifestSchema.safeParse(manifestJson);
|
|
37776
37804
|
if (!result.success) {
|
|
37777
37805
|
throw new ImportError(
|
|
@@ -37780,6 +37808,16 @@ async function importZip(buf, root) {
|
|
|
37780
37808
|
);
|
|
37781
37809
|
}
|
|
37782
37810
|
const manifest = result.data;
|
|
37811
|
+
if (manifestMode(manifest) === "hosted") {
|
|
37812
|
+
const filenames = Object.keys(zip.files).filter((n) => !zip.files[n].dir);
|
|
37813
|
+
const extras = filenames.filter((n) => n !== "manifest.json");
|
|
37814
|
+
if (extras.length > 0) {
|
|
37815
|
+
throw new ImportError(
|
|
37816
|
+
"HOSTED_ZIP_EXTRA_FILES",
|
|
37817
|
+
`hosted extension may only contain manifest.json (extra: ${extras.join(", ")})`
|
|
37818
|
+
);
|
|
37819
|
+
}
|
|
37820
|
+
}
|
|
37783
37821
|
const destDir = import_node_path19.default.join(root, manifest.id);
|
|
37784
37822
|
let destExists = false;
|
|
37785
37823
|
try {
|
|
@@ -40240,7 +40278,6 @@ function buildReadyFrame(deps, client) {
|
|
|
40240
40278
|
fileSharing.httpBaseUrl = httpBaseUrl;
|
|
40241
40279
|
if (deps.httpToken) fileSharing.httpToken = deps.httpToken;
|
|
40242
40280
|
}
|
|
40243
|
-
const daemonSource = process.env.CLAWD_DAEMON_SOURCE === "ota" ? "ota" : "packaged";
|
|
40244
40281
|
return {
|
|
40245
40282
|
version,
|
|
40246
40283
|
protocolVersion: PROTOCOL_VERSION,
|
|
@@ -40250,7 +40287,6 @@ function buildReadyFrame(deps, client) {
|
|
|
40250
40287
|
runningSessions: info.runningSessions,
|
|
40251
40288
|
tunnelUrl,
|
|
40252
40289
|
mode: deps.mode,
|
|
40253
|
-
daemonSource,
|
|
40254
40290
|
...fileSharing
|
|
40255
40291
|
};
|
|
40256
40292
|
}
|
|
@@ -40940,10 +40976,17 @@ function pickExtId(frame) {
|
|
|
40940
40976
|
}
|
|
40941
40977
|
function composeState(rec, running, crashed, getPort) {
|
|
40942
40978
|
if (rec.state === "invalid") return rec;
|
|
40979
|
+
if (manifestMode(rec.manifest) === "hosted") {
|
|
40980
|
+
return {
|
|
40981
|
+
...rec,
|
|
40982
|
+
state: "running",
|
|
40983
|
+
target: { kind: "hosted", url: rec.manifest.entry.url }
|
|
40984
|
+
};
|
|
40985
|
+
}
|
|
40943
40986
|
if (running.has(rec.extId)) {
|
|
40944
40987
|
const port = getPort(rec.extId);
|
|
40945
40988
|
if (port == null) return rec;
|
|
40946
|
-
return { ...rec, state: "running", port };
|
|
40989
|
+
return { ...rec, state: "running", target: { kind: "local", port } };
|
|
40947
40990
|
}
|
|
40948
40991
|
if (crashed.has(rec.extId)) return { ...rec, state: "crashed" };
|
|
40949
40992
|
return rec;
|
|
@@ -40965,8 +41008,8 @@ function buildExtensionHandlers(deps) {
|
|
|
40965
41008
|
const open = async (frame, _client, ctx) => {
|
|
40966
41009
|
assertOwner(ctx);
|
|
40967
41010
|
const extId = pickExtId(frame);
|
|
40968
|
-
const
|
|
40969
|
-
return { response:
|
|
41011
|
+
const target = await deps.runtime.open(extId);
|
|
41012
|
+
return { response: target };
|
|
40970
41013
|
};
|
|
40971
41014
|
const close = async (frame, _client, ctx) => {
|
|
40972
41015
|
assertOwner(ctx);
|
|
@@ -41516,16 +41559,20 @@ var Runtime = class {
|
|
|
41516
41559
|
}
|
|
41517
41560
|
async open(extId) {
|
|
41518
41561
|
const existing = this.handles.get(extId);
|
|
41519
|
-
if (existing) return { port: existing.port };
|
|
41562
|
+
if (existing) return { kind: "local", port: existing.port };
|
|
41520
41563
|
const records = await loadAll(this.root);
|
|
41521
41564
|
const rec = records.find((r) => r.extId === extId);
|
|
41522
41565
|
if (!rec) throw new RuntimeError("NOT_FOUND", `extension ${extId} not installed`);
|
|
41523
41566
|
if (rec.state === "invalid")
|
|
41524
41567
|
throw new RuntimeError("INVALID_MANIFEST", rec.invalidReason);
|
|
41568
|
+
if (manifestMode(rec.manifest) === "hosted") {
|
|
41569
|
+
return { kind: "hosted", url: rec.manifest.entry.url };
|
|
41570
|
+
}
|
|
41525
41571
|
const port = await this.allocator.allocate().catch(() => {
|
|
41526
41572
|
throw new RuntimeError("PORT_EXHAUSTED", "no free port in configured range");
|
|
41527
41573
|
});
|
|
41528
|
-
const
|
|
41574
|
+
const startCommand = rec.manifest.runtime.startCommand;
|
|
41575
|
+
const cmd = startCommand.replace(
|
|
41529
41576
|
/\$CLAWOS_EXT_PORT/g,
|
|
41530
41577
|
String(port)
|
|
41531
41578
|
);
|
|
@@ -41563,7 +41610,7 @@ var Runtime = class {
|
|
|
41563
41610
|
try {
|
|
41564
41611
|
await this.waitForHealthz(port, () => earlyExit, handle);
|
|
41565
41612
|
this.crashed.delete(extId);
|
|
41566
|
-
return { port };
|
|
41613
|
+
return { kind: "local", port };
|
|
41567
41614
|
} catch (e) {
|
|
41568
41615
|
if (this.handles.get(extId) === handle) {
|
|
41569
41616
|
this.handles.delete(extId);
|
package/package.json
CHANGED