oasis_test_v2 2.2.84 → 2.2.85
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/index.js +304 -42
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2977,6 +2977,7 @@ async function fetchResultPackage(base, fetchImpl, runId) {
|
|
|
2977
2977
|
function toEpochMs(v2) {
|
|
2978
2978
|
if (typeof v2 === "number" && Number.isFinite(v2)) return v2;
|
|
2979
2979
|
if (typeof v2 === "string" && v2.length > 0) {
|
|
2980
|
+
if (/^\d+(\.\d+)?$/.test(v2.trim())) return Number(v2.trim());
|
|
2980
2981
|
const ms = Date.parse(v2);
|
|
2981
2982
|
return Number.isNaN(ms) ? void 0 : ms;
|
|
2982
2983
|
}
|
|
@@ -2993,6 +2994,98 @@ function latestSucceededRun(runs) {
|
|
|
2993
2994
|
}
|
|
2994
2995
|
return best;
|
|
2995
2996
|
}
|
|
2997
|
+
function liveBoardRuns(st) {
|
|
2998
|
+
const out = [];
|
|
2999
|
+
const known = /* @__PURE__ */ new Set();
|
|
3000
|
+
for (const t of st.turns ?? []) {
|
|
3001
|
+
if (t.runId !== null) known.add(t.runId);
|
|
3002
|
+
if (isTerminalRunStatus(t.status)) continue;
|
|
3003
|
+
out.push({ key: t.runId ?? `msg:${t.messageId ?? "?"}`, status: t.status, ...t.agentId ? { agentId: t.agentId } : {}, source: "conversation" });
|
|
3004
|
+
}
|
|
3005
|
+
for (const r of st.runs) {
|
|
3006
|
+
if (known.has(r.runId) || r.runId.length === 0) continue;
|
|
3007
|
+
if (r.status !== "running" && r.status !== "queued") continue;
|
|
3008
|
+
out.push({ key: r.runId, status: r.status, ...r.agentId ? { agentId: r.agentId } : {}, source: "registry" });
|
|
3009
|
+
}
|
|
3010
|
+
return out;
|
|
3011
|
+
}
|
|
3012
|
+
function latestEndedRun(st) {
|
|
3013
|
+
let best;
|
|
3014
|
+
for (const t of st.turns ?? []) {
|
|
3015
|
+
if (!isTerminalRunStatus(t.status)) continue;
|
|
3016
|
+
if (best === void 0 || (t.endedAt ?? Number.NEGATIVE_INFINITY) > (best.endedAt ?? Number.NEGATIVE_INFINITY)) best = t;
|
|
3017
|
+
}
|
|
3018
|
+
if (best) return { runId: best.runId, status: best.status, ...best.agentId ? { agentId: best.agentId } : {}, ...best.error ? { error: best.error } : {} };
|
|
3019
|
+
const r = st.runs.find((x2) => isTerminalRunStatus(x2.status));
|
|
3020
|
+
return r ? { runId: r.runId, status: r.status, ...r.agentId ? { agentId: r.agentId } : {}, ...r.error ? { error: r.error } : {} } : void 0;
|
|
3021
|
+
}
|
|
3022
|
+
function snapshotSourceRunId(st) {
|
|
3023
|
+
let best;
|
|
3024
|
+
for (const t of st.turns ?? []) {
|
|
3025
|
+
if (t.status !== "succeeded" || t.runId === null) continue;
|
|
3026
|
+
if (best === void 0 || (t.endedAt ?? Number.NEGATIVE_INFINITY) > (best.endedAt ?? Number.NEGATIVE_INFINITY)) best = t;
|
|
3027
|
+
}
|
|
3028
|
+
return best?.runId ?? latestSucceededRun(st.runs)?.runId;
|
|
3029
|
+
}
|
|
3030
|
+
function nonEmptyStr(v2) {
|
|
3031
|
+
return typeof v2 === "string" && v2.trim().length > 0 ? v2 : void 0;
|
|
3032
|
+
}
|
|
3033
|
+
function turnError(m2, status) {
|
|
3034
|
+
const events = Array.isArray(m2["events"]) ? m2["events"] : [];
|
|
3035
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
3036
|
+
const e = events[i];
|
|
3037
|
+
if (!e || typeof e !== "object") continue;
|
|
3038
|
+
const ev = e;
|
|
3039
|
+
if (ev["kind"] === "status" && ev["label"] === "error" && nonEmptyStr(ev["detail"])) return ev["detail"];
|
|
3040
|
+
}
|
|
3041
|
+
return status !== "succeeded" && isTerminalRunStatus(status) ? nonEmptyStr(m2["content"]) : void 0;
|
|
3042
|
+
}
|
|
3043
|
+
async function fetchBoardTurns(base, fetchImpl, boardKey) {
|
|
3044
|
+
const convPath = `/api/projects/${encodeURIComponent(boardKey)}/conversations`;
|
|
3045
|
+
const guard = (err) => {
|
|
3046
|
+
if (err instanceof OdHttpError && (err.status === 401 || err.status === 403)) throw err;
|
|
3047
|
+
return null;
|
|
3048
|
+
};
|
|
3049
|
+
let convs;
|
|
3050
|
+
try {
|
|
3051
|
+
convs = (await odApi(base, fetchImpl, "GET", convPath)).conversations ?? [];
|
|
3052
|
+
} catch (err) {
|
|
3053
|
+
if (err instanceof OdHttpError && err.status === 404) return [];
|
|
3054
|
+
return guard(err);
|
|
3055
|
+
}
|
|
3056
|
+
const turns = [];
|
|
3057
|
+
for (const c of convs) {
|
|
3058
|
+
const cid = nonEmptyStr(c["id"]);
|
|
3059
|
+
if (cid === void 0) continue;
|
|
3060
|
+
let msgs;
|
|
3061
|
+
try {
|
|
3062
|
+
msgs = (await odApi(base, fetchImpl, "GET", `${convPath}/${encodeURIComponent(cid)}/messages`)).messages ?? [];
|
|
3063
|
+
} catch (err) {
|
|
3064
|
+
if (err instanceof OdHttpError && err.status === 404) continue;
|
|
3065
|
+
return guard(err);
|
|
3066
|
+
}
|
|
3067
|
+
for (const m2 of msgs) {
|
|
3068
|
+
if (!m2 || typeof m2 !== "object" || m2["role"] !== "assistant") continue;
|
|
3069
|
+
const status = nonEmptyStr(m2["runStatus"]);
|
|
3070
|
+
if (status === void 0) continue;
|
|
3071
|
+
const runId = nonEmptyStr(m2["runId"]) ?? null;
|
|
3072
|
+
const messageId = nonEmptyStr(m2["id"]) ?? null;
|
|
3073
|
+
if (runId === null && messageId === null) continue;
|
|
3074
|
+
const turn = { conversationId: cid, runId, messageId, status };
|
|
3075
|
+
const agentId = nonEmptyStr(m2["agentId"]);
|
|
3076
|
+
if (agentId) turn.agentId = agentId;
|
|
3077
|
+
const error2 = turnError(m2, status);
|
|
3078
|
+
if (error2) turn.error = error2;
|
|
3079
|
+
const startedAt = toEpochMs(m2["startedAt"]) ?? toEpochMs(m2["createdAt"]);
|
|
3080
|
+
if (startedAt !== void 0) turn.startedAt = startedAt;
|
|
3081
|
+
const endedAt = toEpochMs(m2["endedAt"]);
|
|
3082
|
+
if (endedAt !== void 0) turn.endedAt = endedAt;
|
|
3083
|
+
turns.push(turn);
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
turns.sort((a, b2) => (b2.startedAt ?? Number.NEGATIVE_INFINITY) - (a.startedAt ?? Number.NEGATIVE_INFINITY) || 0);
|
|
3087
|
+
return turns;
|
|
3088
|
+
}
|
|
2996
3089
|
async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
2997
3090
|
const boardKey = deriveBoardKey(artifactId);
|
|
2998
3091
|
let boardExists = true;
|
|
@@ -3035,7 +3128,31 @@ async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
|
3035
3128
|
} catch {
|
|
3036
3129
|
}
|
|
3037
3130
|
}
|
|
3038
|
-
|
|
3131
|
+
const turns = boardExists ? await fetchBoardTurns(base, fetchImpl, boardKey) : [];
|
|
3132
|
+
return { boardKey, boardExists, runs, turns, artifacts };
|
|
3133
|
+
}
|
|
3134
|
+
async function waitBoardSettled(base, fetchImpl, artifactId, opts = {}) {
|
|
3135
|
+
const interval = opts.intervalMs ?? 2e4;
|
|
3136
|
+
const timeout = opts.timeoutMs ?? 100 * 6e4;
|
|
3137
|
+
const sleep6 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
3138
|
+
const now = opts.now ?? Date.now;
|
|
3139
|
+
const started = now();
|
|
3140
|
+
let lastKey = null;
|
|
3141
|
+
let waited = false;
|
|
3142
|
+
for (; ; ) {
|
|
3143
|
+
const st = await fetchBoardStatus(base, fetchImpl, artifactId);
|
|
3144
|
+
const elapsedMs = now() - started;
|
|
3145
|
+
if (!st.boardExists) return { status: st, settled: true, waited, live: [], elapsedMs };
|
|
3146
|
+
const live = liveBoardRuns(st);
|
|
3147
|
+
const unreadable = st.turns === null;
|
|
3148
|
+
if (live.length === 0 && !unreadable) return { status: st, settled: true, waited, live, elapsedMs };
|
|
3149
|
+
const key2 = unreadable && live.length === 0 ? "?" : live.map((r) => `${r.key}=${r.status}`).sort().join(",");
|
|
3150
|
+
opts.onPoll?.({ live, elapsedMs, changed: key2 !== lastKey, unreadable });
|
|
3151
|
+
lastKey = key2;
|
|
3152
|
+
if (elapsedMs >= timeout) return { status: st, settled: false, waited: true, live, elapsedMs };
|
|
3153
|
+
waited = true;
|
|
3154
|
+
await sleep6(Math.min(interval, Math.max(0, timeout - elapsedMs)));
|
|
3155
|
+
}
|
|
3039
3156
|
}
|
|
3040
3157
|
async function pumpDesignEvents(base, fetchImpl, runId, onLine) {
|
|
3041
3158
|
const res = await fetchImpl(`${base}/api/runs/${runId}/events`);
|
|
@@ -3104,16 +3221,25 @@ async function harvestBoard(base, fetchImpl, publicBase, workRoot, boardKey, run
|
|
|
3104
3221
|
}
|
|
3105
3222
|
}
|
|
3106
3223
|
}
|
|
3107
|
-
fs2.writeFileSync(
|
|
3108
|
-
path2.join(dir, "board.link"),
|
|
3109
|
-
`${publicBase}/projects/${boardKey}
|
|
3110
|
-
\u5165\u53E3\u7A3F\uFF1A${entry}
|
|
3111
|
-
\u5FEB\u7167\u6765\u6E90 run\uFF1A${runId}
|
|
3112
|
-
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
3113
|
-
`
|
|
3114
|
-
);
|
|
3224
|
+
fs2.writeFileSync(path2.join(dir, BOARD_LINK_FILE), formatBoardLink({ publicBase, boardKey, entry, runId }));
|
|
3115
3225
|
return { dir, entry };
|
|
3116
3226
|
}
|
|
3227
|
+
function formatBoardLink(args) {
|
|
3228
|
+
return `${args.publicBase}/projects/${args.boardKey}
|
|
3229
|
+
\u5165\u53E3\u7A3F\uFF1A${args.entry}
|
|
3230
|
+
${SOURCE_RUN_LABEL}${args.runId}
|
|
3231
|
+
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
3232
|
+
`;
|
|
3233
|
+
}
|
|
3234
|
+
function parseBoardLinkSourceRun(text7) {
|
|
3235
|
+
for (const line2 of text7.split(/\r?\n/)) {
|
|
3236
|
+
const t = line2.trim();
|
|
3237
|
+
if (!t.startsWith(SOURCE_RUN_LABEL)) continue;
|
|
3238
|
+
const id = t.slice(SOURCE_RUN_LABEL.length).trim();
|
|
3239
|
+
return id.length > 0 && id !== UNKNOWN_SOURCE_RUN ? id : null;
|
|
3240
|
+
}
|
|
3241
|
+
return null;
|
|
3242
|
+
}
|
|
3117
3243
|
async function startDesignChatTurn(opts) {
|
|
3118
3244
|
const fetchImpl = withOdToken(opts.fetchImpl ?? fetch, opts.token);
|
|
3119
3245
|
const boardKey = deriveBoardKey(opts.artifactId);
|
|
@@ -3143,7 +3269,7 @@ async function runDesignChatTurn(opts) {
|
|
|
3143
3269
|
const { artifacts, fileCount } = await fetchResultPackage(opts.base, fetchImpl, runId);
|
|
3144
3270
|
return { boardKey, conversationId, runId, userMessageId, artifacts, fileCount };
|
|
3145
3271
|
}
|
|
3146
|
-
var import_node_crypto2, fs2, path2, OdHttpError, TASK_CONTEXT_DIR;
|
|
3272
|
+
var import_node_crypto2, fs2, path2, OdHttpError, TASK_CONTEXT_DIR, TERMINAL_TURN_STATUS, isTerminalRunStatus, BOARD_LINK_FILE, SOURCE_RUN_LABEL, UNKNOWN_SOURCE_RUN;
|
|
3147
3273
|
var init_driver = __esm({
|
|
3148
3274
|
"../adapters/src/open-design/driver.ts"() {
|
|
3149
3275
|
"use strict";
|
|
@@ -3157,6 +3283,11 @@ var init_driver = __esm({
|
|
|
3157
3283
|
}
|
|
3158
3284
|
};
|
|
3159
3285
|
TASK_CONTEXT_DIR = "task-context/";
|
|
3286
|
+
TERMINAL_TURN_STATUS = /* @__PURE__ */ new Set(["succeeded", "failed", "canceled", "cancelled"]);
|
|
3287
|
+
isTerminalRunStatus = (s2) => TERMINAL_TURN_STATUS.has(s2);
|
|
3288
|
+
BOARD_LINK_FILE = "board.link";
|
|
3289
|
+
SOURCE_RUN_LABEL = "\u5FEB\u7167\u6765\u6E90 run\uFF1A";
|
|
3290
|
+
UNKNOWN_SOURCE_RUN = "status-pull";
|
|
3160
3291
|
}
|
|
3161
3292
|
});
|
|
3162
3293
|
|
|
@@ -141016,14 +141147,19 @@ ${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
|
141016
141147
|
})() : canvasMode ? [
|
|
141017
141148
|
// 内核只出「你产什么 + 内核权威锚点」——**设计工作流散文全在你的人设(identity/AGENTS.md「产出流程」)**,
|
|
141018
141149
|
// 那是单一真源、改它=改配置不发版(提案 design-conversational-driving 治本,2026-07-17)。这里不重复正文,
|
|
141019
|
-
//
|
|
141150
|
+
// 只钉住内核不能漂的几件事:真实 artifactId、缺前置的逃生口 gap,以及「下单后在会话里 status --wait 等结果」
|
|
141151
|
+
//(2026-09-24 加:它直接关系引擎的零产出判定——下单即退出会被判零产出→协议续唤→连败熔断;人设各公司
|
|
141152
|
+
// 各一份、未必同步更新,这条放内核才保证每个设计员工都拿得到)。
|
|
141020
141153
|
`\u4F60\u8D1F\u8D23 **design \u4EA7\u7269 \`${artifactId}\`**\uFF0C\u8FD0\u884C\u5728**\u901A\u7528\u8FD0\u884C\u65F6**\u4E0A\u2014\u2014\u4F60\u662F\u7532\u65B9\u8BBE\u8BA1\u8D1F\u8D23\u4EBA\uFF0C\u591A\u8F6E\u5BF9\u8BDD\u9A71\u52A8**\u534F\u4F5C\u753B\u677F\u5F15\u64CE**\u6253\u78E8\u754C\u9762\u7A3F\u3002`,
|
|
141021
141154
|
``,
|
|
141022
141155
|
`**\u5B8C\u6574\u5DE5\u4F5C\u6D41\uFF08\u600E\u4E48\u53D6\u8D27/\u8D77\u8F6E/\u8BFB\u4EA7\u7269/\u4EA4\u7A3F/\u522B\u624B\u6539\u677F\u6587\u4EF6\u2026\uFF09\u89C1\u4F60\u7684\u4EBA\u8BBE \`identity/AGENTS.md\` \u7684\u300C\u4EA7\u51FA\u6D41\u7A0B\uFF08design \u4EA7\u7269\uFF09\u300D**\u2014\u2014\u628A\u91CC\u9762 \`<artifactId>\` \u90FD\u6362\u6210\u672C\u4EA7\u7269 \`${artifactId}\`\u3002`,
|
|
141023
141156
|
``,
|
|
141024
|
-
`\u5185\u6838\u53EA\u5728\u6B64\u9489\
|
|
141157
|
+
`\u5185\u6838\u53EA\u5728\u6B64\u9489\u51E0\u6761\u4E0D\u53EF\u6F02\u7684\uFF1A`,
|
|
141025
141158
|
`- **\u4EA4\u7A3F\u8D70 \`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "\u2026"\`**\uFF08proposed \u624D\u8FDB\u7248\u672C\u53F2\u3001\u4E0B\u6E38\u624D\u62FF\u5F97\u5230\uFF1B\u4E0D propose = head \u4ECD \u2205\uFF09\uFF1B`,
|
|
141026
|
-
`- \u7F3A**\u8FD8\u4E0D\u5B58\u5728\u7684\u4E0A\u6E38\u524D\u7F6E** \u2192 \`oasis gap ${artifactId} --desc "<\u7F3A\u4EC0\u4E48>"\` \u4EA4\u4E0A\u53BB\uFF1B\u5DF2\u505A\u5B8C\u7684\u90E8\u5206\u7167\u5E38 \`propose\`\uFF0C\u4F46\u8FD9\u4E00\u8F6E \`conclude\` \u4F1A\u88AB\u62D2\uFF0C\u63D0\u4EA4\u5B8C\u5373\u6536\u5DE5\u3002
|
|
141159
|
+
`- \u7F3A**\u8FD8\u4E0D\u5B58\u5728\u7684\u4E0A\u6E38\u524D\u7F6E** \u2192 \`oasis gap ${artifactId} --desc "<\u7F3A\u4EC0\u4E48>"\` \u4EA4\u4E0A\u53BB\uFF1B\u5DF2\u505A\u5B8C\u7684\u90E8\u5206\u7167\u5E38 \`propose\`\uFF0C\u4F46\u8FD9\u4E00\u8F6E \`conclude\` \u4F1A\u88AB\u62D2\uFF0C\u63D0\u4EA4\u5B8C\u5373\u6536\u5DE5\u3002`,
|
|
141160
|
+
`- **\u5728\u672C\u4F1A\u8BDD\u91CC\u7B49\u753B\u677F\u51FA\u7ED3\u679C**\uFF08\u540C\u5F00\u53D1\u7B49 CI\uFF09\uFF1A\u5F00\u5DE5\u5148 \`oasis design status ${artifactId}\`\uFF08\u6062\u590D\u4F18\u5148\uFF0C\u677F\u4E0A\u5DF2\u6709\u8D27/\u5DF2\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u522B\u91CD\u4E0B\uFF09\uFF1B\u4E0B\u5355\u7528 \`oasis design chat ${artifactId} \u2026 --async\`\uFF0C\u7136\u540E**\u7ACB\u523B** \`oasis design status ${artifactId} --wait --pull\` \u963B\u585E\u7B49\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\u5E76\u62C9\u8D27\uFF08\u6700\u957F\u7EA6 100 \u5206\u949F\uFF1B\u963B\u585E\u671F\u95F4\u4E0D\u8017 token\uFF09\u3002\u6210\u529F \u2192 \u6838\u5BF9 \u2192 propose\uFF1B\u5931\u8D25 \u2192 \u6309\u5B83\u7ED9\u7684\u539F\u56E0\u6362\u5F15\u64CE\uFF08\`--agent\`\uFF09\u6216\u8865\u6E05\u9700\u6C42\u540E\u91CD\u4E0B\uFF0C\u518D \`--wait\`\u3002`,
|
|
141161
|
+
` - **\u4E0D\u8981\u4E0B\u5355\u540E\u76F4\u63A5\u7ED3\u675F\u4F1A\u8BDD**\u2014\u2014\u6CA1\u4EA4\u4E1C\u897F\u5C31\u6536\u5DE5\u4F1A\u88AB\u5224\u96F6\u4EA7\u51FA\uFF1B**\u4E5F\u4E0D\u8981\u81EA\u5DF1\u9694\u51E0\u5206\u949F\u624B\u52A8 status \u8F6E\u8BE2**\u2014\u2014\u6BCF\u67E5\u4E00\u6B21\u90FD\u8981\u63A8\u7406\u4E00\u6B21\u3002\u547D\u4EE4\u82E5\u88AB\u6267\u884C\u5DE5\u5177\u7684\u5355\u6761\u8D85\u65F6\u6253\u65AD\u6216\u8D85\u65F6\u9000\u51FA\uFF0C\u539F\u6837\u518D\u8DD1\u4E00\u6B21 \`--wait\` \u63A5\u7740\u7B49\uFF08\u5B83\u7B49\u7684\u662F\u753B\u677F\uFF0C\u4E0D\u4F1A\u91CD\u590D\u4E0B\u5355\uFF09\u3002`,
|
|
141162
|
+
`- \u88AB\u753B\u677F\u5DE1\u68C0\u7684\u4FE1\u5524\u9192\u65F6\uFF1A\u5148\u770B\u5F53\u524D\u7248\u672C\u88C5\u7BB1\u5355 board.link \u91CC\u7684\u300C\u5FEB\u7167\u6765\u6E90 run\u300D\u662F\u4E0D\u662F\u5C31\u662F\u4FE1\u91CC\u90A3\u4E00\u8F6E\u2014\u2014\u662F\u5C31 \`oasis resolve <\u4FE1 id>\`\uFF0C\u522B\u91CD\u590D propose\u3002`
|
|
141027
141163
|
] : (() => {
|
|
141028
141164
|
const codeRepo = args.codeRepo ?? null;
|
|
141029
141165
|
const repos = typeDef?.contentType === "code" ? codeRepo?.repos : void 0;
|
|
@@ -277486,11 +277622,18 @@ function messageError(m2, status) {
|
|
|
277486
277622
|
}
|
|
277487
277623
|
return { error: null, errorCode: null };
|
|
277488
277624
|
}
|
|
277625
|
+
function ownerIsWorking(model, a) {
|
|
277626
|
+
if (a.latestWorkState !== "running") return false;
|
|
277627
|
+
const latest = [...model.revisions.values()].filter((r) => r.artifactId === a.id && r.lane !== "reply").sort((x2, y) => y.createdAt.localeCompare(x2.createdAt))[0];
|
|
277628
|
+
return latest !== void 0 && latest.author === a.owner;
|
|
277629
|
+
}
|
|
277489
277630
|
var RUN_MARKER_PREFIX, boardWatchRunMarker, parseRunMarker, SINCE_MARKER_PREFIX, boardWatchSinceMarker, parseSinceMarker, TERMINAL_RUN_STATUS, MAX_REASON_CHARS, MAX_LISTED_FILES, BoardWatcher;
|
|
277490
277631
|
var init_board_watch = __esm({
|
|
277491
277632
|
"../server/src/design/board-watch.ts"() {
|
|
277492
277633
|
"use strict";
|
|
277634
|
+
init_src();
|
|
277493
277635
|
init_src7();
|
|
277636
|
+
init_src2();
|
|
277494
277637
|
RUN_MARKER_PREFIX = "[od-board-watch run:";
|
|
277495
277638
|
boardWatchRunMarker = (roundKey) => `${RUN_MARKER_PREFIX}${roundKey}]`;
|
|
277496
277639
|
parseRunMarker = (body2) => {
|
|
@@ -277523,6 +277666,14 @@ var init_board_watch = __esm({
|
|
|
277523
277666
|
seenConvAt = /* @__PURE__ */ new Map();
|
|
277524
277667
|
/** 公司 → 上次记下的失败原文(同样的错只记一次;成功一轮就清掉)。 */
|
|
277525
277668
|
companyLastError = /* @__PURE__ */ new Map();
|
|
277669
|
+
/** `<公司>\0<artifactId>\0<轮次键>` → 这一轮已被取走(head 来自它或更晚的一轮),不再重判。只在内存,不写假信。 */
|
|
277670
|
+
takenRounds = /* @__PURE__ */ new Set();
|
|
277671
|
+
/** `<公司>\0<boardKey>` → (runId → endedAt):判断 head 的快照来源 run 是不是「更晚的一轮」用。 */
|
|
277672
|
+
roundEndedAt = /* @__PURE__ */ new Map();
|
|
277673
|
+
/** `<公司>\0<revisionId>` → 该版 board.link 的快照来源 runId(null = 没有/读不到)。revision 内容不可变,缓存安全。 */
|
|
277674
|
+
revisionSourceRun = /* @__PURE__ */ new Map();
|
|
277675
|
+
/** 因 owner 在做而压着没写的 `<公司>\0<artifactId>`(只为日志只打一次)。 */
|
|
277676
|
+
deferredLogged = /* @__PURE__ */ new Set();
|
|
277526
277677
|
async odGet(path47) {
|
|
277527
277678
|
const fetchImpl = this.deps.fetchImpl ?? fetch;
|
|
277528
277679
|
try {
|
|
@@ -277583,7 +277734,8 @@ var init_board_watch = __esm({
|
|
|
277583
277734
|
if (listCompanies && kernelFor) {
|
|
277584
277735
|
for (const companyId of await listCompanies()) {
|
|
277585
277736
|
try {
|
|
277586
|
-
|
|
277737
|
+
const blobs = this.deps.blobsFor ? await this.deps.blobsFor(companyId) : void 0;
|
|
277738
|
+
await this.tickCompany(companyId, await kernelFor(companyId), now, denied, blobs);
|
|
277587
277739
|
this.companyLastError.delete(companyId);
|
|
277588
277740
|
} catch (err) {
|
|
277589
277741
|
const msg = String(err);
|
|
@@ -277593,7 +277745,7 @@ var init_board_watch = __esm({
|
|
|
277593
277745
|
}
|
|
277594
277746
|
}
|
|
277595
277747
|
} else {
|
|
277596
|
-
await this.tickCompany("", this.deps.kernel, now, denied);
|
|
277748
|
+
await this.tickCompany("", this.deps.kernel, now, denied, this.deps.blobs);
|
|
277597
277749
|
}
|
|
277598
277750
|
if (denied.length > 0) {
|
|
277599
277751
|
const codes = [...new Set(denied.map((d) => d.status))].join("/");
|
|
@@ -277604,7 +277756,7 @@ var init_board_watch = __esm({
|
|
|
277604
277756
|
}
|
|
277605
277757
|
}
|
|
277606
277758
|
/** 巡一家公司(company 为空串 = 单 kernel 模式);被拒的板记进 denied,由 tick 统一汇总成一行。 */
|
|
277607
|
-
async tickCompany(company, kernel, now, denied) {
|
|
277759
|
+
async tickCompany(company, kernel, now, denied, blobs) {
|
|
277608
277760
|
const { boardKeyOf, log: log3 } = this.deps;
|
|
277609
277761
|
const graceMs = this.deps.firstLookGraceMs ?? 10 * 6e4;
|
|
277610
277762
|
const maxPerTick = this.deps.maxLettersPerTick ?? 2;
|
|
@@ -277639,12 +277791,40 @@ var init_board_watch = __esm({
|
|
|
277639
277791
|
continue;
|
|
277640
277792
|
}
|
|
277641
277793
|
if (recordedSince === null && !this.pinnedSince.has(pinKey)) this.pinnedSince.set(pinKey, since);
|
|
277642
|
-
const
|
|
277794
|
+
const endedAtOf = this.roundEndedAt.get(`${company}\0${boardKey}`) ?? /* @__PURE__ */ new Map();
|
|
277795
|
+
this.roundEndedAt.set(`${company}\0${boardKey}`, endedAtOf);
|
|
277796
|
+
for (const r of read3.value.rounds) if (r.runId !== null) endedAtOf.set(r.runId, r.endedAt);
|
|
277797
|
+
const takenKey = (r) => `${company}\0${a.id}\0${r.key}`;
|
|
277798
|
+
const fresh = read3.value.rounds.filter((r) => r.endedAt > since && !lettered.has(r.key) && !this.takenRounds.has(takenKey(r))).sort((x2, y) => x2.endedAt - y.endedAt);
|
|
277799
|
+
const deferKey = `${company}\0${a.id}`;
|
|
277800
|
+
if (fresh.length > 0 && ownerIsWorking(model, a)) {
|
|
277801
|
+
if (!this.deferredLogged.has(deferKey)) {
|
|
277802
|
+
this.deferredLogged.add(deferKey);
|
|
277803
|
+
log3?.(`[board-watch] ${tag}${a.id} \u7684 owner \u6B63\u5728\u6267\u884C\u8FD9\u4E2A\u8282\u70B9\uFF0C\u677F ${boardKey} \u4E0A ${fresh.length} \u8F6E\u7ED3\u675F\u7684\u5BF9\u8BDD\u5148\u4E0D\u5199\u4FE1\uFF0C\u7B49\u5B83\u8FD9\u8F6E work \u7ED3\u675F\u518D\u770B`);
|
|
277804
|
+
}
|
|
277805
|
+
continue;
|
|
277806
|
+
}
|
|
277807
|
+
this.deferredLogged.delete(deferKey);
|
|
277808
|
+
const sourceRuns = fresh.length > 0 && blobs ? await this.headSourceRuns(company, blobs, model, a, log3, tag) : [];
|
|
277809
|
+
const takenBy = (r) => {
|
|
277810
|
+
for (const src of sourceRuns) {
|
|
277811
|
+
if (r.runId !== null && src === r.runId) return src;
|
|
277812
|
+
const srcEnded = endedAtOf.get(src);
|
|
277813
|
+
if (srcEnded !== void 0 && srcEnded >= r.endedAt) return src;
|
|
277814
|
+
}
|
|
277815
|
+
return null;
|
|
277816
|
+
};
|
|
277643
277817
|
const seen = /* @__PURE__ */ new Set();
|
|
277644
277818
|
for (const r of fresh) {
|
|
277645
277819
|
if (written >= maxPerTick) break;
|
|
277646
277820
|
if (seen.has(r.key)) continue;
|
|
277647
277821
|
seen.add(r.key);
|
|
277822
|
+
const src = takenBy(r);
|
|
277823
|
+
if (src !== null) {
|
|
277824
|
+
this.takenRounds.add(takenKey(r));
|
|
277825
|
+
log3?.(`[board-watch] ${tag}${a.id} \u2190 \u677F ${boardKey} \u4E00\u8F6E\u5BF9\u8BDD\u7ED3\u675F\uFF08${r.key.slice(0, 12)} ${r.status}\uFF09\uFF0C\u5F53\u524D\u7248\u672C\u7684\u5FEB\u7167\u6765\u6E90 run ${src} \u5DF2\u8986\u76D6\u5B83 \u2192 \u4E0D\u5199\u4FE1`);
|
|
277826
|
+
continue;
|
|
277827
|
+
}
|
|
277648
277828
|
const ok3 = r.status === "succeeded";
|
|
277649
277829
|
const reason = ok3 ? null : r.error ?? (r.runId !== null ? await this.runErrorFromRegistry(boardKey, r.runId) : null);
|
|
277650
277830
|
await kernel.annotate({ artifactId: a.id, actor, body: this.letterBody(a.id, boardKey, r, since, reason), kind: "comment" });
|
|
@@ -277657,6 +277837,36 @@ var init_board_watch = __esm({
|
|
|
277657
277837
|
}
|
|
277658
277838
|
}
|
|
277659
277839
|
}
|
|
277840
|
+
/**
|
|
277841
|
+
* 当前 head 与最近一版装箱单(两者可能不同:head 在跑空壳/被打回时回落)各自 board.link 里的快照来源 runId。
|
|
277842
|
+
* 读不到(非装箱单、没有 board.link、blob 缺失、占位 status-pull)的不算。
|
|
277843
|
+
*/
|
|
277844
|
+
async headSourceRuns(company, blobs, model, a, log3, tag) {
|
|
277845
|
+
const candidates = [];
|
|
277846
|
+
const head = a.currentRev ? model.revisions.get(a.currentRev) : void 0;
|
|
277847
|
+
if (head) candidates.push(head);
|
|
277848
|
+
const latestManifest = [...model.revisions.values()].filter((r) => r.artifactId === a.id && r.contentKind === "manifest" && r.contentRef.length > 0).sort((x2, y) => y.createdAt.localeCompare(x2.createdAt))[0];
|
|
277849
|
+
if (latestManifest && latestManifest.id !== head?.id) candidates.push(latestManifest);
|
|
277850
|
+
const out = [];
|
|
277851
|
+
for (const rev of candidates) {
|
|
277852
|
+
if (rev.contentKind !== "manifest" || rev.contentRef.length === 0) continue;
|
|
277853
|
+
const cacheKey = `${company}\0${rev.id}`;
|
|
277854
|
+
let src = this.revisionSourceRun.get(cacheKey);
|
|
277855
|
+
if (src === void 0) {
|
|
277856
|
+
try {
|
|
277857
|
+
const manifest = parseManifest(await blobs.get(rev.contentRef));
|
|
277858
|
+
const entry = manifest.entries.find((e) => e.path === BOARD_LINK_FILE);
|
|
277859
|
+
src = entry ? parseBoardLinkSourceRun(new TextDecoder().decode(await blobs.get(entry.hash))) : null;
|
|
277860
|
+
} catch (err) {
|
|
277861
|
+
log3?.(`[board-watch] ${tag}\u8BFB ${a.id} \u7248\u672C ${rev.id} \u7684 board.link \u5931\u8D25\uFF08${String(err)}\uFF09\uFF0C\u6309\u300C\u4E0D\u77E5\u9053\u6765\u81EA\u54EA\u4E00\u8F6E\u300D\u5904\u7406`);
|
|
277862
|
+
src = null;
|
|
277863
|
+
}
|
|
277864
|
+
this.revisionSourceRun.set(cacheKey, src);
|
|
277865
|
+
}
|
|
277866
|
+
if (src !== null) out.push(src);
|
|
277867
|
+
}
|
|
277868
|
+
return out;
|
|
277869
|
+
}
|
|
277660
277870
|
letterBody(artifactId, boardKey, r, since, reason) {
|
|
277661
277871
|
const marker = `${boardWatchRunMarker(r.key)} ${boardWatchSinceMarker(since)}`;
|
|
277662
277872
|
const round = `${r.runId !== null ? `run ${r.runId.slice(0, 8)}` : `\u6D88\u606F ${r.key.slice(4, 12)}`}\uFF0C\u5F15\u64CE=${r.agentId ?? "?"}\uFF0C\u7ED3\u675F\u4E8E ${new Date(r.endedAt).toISOString()}`;
|
|
@@ -277667,7 +277877,8 @@ var init_board_watch = __esm({
|
|
|
277667
277877
|
`\u753B\u677F ${boardKey} \u4E0A\u6709\u4E00\u8F6E\u5BF9\u8BDD\u8DD1\u5B8C\u4E86\uFF08${round}\uFF09\uFF0C\u8FD9\u4E00\u8F6E\u4EA7\u51FA\uFF1A`,
|
|
277668
277878
|
files,
|
|
277669
277879
|
``,
|
|
277670
|
-
`\
|
|
277880
|
+
`\u5148\u770B\u8FD9\u4E00\u8F6E\u662F\u4E0D\u662F\u5DF2\u7ECF\u4EA4\u8FC7\uFF1A\u5F53\u524D\u7248\u672C\u88C5\u7BB1\u5355\u91CC board.link \u7684\u300C\u5FEB\u7167\u6765\u6E90 run\u300D\u5982\u679C\u5C31\u662F ${r.runId ?? "\u8FD9\u4E00\u8F6E"}\uFF0C\u8BF4\u660E\u5DF2\u53D6\u8D70\uFF0C\`oasis resolve <\u672C\u4FE1 id> --as resolved\` \u5373\u53EF\uFF0C\u522B\u91CD\u590D propose\u3002`,
|
|
277881
|
+
`\u6CA1\u4EA4\u8FC7\u5C31\u53D6\u8D27\u6838\u5BF9\uFF1A\`oasis design status ${artifactId} --wait --pull\`\uFF08\u677F\u4E0A\u8FD8\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u4F1A\u5148\u7B49\u5B83\u8DD1\u5B8C\uFF09\u2192 \u5BF9\u7740 DESIGN_BRIEF.md \u4E0E inputs/ \u9010\u5B57\u6BB5\u6838\uFF08\u6570\u636E\u5BF9\u4E0D\u5BF9\u3001\u72B6\u6001\u5168\u4E0D\u5168\u3001\u6709\u6CA1\u6709\u7F16\u9020\uFF09\u3002\u591F\u597D\u5C31 \`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"\`\uFF1B\u8981\u6539\u5C31\u56DE\u677F\u4E0A\u518D\u6765\u4E00\u8F6E \`oasis design chat ${artifactId} --turn continue --message "<\u8981\u6539\u4EC0\u4E48>" --async\`\uFF0C\u968F\u540E \`oasis design status ${artifactId} --wait --pull\` \u7B49\u7ED3\u679C\uFF08\u26D4 \u522B\u628A --pull \u4E0B\u6765\u7684\u6587\u4EF6\u5728\u672C\u5730\u624B\u6539\u540E propose\uFF09\u3002\u8FD9\u4E00\u8F6E\u82E5\u662F\u4EBA\u76F4\u63A5\u5728\u677F\u4E0A\u804A\u51FA\u6765\u7684\u3001\u5185\u5BB9\u4E0D\u5FC5\u6536\u5F55\uFF0C\u56DE\u5E16\u8BF4\u660E\u540E\u6309 wontfix \u5904\u7406\u5373\u53EF\uFF08\u540C\u4E00\u8F6E\u4E0D\u4F1A\u518D\u6765\u4FE1\uFF09\u3002`
|
|
277671
277882
|
].join("\n");
|
|
277672
277883
|
}
|
|
277673
277884
|
const quoted = reason === null ? null : reason.length > MAX_REASON_CHARS ? `${reason.slice(0, MAX_REASON_CHARS)}\u2026` : reason;
|
|
@@ -277676,7 +277887,7 @@ var init_board_watch = __esm({
|
|
|
277676
277887
|
`\u753B\u677F ${boardKey} \u4E0A\u6709\u4E00\u8F6E\u5BF9\u8BDD**\u6CA1\u8DD1\u6210**\uFF08\u7EC8\u6001=${r.status}\uFF0C${round}\uFF09\u3002`,
|
|
277677
277888
|
quoted !== null ? `od \u8BB0\u7684\u539F\u56E0\uFF08\u539F\u6587\uFF09\uFF1A${quoted}${r.errorCode !== null ? `\uFF08\u9519\u8BEF\u7801 ${r.errorCode}\uFF09` : ""}` : `od \u6CA1\u6709\u8BB0\u5F55\u8FD9\u4E00\u8F6E\u7684\u5931\u8D25\u539F\u56E0\u3002`,
|
|
277678
277889
|
``,
|
|
277679
|
-
`\u5148 \`oasis design status ${artifactId}\` \u770B\u677F\u4E0A\u6709\u6CA1\u6709\u53EF\u7528\u7684\u4E0A\u4E00\u7248\uFF1A\u6709\u5C31\u7167\u5E38\u53D6\u8D27\u6838\u5BF9\u3002\u8981\u91CD\u8DD1\u5C31\u81EA\u5DF1\u5224\u65AD\uFF1A\u50CF\u662F\u989D\u5EA6/\u9650\u6D41\u5C31\u7B49\u6062\u590D\u540E\u518D\u6765\uFF0C\u6216\u6362\u4E2A\u5F15\u64CE \`oasis design chat ${artifactId} --agent <\u5F15\u64CE> --message "<\u2026>" --async\`\uFF1B\u50CF\u662F\u9700\u6C42/\u6570\u636E\u95EE\u9898\u5C31\u628A\u5B83\u4EEC\u9489\u5F97\u66F4\u6B7B\u540E\u91CD\u8D77\u4E00\u8F6E\
|
|
277890
|
+
`\u5148 \`oasis design status ${artifactId}\` \u770B\u677F\u4E0A\u6709\u6CA1\u6709\u53EF\u7528\u7684\u4E0A\u4E00\u7248\uFF1A\u6709\u5C31\u7167\u5E38\u53D6\u8D27\u6838\u5BF9\u3002\u8981\u91CD\u8DD1\u5C31\u81EA\u5DF1\u5224\u65AD\uFF1A\u50CF\u662F\u989D\u5EA6/\u9650\u6D41\u5C31\u7B49\u6062\u590D\u540E\u518D\u6765\uFF0C\u6216\u6362\u4E2A\u5F15\u64CE \`oasis design chat ${artifactId} --turn continue --agent <\u5F15\u64CE> --message "<\u2026>" --async\`\uFF1B\u50CF\u662F\u9700\u6C42/\u6570\u636E\u95EE\u9898\u5C31\u628A\u5B83\u4EEC\u9489\u5F97\u66F4\u6B7B\u540E\u91CD\u8D77\u4E00\u8F6E\u3002\u91CD\u4E0B\u4E4B\u540E\u7ACB\u523B \`oasis design status ${artifactId} --wait --pull\` \u5728\u4F1A\u8BDD\u91CC\u7B49\u7ED3\u679C\uFF0C\u522B\u4E0B\u5355\u5C31\u6536\u5DE5\u3002\u4ECD\u4E0D\u884C\u7528 \`oasis gap ${artifactId} --desc "<\u5361\u5728\u54EA>"\` \u5192\u6CE1\u7ED9\u4EBA\u3002`
|
|
277680
277891
|
].join("\n");
|
|
277681
277892
|
}
|
|
277682
277893
|
};
|
|
@@ -278809,6 +279020,7 @@ __export(src_exports2, {
|
|
|
278809
279020
|
openNewEngine: () => openNewEngine,
|
|
278810
279021
|
operatorCrossCompanyRead: () => operatorCrossCompanyRead,
|
|
278811
279022
|
outputsPartProvider: () => outputsPartProvider,
|
|
279023
|
+
ownerIsWorking: () => ownerIsWorking,
|
|
278812
279024
|
packMatches: () => packMatches,
|
|
278813
279025
|
parentConversationTaskLines: () => parentConversationTaskLines,
|
|
278814
279026
|
parseConnectorSkillId: () => parseConnectorSkillId,
|
|
@@ -289309,6 +289521,8 @@ ${nodeFault}` : "");
|
|
|
289309
289521
|
return [defaultCompanyId, ...active.filter((id) => id !== defaultCompanyId)];
|
|
289310
289522
|
},
|
|
289311
289523
|
kernelFor: async (companyId) => (await getEngine(companyId)).kernel,
|
|
289524
|
+
// 读 head 装箱单里的 board.link(「快照来源 run」)判断这一轮是否已被取走,已取走就不写信
|
|
289525
|
+
blobsFor: async (companyId) => (await getEngine(companyId)).blobs,
|
|
289312
289526
|
odBase,
|
|
289313
289527
|
...odToken ? { odToken } : {},
|
|
289314
289528
|
boardKeyOf: deriveBoardKey,
|
|
@@ -292568,29 +292782,32 @@ var COMMAND_DECLS = {
|
|
|
292568
292782
|
flags: [
|
|
292569
292783
|
{ name: "message", desc: "\u6D88\u606F\u5185\u5BB9", required: true },
|
|
292570
292784
|
{ name: "turn", desc: "\u5BF9\u8BDD\u8F6E\u6B21\uFF08first | continue\uFF09" },
|
|
292571
|
-
{ name: "async", desc: "\
|
|
292785
|
+
{ name: "async", desc: "\u4E0B\u5355\u5373\u8FD4\uFF1B\u968F\u540E\u7528 design status --wait --pull \u963B\u585E\u7B49\u7ED3\u679C" },
|
|
292572
292786
|
{ name: "system", desc: "\u7CFB\u7EDF\u63D0\u793A" }
|
|
292573
292787
|
],
|
|
292574
292788
|
examples: ['oasis design chat artifact:design:xyz --message "\u628A\u6309\u94AE\u6539\u6210\u84DD\u8272" --turn continue']
|
|
292575
292789
|
},
|
|
292576
292790
|
"design status": {
|
|
292577
292791
|
group: "\u8BBE\u8BA1\u7A3F",
|
|
292578
|
-
usage: "oasis design status <artifactId> [--pull]",
|
|
292579
|
-
description: "\u67E5\u753B\u677F\u73B0\u72B6\uFF08\u6062\u590D\u4F18\u5148\uFF09\u3002\u88AB\u6D3E\u53D1\u5148\u8DD1\u5B83\u2014\u2014\u5F15\u64CE\u5728\u8DD1\u5C31\u522B\u8D77\u65B0\u8F6E\u3002",
|
|
292792
|
+
usage: "oasis design status <artifactId> [--pull] [--wait [--wait-timeout <\u5206\u949F>]]",
|
|
292793
|
+
description: "\u67E5\u753B\u677F\u73B0\u72B6\uFF08\u6062\u590D\u4F18\u5148\uFF09\u3002\u88AB\u6D3E\u53D1\u5148\u8DD1\u5B83\u2014\u2014\u5F15\u64CE\u5728\u8DD1\u5C31\u522B\u8D77\u65B0\u8F6E\u3002--wait\uFF1A\u677F\u4E0A\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u963B\u585E\u7B49\u5230\u5168\u90E8\u7ED3\u675F\uFF08\u4E0D\u7BA1\u662F\u8C01\u8D77\u7684\uFF09\uFF0C\u518D\u6253\u5370\u7ED3\u679C\uFF1B\u8D85\u65F6\u975E\u96F6\u9000\u51FA\u3002",
|
|
292580
292794
|
positional: [
|
|
292581
292795
|
{ name: "<artifactId>", required: true, desc: "\u4EA7\u7269 id" }
|
|
292582
292796
|
],
|
|
292583
292797
|
flags: [
|
|
292584
|
-
{ name: "pull", desc: "\u62C9\u53D6\u6700\u65B0\u753B\u677F\u5185\u5BB9\u5230\u672C\u5730" }
|
|
292798
|
+
{ name: "pull", desc: "\u62C9\u53D6\u6700\u65B0\u753B\u677F\u5185\u5BB9\u5230\u672C\u5730\uFF08\u5E26 --wait \u65F6\uFF1A\u7B49\u5B8C\u4E14\u6700\u8FD1\u4E00\u8F6E\u6210\u529F\u624D\u62C9\uFF09" },
|
|
292799
|
+
{ name: "wait", desc: "\u677F\u4E0A\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u963B\u585E\u7B49\u5B83\u4EEC\u7ED3\u675F\uFF08\u540C gh pr checks --watch\uFF09", boolean: true },
|
|
292800
|
+
{ name: "wait-timeout", desc: "--wait \u6700\u591A\u7B49\u51E0\u5206\u949F\uFF08\u9ED8\u8BA4 100\uFF09" },
|
|
292801
|
+
{ name: "wait-interval", desc: "--wait \u8F6E\u8BE2\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 20\uFF09" }
|
|
292585
292802
|
],
|
|
292586
|
-
examples: ["oasis design status artifact:design:xyz --pull"]
|
|
292803
|
+
examples: ["oasis design status artifact:design:xyz --wait --pull", "oasis design status artifact:design:xyz --pull"]
|
|
292587
292804
|
},
|
|
292588
292805
|
design: {
|
|
292589
292806
|
group: "\u8BBE\u8BA1\u7A3F",
|
|
292590
292807
|
usage: "oasis design <chat|status> <artifactId> ...",
|
|
292591
292808
|
description: "\u8BBE\u8BA1\u4EA7\u7269\u76F8\u5173\u64CD\u4F5C\u3002\u8FDE\u54EA\u4E2A open-design\uFF1A\u5458\u5DE5\u5F00\u4E86 open-design \u8FDE\u63A5\u5668\u5C31\u8FDE\u5B83\u767B\u8BB0\u7684\u5730\u5740\u5E76\u5E26\u4EE4\u724C\uFF08\u4EFB\u610F\u8282\u70B9\u53EF\u7528\uFF09\uFF0C\u5426\u5219 $OASIS_OPEN_DESIGN_URL\uFF0C\u518D\u5426\u5219\u672C\u673A\u3002",
|
|
292592
292809
|
subCommands: ["design chat", "design status"],
|
|
292593
|
-
examples: ['oasis design chat artifact:design:xyz --message "\u8BBE\u8BA1\u767B\u5F55\u9875" --async']
|
|
292810
|
+
examples: ['oasis design chat artifact:design:xyz --message "\u8BBE\u8BA1\u767B\u5F55\u9875" --async', "oasis design status artifact:design:xyz --wait --pull"]
|
|
292594
292811
|
},
|
|
292595
292812
|
// —— 图机制(§6/§7) ——
|
|
292596
292813
|
annotate: {
|
|
@@ -294268,6 +294485,15 @@ function needPos(positional, i, usage) {
|
|
|
294268
294485
|
if (v2 === void 0) throw new Error(`\u7528\u6CD5: ${usage}`);
|
|
294269
294486
|
return v2;
|
|
294270
294487
|
}
|
|
294488
|
+
function positiveNumberFlag(flags, name, dflt) {
|
|
294489
|
+
const raw = flags.get(name);
|
|
294490
|
+
if (raw === void 0) return dflt;
|
|
294491
|
+
const n = Number(raw);
|
|
294492
|
+
if (!Number.isFinite(n) || n <= 0) throw new Error(`--${name} \u8981\u4E00\u4E2A\u6B63\u6570\uFF08\u6536\u5230\uFF1A${raw}\uFF09`);
|
|
294493
|
+
return n;
|
|
294494
|
+
}
|
|
294495
|
+
var shortRunKey = (key2) => key2.startsWith("msg:") ? `\u6D88\u606F ${key2.slice(4, 12)}` : `run ${key2.slice(0, 8)}`;
|
|
294496
|
+
var clipReason = (reason) => reason.length > 300 ? `${reason.slice(0, 300)}\u2026` : reason;
|
|
294271
294497
|
function semicolonList(raw, field) {
|
|
294272
294498
|
if (raw === void 0) return {};
|
|
294273
294499
|
const items = raw.split(";").map((x2) => x2.trim()).filter(Boolean);
|
|
@@ -294470,7 +294696,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
294470
294696
|
}
|
|
294471
294697
|
}
|
|
294472
294698
|
}
|
|
294473
|
-
var CLI_VERSION = "2.2.
|
|
294699
|
+
var CLI_VERSION = "2.2.85" ? "2.2.85" : "dev";
|
|
294474
294700
|
function apiHeaders(token, company) {
|
|
294475
294701
|
const headers = {
|
|
294476
294702
|
authorization: `Bearer ${token}`,
|
|
@@ -296240,7 +296466,7 @@ ${res.warning}`);
|
|
|
296240
296466
|
println(`[design] \u753B\u677F ${deriveBoardKey(artifactId)} \u2190 ${artifactId}\uFF1B${isContinue ? "\u7EED\u8F6E" : "\u9996\u8F6E"}\uFF08--async\uFF09\u2192 od \u5F15\u64CE ${odLabel} \u2026`);
|
|
296241
296467
|
const started = await startDesignChatTurn(baseTurnOpts);
|
|
296242
296468
|
println(`[design] \u5DF2\u4E0B\u5355\uFF1Arun ${started.runId.slice(0, 8)}\uFF08board ${started.boardKey}, \u53EF\u89C1 user \u56DE\u5408 ${started.userMessageId.slice(0, 8)}\uFF09\u3002\u5F15\u64CE\u901A\u5E38\u8981 13\u201344 \u5206\u949F\u3002`);
|
|
296243
|
-
println(`[design] \
|
|
296469
|
+
println(`[design] \u4E0B\u4E00\u6B65\u7ACB\u523B\u6267\u884C\uFF1Aoasis design status ${artifactId} --wait --pull\uFF08\u963B\u585E\u7B49\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\u5E76\u62C9\u8D27\uFF0C\u6700\u957F\u7B49 100 \u5206\u949F\uFF09\u3002\u522B\u4E0B\u5355\u540E\u76F4\u63A5\u7ED3\u675F\u4F1A\u8BDD\uFF0C\u4E5F\u522B\u81EA\u5DF1\u9694\u51E0\u5206\u949F\u624B\u52A8 status\u3002`);
|
|
296244
296470
|
break;
|
|
296245
296471
|
}
|
|
296246
296472
|
println(`[design] \u753B\u677F ${deriveBoardKey(artifactId)} \u2190 ${artifactId}\uFF1B${isContinue ? "\u7EED\u8F6E" : "\u9996\u8F6E"}\u5BF9\u8BDD\u9A71\u52A8 od \u5F15\u64CE ${odLabel} \u2026`);
|
|
@@ -296254,46 +296480,82 @@ ${res.warning}`);
|
|
|
296254
296480
|
break;
|
|
296255
296481
|
}
|
|
296256
296482
|
if (sub === "status") {
|
|
296257
|
-
const artifactId = needPos(positional, 1, "oasis design status <artifactId> [--pull]");
|
|
296483
|
+
const artifactId = needPos(positional, 1, "oasis design status <artifactId> [--pull] [--wait]");
|
|
296258
296484
|
const od = resolveOpenDesignEndpoint(flags.get("od-url"));
|
|
296259
296485
|
const odBase = od.base;
|
|
296260
296486
|
const odFetch = withOdToken(fetch, od.token);
|
|
296261
|
-
|
|
296487
|
+
let st;
|
|
296488
|
+
let waitedForRun = false;
|
|
296489
|
+
if (flags.get("wait") === "true") {
|
|
296490
|
+
const timeoutMin = positiveNumberFlag(flags, "wait-timeout", 100);
|
|
296491
|
+
const intervalSec = positiveNumberFlag(flags, "wait-interval", 20);
|
|
296492
|
+
const fmt = (ms) => `${Math.floor(ms / 6e4)} \u5206 ${Math.floor(ms % 6e4 / 1e3)} \u79D2`;
|
|
296493
|
+
const waited = await waitBoardSettled(odBase, odFetch, artifactId, {
|
|
296494
|
+
timeoutMs: timeoutMin * 6e4,
|
|
296495
|
+
intervalMs: intervalSec * 1e3,
|
|
296496
|
+
// 每次轮询打一行撑 liveness;状态没变只打短的一行,别刷屏
|
|
296497
|
+
onPoll: ({ live: live2, elapsedMs, changed, unreadable }) => {
|
|
296498
|
+
if (!changed) return println(`[design] \u2026\u4ECD\u5728\u7B49\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF09`);
|
|
296499
|
+
if (live2.length === 0 && unreadable) return println(`[design] \u8FD9\u6B21\u6CA1\u8BFB\u5230\u753B\u677F\u5BF9\u8BDD\u8BB0\u5F55\uFF08od \u6682\u65F6\u4E0D\u901A\uFF1F\uFF09\uFF0C\u63A5\u7740\u7B49\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF09`);
|
|
296500
|
+
const runs = live2.map((r) => `${shortRunKey(r.key)} \u72B6\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}`).join("\uFF1B");
|
|
296501
|
+
println(`[design] \u7B49\u753B\u677F\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\uFF1A${runs}\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF0C\u4E0A\u9650 ${timeoutMin} \u5206\u949F\uFF09`);
|
|
296502
|
+
}
|
|
296503
|
+
});
|
|
296504
|
+
st = waited.status;
|
|
296505
|
+
waitedForRun = waited.waited;
|
|
296506
|
+
if (!waited.settled) {
|
|
296507
|
+
const runs = waited.live.map((r) => `${shortRunKey(r.key)} \u72B6\u6001=${r.status}`).join("\u3001") || "\u5BF9\u8BDD\u8BB0\u5F55\u8BFB\u4E0D\u5230";
|
|
296508
|
+
println(`[design] \u7B49\u4E86 ${fmt(waited.elapsedMs)}\uFF0C\u753B\u677F\u4E0A\u8FD9\u4E00\u8F6E\u8FD8\u6CA1\u7ED3\u675F\uFF08${runs}\uFF09\u2014\u2014\u5F15\u64CE\u8FD8\u5728\u8DD1\uFF0C\u53EF\u7A0D\u540E\u518D oasis design status ${artifactId} --wait${flags.get("pull") === "true" ? " --pull" : ""}\u3002\u522B\u53E6\u8D77\u65B0\u8F6E\u3002`);
|
|
296509
|
+
process.exitCode = 2;
|
|
296510
|
+
break;
|
|
296511
|
+
}
|
|
296512
|
+
if (waitedForRun) println(`[design] \u753B\u677F\u4E0A\u7684\u8F6E\u6B21\u90FD\u5DF2\u7ED3\u675F\uFF08\u7B49\u4E86 ${fmt(waited.elapsedMs)}\uFF09\u3002`);
|
|
296513
|
+
} else {
|
|
296514
|
+
st = await fetchBoardStatus(odBase, odFetch, artifactId);
|
|
296515
|
+
}
|
|
296262
296516
|
if (!st.boardExists) {
|
|
296263
|
-
println(`[design] \u753B\u677F ${st.boardKey} \u5C1A\u4E0D\u5B58\u5728\u2014\u2014\u8FD8\u6CA1\u8D77\u8FC7\u4EFB\u4F55\u4E00\u8F6E\u3002\u5F00\u5DE5\uFF1Aoasis design chat ${artifactId} --message "<\u8BBE\u8BA1\u9700\u6C42+\u771F\u5B9E\u6570\u636E>" --async`);
|
|
296517
|
+
println(`[design] \u753B\u677F ${st.boardKey} \u5C1A\u4E0D\u5B58\u5728\u2014\u2014\u8FD8\u6CA1\u8D77\u8FC7\u4EFB\u4F55\u4E00\u8F6E\u3002\u5F00\u5DE5\uFF1Aoasis design chat ${artifactId} --message "<\u8BBE\u8BA1\u9700\u6C42+\u771F\u5B9E\u6570\u636E>" --async\uFF0C\u968F\u540E oasis design status ${artifactId} --wait --pull`);
|
|
296264
296518
|
break;
|
|
296265
296519
|
}
|
|
296266
|
-
const live = st
|
|
296520
|
+
const live = liveBoardRuns(st);
|
|
296267
296521
|
if (live.length > 0) {
|
|
296268
|
-
for (const r of live) println(`[design] \u5F15\u64CE\u5728\u8DD1\
|
|
296522
|
+
for (const r of live) println(`[design] \u5F15\u64CE\u5728\u8DD1\uFF1A${shortRunKey(r.key)} \u72B6\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}\u2014\u2014\u522B\u518D\u8D77\u65B0\u8F6E\uFF1B\u7528 oasis design status ${artifactId} --wait --pull \u963B\u585E\u7B49\u5B83\u8DD1\u5B8C\u5E76\u62C9\u8D27\u3002`);
|
|
296269
296523
|
} else if (st.runs.length > 0) {
|
|
296270
296524
|
for (const r of st.runs.slice(0, 3)) {
|
|
296271
296525
|
println(`[design] \u8FD1\u671F run\uFF1A${r.runId.slice(0, 8)} \u7EC8\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}`);
|
|
296272
|
-
if (r.status === "failed" && r.error) {
|
|
296273
|
-
|
|
296274
|
-
|
|
296275
|
-
|
|
296526
|
+
if (r.status === "failed" && r.error) println(`[design] \u5931\u8D25\u539F\u56E0\uFF08od \u539F\u6587\uFF09\uFF1A${clipReason(r.error)}`);
|
|
296527
|
+
}
|
|
296528
|
+
} else if ((st.turns ?? []).length > 0) {
|
|
296529
|
+
for (const t of (st.turns ?? []).slice(0, 3)) {
|
|
296530
|
+
println(`[design] \u8FD1\u671F run\uFF08\u5BF9\u8BDD\u8BB0\u5F55\uFF09\uFF1A${(t.runId ?? t.messageId ?? "?").slice(0, 8)} \u7EC8\u6001=${t.status}${t.agentId ? ` \u5F15\u64CE=${t.agentId}` : ""}`);
|
|
296531
|
+
if (t.status !== "succeeded" && t.error) println(`[design] \u5931\u8D25\u539F\u56E0\uFF08od \u539F\u6587\uFF09\uFF1A${clipReason(t.error)}`);
|
|
296276
296532
|
}
|
|
296277
296533
|
} else {
|
|
296278
296534
|
println(`[design] \u65E0\u5728\u4E16 run \u8BB0\u5F55\uFF08od \u91CD\u542F\u540E\u4E3A\u7A7A\uFF0C\u5C5E\u6B63\u5E38\uFF09\u2014\u2014\u770B\u4E0B\u9762\u677F\u4E0A\u4EA7\u7269\u5373\u6301\u4E45\u771F\u76F8\u3002`);
|
|
296279
296535
|
}
|
|
296536
|
+
const last = latestEndedRun(st);
|
|
296537
|
+
const lastFailed = waitedForRun && last !== void 0 && last.status !== "succeeded";
|
|
296538
|
+
if (lastFailed) {
|
|
296539
|
+
println(`[design] \u521A\u7ED3\u675F\u7684\u8FD9\u4E00\u8F6E\u6CA1\u8DD1\u6210\uFF08\u7EC8\u6001=${last.status}${last.agentId ? ` \u5F15\u64CE=${last.agentId}` : ""}\uFF09${last.error ? `\uFF1A${clipReason(last.error)}` : "\uFF0Cod \u6CA1\u8BB0\u539F\u56E0"}\u3002`);
|
|
296540
|
+
println(`[design] \u50CF\u989D\u5EA6/\u9650\u6D41/\u5F15\u64CE\u6545\u969C \u2192 \u6362\u5F15\u64CE\u91CD\u4E0B\uFF1Aoasis design chat ${artifactId} --turn continue --agent <\u53E6\u4E00\u4E2A\u5F15\u64CE> --message "<\u2026>" --async\uFF1B\u50CF\u9700\u6C42/\u6570\u636E\u4E0D\u6E05 \u2192 \u8865\u6E05\u695A\u540E\u91CD\u4E0B\uFF1B\u4E0B\u5B8C\u7167\u65E7 oasis design status ${artifactId} --wait --pull\u3002`);
|
|
296541
|
+
}
|
|
296280
296542
|
if (st.artifacts.length === 0) {
|
|
296281
|
-
println(`[design] \u677F\u4E0A\u8FD8\u6CA1\u6709\u4EA4\u4ED8\u7269\u3002${live.length > 0 ?
|
|
296543
|
+
println(`[design] \u677F\u4E0A\u8FD8\u6CA1\u6709\u4EA4\u4ED8\u7269\u3002${live.length > 0 ? `\u7B49\u5F15\u64CE\u8DD1\u5B8C\uFF1Aoasis design status ${artifactId} --wait --pull` : `\u8D77\u4E00\u8F6E\uFF1Aoasis design chat ${artifactId} --message "<\u2026>" --async\uFF0C\u968F\u540E oasis design status ${artifactId} --wait --pull`}`);
|
|
296282
296544
|
break;
|
|
296283
296545
|
}
|
|
296284
296546
|
println(`[design] \u677F\u4E0A\u4EA4\u4ED8\u7269\uFF08\u6301\u4E45\uFF0C\u65B0\u2192\u65E7\uFF09\uFF1A`);
|
|
296285
296547
|
for (const a of st.artifacts) println(` - ${a.path}\uFF08${a.kind ?? "?"}\uFF09status=${a.status ?? "?"}${a.mtime ? ` \xB7 ${new Date(a.mtime).toISOString()}` : ""}`);
|
|
296286
|
-
if (flags.get("pull") === "true") {
|
|
296548
|
+
if (flags.get("pull") === "true" && !lastFailed) {
|
|
296287
296549
|
const odPublic = (flags.get("od-public-url") ?? process.env["OASIS_OPEN_DESIGN_PUBLIC_URL"] ?? "https://design.open-friday.com").replace(/\/$/, "");
|
|
296288
|
-
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey,
|
|
296550
|
+
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey, snapshotSourceRunId(st) ?? "status-pull");
|
|
296289
296551
|
println(`[design] \u5DF2\u62C9\u5230\u672C\u5730\uFF1A${dir2}\uFF08\u5165\u53E3 ${entry}\uFF09`);
|
|
296290
296552
|
println(`[design] \u8BFB\u5B8C\u6EE1\u610F\u5373\u4EA4\u7A3F\uFF1Aoasis propose ${artifactId} --from-dir ${dir2} --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"`);
|
|
296291
|
-
} else {
|
|
296553
|
+
} else if (!lastFailed) {
|
|
296292
296554
|
println(`[design] \u53D6\u8D27\uFF1Aoasis design status ${artifactId} --pull\uFF08\u62C9\u5230\u672C\u5730\u76EE\u5F55\u8BFB\uFF0C\u8BFB\u5B8C propose --from-dir \u4EA4\u7A3F\uFF09`);
|
|
296293
296555
|
}
|
|
296294
296556
|
break;
|
|
296295
296557
|
}
|
|
296296
|
-
throw new Error("\u7528\u6CD5\uFF1Aoasis design chat <artifactId> --message <t> [--turn first|continue] [--async]\uFF1Boasis design status <artifactId> [--pull]");
|
|
296558
|
+
throw new Error("\u7528\u6CD5\uFF1Aoasis design chat <artifactId> --message <t> [--turn first|continue] [--async]\uFF1Boasis design status <artifactId> [--pull] [--wait [--wait-timeout <\u5206\u949F>]]");
|
|
296297
296559
|
}
|
|
296298
296560
|
case "merge": {
|
|
296299
296561
|
const artifactId = needPos(positional, 0, "oasis merge <artifactId> [revisionId]");
|
|
@@ -298390,7 +298652,7 @@ function shimScript() {
|
|
|
298390
298652
|
}
|
|
298391
298653
|
|
|
298392
298654
|
// src/index.ts
|
|
298393
|
-
var PKG_VERSION = true ? "2.2.
|
|
298655
|
+
var PKG_VERSION = true ? "2.2.85" : "dev";
|
|
298394
298656
|
var LOCAL_BIN = localBin();
|
|
298395
298657
|
var NPM_PREFIX = npmPrefix();
|
|
298396
298658
|
var INSTANCE = DEFAULT_INSTANCE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oasis_test_v2",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.85",
|
|
4
4
|
"description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"oasis": "./dist/index.js"
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"oasisRelease": {
|
|
29
|
-
"sourceHead": "
|
|
29
|
+
"sourceHead": "760b80b59c0caa8c7469a804b84360f5ecf3a71a"
|
|
30
30
|
}
|
|
31
31
|
}
|