@clawos-dev/clawd 0.2.313 → 0.2.315
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 +391 -38
- package/dist/dispatch/mcp-server.cjs +51 -0
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-WSJ3n_b6.js → guest-BXt2wUpx.js} +133 -133
- package/dist/share-ui/assets/guest-CGOgWqD2.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-C9uDSkcF.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -6584,6 +6584,32 @@ var init_shift_internal = __esm({
|
|
|
6584
6584
|
}
|
|
6585
6585
|
});
|
|
6586
6586
|
|
|
6587
|
+
// ../protocol/src/github.ts
|
|
6588
|
+
var GITHUB_PR_ROLES, REPO_SEGMENT, owner, repo, number, GithubPrListArgs, GithubPrDetailArgs, GithubPrMergeArgs, GithubPrCommentArgs, GithubPrSetReadyArgs, GithubCollaboratorsArgs, GithubPrRequestReviewersArgs;
|
|
6589
|
+
var init_github = __esm({
|
|
6590
|
+
"../protocol/src/github.ts"() {
|
|
6591
|
+
"use strict";
|
|
6592
|
+
init_zod();
|
|
6593
|
+
GITHUB_PR_ROLES = ["created", "review-requested"];
|
|
6594
|
+
REPO_SEGMENT = /^[A-Za-z0-9._-]+$/;
|
|
6595
|
+
owner = external_exports.string().min(1).regex(REPO_SEGMENT);
|
|
6596
|
+
repo = external_exports.string().min(1).regex(REPO_SEGMENT);
|
|
6597
|
+
number = external_exports.number().int().positive();
|
|
6598
|
+
GithubPrListArgs = external_exports.object({ role: external_exports.enum(GITHUB_PR_ROLES) });
|
|
6599
|
+
GithubPrDetailArgs = external_exports.object({ owner, repo, number });
|
|
6600
|
+
GithubPrMergeArgs = external_exports.object({ owner, repo, number, expectedHeadSha: external_exports.string().min(1) });
|
|
6601
|
+
GithubPrCommentArgs = external_exports.object({ owner, repo, number, body: external_exports.string().min(1) });
|
|
6602
|
+
GithubPrSetReadyArgs = external_exports.object({ owner, repo, number, ready: external_exports.boolean() });
|
|
6603
|
+
GithubCollaboratorsArgs = external_exports.object({ owner, repo });
|
|
6604
|
+
GithubPrRequestReviewersArgs = external_exports.object({
|
|
6605
|
+
owner,
|
|
6606
|
+
repo,
|
|
6607
|
+
number,
|
|
6608
|
+
reviewers: external_exports.array(external_exports.string().min(1)).min(1)
|
|
6609
|
+
});
|
|
6610
|
+
}
|
|
6611
|
+
});
|
|
6612
|
+
|
|
6587
6613
|
// ../protocol/src/lark-bot-schemas.ts
|
|
6588
6614
|
var LarkBotPersonaArgs, LarkBotUnbindArgs, LarkBotStatusArgs, LarkBotProvisionArgs, LarkBotProvisionCancelArgs, LARK_BOT_PROVISION_ERROR_REASONS, LarkBotProvisionErrorReasonSchema, LarkBotBindManualArgs, LarkBotGroupSchema, LarkBotStatusResultSchema, LarkBotStateFrameSchema;
|
|
6589
6615
|
var init_lark_bot_schemas = __esm({
|
|
@@ -7878,6 +7904,7 @@ var init_methods = __esm({
|
|
|
7878
7904
|
init_inbox();
|
|
7879
7905
|
init_peer_exec();
|
|
7880
7906
|
init_shift_internal();
|
|
7907
|
+
init_github();
|
|
7881
7908
|
init_lark_bot_schemas();
|
|
7882
7909
|
init_persona_schemas();
|
|
7883
7910
|
init_schemas();
|
|
@@ -8041,6 +8068,38 @@ var init_methods = __esm({
|
|
|
8041
8068
|
summary: "\u5217\u51FA owner \u7684\u5168\u90E8 shift\uFF08\u6392\u73ED\uFF09\uFF0C\u7ED9 UI \u65E5\u5386\u6E32\u67D3\u7528\uFF1Bowner-only",
|
|
8042
8069
|
args: NO_ARGS
|
|
8043
8070
|
},
|
|
8071
|
+
"github:status": {
|
|
8072
|
+
summary: "\u63A2\u6D4B\u672C\u673A gh CLI\uFF08PR \u6536\u4EF6\u7BB1\u524D\u7F6E\uFF09\uFF1A\u662F\u5426\u5B89\u88C5\u3001\u662F\u5426\u5DF2\u767B\u5F55 github.com\u3001\u767B\u5F55\u540D\u3002\u65E0\u53C2\u6570",
|
|
8073
|
+
args: NO_ARGS
|
|
8074
|
+
},
|
|
8075
|
+
"github:prList": {
|
|
8076
|
+
summary: "\u5217 open PR\uFF08\u542B draft\uFF09\u3002role=created \u7531\u6211\u521B\u5EFA / review-requested \u8BF7\u6C42\u6211\u8BC4\u5BA1\uFF1BGitHub \u5168\u57DF search\uFF0Cupdated \u5012\u5E8F",
|
|
8077
|
+
args: GithubPrListArgs
|
|
8078
|
+
},
|
|
8079
|
+
"github:prDetail": {
|
|
8080
|
+
summary: "\u5355\u4E2A PR \u8BE6\u60C5\uFF1A\u5206\u652F/diffstat/\u5BA1\u67E5\u8005/\u8BC4\u8BBA\u6570/checks \u9010\u9879/mergeable/headRefOid\uFF08\u5408\u5E76\u5E76\u53D1\u4FDD\u62A4\u7528\uFF09",
|
|
8081
|
+
args: GithubPrDetailArgs
|
|
8082
|
+
},
|
|
8083
|
+
"github:prMerge": {
|
|
8084
|
+
summary: "squash \u5408\u5E76\u3002expectedHeadSha \u4E0E\u670D\u52A1\u7AEF\u4E0D\u7B26\u65F6\u4E0D\u5408\u5E76\uFF0C\u8FD4\u56DE merged:false + reason=head-changed",
|
|
8085
|
+
args: GithubPrMergeArgs
|
|
8086
|
+
},
|
|
8087
|
+
"github:prComment": {
|
|
8088
|
+
summary: "\u53D1 issue \u8BC4\u8BBA\u5230 PR",
|
|
8089
|
+
args: GithubPrCommentArgs
|
|
8090
|
+
},
|
|
8091
|
+
"github:prSetReady": {
|
|
8092
|
+
summary: "draft\u2194ready \u5207\u6362\uFF1Aready=true \u8F6C\u53EF\u8BC4\u5BA1\uFF0Cfalse \u8F6C\u8349\u7A3F",
|
|
8093
|
+
args: GithubPrSetReadyArgs
|
|
8094
|
+
},
|
|
8095
|
+
"github:collaborators": {
|
|
8096
|
+
summary: "\u5217 repo collaborators \u767B\u5F55\u540D\uFF08\u5BA1\u67E5\u8005\u9009\u4EBA\u540D\u5355\uFF09",
|
|
8097
|
+
args: GithubCollaboratorsArgs
|
|
8098
|
+
},
|
|
8099
|
+
"github:prRequestReviewers": {
|
|
8100
|
+
summary: "\u7ED9 PR \u8BF7\u6C42\u5BA1\u67E5\u8005\uFF08\u8FFD\u52A0\uFF0C\u4E0D\u8986\u76D6\u5DF2\u6709\uFF09",
|
|
8101
|
+
args: GithubPrRequestReviewersArgs
|
|
8102
|
+
},
|
|
8044
8103
|
"shift-internal:add": {
|
|
8045
8104
|
summary: "\u6392\u4E00\u4E2A shift\uFF08\u5230\u70B9\u81EA\u52A8\u62C9\u8D77 persona \u5E72\u6D3B\uFF09\u3002\u7701\u7565 targetPersona = \u6D3E\u7ED9\u8C03\u7528\u65B9\u81EA\u5DF1",
|
|
8046
8105
|
args: ShiftInternalAddArgs
|
|
@@ -8529,6 +8588,7 @@ var init_runtime = __esm({
|
|
|
8529
8588
|
init_dispatch();
|
|
8530
8589
|
init_log();
|
|
8531
8590
|
init_visitor_schemas();
|
|
8591
|
+
init_github();
|
|
8532
8592
|
init_shift_internal();
|
|
8533
8593
|
init_lark_bot_schemas();
|
|
8534
8594
|
init_lark_bot_format();
|
|
@@ -11987,11 +12047,11 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
11987
12047
|
}
|
|
11988
12048
|
return value === void 0 ? Infinity : value;
|
|
11989
12049
|
}
|
|
11990
|
-
function getItemCount(
|
|
11991
|
-
if (
|
|
12050
|
+
function getItemCount(number2) {
|
|
12051
|
+
if (number2 === 1) {
|
|
11992
12052
|
return "1 item";
|
|
11993
12053
|
}
|
|
11994
|
-
return `${
|
|
12054
|
+
return `${number2} items`;
|
|
11995
12055
|
}
|
|
11996
12056
|
function getUniqueReplacerSet(replacerArray) {
|
|
11997
12057
|
const replacerSet = /* @__PURE__ */ new Set();
|
|
@@ -12708,8 +12768,8 @@ var require_pino = __commonJS({
|
|
|
12708
12768
|
bindings(bindings) {
|
|
12709
12769
|
return bindings;
|
|
12710
12770
|
},
|
|
12711
|
-
level(label,
|
|
12712
|
-
return { level:
|
|
12771
|
+
level(label, number2) {
|
|
12772
|
+
return { level: number2 };
|
|
12713
12773
|
}
|
|
12714
12774
|
}),
|
|
12715
12775
|
hooks: {
|
|
@@ -22167,19 +22227,19 @@ var require_luxon = __commonJS({
|
|
|
22167
22227
|
return Math.floor(f);
|
|
22168
22228
|
}
|
|
22169
22229
|
}
|
|
22170
|
-
function roundTo(
|
|
22230
|
+
function roundTo(number2, digits, rounding = "round") {
|
|
22171
22231
|
const factor = 10 ** digits;
|
|
22172
22232
|
switch (rounding) {
|
|
22173
22233
|
case "expand":
|
|
22174
|
-
return
|
|
22234
|
+
return number2 > 0 ? Math.ceil(number2 * factor) / factor : Math.floor(number2 * factor) / factor;
|
|
22175
22235
|
case "trunc":
|
|
22176
|
-
return Math.trunc(
|
|
22236
|
+
return Math.trunc(number2 * factor) / factor;
|
|
22177
22237
|
case "round":
|
|
22178
|
-
return Math.round(
|
|
22238
|
+
return Math.round(number2 * factor) / factor;
|
|
22179
22239
|
case "floor":
|
|
22180
|
-
return Math.floor(
|
|
22240
|
+
return Math.floor(number2 * factor) / factor;
|
|
22181
22241
|
case "ceil":
|
|
22182
|
-
return Math.ceil(
|
|
22242
|
+
return Math.ceil(number2 * factor) / factor;
|
|
22183
22243
|
default:
|
|
22184
22244
|
throw new RangeError(`Value rounding ${rounding} is out of range`);
|
|
22185
22245
|
}
|
|
@@ -51598,6 +51658,43 @@ function createShiftStore(deps) {
|
|
|
51598
51658
|
return { load, flushNow, list, get, add, update, remove, appendRun, patchState };
|
|
51599
51659
|
}
|
|
51600
51660
|
|
|
51661
|
+
// src/github/gh.ts
|
|
51662
|
+
var import_node_child_process7 = require("child_process");
|
|
51663
|
+
var GhError = class extends Error {
|
|
51664
|
+
constructor(kind, message, stderr) {
|
|
51665
|
+
super(message);
|
|
51666
|
+
this.kind = kind;
|
|
51667
|
+
this.stderr = stderr;
|
|
51668
|
+
this.name = "GhError";
|
|
51669
|
+
}
|
|
51670
|
+
kind;
|
|
51671
|
+
stderr;
|
|
51672
|
+
};
|
|
51673
|
+
var DEFAULT_TIMEOUT_MS2 = 15e3;
|
|
51674
|
+
var MAX_BUFFER = 4 * 1024 * 1024;
|
|
51675
|
+
function createGhRunner(defaults) {
|
|
51676
|
+
const baseTimeoutMs = defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
51677
|
+
return {
|
|
51678
|
+
run(args, opts) {
|
|
51679
|
+
return new Promise((resolve6, reject) => {
|
|
51680
|
+
(0, import_node_child_process7.execFile)(
|
|
51681
|
+
"gh",
|
|
51682
|
+
args,
|
|
51683
|
+
{ timeout: opts?.timeoutMs ?? baseTimeoutMs, maxBuffer: MAX_BUFFER },
|
|
51684
|
+
(err, stdout, stderr) => {
|
|
51685
|
+
if (!err) return resolve6(stdout);
|
|
51686
|
+
if (err.code === "ENOENT") {
|
|
51687
|
+
return reject(new GhError("gh-missing", "GitHub CLI (gh) \u672A\u5B89\u88C5"));
|
|
51688
|
+
}
|
|
51689
|
+
const detail = (stderr ?? "").trim();
|
|
51690
|
+
reject(new GhError("gh-error", detail !== "" ? detail : err.message, detail));
|
|
51691
|
+
}
|
|
51692
|
+
);
|
|
51693
|
+
});
|
|
51694
|
+
}
|
|
51695
|
+
};
|
|
51696
|
+
}
|
|
51697
|
+
|
|
51601
51698
|
// src/shift/scheduler.ts
|
|
51602
51699
|
function cleanupOrphanRunningRuns(store, now) {
|
|
51603
51700
|
for (const shift of store.list()) {
|
|
@@ -56435,7 +56532,7 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
56435
56532
|
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
56436
56533
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
56437
56534
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
56438
|
-
var
|
|
56535
|
+
var import_node_child_process10 = require("child_process");
|
|
56439
56536
|
|
|
56440
56537
|
// src/tunnel/tunnel-store.ts
|
|
56441
56538
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
@@ -56571,7 +56668,7 @@ function escape(v2) {
|
|
|
56571
56668
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
56572
56669
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
56573
56670
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
56574
|
-
var
|
|
56671
|
+
var import_node_child_process8 = require("child_process");
|
|
56575
56672
|
var import_node_stream3 = require("stream");
|
|
56576
56673
|
var import_promises5 = require("stream/promises");
|
|
56577
56674
|
var FRPC_VERSION = "0.68.0";
|
|
@@ -56671,7 +56768,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
56671
56768
|
import_node_fs38.default.mkdirSync(work, { recursive: true });
|
|
56672
56769
|
try {
|
|
56673
56770
|
await new Promise((resolve6, reject) => {
|
|
56674
|
-
const proc = (0,
|
|
56771
|
+
const proc = (0, import_node_child_process8.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
56675
56772
|
proc.on("error", reject);
|
|
56676
56773
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
56677
56774
|
});
|
|
@@ -56689,7 +56786,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
56689
56786
|
// src/tunnel/frpc-process.ts
|
|
56690
56787
|
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
56691
56788
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
56692
|
-
var
|
|
56789
|
+
var import_node_child_process9 = require("child_process");
|
|
56693
56790
|
function frpcPidFilePath(dataDir) {
|
|
56694
56791
|
return import_node_path43.default.join(dataDir, "frpc.pid");
|
|
56695
56792
|
}
|
|
@@ -56775,7 +56872,7 @@ async function killStaleFrpc(deps) {
|
|
|
56775
56872
|
async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
|
|
56776
56873
|
if (process.platform === "win32") return [];
|
|
56777
56874
|
return new Promise((resolve6) => {
|
|
56778
|
-
const ps = (0,
|
|
56875
|
+
const ps = (0, import_node_child_process9.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
|
|
56779
56876
|
let buf = "";
|
|
56780
56877
|
ps.stdout.on("data", (c) => {
|
|
56781
56878
|
buf += c.toString();
|
|
@@ -56944,7 +57041,7 @@ var TunnelManager = class {
|
|
|
56944
57041
|
logLevel: "info"
|
|
56945
57042
|
});
|
|
56946
57043
|
await import_node_fs40.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
56947
|
-
const proc = (this.deps.spawnImpl ??
|
|
57044
|
+
const proc = (this.deps.spawnImpl ?? import_node_child_process10.spawn)(frpcBin, ["-c", tomlPath], {
|
|
56948
57045
|
stdio: ["ignore", "pipe", "pipe"]
|
|
56949
57046
|
});
|
|
56950
57047
|
const logDir = import_node_path44.default.join(this.deps.dataDir, "log");
|
|
@@ -57436,11 +57533,11 @@ var DeviceBindingClientError = class extends Error {
|
|
|
57436
57533
|
code;
|
|
57437
57534
|
cause;
|
|
57438
57535
|
};
|
|
57439
|
-
var
|
|
57536
|
+
var DEFAULT_TIMEOUT_MS3 = 8e3;
|
|
57440
57537
|
async function upsertDeviceBinding(opts) {
|
|
57441
57538
|
const doFetch = opts.fetchImpl ?? fetch;
|
|
57442
57539
|
const ac = new AbortController();
|
|
57443
|
-
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ??
|
|
57540
|
+
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS3);
|
|
57444
57541
|
const body = { unionId: opts.unionId };
|
|
57445
57542
|
if (opts.avatarUrl != null) body.avatarUrl = opts.avatarUrl;
|
|
57446
57543
|
let res;
|
|
@@ -58406,11 +58503,11 @@ init_protocol();
|
|
|
58406
58503
|
init_protocol();
|
|
58407
58504
|
|
|
58408
58505
|
// src/workspace/git.ts
|
|
58409
|
-
var
|
|
58506
|
+
var import_node_child_process11 = require("child_process");
|
|
58410
58507
|
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
58411
58508
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
58412
58509
|
var import_node_util = require("util");
|
|
58413
|
-
var pexec = (0, import_node_util.promisify)(
|
|
58510
|
+
var pexec = (0, import_node_util.promisify)(import_node_child_process11.execFile);
|
|
58414
58511
|
function normalizePath(p2) {
|
|
58415
58512
|
const resolved = import_node_path50.default.resolve(p2);
|
|
58416
58513
|
try {
|
|
@@ -58912,7 +59009,7 @@ function buildWhoamiHandler(deps) {
|
|
|
58912
59009
|
}
|
|
58913
59010
|
};
|
|
58914
59011
|
}
|
|
58915
|
-
const
|
|
59012
|
+
const owner2 = {
|
|
58916
59013
|
...makeOwnerPrincipal(deps.ownerPrincipalId, identity.displayName),
|
|
58917
59014
|
ownerId: identity.ownerId,
|
|
58918
59015
|
provider: identity.provider
|
|
@@ -58956,7 +59053,7 @@ function buildWhoamiHandler(deps) {
|
|
|
58956
59053
|
return {
|
|
58957
59054
|
response: {
|
|
58958
59055
|
type: "whoami:ok",
|
|
58959
|
-
owner,
|
|
59056
|
+
owner: owner2,
|
|
58960
59057
|
capability,
|
|
58961
59058
|
grantedPersonas
|
|
58962
59059
|
}
|
|
@@ -59210,6 +59307,15 @@ var METHOD_GRANT_MAP = {
|
|
|
59210
59307
|
// ---- shift:* (排班 mock,owner-only 读) ----
|
|
59211
59308
|
// mock 阶段只 owner 用;接 guest 后再考虑分级
|
|
59212
59309
|
"shift:list": ADMIN_ANY,
|
|
59310
|
+
// github:*(PR 收件箱,spec 2026-08-11):走 owner 本机 gh 凭据,owner-only 一刀切
|
|
59311
|
+
"github:status": ADMIN_ANY,
|
|
59312
|
+
"github:prList": ADMIN_ANY,
|
|
59313
|
+
"github:prDetail": ADMIN_ANY,
|
|
59314
|
+
"github:prMerge": ADMIN_ANY,
|
|
59315
|
+
"github:prComment": ADMIN_ANY,
|
|
59316
|
+
"github:prSetReady": ADMIN_ANY,
|
|
59317
|
+
"github:collaborators": ADMIN_ANY,
|
|
59318
|
+
"github:prRequestReviewers": ADMIN_ANY,
|
|
59213
59319
|
// ---- shift-internal:* + inbox:sendDm + personaDispatch complete/list ----
|
|
59214
59320
|
// 统一 RPC 鉴权(spec 2026-07-28):原 /api/rpc 白名单 method 收编。调用方 = 本机
|
|
59215
59321
|
// MCP server 持 owner token → ADMIN_ANY 即「owner token 即可」;业务归因(sendDm 的
|
|
@@ -59356,7 +59462,7 @@ function computeMethodAccess(args) {
|
|
|
59356
59462
|
}
|
|
59357
59463
|
|
|
59358
59464
|
// src/version.ts
|
|
59359
|
-
var version = "0.2.
|
|
59465
|
+
var version = "0.2.315".length > 0 ? "0.2.315" : "dev";
|
|
59360
59466
|
|
|
59361
59467
|
// src/cli-probe/probe.ts
|
|
59362
59468
|
var fs56 = __toESM(require("fs"), 1);
|
|
@@ -60372,7 +60478,7 @@ function buildExtensionHandlers(deps) {
|
|
|
60372
60478
|
|
|
60373
60479
|
// src/app-builder/project-store.ts
|
|
60374
60480
|
var import_node_fs46 = require("fs");
|
|
60375
|
-
var
|
|
60481
|
+
var import_node_child_process12 = require("child_process");
|
|
60376
60482
|
var import_node_path57 = require("path");
|
|
60377
60483
|
init_protocol();
|
|
60378
60484
|
var PROJECTS_DIR = "projects";
|
|
@@ -60477,7 +60583,7 @@ var ProjectStore = class {
|
|
|
60477
60583
|
async scaffold(name, templateSrcDir, scaffoldScriptPath) {
|
|
60478
60584
|
const destDir = this.projectDir(name);
|
|
60479
60585
|
return await new Promise((resolve6, reject) => {
|
|
60480
|
-
const child = (0,
|
|
60586
|
+
const child = (0, import_node_child_process12.spawn)("bash", [scaffoldScriptPath, name, templateSrcDir, destDir], {
|
|
60481
60587
|
env: { ...process.env, PATH: process.env.PATH ?? "" },
|
|
60482
60588
|
stdio: ["ignore", "pipe", "pipe"]
|
|
60483
60589
|
});
|
|
@@ -60581,7 +60687,7 @@ var ProjectStore = class {
|
|
|
60581
60687
|
};
|
|
60582
60688
|
|
|
60583
60689
|
// src/app-builder/kill-port.ts
|
|
60584
|
-
var
|
|
60690
|
+
var import_node_child_process13 = require("child_process");
|
|
60585
60691
|
async function killPortOccupants(port, ownedPids, logger) {
|
|
60586
60692
|
let pids;
|
|
60587
60693
|
try {
|
|
@@ -60623,7 +60729,7 @@ async function killPortOccupants(port, ownedPids, logger) {
|
|
|
60623
60729
|
}
|
|
60624
60730
|
function listPidsOnPort(port) {
|
|
60625
60731
|
return new Promise((resolve6, reject) => {
|
|
60626
|
-
(0,
|
|
60732
|
+
(0, import_node_child_process13.execFile)(
|
|
60627
60733
|
"lsof",
|
|
60628
60734
|
["-ti", `:${port}`],
|
|
60629
60735
|
{ timeout: 3e3 },
|
|
@@ -60695,7 +60801,7 @@ var PublishJobRegistry = class {
|
|
|
60695
60801
|
};
|
|
60696
60802
|
|
|
60697
60803
|
// src/app-builder/publish-job-runner.ts
|
|
60698
|
-
var
|
|
60804
|
+
var import_node_child_process14 = require("child_process");
|
|
60699
60805
|
var import_node_fs47 = require("fs");
|
|
60700
60806
|
var import_node_path58 = require("path");
|
|
60701
60807
|
|
|
@@ -60724,7 +60830,7 @@ function tailStderrLines(buf, n) {
|
|
|
60724
60830
|
// src/app-builder/publish-job-runner.ts
|
|
60725
60831
|
async function startPublishJob(deps, args) {
|
|
60726
60832
|
const { registry: registry2, projectDir } = deps;
|
|
60727
|
-
const spawn12 = deps.spawnImpl ??
|
|
60833
|
+
const spawn12 = deps.spawnImpl ?? import_node_child_process14.spawn;
|
|
60728
60834
|
if (registry2.has(args.name)) {
|
|
60729
60835
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
60730
60836
|
}
|
|
@@ -61494,6 +61600,250 @@ function buildShiftHandlers(deps) {
|
|
|
61494
61600
|
};
|
|
61495
61601
|
}
|
|
61496
61602
|
|
|
61603
|
+
// src/handlers/github.ts
|
|
61604
|
+
init_protocol();
|
|
61605
|
+
|
|
61606
|
+
// src/github/graphql.ts
|
|
61607
|
+
function buildPrSearchQuery(role) {
|
|
61608
|
+
const roleQualifier = role === "created" ? "author:@me" : "review-requested:@me";
|
|
61609
|
+
return `is:pr is:open ${roleQualifier} sort:updated-desc`;
|
|
61610
|
+
}
|
|
61611
|
+
var PR_LIST_QUERY = `
|
|
61612
|
+
query($searchQuery: String!, $first: Int!) {
|
|
61613
|
+
search(query: $searchQuery, type: ISSUE, first: $first) {
|
|
61614
|
+
nodes {
|
|
61615
|
+
... on PullRequest {
|
|
61616
|
+
number title isDraft updatedAt additions deletions headRefName
|
|
61617
|
+
author { login }
|
|
61618
|
+
repository { nameWithOwner }
|
|
61619
|
+
commits(last: 1) { nodes { commit { statusCheckRollup { state } } } }
|
|
61620
|
+
}
|
|
61621
|
+
}
|
|
61622
|
+
}
|
|
61623
|
+
}`;
|
|
61624
|
+
var PR_DETAIL_QUERY = `
|
|
61625
|
+
query($owner: String!, $repo: String!, $number: Int!) {
|
|
61626
|
+
repository(owner: $owner, name: $repo) {
|
|
61627
|
+
pullRequest(number: $number) {
|
|
61628
|
+
number title body state isDraft updatedAt additions deletions
|
|
61629
|
+
headRefName baseRefName headRefOid mergeable
|
|
61630
|
+
author { login }
|
|
61631
|
+
reviewRequests(first: 50) { nodes { requestedReviewer { ... on User { login } } } }
|
|
61632
|
+
comments { totalCount }
|
|
61633
|
+
commits(last: 1) { nodes { commit { statusCheckRollup {
|
|
61634
|
+
state
|
|
61635
|
+
contexts(first: 100) { nodes {
|
|
61636
|
+
__typename
|
|
61637
|
+
... on CheckRun { name status conclusion }
|
|
61638
|
+
... on StatusContext { context state }
|
|
61639
|
+
} }
|
|
61640
|
+
} } } }
|
|
61641
|
+
}
|
|
61642
|
+
}
|
|
61643
|
+
}`;
|
|
61644
|
+
function mapRollupState(state) {
|
|
61645
|
+
if (state == null) return "none";
|
|
61646
|
+
if (state === "SUCCESS") return "success";
|
|
61647
|
+
if (state === "PENDING" || state === "EXPECTED") return "pending";
|
|
61648
|
+
return "failure";
|
|
61649
|
+
}
|
|
61650
|
+
function mapCheckNode(node) {
|
|
61651
|
+
if (node.__typename === "CheckRun") {
|
|
61652
|
+
const name = typeof node.name === "string" ? node.name : "";
|
|
61653
|
+
if (name === "") return null;
|
|
61654
|
+
if (node.status !== "COMPLETED") return { name, conclusion: "pending" };
|
|
61655
|
+
return { name, conclusion: node.conclusion === "SUCCESS" ? "success" : "failure" };
|
|
61656
|
+
}
|
|
61657
|
+
if (node.__typename === "StatusContext") {
|
|
61658
|
+
const name = typeof node.context === "string" ? node.context : "";
|
|
61659
|
+
if (name === "") return null;
|
|
61660
|
+
if (node.state === "SUCCESS") return { name, conclusion: "success" };
|
|
61661
|
+
if (node.state === "PENDING" || node.state === "EXPECTED") return { name, conclusion: "pending" };
|
|
61662
|
+
return { name, conclusion: "failure" };
|
|
61663
|
+
}
|
|
61664
|
+
return null;
|
|
61665
|
+
}
|
|
61666
|
+
function mapPrState(state, isDraft) {
|
|
61667
|
+
if (state === "MERGED") return "merged";
|
|
61668
|
+
if (state === "CLOSED") return "closed";
|
|
61669
|
+
return isDraft === true ? "draft" : "open";
|
|
61670
|
+
}
|
|
61671
|
+
function asRecord(v2) {
|
|
61672
|
+
return typeof v2 === "object" && v2 !== null ? v2 : {};
|
|
61673
|
+
}
|
|
61674
|
+
function lastCommitRollup(node) {
|
|
61675
|
+
const first = asRecord(node.commits).nodes?.[0];
|
|
61676
|
+
return asRecord(asRecord(first).commit).statusCheckRollup;
|
|
61677
|
+
}
|
|
61678
|
+
function parsePrListResponse(json) {
|
|
61679
|
+
const nodes = asRecord(asRecord(asRecord(json).data).search).nodes ?? [];
|
|
61680
|
+
const items = [];
|
|
61681
|
+
for (const raw of nodes) {
|
|
61682
|
+
const n = asRecord(raw);
|
|
61683
|
+
if (typeof n.number !== "number") continue;
|
|
61684
|
+
const nameWithOwner = String(asRecord(n.repository).nameWithOwner ?? "");
|
|
61685
|
+
const slash = nameWithOwner.indexOf("/");
|
|
61686
|
+
if (slash <= 0) continue;
|
|
61687
|
+
const rollup = lastCommitRollup(n);
|
|
61688
|
+
items.push({
|
|
61689
|
+
owner: nameWithOwner.slice(0, slash),
|
|
61690
|
+
repo: nameWithOwner.slice(slash + 1),
|
|
61691
|
+
number: n.number,
|
|
61692
|
+
title: String(n.title ?? ""),
|
|
61693
|
+
state: mapPrState("OPEN", n.isDraft),
|
|
61694
|
+
headRef: String(n.headRefName ?? ""),
|
|
61695
|
+
additions: typeof n.additions === "number" ? n.additions : 0,
|
|
61696
|
+
deletions: typeof n.deletions === "number" ? n.deletions : 0,
|
|
61697
|
+
updatedAt: String(n.updatedAt ?? ""),
|
|
61698
|
+
author: String(asRecord(n.author).login ?? ""),
|
|
61699
|
+
checksRollup: rollup == null ? "none" : mapRollupState(asRecord(rollup).state)
|
|
61700
|
+
});
|
|
61701
|
+
}
|
|
61702
|
+
return items;
|
|
61703
|
+
}
|
|
61704
|
+
function parsePrDetailResponse(json, repoRef) {
|
|
61705
|
+
const pr = asRecord(asRecord(asRecord(json).data).repository).pullRequest;
|
|
61706
|
+
if (pr == null || typeof pr !== "object") return null;
|
|
61707
|
+
const n = asRecord(pr);
|
|
61708
|
+
const rollup = lastCommitRollup(n);
|
|
61709
|
+
const contextNodes = asRecord(asRecord(rollup).contexts).nodes ?? [];
|
|
61710
|
+
const checks = [];
|
|
61711
|
+
for (const c of contextNodes) {
|
|
61712
|
+
const mapped = mapCheckNode(asRecord(c));
|
|
61713
|
+
if (mapped) checks.push(mapped);
|
|
61714
|
+
}
|
|
61715
|
+
const reviewerNodes = asRecord(n.reviewRequests).nodes ?? [];
|
|
61716
|
+
const reviewers = reviewerNodes.map((r) => String(asRecord(asRecord(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
|
|
61717
|
+
const mergeable = n.mergeable === "MERGEABLE" ? "mergeable" : n.mergeable === "CONFLICTING" ? "conflicting" : "unknown";
|
|
61718
|
+
const commentCountRaw = asRecord(n.comments).totalCount;
|
|
61719
|
+
return {
|
|
61720
|
+
owner: repoRef.owner,
|
|
61721
|
+
repo: repoRef.repo,
|
|
61722
|
+
number: typeof n.number === "number" ? n.number : 0,
|
|
61723
|
+
title: String(n.title ?? ""),
|
|
61724
|
+
body: String(n.body ?? ""),
|
|
61725
|
+
state: mapPrState(n.state, n.isDraft),
|
|
61726
|
+
author: String(asRecord(n.author).login ?? ""),
|
|
61727
|
+
updatedAt: String(n.updatedAt ?? ""),
|
|
61728
|
+
headRef: String(n.headRefName ?? ""),
|
|
61729
|
+
baseRef: String(n.baseRefName ?? ""),
|
|
61730
|
+
headSha: String(n.headRefOid ?? ""),
|
|
61731
|
+
additions: typeof n.additions === "number" ? n.additions : 0,
|
|
61732
|
+
deletions: typeof n.deletions === "number" ? n.deletions : 0,
|
|
61733
|
+
mergeable,
|
|
61734
|
+
reviewers,
|
|
61735
|
+
commentCount: typeof commentCountRaw === "number" ? commentCountRaw : 0,
|
|
61736
|
+
checksRollup: rollup == null ? "none" : mapRollupState(asRecord(rollup).state),
|
|
61737
|
+
checks
|
|
61738
|
+
};
|
|
61739
|
+
}
|
|
61740
|
+
|
|
61741
|
+
// src/handlers/github.ts
|
|
61742
|
+
var HOSTNAME = "github.com";
|
|
61743
|
+
function buildGithubHandlers(deps) {
|
|
61744
|
+
const { gh } = deps;
|
|
61745
|
+
return {
|
|
61746
|
+
"github:status": async () => {
|
|
61747
|
+
try {
|
|
61748
|
+
await gh.run(["--version"]);
|
|
61749
|
+
} catch (err) {
|
|
61750
|
+
if (err instanceof GhError && err.kind === "gh-missing") {
|
|
61751
|
+
return { response: { installed: false, authenticated: false } };
|
|
61752
|
+
}
|
|
61753
|
+
throw err;
|
|
61754
|
+
}
|
|
61755
|
+
try {
|
|
61756
|
+
await gh.run(["auth", "status", "--active", "--hostname", HOSTNAME]);
|
|
61757
|
+
} catch {
|
|
61758
|
+
return { response: { installed: true, authenticated: false } };
|
|
61759
|
+
}
|
|
61760
|
+
const login = (await gh.run(["api", "user", "--jq", ".login"])).trim();
|
|
61761
|
+
const response = { installed: true, authenticated: true, login };
|
|
61762
|
+
return { response };
|
|
61763
|
+
},
|
|
61764
|
+
"github:prList": async (frame) => {
|
|
61765
|
+
const { role } = GithubPrListArgs.parse(frame);
|
|
61766
|
+
const stdout = await gh.run([
|
|
61767
|
+
"api",
|
|
61768
|
+
"graphql",
|
|
61769
|
+
"-f",
|
|
61770
|
+
`query=${PR_LIST_QUERY}`,
|
|
61771
|
+
"-f",
|
|
61772
|
+
`searchQuery=${buildPrSearchQuery(role)}`,
|
|
61773
|
+
"-F",
|
|
61774
|
+
// 上限 50:超出即静默截断(收件箱语义按 updated 倒序取最近的,够用;真溢出再谈分页)
|
|
61775
|
+
"first=50"
|
|
61776
|
+
]);
|
|
61777
|
+
const prs = parsePrListResponse(JSON.parse(stdout));
|
|
61778
|
+
return { response: { prs } };
|
|
61779
|
+
},
|
|
61780
|
+
"github:prDetail": async (frame) => {
|
|
61781
|
+
const { owner: owner2, repo: repo2, number: number2 } = GithubPrDetailArgs.parse(frame);
|
|
61782
|
+
const stdout = await gh.run([
|
|
61783
|
+
"api",
|
|
61784
|
+
"graphql",
|
|
61785
|
+
"-f",
|
|
61786
|
+
`query=${PR_DETAIL_QUERY}`,
|
|
61787
|
+
"-f",
|
|
61788
|
+
`owner=${owner2}`,
|
|
61789
|
+
"-f",
|
|
61790
|
+
`repo=${repo2}`,
|
|
61791
|
+
"-F",
|
|
61792
|
+
`number=${number2}`
|
|
61793
|
+
]);
|
|
61794
|
+
const pr = parsePrDetailResponse(JSON.parse(stdout), { owner: owner2, repo: repo2 });
|
|
61795
|
+
return { response: { pr } };
|
|
61796
|
+
},
|
|
61797
|
+
"github:prMerge": async (frame) => {
|
|
61798
|
+
const { owner: owner2, repo: repo2, number: number2, expectedHeadSha } = GithubPrMergeArgs.parse(frame);
|
|
61799
|
+
try {
|
|
61800
|
+
await gh.run([
|
|
61801
|
+
"pr",
|
|
61802
|
+
"merge",
|
|
61803
|
+
String(number2),
|
|
61804
|
+
"--repo",
|
|
61805
|
+
`${owner2}/${repo2}`,
|
|
61806
|
+
"--squash",
|
|
61807
|
+
"--match-head-commit",
|
|
61808
|
+
expectedHeadSha
|
|
61809
|
+
]);
|
|
61810
|
+
} catch (err) {
|
|
61811
|
+
if (err instanceof GhError && /head/i.test(err.message) && /modif|match/i.test(err.message)) {
|
|
61812
|
+
return { response: { merged: false, reason: "head-changed", message: err.message } };
|
|
61813
|
+
}
|
|
61814
|
+
throw err;
|
|
61815
|
+
}
|
|
61816
|
+
return { response: { merged: true } };
|
|
61817
|
+
},
|
|
61818
|
+
"github:prComment": async (frame) => {
|
|
61819
|
+
const { owner: owner2, repo: repo2, number: number2, body } = GithubPrCommentArgs.parse(frame);
|
|
61820
|
+
await gh.run(["api", `repos/${owner2}/${repo2}/issues/${number2}/comments`, "-f", `body=${body}`]);
|
|
61821
|
+
return { response: { posted: true } };
|
|
61822
|
+
},
|
|
61823
|
+
"github:prSetReady": async (frame) => {
|
|
61824
|
+
const { owner: owner2, repo: repo2, number: number2, ready } = GithubPrSetReadyArgs.parse(frame);
|
|
61825
|
+
const args = ["pr", "ready", String(number2), "--repo", `${owner2}/${repo2}`];
|
|
61826
|
+
if (!ready) args.push("--undo");
|
|
61827
|
+
await gh.run(args);
|
|
61828
|
+
return { response: { updated: true } };
|
|
61829
|
+
},
|
|
61830
|
+
"github:collaborators": async (frame) => {
|
|
61831
|
+
const { owner: owner2, repo: repo2 } = GithubCollaboratorsArgs.parse(frame);
|
|
61832
|
+
const stdout = await gh.run(["api", `repos/${owner2}/${repo2}/collaborators?per_page=100`]);
|
|
61833
|
+
const arr = JSON.parse(stdout);
|
|
61834
|
+
const logins = arr.map((c) => String(c.login ?? "")).filter((s) => s !== "");
|
|
61835
|
+
return { response: { logins } };
|
|
61836
|
+
},
|
|
61837
|
+
"github:prRequestReviewers": async (frame) => {
|
|
61838
|
+
const { owner: owner2, repo: repo2, number: number2, reviewers } = GithubPrRequestReviewersArgs.parse(frame);
|
|
61839
|
+
const args = ["api", "-X", "POST", `repos/${owner2}/${repo2}/pulls/${number2}/requested_reviewers`];
|
|
61840
|
+
for (const r of reviewers) args.push("-f", `reviewers[]=${r}`);
|
|
61841
|
+
await gh.run(args);
|
|
61842
|
+
return { response: { requested: true } };
|
|
61843
|
+
}
|
|
61844
|
+
};
|
|
61845
|
+
}
|
|
61846
|
+
|
|
61497
61847
|
// src/handlers/visitor.ts
|
|
61498
61848
|
init_protocol();
|
|
61499
61849
|
function ensureOwner4(ctx) {
|
|
@@ -61611,15 +61961,15 @@ var import_node_crypto18 = require("crypto");
|
|
|
61611
61961
|
init_protocol();
|
|
61612
61962
|
|
|
61613
61963
|
// src/peer-ops/run-command.ts
|
|
61614
|
-
var
|
|
61964
|
+
var import_node_child_process15 = require("child_process");
|
|
61615
61965
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
61616
|
-
var
|
|
61966
|
+
var DEFAULT_TIMEOUT_MS4 = 3e4;
|
|
61617
61967
|
var MAX_TIMEOUT_MS = 3e5;
|
|
61618
61968
|
var MAX_OUTPUT_BYTES = 1048576;
|
|
61619
61969
|
function runCommand(command, opts = {}) {
|
|
61620
|
-
const timeoutMs = Math.min(opts.timeoutMs ??
|
|
61970
|
+
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS4, MAX_TIMEOUT_MS);
|
|
61621
61971
|
return new Promise((resolve6) => {
|
|
61622
|
-
const child = (0,
|
|
61972
|
+
const child = (0, import_node_child_process15.spawn)("bash", ["-c", command], { cwd: import_node_os21.default.homedir() });
|
|
61623
61973
|
const out = [];
|
|
61624
61974
|
const err = [];
|
|
61625
61975
|
let outBytes = 0;
|
|
@@ -61824,6 +62174,7 @@ function buildMethodHandlers(deps) {
|
|
|
61824
62174
|
ownerIdProvider: deps.shiftOwnerIdProvider,
|
|
61825
62175
|
now: () => Date.now()
|
|
61826
62176
|
}),
|
|
62177
|
+
...buildGithubHandlers({ gh: deps.ghRunner }),
|
|
61827
62178
|
...buildVisitorHandlers({ visitorStore: deps.visitorStore })
|
|
61828
62179
|
};
|
|
61829
62180
|
handlers["meta:methods"] = buildMetaMethodsHandler({
|
|
@@ -61834,7 +62185,7 @@ function buildMethodHandlers(deps) {
|
|
|
61834
62185
|
}
|
|
61835
62186
|
|
|
61836
62187
|
// src/app-builder/dev-server-supervisor.ts
|
|
61837
|
-
var
|
|
62188
|
+
var import_node_child_process16 = require("child_process");
|
|
61838
62189
|
var import_node_events2 = require("events");
|
|
61839
62190
|
var DEFAULT_READY_PATTERN = /Local:\s+https?:\/\/|Nest application successfully started|server listening on/i;
|
|
61840
62191
|
var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
@@ -61871,7 +62222,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
61871
62222
|
tunnelHost: args.tunnelHost,
|
|
61872
62223
|
devCommand: cmd
|
|
61873
62224
|
});
|
|
61874
|
-
const child = (0,
|
|
62225
|
+
const child = (0, import_node_child_process16.spawn)("sh", ["-c", cmd], {
|
|
61875
62226
|
cwd: args.cwd,
|
|
61876
62227
|
env,
|
|
61877
62228
|
stdio: "pipe",
|
|
@@ -62123,7 +62474,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
62123
62474
|
}
|
|
62124
62475
|
|
|
62125
62476
|
// src/extension/runtime.ts
|
|
62126
|
-
var
|
|
62477
|
+
var import_node_child_process17 = require("child_process");
|
|
62127
62478
|
var import_node_path62 = __toESM(require("path"), 1);
|
|
62128
62479
|
var import_promises12 = require("timers/promises");
|
|
62129
62480
|
|
|
@@ -62231,7 +62582,7 @@ var Runtime = class {
|
|
|
62231
62582
|
CLAWOS_EXT_PORT: String(port),
|
|
62232
62583
|
CLAWOS_EXT_ID: extId
|
|
62233
62584
|
};
|
|
62234
|
-
const child = (0,
|
|
62585
|
+
const child = (0, import_node_child_process17.spawn)("sh", ["-c", cmd], {
|
|
62235
62586
|
cwd: dir,
|
|
62236
62587
|
env,
|
|
62237
62588
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -63284,6 +63635,8 @@ async function startDaemon(config) {
|
|
|
63284
63635
|
// daemon 稳定身份),跟我们 ShiftStore boot 时用的 provider 一致。
|
|
63285
63636
|
shiftStore,
|
|
63286
63637
|
shiftOwnerIdProvider: () => ownerPrincipalId,
|
|
63638
|
+
// PR 收件箱:github:* handler spawn 本机 gh CLI(凭据复用 gh 登录态)
|
|
63639
|
+
ghRunner: createGhRunner(),
|
|
63287
63640
|
// persona web 分享:visitor:list owner RPC 读访客名单(同 exchange upsert 的实例)
|
|
63288
63641
|
visitorStore
|
|
63289
63642
|
})
|