@clawos-dev/clawd 0.2.687 → 0.2.690
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 +267 -94
- package/dist/cloud-persona-conversations.html +1 -1
- package/dist/cloud-persona-metrics.html +1 -1
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-CKWAbuoe.js → guest-DK7O40Xi.js} +144 -144
- package/dist/share-ui/assets/guest-bkR2YgJq.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-4rwUzpVX.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -43380,7 +43380,7 @@ var require_websocket = __commonJS({
|
|
|
43380
43380
|
var http2 = require("http");
|
|
43381
43381
|
var net2 = require("net");
|
|
43382
43382
|
var tls = require("tls");
|
|
43383
|
-
var { randomBytes: randomBytes2, createHash:
|
|
43383
|
+
var { randomBytes: randomBytes2, createHash: createHash6 } = require("crypto");
|
|
43384
43384
|
var { Duplex, Readable: Readable4 } = require("stream");
|
|
43385
43385
|
var { URL: URL2 } = require("url");
|
|
43386
43386
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -44040,7 +44040,7 @@ var require_websocket = __commonJS({
|
|
|
44040
44040
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
44041
44041
|
return;
|
|
44042
44042
|
}
|
|
44043
|
-
const digest =
|
|
44043
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
44044
44044
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
44045
44045
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
44046
44046
|
return;
|
|
@@ -44407,7 +44407,7 @@ var require_websocket_server = __commonJS({
|
|
|
44407
44407
|
var EventEmitter2 = require("events");
|
|
44408
44408
|
var http2 = require("http");
|
|
44409
44409
|
var { Duplex } = require("stream");
|
|
44410
|
-
var { createHash:
|
|
44410
|
+
var { createHash: createHash6 } = require("crypto");
|
|
44411
44411
|
var extension2 = require_extension();
|
|
44412
44412
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
44413
44413
|
var subprotocol2 = require_subprotocol();
|
|
@@ -44708,7 +44708,7 @@ var require_websocket_server = __commonJS({
|
|
|
44708
44708
|
);
|
|
44709
44709
|
}
|
|
44710
44710
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
44711
|
-
const digest =
|
|
44711
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
44712
44712
|
const headers = [
|
|
44713
44713
|
"HTTP/1.1 101 Switching Protocols",
|
|
44714
44714
|
"Upgrade: websocket",
|
|
@@ -46776,7 +46776,7 @@ function requireEnvironmentIdentity(stores, environment) {
|
|
|
46776
46776
|
var import_node_path89 = __toESM(require("path"), 1);
|
|
46777
46777
|
var import_node_fs68 = __toESM(require("fs"), 1);
|
|
46778
46778
|
var import_node_os33 = __toESM(require("os"), 1);
|
|
46779
|
-
var
|
|
46779
|
+
var import_node_crypto31 = require("crypto");
|
|
46780
46780
|
var import_node_url6 = require("url");
|
|
46781
46781
|
|
|
46782
46782
|
// src/logger.ts
|
|
@@ -53581,6 +53581,10 @@ async function centralRequest(opts, path111, init) {
|
|
|
53581
53581
|
}
|
|
53582
53582
|
clearTimeout(timer);
|
|
53583
53583
|
if (res.status === 401) {
|
|
53584
|
+
const detail = await res.json().catch(() => null);
|
|
53585
|
+
if (path111 === "/api/persona-cloud/github/oauth/token" && detail?.errorCode === "GITHUB_REAUTH_REQUIRED") {
|
|
53586
|
+
throw new CentralClientError("API_ERROR", typeof detail.message === "string" ? detail.message : "\u8BF7\u91CD\u65B0\u5173\u8054 GitHub", void 0, 401);
|
|
53587
|
+
}
|
|
53584
53588
|
throw new CentralClientError("UNAUTHORIZED", "login pass rejected by center");
|
|
53585
53589
|
}
|
|
53586
53590
|
if (!res.ok) {
|
|
@@ -53759,11 +53763,12 @@ async function centralGithubAuthToken(opts) {
|
|
|
53759
53763
|
const body = await centralRequest(opts, "/api/persona-cloud/github/oauth/token", {
|
|
53760
53764
|
method: "POST",
|
|
53761
53765
|
bearer: opts.loginPass,
|
|
53762
|
-
body: {}
|
|
53766
|
+
body: { ...opts.rejectedToken ? { rejectedToken: opts.rejectedToken } : {} }
|
|
53763
53767
|
});
|
|
53764
53768
|
if (body.token === null || body.token === void 0) return void 0;
|
|
53765
53769
|
if (typeof body.token !== "string" || !body.token) throw new CentralClientError("BAD_RESPONSE", "github/oauth/token: malformed token");
|
|
53766
|
-
|
|
53770
|
+
if (body.expiresAt !== void 0 && (typeof body.expiresAt !== "string" || !Number.isFinite(Date.parse(body.expiresAt)))) throw new CentralClientError("BAD_RESPONSE", "github/oauth/token: malformed expiry");
|
|
53771
|
+
return { token: body.token, login: typeof body.login === "string" ? body.login : "", ...typeof body.expiresAt === "string" ? { expiresAt: body.expiresAt } : {} };
|
|
53767
53772
|
}
|
|
53768
53773
|
async function centralClaimPublisher(opts) {
|
|
53769
53774
|
await centralRequest(opts, `/api/persona-cloud/personas/${encodeURIComponent(opts.personaId)}/publisher`, {
|
|
@@ -57519,8 +57524,8 @@ function createGhRunner(defaults) {
|
|
|
57519
57524
|
const baseTimeoutMs = defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
57520
57525
|
const spawn17 = defaults?.execFile ?? import_node_child_process9.execFile;
|
|
57521
57526
|
return {
|
|
57522
|
-
run(args, opts) {
|
|
57523
|
-
const token = defaults?.token?.();
|
|
57527
|
+
async run(args, opts) {
|
|
57528
|
+
const token = await defaults?.token?.();
|
|
57524
57529
|
return new Promise((resolve9, reject) => {
|
|
57525
57530
|
spawn17(
|
|
57526
57531
|
"gh",
|
|
@@ -58044,25 +58049,59 @@ var CloudGatewayClient = class {
|
|
|
58044
58049
|
return list.find((p3) => p3.personaId === gatewayPersonaId)?.connectors ?? [];
|
|
58045
58050
|
}
|
|
58046
58051
|
async workspaceCommand(personaId2, input) {
|
|
58047
|
-
const
|
|
58048
|
-
const
|
|
58049
|
-
|
|
58050
|
-
|
|
58051
|
-
|
|
58052
|
-
|
|
58053
|
-
|
|
58054
|
-
|
|
58055
|
-
|
|
58056
|
-
|
|
58057
|
-
|
|
58052
|
+
const started = performance.now();
|
|
58053
|
+
const traceId = typeof input.traceId === "string" && /^[A-Za-z0-9:_-]{1,128}$/.test(input.traceId) ? input.traceId : crypto.randomUUID();
|
|
58054
|
+
const { traceId: _trace, ...body } = input;
|
|
58055
|
+
const meta = {
|
|
58056
|
+
traceId,
|
|
58057
|
+
sessionId: input.sessionId,
|
|
58058
|
+
personaId: personaId2,
|
|
58059
|
+
action: input.action,
|
|
58060
|
+
page: typeof input.page === "number" && Number.isInteger(input.page) && input.page >= 1 && input.page <= 1e3 ? input.page : void 0,
|
|
58061
|
+
hasSearch: typeof input.search === "string" && input.search.length > 0,
|
|
58062
|
+
searchLength: typeof input.search === "string" ? input.search.length : 0,
|
|
58063
|
+
hasCursor: typeof input.cursor === "string"
|
|
58064
|
+
};
|
|
58065
|
+
const log = (event, detail) => {
|
|
58066
|
+
try {
|
|
58067
|
+
this.deps.logger?.info("cloud.workspace.daemon." + event, { ...meta, ...detail });
|
|
58068
|
+
} catch {
|
|
58058
58069
|
}
|
|
58059
|
-
|
|
58060
|
-
const
|
|
58061
|
-
|
|
58062
|
-
|
|
58063
|
-
|
|
58064
|
-
|
|
58065
|
-
|
|
58070
|
+
};
|
|
58071
|
+
const measure = async (stage, run) => {
|
|
58072
|
+
const at3 = performance.now();
|
|
58073
|
+
let outcome2 = "error";
|
|
58074
|
+
try {
|
|
58075
|
+
const value = await run();
|
|
58076
|
+
outcome2 = "ok";
|
|
58077
|
+
return value;
|
|
58078
|
+
} finally {
|
|
58079
|
+
log("stage", { stage, outcome: outcome2, durationMs: Math.round(performance.now() - at3) });
|
|
58080
|
+
}
|
|
58081
|
+
};
|
|
58082
|
+
let outcome = "error";
|
|
58083
|
+
let statusCode;
|
|
58084
|
+
log("started", {});
|
|
58085
|
+
try {
|
|
58086
|
+
const { apiKey, gatewayUrl } = await measure("credentials", () => this.credentials());
|
|
58087
|
+
const res = await measure("gateway.headers", () => this.fetchImpl(
|
|
58088
|
+
gatewayUrl + GATEWAY_ROUTES.workspace(personaId2),
|
|
58089
|
+
{
|
|
58090
|
+
method: "POST",
|
|
58091
|
+
headers: { authorization: "Bearer " + apiKey, "content-type": "application/json", "x-trace-id": traceId },
|
|
58092
|
+
body: JSON.stringify(body),
|
|
58093
|
+
signal: AbortSignal.timeout(3e5)
|
|
58094
|
+
}
|
|
58095
|
+
));
|
|
58096
|
+
statusCode = res.status;
|
|
58097
|
+
const result = await measure("gateway.body", () => res.json());
|
|
58098
|
+
if (!res.ok) throw new Error(result.error?.message ?? "Cloud workspace request failed (" + res.status + ")");
|
|
58099
|
+
const parsed = CloudWorkspaceResultSchema.parse(result);
|
|
58100
|
+
outcome = "ok";
|
|
58101
|
+
return parsed;
|
|
58102
|
+
} finally {
|
|
58103
|
+
log("finished", { outcome, statusCode, durationMs: Math.round(performance.now() - started) });
|
|
58104
|
+
}
|
|
58066
58105
|
}
|
|
58067
58106
|
async openTurn(personaId2, opts) {
|
|
58068
58107
|
const { apiKey, gatewayUrl } = await this.credentials();
|
|
@@ -62165,23 +62204,38 @@ function createGithubApi(args) {
|
|
|
62165
62204
|
const seal = args.seal ?? sealWithSodium;
|
|
62166
62205
|
const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
|
|
62167
62206
|
const secretsPath = (slug, environment) => `/repos/${slug}/${environment ? `environments/${encodeURIComponent(environment)}` : "actions"}/secrets`;
|
|
62168
|
-
async function
|
|
62169
|
-
let
|
|
62170
|
-
|
|
62171
|
-
|
|
62172
|
-
|
|
62173
|
-
|
|
62174
|
-
|
|
62175
|
-
|
|
62176
|
-
|
|
62177
|
-
|
|
62178
|
-
}
|
|
62179
|
-
|
|
62180
|
-
|
|
62181
|
-
}
|
|
62182
|
-
|
|
62183
|
-
|
|
62207
|
+
async function authenticatedFetch(path111, init) {
|
|
62208
|
+
let token = args.identity ? (await args.identity.refresh())?.token : args.token;
|
|
62209
|
+
if (!token) throw new GithubApiError(401, "\u8BF7\u5148\u5173\u8054 GitHub");
|
|
62210
|
+
for (let attempt = 0; ; attempt++) {
|
|
62211
|
+
let res;
|
|
62212
|
+
try {
|
|
62213
|
+
res = await doFetch(API + path111, {
|
|
62214
|
+
...init,
|
|
62215
|
+
headers: { ...init.headers, Authorization: "Bearer " + token },
|
|
62216
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
62217
|
+
});
|
|
62218
|
+
} catch (err) {
|
|
62219
|
+
throw new GithubApiError(0, "\u8FDE\u4E0D\u4E0A GitHub\uFF1A" + (err instanceof Error ? err.message : String(err)));
|
|
62220
|
+
}
|
|
62221
|
+
if (res.status !== 401 || attempt !== 0 || !args.identity) return res;
|
|
62222
|
+
const renewed = await args.identity.recover(token);
|
|
62223
|
+
if (!renewed || renewed.token === token) return res;
|
|
62224
|
+
await res.body?.cancel();
|
|
62225
|
+
token = renewed.token;
|
|
62184
62226
|
}
|
|
62227
|
+
}
|
|
62228
|
+
async function request(method, path111, body) {
|
|
62229
|
+
const res = await authenticatedFetch(path111, {
|
|
62230
|
+
method,
|
|
62231
|
+
redirect: "error",
|
|
62232
|
+
headers: {
|
|
62233
|
+
Accept: "application/vnd.github+json",
|
|
62234
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
62235
|
+
...body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
62236
|
+
},
|
|
62237
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
62238
|
+
});
|
|
62185
62239
|
const text = await res.text();
|
|
62186
62240
|
let json = void 0;
|
|
62187
62241
|
if (text) {
|
|
@@ -62266,8 +62320,8 @@ function createGithubApi(args) {
|
|
|
62266
62320
|
const signal = AbortSignal.timeout(timeoutMs);
|
|
62267
62321
|
let res;
|
|
62268
62322
|
try {
|
|
62269
|
-
res = await
|
|
62270
|
-
headers: {
|
|
62323
|
+
res = await authenticatedFetch(`/repos/${slug}/actions/artifacts/${artifactId}/zip`, {
|
|
62324
|
+
headers: { Accept: "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28" },
|
|
62271
62325
|
redirect: "manual",
|
|
62272
62326
|
signal
|
|
62273
62327
|
});
|
|
@@ -62892,7 +62946,8 @@ function networkOptions(auth) {
|
|
|
62892
62946
|
return auth?.source === "file" ? { prefix: [...QUIET_GIT_ARGS, "-c", "credential.helper=", "-c", `credential.helper=${INLINE_HELPER}`], env: { ...QUIET_GIT_ENV, CLAWD_GITHUB_TOKEN: auth.token } } : { prefix: [...QUIET_GIT_ARGS], env: QUIET_GIT_ENV };
|
|
62893
62947
|
}
|
|
62894
62948
|
async function networkGit(exec, dir, auth, args, what) {
|
|
62895
|
-
const
|
|
62949
|
+
const current = typeof auth === "function" ? await auth() : auth;
|
|
62950
|
+
const opts = networkOptions(current);
|
|
62896
62951
|
return mustGit(exec, dir, [...opts.prefix, ...args], what, { timeoutMs: 12e4, env: opts.env });
|
|
62897
62952
|
}
|
|
62898
62953
|
async function gitPush(exec, dir, auth, refspec = "HEAD:refs/heads/integration") {
|
|
@@ -63807,7 +63862,11 @@ function buildDeployHandlers(deps) {
|
|
|
63807
63862
|
async function requireGithub() {
|
|
63808
63863
|
const auth = await deps.githubIdentity.refresh();
|
|
63809
63864
|
if (!auth) throw new ClawdError(ERROR_CODES.INTERNAL, NO_GITHUB_AUTH);
|
|
63810
|
-
return { auth
|
|
63865
|
+
return { auth: async () => {
|
|
63866
|
+
const current = await deps.githubIdentity.refresh();
|
|
63867
|
+
if (!current) throw new ClawdError(ERROR_CODES.INTERNAL, NO_GITHUB_AUTH);
|
|
63868
|
+
return current;
|
|
63869
|
+
}, api: deps.githubApi(auth.token) };
|
|
63811
63870
|
}
|
|
63812
63871
|
function mustPersona(personaId2) {
|
|
63813
63872
|
if (!deps.hasPersona(personaId2)) {
|
|
@@ -65032,13 +65091,82 @@ function createGithubIdentity(deps) {
|
|
|
65032
65091
|
let pendingOauth = null;
|
|
65033
65092
|
let staleCenterToken;
|
|
65034
65093
|
const listeners = /* @__PURE__ */ new Set();
|
|
65035
|
-
|
|
65036
|
-
|
|
65037
|
-
|
|
65038
|
-
|
|
65039
|
-
|
|
65094
|
+
let managedToken;
|
|
65095
|
+
const oauthCandidate = (token) => /^gh[ou]_/.test(token);
|
|
65096
|
+
const oauthManaged = (token) => oauthCandidate(token) && (managedToken === token || deps.isManaged?.(token) === true);
|
|
65097
|
+
let acquisition;
|
|
65098
|
+
let centerFlight;
|
|
65099
|
+
let centerCache;
|
|
65100
|
+
let writes = Promise.resolve();
|
|
65101
|
+
function remember(got) {
|
|
65102
|
+
const expiry = got.expiresAt ? Date.parse(got.expiresAt) - 6e4 : Infinity;
|
|
65103
|
+
centerCache = { token: got.token, until: Math.min(deps.now() + 2e4, expiry) };
|
|
65104
|
+
}
|
|
65105
|
+
function persist(token, generation, managed = false) {
|
|
65106
|
+
const write = writes.catch(() => {
|
|
65107
|
+
}).then(async () => {
|
|
65108
|
+
if (generation !== seq) return;
|
|
65109
|
+
const stored = await deps.store(token);
|
|
65110
|
+
if (generation !== seq) return;
|
|
65111
|
+
deps.markManaged?.(managed ? token : void 0);
|
|
65112
|
+
managedToken = managed ? token : void 0;
|
|
65113
|
+
auth = stored;
|
|
65114
|
+
statusCache.clear();
|
|
65115
|
+
pendingOauth = null;
|
|
65116
|
+
for (const cb of listeners) cb();
|
|
65117
|
+
});
|
|
65118
|
+
writes = write;
|
|
65119
|
+
return write;
|
|
65120
|
+
}
|
|
65121
|
+
async function syncCenter(local, rejectedToken) {
|
|
65122
|
+
if (!oauthCandidate(local.token)) return local;
|
|
65123
|
+
const managed = oauthManaged(local.token);
|
|
65124
|
+
if (!rejectedToken && centerCache?.token === local.token && deps.now() < centerCache.until) return local;
|
|
65125
|
+
if (centerFlight) return centerFlight;
|
|
65126
|
+
const generation = seq;
|
|
65127
|
+
const task = (async () => {
|
|
65128
|
+
let got;
|
|
65129
|
+
try {
|
|
65130
|
+
got = await deps.oauth.token(rejectedToken);
|
|
65131
|
+
} catch (err) {
|
|
65132
|
+
if (managed) throw err;
|
|
65133
|
+
return local;
|
|
65134
|
+
}
|
|
65135
|
+
if (generation !== seq) return auth;
|
|
65136
|
+
if (!got || !managed && got.token !== local.token) {
|
|
65137
|
+
remember({ token: local.token });
|
|
65138
|
+
return local;
|
|
65139
|
+
}
|
|
65140
|
+
if (!managed || got.token !== local.token) await persist(got.token, generation, true);
|
|
65141
|
+
if (generation !== seq) return auth;
|
|
65142
|
+
remember(got);
|
|
65143
|
+
return auth ?? local;
|
|
65144
|
+
})().finally(() => {
|
|
65145
|
+
if (centerFlight === task) centerFlight = void 0;
|
|
65146
|
+
});
|
|
65147
|
+
centerFlight = task;
|
|
65148
|
+
return task;
|
|
65149
|
+
}
|
|
65150
|
+
function refresh() {
|
|
65151
|
+
if (acquisition) return acquisition;
|
|
65152
|
+
const generation = seq;
|
|
65153
|
+
const task = (async () => {
|
|
65154
|
+
const resolved = await deps.resolve();
|
|
65155
|
+
if (generation !== seq) return auth;
|
|
65156
|
+
auth = resolved;
|
|
65157
|
+
return resolved ? syncCenter(resolved) : void 0;
|
|
65158
|
+
})().finally(() => {
|
|
65159
|
+
if (acquisition === task) acquisition = void 0;
|
|
65160
|
+
});
|
|
65161
|
+
acquisition = task;
|
|
65162
|
+
return task;
|
|
65040
65163
|
}
|
|
65041
|
-
async function
|
|
65164
|
+
async function recover(rejectedToken) {
|
|
65165
|
+
const current = await refresh();
|
|
65166
|
+
if (!current || current.token !== rejectedToken || !oauthManaged(current.token)) return current;
|
|
65167
|
+
return syncCenter(current, rejectedToken);
|
|
65168
|
+
}
|
|
65169
|
+
async function whoami(a2, recovering = false) {
|
|
65042
65170
|
const hit = statusCache.get(a2.token);
|
|
65043
65171
|
if (hit && deps.now() - hit.at < cacheMs) return hit.status;
|
|
65044
65172
|
let status2;
|
|
@@ -65046,19 +65174,26 @@ function createGithubIdentity(deps) {
|
|
|
65046
65174
|
const { login } = await deps.api(a2.token).whoami();
|
|
65047
65175
|
status2 = { status: "authorized", login, source: a2.source };
|
|
65048
65176
|
} catch (err) {
|
|
65177
|
+
if (!recovering && err instanceof GithubApiError && err.status === 401 && oauthManaged(a2.token)) {
|
|
65178
|
+
try {
|
|
65179
|
+
const renewed = await recover(a2.token);
|
|
65180
|
+
if (renewed && renewed.token !== a2.token) return whoami(renewed, true);
|
|
65181
|
+
} catch (recoveryError) {
|
|
65182
|
+
return { status: "invalid", message: recoveryError instanceof Error ? recoveryError.message : String(recoveryError) };
|
|
65183
|
+
}
|
|
65184
|
+
}
|
|
65049
65185
|
status2 = { status: "invalid", message: err instanceof Error ? err.message : String(err) };
|
|
65050
65186
|
}
|
|
65051
65187
|
statusCache.set(a2.token, { at: deps.now(), status: status2 });
|
|
65052
65188
|
return status2;
|
|
65053
65189
|
}
|
|
65054
65190
|
async function adopt(token) {
|
|
65055
|
-
|
|
65056
|
-
|
|
65057
|
-
|
|
65058
|
-
pendingOauth = null;
|
|
65059
|
-
for (const cb of listeners) cb();
|
|
65191
|
+
const generation = ++seq;
|
|
65192
|
+
centerCache = void 0;
|
|
65193
|
+
await persist(token, generation);
|
|
65060
65194
|
}
|
|
65061
65195
|
async function claimCenterToken() {
|
|
65196
|
+
const generation = seq;
|
|
65062
65197
|
let got;
|
|
65063
65198
|
try {
|
|
65064
65199
|
got = await deps.oauth.token();
|
|
@@ -65072,7 +65207,9 @@ function createGithubIdentity(deps) {
|
|
|
65072
65207
|
if (err instanceof GithubApiError && err.status === 401) staleCenterToken = got.token;
|
|
65073
65208
|
return false;
|
|
65074
65209
|
}
|
|
65075
|
-
|
|
65210
|
+
if (generation !== seq) return false;
|
|
65211
|
+
await persist(got.token, ++seq, true);
|
|
65212
|
+
remember(got);
|
|
65076
65213
|
return true;
|
|
65077
65214
|
}
|
|
65078
65215
|
async function settlePendingOauth() {
|
|
@@ -65090,13 +65227,19 @@ function createGithubIdentity(deps) {
|
|
|
65090
65227
|
}
|
|
65091
65228
|
async function status() {
|
|
65092
65229
|
await settlePendingOauth();
|
|
65093
|
-
|
|
65230
|
+
let a2;
|
|
65231
|
+
try {
|
|
65232
|
+
a2 = await refresh();
|
|
65233
|
+
} catch (err) {
|
|
65234
|
+
return { status: "invalid", message: err instanceof Error ? err.message : String(err) };
|
|
65235
|
+
}
|
|
65094
65236
|
const current = a2 ? await whoami(a2) : { status: "missing" };
|
|
65095
65237
|
return pendingOauth && current.status !== "authorized" ? { status: "pending", authUrl: pendingOauth.authUrl } : current;
|
|
65096
65238
|
}
|
|
65097
65239
|
return {
|
|
65098
65240
|
cached: () => auth,
|
|
65099
65241
|
refresh,
|
|
65242
|
+
recover,
|
|
65100
65243
|
status,
|
|
65101
65244
|
adopt,
|
|
65102
65245
|
async authorize(raw) {
|
|
@@ -65111,7 +65254,7 @@ function createGithubIdentity(deps) {
|
|
|
65111
65254
|
},
|
|
65112
65255
|
// 已有身份时重新授权;直接返回 pending 链接,不能经 status() 被旧的 authorized 状态遮掉。
|
|
65113
65256
|
async oauthStart(returnTo) {
|
|
65114
|
-
const local = await
|
|
65257
|
+
const local = await deps.resolve();
|
|
65115
65258
|
if (!local && await claimCenterToken()) return status();
|
|
65116
65259
|
try {
|
|
65117
65260
|
staleCenterToken = (await deps.oauth.token())?.token;
|
|
@@ -69800,7 +69943,7 @@ var ContactStore = class {
|
|
|
69800
69943
|
};
|
|
69801
69944
|
|
|
69802
69945
|
// src/contact/connect-remote.ts
|
|
69803
|
-
var
|
|
69946
|
+
var crypto6 = __toESM(require("crypto"), 1);
|
|
69804
69947
|
init_protocol();
|
|
69805
69948
|
var HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
69806
69949
|
var RPC_TIMEOUT_MS = 5e3;
|
|
@@ -69855,7 +69998,7 @@ async function connectRemote(args) {
|
|
|
69855
69998
|
ws.once("close", onClose);
|
|
69856
69999
|
});
|
|
69857
70000
|
function call(method, payload) {
|
|
69858
|
-
const requestId =
|
|
70001
|
+
const requestId = crypto6.randomUUID();
|
|
69859
70002
|
return new Promise((resolve9, reject) => {
|
|
69860
70003
|
const onMessage = (raw) => {
|
|
69861
70004
|
let f2;
|
|
@@ -72324,7 +72467,7 @@ function buildDeviceHandlers(deps) {
|
|
|
72324
72467
|
}
|
|
72325
72468
|
|
|
72326
72469
|
// src/feishu-auth/verify-token.ts
|
|
72327
|
-
var
|
|
72470
|
+
var crypto13 = __toESM(require("crypto"), 1);
|
|
72328
72471
|
var CONNECT_TOKEN_PREFIX = "clawdtk1";
|
|
72329
72472
|
function verifyConnectToken(args) {
|
|
72330
72473
|
const now = args.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
@@ -72336,7 +72479,7 @@ function verifyConnectToken(args) {
|
|
|
72336
72479
|
const data = `${prefix}.${payloadB64}`;
|
|
72337
72480
|
let signatureValid = false;
|
|
72338
72481
|
try {
|
|
72339
|
-
signatureValid =
|
|
72482
|
+
signatureValid = crypto13.verify(
|
|
72340
72483
|
null,
|
|
72341
72484
|
Buffer.from(data, "utf8"),
|
|
72342
72485
|
args.publicKeyPem,
|
|
@@ -74996,6 +75139,7 @@ function buildCloudConnectorsHandlers(deps) {
|
|
|
74996
75139
|
|
|
74997
75140
|
// src/handlers/cloud-workspace.ts
|
|
74998
75141
|
init_protocol();
|
|
75142
|
+
var import_node_crypto26 = require("crypto");
|
|
74999
75143
|
function buildCloudWorkspaceHandlers(deps) {
|
|
75000
75144
|
return {
|
|
75001
75145
|
"cloud:workspace": async (frame, _client, ctx) => {
|
|
@@ -75023,17 +75167,34 @@ function buildCloudWorkspaceHandlers(deps) {
|
|
|
75023
75167
|
) || file.cloudPendingTurns?.length))
|
|
75024
75168
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "\u8BF7\u7B49\u5F85\u5F53\u524D\u4EFB\u52A1\u5B8C\u6210");
|
|
75025
75169
|
const conversationId = file.cloudConversationId ?? file.cloudExecutionId ?? file.sessionId;
|
|
75026
|
-
const
|
|
75027
|
-
|
|
75028
|
-
|
|
75029
|
-
|
|
75030
|
-
|
|
75031
|
-
|
|
75032
|
-
}
|
|
75033
|
-
|
|
75034
|
-
|
|
75035
|
-
|
|
75036
|
-
|
|
75170
|
+
const traceId = typeof frame.requestId === "string" && /^[A-Za-z0-9:_-]{1,128}$/.test(frame.requestId) ? frame.requestId : (0, import_node_crypto26.randomUUID)();
|
|
75171
|
+
const started = performance.now();
|
|
75172
|
+
const meta = { traceId, sessionId: args.sessionId, action: args.action };
|
|
75173
|
+
const log = (event, detail) => {
|
|
75174
|
+
try {
|
|
75175
|
+
deps.logger?.info("cloud.workspace.rpc." + event, { ...meta, ...detail });
|
|
75176
|
+
} catch {
|
|
75177
|
+
}
|
|
75178
|
+
};
|
|
75179
|
+
let outcome = "error";
|
|
75180
|
+
log("started", {});
|
|
75181
|
+
try {
|
|
75182
|
+
const result = CloudWorkspaceResultSchema.parse(
|
|
75183
|
+
await deps.command(file, {
|
|
75184
|
+
...args,
|
|
75185
|
+
traceId,
|
|
75186
|
+
workspaceId: file.cloudWorkspace?.workspaceId ?? file.sessionId,
|
|
75187
|
+
conversationId,
|
|
75188
|
+
...file.toolSessionId ? { threadId: file.toolSessionId } : {}
|
|
75189
|
+
})
|
|
75190
|
+
);
|
|
75191
|
+
if (result.binding && !file.cloudWorkspace)
|
|
75192
|
+
deps.bind(file.sessionId, result.binding, conversationId);
|
|
75193
|
+
outcome = "ok";
|
|
75194
|
+
return { response: { type: "cloud:workspace:ok", ...result } };
|
|
75195
|
+
} finally {
|
|
75196
|
+
log("finished", { outcome, durationMs: Math.round(performance.now() - started) });
|
|
75197
|
+
}
|
|
75037
75198
|
}
|
|
75038
75199
|
};
|
|
75039
75200
|
}
|
|
@@ -75363,7 +75524,7 @@ function computeMethodAccess(args) {
|
|
|
75363
75524
|
}
|
|
75364
75525
|
|
|
75365
75526
|
// src/version.ts
|
|
75366
|
-
var version = "0.2.
|
|
75527
|
+
var version = "0.2.690".length > 0 ? "0.2.690" : "dev";
|
|
75367
75528
|
|
|
75368
75529
|
// src/cli-probe/probe.ts
|
|
75369
75530
|
var fs86 = __toESM(require("fs"), 1);
|
|
@@ -75759,7 +75920,7 @@ init_protocol();
|
|
|
75759
75920
|
// src/extension/bundle-zip.ts
|
|
75760
75921
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
75761
75922
|
var import_node_path78 = __toESM(require("path"), 1);
|
|
75762
|
-
var
|
|
75923
|
+
var import_node_crypto27 = __toESM(require("crypto"), 1);
|
|
75763
75924
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
75764
75925
|
async function bundleExtensionDir(dir) {
|
|
75765
75926
|
const entries = await listFilesSorted(dir);
|
|
@@ -75774,7 +75935,7 @@ async function bundleExtensionDir(dir) {
|
|
|
75774
75935
|
compression: "DEFLATE",
|
|
75775
75936
|
compressionOptions: { level: 6 }
|
|
75776
75937
|
});
|
|
75777
|
-
const sha256 =
|
|
75938
|
+
const sha256 = import_node_crypto27.default.createHash("sha256").update(buffer).digest("hex");
|
|
75778
75939
|
return { buffer, sha256 };
|
|
75779
75940
|
}
|
|
75780
75941
|
var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
@@ -75842,7 +76003,7 @@ function computePublishCheck(args) {
|
|
|
75842
76003
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
75843
76004
|
var import_node_path80 = __toESM(require("path"), 1);
|
|
75844
76005
|
var import_node_os30 = __toESM(require("os"), 1);
|
|
75845
|
-
var
|
|
76006
|
+
var import_node_crypto28 = __toESM(require("crypto"), 1);
|
|
75846
76007
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
75847
76008
|
|
|
75848
76009
|
// src/extension/paths.ts
|
|
@@ -75871,7 +76032,7 @@ var InstallError = class extends Error {
|
|
|
75871
76032
|
};
|
|
75872
76033
|
async function installFromChannel(args, deps) {
|
|
75873
76034
|
const { channelRef, snapshotHash, bundleZip } = args;
|
|
75874
|
-
const computed =
|
|
76035
|
+
const computed = import_node_crypto28.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
75875
76036
|
if (computed !== snapshotHash) {
|
|
75876
76037
|
throw new InstallError(
|
|
75877
76038
|
"HASH_MISMATCH",
|
|
@@ -75963,7 +76124,7 @@ async function installFromChannel(args, deps) {
|
|
|
75963
76124
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
75964
76125
|
var import_node_path81 = __toESM(require("path"), 1);
|
|
75965
76126
|
var import_node_os31 = __toESM(require("os"), 1);
|
|
75966
|
-
var
|
|
76127
|
+
var import_node_crypto29 = __toESM(require("crypto"), 1);
|
|
75967
76128
|
var import_jszip5 = __toESM(require_lib3(), 1);
|
|
75968
76129
|
var UpdateError = class extends Error {
|
|
75969
76130
|
constructor(code, message) {
|
|
@@ -76001,7 +76162,7 @@ async function updateFromChannel(args, deps) {
|
|
|
76001
76162
|
if (e instanceof UpdateError) throw e;
|
|
76002
76163
|
throw e;
|
|
76003
76164
|
}
|
|
76004
|
-
const computed =
|
|
76165
|
+
const computed = import_node_crypto29.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
76005
76166
|
if (computed !== snapshotHash) {
|
|
76006
76167
|
throw new UpdateError(
|
|
76007
76168
|
"HASH_MISMATCH",
|
|
@@ -77129,7 +77290,7 @@ async function uninstall(deps) {
|
|
|
77129
77290
|
}
|
|
77130
77291
|
|
|
77131
77292
|
// src/handlers/index.ts
|
|
77132
|
-
var
|
|
77293
|
+
var import_node_crypto30 = require("crypto");
|
|
77133
77294
|
|
|
77134
77295
|
// src/handlers/peer-exec.ts
|
|
77135
77296
|
init_protocol();
|
|
@@ -77286,7 +77447,7 @@ function buildMethodHandlers(deps) {
|
|
|
77286
77447
|
const c2 = deps.contactStore.get(deviceId);
|
|
77287
77448
|
return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
|
|
77288
77449
|
},
|
|
77289
|
-
genId: () => (0,
|
|
77450
|
+
genId: () => (0, import_node_crypto30.randomUUID)(),
|
|
77290
77451
|
now: () => Date.now(),
|
|
77291
77452
|
forwardInboxPostToPeer,
|
|
77292
77453
|
logger: deps.logger
|
|
@@ -78011,7 +78172,7 @@ async function startDaemon(config) {
|
|
|
78011
78172
|
const channelStore = createChannelStore({
|
|
78012
78173
|
filePath: import_node_path89.default.join(config.dataDir, "channels.json"),
|
|
78013
78174
|
now: () => Date.now(),
|
|
78014
|
-
genId: () => `ch-${(0,
|
|
78175
|
+
genId: () => `ch-${(0, import_node_crypto31.randomUUID)().slice(0, 8)}`,
|
|
78015
78176
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
78016
78177
|
reason: err instanceof Error ? err.message : String(err)
|
|
78017
78178
|
})
|
|
@@ -78020,7 +78181,7 @@ async function startDaemon(config) {
|
|
|
78020
78181
|
const topicStore = createTopicStore({
|
|
78021
78182
|
filePath: import_node_path89.default.join(config.dataDir, "topics.json"),
|
|
78022
78183
|
now: () => Date.now(),
|
|
78023
|
-
genId: () => `tp-${(0,
|
|
78184
|
+
genId: () => `tp-${(0, import_node_crypto31.randomUUID)().slice(0, 8)}`,
|
|
78024
78185
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
78025
78186
|
reason: err instanceof Error ? err.message : String(err)
|
|
78026
78187
|
})
|
|
@@ -78028,7 +78189,7 @@ async function startDaemon(config) {
|
|
|
78028
78189
|
await topicStore.load();
|
|
78029
78190
|
let deliverPendingRef;
|
|
78030
78191
|
const personaDispatchManager = new PersonaDispatchManager({
|
|
78031
|
-
genId: () => (0,
|
|
78192
|
+
genId: () => (0, import_node_crypto31.randomUUID)(),
|
|
78032
78193
|
store: dispatchStore,
|
|
78033
78194
|
now: () => Date.now(),
|
|
78034
78195
|
onCompleted: (sid) => deliverPendingRef?.(sid),
|
|
@@ -78051,7 +78212,14 @@ async function startDaemon(config) {
|
|
|
78051
78212
|
const localSecretsDir = import_node_path89.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
78052
78213
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
78053
78214
|
const githubTokenFile = import_node_path89.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
78215
|
+
const managedGithubVar = "CLAWD_GITHUB_MANAGED_TOKEN_SHA256";
|
|
78216
|
+
const githubFingerprint = (token) => (0, import_node_crypto31.createHash)("sha256").update(token).digest("hex");
|
|
78054
78217
|
const githubIdentity = createGithubIdentity({
|
|
78218
|
+
isManaged: (token) => readEnvFileVar(githubTokenFile, managedGithubVar) === githubFingerprint(token),
|
|
78219
|
+
markManaged: (token) => {
|
|
78220
|
+
if (token) upsertEnvFileVar(githubTokenFile, managedGithubVar, githubFingerprint(token));
|
|
78221
|
+
else removeEnvFileVar(githubTokenFile, managedGithubVar);
|
|
78222
|
+
},
|
|
78055
78223
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
78056
78224
|
store: (token) => storeGithubAuth({
|
|
78057
78225
|
exec: runCommand,
|
|
@@ -78073,19 +78241,23 @@ async function startDaemon(config) {
|
|
|
78073
78241
|
throw new ClawdError(ERROR_CODES.INTERNAL, `\u5411\u4E2D\u5FC3\u8981 GitHub \u6388\u6743\u94FE\u63A5\u6CA1\u6210\uFF1A${err instanceof Error ? err.message : String(err)}`);
|
|
78074
78242
|
}
|
|
78075
78243
|
},
|
|
78076
|
-
token: async () => {
|
|
78244
|
+
token: async (rejectedToken) => {
|
|
78077
78245
|
const r2 = ownerIdentityStore.read();
|
|
78078
78246
|
if (!r2) return void 0;
|
|
78079
|
-
return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass });
|
|
78247
|
+
return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass, ...rejectedToken ? { rejectedToken } : {} });
|
|
78080
78248
|
}
|
|
78081
78249
|
},
|
|
78082
78250
|
now: () => Date.now(),
|
|
78083
78251
|
logger
|
|
78084
78252
|
});
|
|
78085
|
-
void githubIdentity.refresh()
|
|
78253
|
+
void githubIdentity.refresh().catch(() => {
|
|
78254
|
+
logger.warn("github.identity.warm-failed");
|
|
78255
|
+
});
|
|
78086
78256
|
const resolvePersonaMcpConfig = (personaId2) => {
|
|
78087
78257
|
const secrets = secretsWithGithubIdentity(readSecrets(), githubIdentity.cached());
|
|
78088
|
-
void githubIdentity.refresh()
|
|
78258
|
+
void githubIdentity.refresh().catch(() => {
|
|
78259
|
+
logger.warn("github.identity.sync-failed");
|
|
78260
|
+
});
|
|
78089
78261
|
return renderPersonaMcpSecrets({
|
|
78090
78262
|
personaId: personaId2,
|
|
78091
78263
|
personaDir: import_node_path89.default.join(config.dataDir, "personas", personaId2),
|
|
@@ -78881,6 +79053,7 @@ async function startDaemon(config) {
|
|
|
78881
79053
|
}
|
|
78882
79054
|
},
|
|
78883
79055
|
cloudWorkspace: {
|
|
79056
|
+
logger,
|
|
78884
79057
|
getFile: (id) => manager.get({ sessionId: id }).response,
|
|
78885
79058
|
status: (id) => manager.getCurrentStatus(id),
|
|
78886
79059
|
bind: (id, binding, conversationId) => manager.bindCloudWorkspace(id, binding, conversationId),
|
|
@@ -78913,7 +79086,7 @@ async function startDaemon(config) {
|
|
|
78913
79086
|
shiftStore,
|
|
78914
79087
|
shiftOwnerIdProvider: () => ownerPrincipalId,
|
|
78915
79088
|
// PR 收件箱:github:* handler spawn 本机 gh CLI,凭据是 clawd 的 GitHub 身份(GH_TOKEN),没有才是 gh 自己的登录态
|
|
78916
|
-
ghRunner: createGhRunner({ token: () => githubIdentity.
|
|
79089
|
+
ghRunner: createGhRunner({ token: async () => (await githubIdentity.refresh())?.token }),
|
|
78917
79090
|
githubIdentity,
|
|
78918
79091
|
visitorStore
|
|
78919
79092
|
})
|
|
@@ -79023,7 +79196,7 @@ async function startDaemon(config) {
|
|
|
79023
79196
|
fetchArtifact: downloadArtifact(runCommand),
|
|
79024
79197
|
debianPackage: lookupDebianPackage(),
|
|
79025
79198
|
githubIdentity,
|
|
79026
|
-
githubApi: (token) => createGithubApi({ token }),
|
|
79199
|
+
githubApi: (token) => createGithubApi({ token, identity: githubIdentity }),
|
|
79027
79200
|
org: PERSONA_REPO_ORG,
|
|
79028
79201
|
claimPublisher: async (personaId2, environment = "production") => {
|
|
79029
79202
|
const loginPass = targetLoginPass(environment);
|