@siming-org/core 0.6.5 → 0.7.0
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.d.ts +330 -12
- package/dist/index.js +929 -416
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
|
-
import { z as
|
|
3
|
+
import { z as z21 } from "zod";
|
|
4
4
|
|
|
5
5
|
// src/store/client.ts
|
|
6
6
|
import { MongoClient } from "mongodb";
|
|
@@ -62,9 +62,9 @@ function createRepo(collection, options = {}) {
|
|
|
62
62
|
const doc = await collection.findOne({ [nameField]: name });
|
|
63
63
|
return doc ? toEntity(doc) : null;
|
|
64
64
|
},
|
|
65
|
-
async create(data) {
|
|
65
|
+
async create(data, session) {
|
|
66
66
|
const now = /* @__PURE__ */ new Date();
|
|
67
|
-
const result = await collection.insertOne({ ...data, createdAt: now, updatedAt: now });
|
|
67
|
+
const result = await collection.insertOne({ ...data, createdAt: now, updatedAt: now }, ...session ? [{ session }] : []);
|
|
68
68
|
return { ...data, createdAt: now, updatedAt: now, id: result.insertedId.toString() };
|
|
69
69
|
},
|
|
70
70
|
async update(id, patch) {
|
|
@@ -129,6 +129,9 @@ var BIZ_CODE_MESSAGES = {
|
|
|
129
129
|
CHECK_NOT_FOUND: "\u5B8C\u6210\u5224\u5B9A\u6761\u76EE\u4E0D\u5B58\u5728\uFF08id \u5931\u6548\u6216\u5DF2\u88AB\u8986\u76D6\uFF0C\u91CD\u65B0 task context \u67E5\u770B\u6761\u76EE\uFF09",
|
|
130
130
|
NODE_RECORD_NOT_WRITABLE: "\u8282\u70B9\u8BB0\u5F55\u4E0D\u53EF\u5199\uFF08\u8282\u70B9\u672A\u6FC0\u6D3B/\u5DF2\u8DF3\u8FC7\u2014\u2014\u6D41\u7A0B\u672A\u63A8\u8FDB\u5230\u8BE5\u8282\u70B9\uFF09",
|
|
131
131
|
TASK_TERMINATED: "\u4EFB\u52A1\u5DF2\u5B8C\u7ED3\uFF08completed/cancelled\uFF09\uFF0C\u7981\u6B62\u5199\u5165",
|
|
132
|
+
// T202609130009:终态重开域(不复用 TASK_TERMINATED——调用方语义相反,同码不同义污染按码判定)
|
|
133
|
+
TASK_NOT_TERMINATED: "\u4EFB\u52A1\u975E\u7EC8\u6001\uFF08active/paused\uFF09\uFF0C\u65E0\u9700\u91CD\u5F00",
|
|
134
|
+
TASK_FINALIZE_CONFIRMATION_REQUIRED: "\u4EFB\u52A1\u4F4D\u4E8E\u6700\u540E\u8282\u70B9\uFF1A\u786E\u8BA4\u5168\u90E8\u4EA7\u51FA\u5B8C\u6574\u540E\uFF0C\u643A\u5E26\u6536\u5C3E\u786E\u8BA4\uFF08finalize\uFF09\u91CD\u65B0\u63A8\u8FDB",
|
|
132
135
|
// T202608240003:类型化任务节点路径(创建时剪枝 + 类型×轨道入口校验)
|
|
133
136
|
TASK_PRUNE_GRAPH_INVALID: "\u526A\u679D\u540E DAG \u56FE\u4E0D\u5B8C\u6574\uFF08\u8282\u70B9\u6E05\u5355\u4E0E\u6A21\u677F\u7ED3\u6784\u4E0D\u517C\u5BB9\uFF0C\u89C1\u9519\u8BEF\u8BE6\u60C5\uFF09",
|
|
134
137
|
TASK_SKIP_NODE_NOT_FOUND: "skip \u6E05\u5355\u542B\u6A21\u677F\u4E0D\u5B58\u5728\u7684\u8282\u70B9 id\uFF08\u89C1\u9519\u8BEF\u8BE6\u60C5\u7684\u5408\u6CD5\u8282\u70B9\u6E05\u5355\uFF09",
|
|
@@ -153,7 +156,12 @@ var BIZ_CODE_MESSAGES = {
|
|
|
153
156
|
NODE_LIBRARY_COMPOSITION_NOT_FOUND: "\u7EC4\u5408\u5B9A\u4E49\u4E0D\u5B58\u5728\uFF08\u591A\u5E93\u540C\u540D\u7EC4\u5408\u9700\u663E\u5F0F\u6307\u5B9A\u6765\u6E90\u5E93\uFF09",
|
|
154
157
|
UPGRADE_DECISION_REQUIRED: "\u672C\u5730\u5DF2\u4FEE\u6539\u7684\u8282\u70B9\u5FC5\u987B\u663E\u5F0F\u51B3\u7B56\uFF08upgrade/keep/skip\uFF09",
|
|
155
158
|
UPGRADE_STALE: "\u6A21\u677F\u72B6\u6001\u4E0E\u5347\u7EA7\u8BA1\u5212\u4E0D\u7B26\uFF08\u8BA1\u5212\u540E\u6A21\u677F\u5DF2\u88AB\u7F16\u8F91\uFF09\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6\u5347\u7EA7\u8BA1\u5212",
|
|
156
|
-
FLOW_MANIFEST_INVALID: "\u8282\u70B9\u5E93 manifest \u683C\u5F0F\u6216\u7248\u672C\u4E0D\u652F\u6301"
|
|
159
|
+
FLOW_MANIFEST_INVALID: "\u8282\u70B9\u5E93 manifest \u683C\u5F0F\u6216\u7248\u672C\u4E0D\u652F\u6301",
|
|
160
|
+
// T202609150002:问题池域(message 由路由层按状态差异化——已转任务携带关联任务标识 / 已取消提示废弃)
|
|
161
|
+
ISSUE_NOT_FOUND: "\u95EE\u9898\u4E0D\u5B58\u5728",
|
|
162
|
+
ISSUE_INVALID_TRANSITION: "\u95EE\u9898\u5DF2\u662F\u7EC8\u6001\uFF0C\u7981\u6B62\u8BE5\u64CD\u4F5C\uFF08\u7EC8\u6001\u65E0\u56DE\u8F6C\uFF09",
|
|
163
|
+
ISSUE_PROJECT_MISMATCH: "\u95EE\u9898\u4E0E\u76EE\u6807\u9879\u76EE\u5F52\u5C5E\u4E0D\u4E00\u81F4\uFF0C\u7981\u6B62\u8DE8\u9879\u76EE\u7EC4\u5408\u8F6C\u51FA",
|
|
164
|
+
ISSUE_BATCH_LIMIT_EXCEEDED: "\u5355\u6B21\u8F6C\u4EFB\u52A1\u89C4\u6A21\u8D85\u9650\uFF08\u7EC4 \u226410\u3001\u6BCF\u7EC4 \u226450\u3001\u53BB\u91CD\u95EE\u9898\u603B\u91CF \u226450\uFF09\uFF0C\u8BF7\u62C6\u5206\u4E3A\u591A\u6B21\u8F6C\u51FA"
|
|
157
165
|
};
|
|
158
166
|
var AppError = class extends Error {
|
|
159
167
|
};
|
|
@@ -1113,7 +1121,7 @@ var DagInstanceSchema = z4.object({
|
|
|
1113
1121
|
prunedNodes: z4.array(z4.string()),
|
|
1114
1122
|
nodeStates: z4.record(z4.string(), NodeStateSchema)
|
|
1115
1123
|
});
|
|
1116
|
-
var HistoryActionSchema = z4.enum(["entered", "advanced", "paused", "resumed", "approved", "rejected", "completed", "cancelled"]);
|
|
1124
|
+
var HistoryActionSchema = z4.enum(["entered", "advanced", "paused", "resumed", "approved", "rejected", "completed", "cancelled", "reopened"]);
|
|
1117
1125
|
var HistoryEntrySchema = z4.object({
|
|
1118
1126
|
nodeId: z4.string(),
|
|
1119
1127
|
action: HistoryActionSchema,
|
|
@@ -1234,10 +1242,21 @@ async function advanceTask(deps, taskId, input) {
|
|
|
1234
1242
|
);
|
|
1235
1243
|
if (!nextEdge) {
|
|
1236
1244
|
if (checkTermination(task.dagInstance.nodes, task.dagInstance.edges, task.dagInstance.nodeStates, completedState, currentNode.id, task.track)) {
|
|
1245
|
+
if (!input?.finalize) {
|
|
1246
|
+
throw new BadRequestError(
|
|
1247
|
+
`Task is at its final node ('${currentNode.id}'). Confirm all outputs are complete, then advance with finalize=true to complete the task.`,
|
|
1248
|
+
void 0,
|
|
1249
|
+
{
|
|
1250
|
+
bizCode: "TASK_FINALIZE_CONFIRMATION_REQUIRED",
|
|
1251
|
+
message: `\u5F53\u524D\u8282\u70B9\u300C${currentNode.label ?? currentNode.id}\u300D\u4E3A\u4EFB\u52A1\u6700\u540E\u8282\u70B9\uFF1A\u786E\u8BA4\u5168\u90E8\u4EA7\u51FA\u5B8C\u6574\u540E\uFF0C\u643A\u5E26\u6536\u5C3E\u786E\u8BA4\u91CD\u65B0\u63A8\u8FDB\uFF08CLI: siming task advance <id> --finalize\uFF1BMCP: finalize=true\uFF1BWeb: \u6536\u5C3E\u786E\u8BA4\u6309\u94AE\uFF09\u3002`
|
|
1252
|
+
}
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1237
1255
|
const patch2 = {
|
|
1238
1256
|
status: "completed",
|
|
1239
1257
|
...summaryPatch,
|
|
1240
|
-
|
|
1258
|
+
// finalize 守卫(上方)已保证此处 input.finalize 恒为 true——completed 条目恒记 finalized:true
|
|
1259
|
+
history: [...task.history, mkHistory(currentNode.id, "completed", { ...noteDetails, finalized: true })],
|
|
1241
1260
|
dagInstance: {
|
|
1242
1261
|
...task.dagInstance,
|
|
1243
1262
|
nodeStates: {
|
|
@@ -1458,6 +1477,105 @@ async function cancelTask(deps, taskId, reason) {
|
|
|
1458
1477
|
expectedCurrentNode: task.currentNode
|
|
1459
1478
|
});
|
|
1460
1479
|
}
|
|
1480
|
+
async function reopenTask(deps, taskId, input, operator) {
|
|
1481
|
+
const task = await deps.getTask(taskId);
|
|
1482
|
+
if (!task) throw new NotFoundError("task", taskId);
|
|
1483
|
+
if (input.reason.trim() === "") {
|
|
1484
|
+
throw new BadRequestError("reopen reason must not be blank", "reason");
|
|
1485
|
+
}
|
|
1486
|
+
if (task.status !== "completed" && task.status !== "cancelled") {
|
|
1487
|
+
throw new BadRequestError(
|
|
1488
|
+
`Cannot reopen: task status is '${task.status}'. Only completed/cancelled tasks can be reopened.`,
|
|
1489
|
+
void 0,
|
|
1490
|
+
{ bizCode: "TASK_NOT_TERMINATED", message: `\u4EFB\u52A1\u975E\u7EC8\u6001\uFF08\u5F53\u524D ${task.status}\uFF09\uFF0C\u65E0\u9700\u91CD\u5F00` }
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
const reasonDetails = {
|
|
1494
|
+
reason: input.reason,
|
|
1495
|
+
...operator !== void 0 ? { operator } : {},
|
|
1496
|
+
fromStatus: task.status
|
|
1497
|
+
};
|
|
1498
|
+
let patch;
|
|
1499
|
+
let toStatus;
|
|
1500
|
+
let restoredPausedAt;
|
|
1501
|
+
if (task.status === "completed") {
|
|
1502
|
+
const last = task.history[task.history.length - 1];
|
|
1503
|
+
if (!last || last.action !== "completed" || last.nodeId !== task.currentNode) {
|
|
1504
|
+
throw new Error(
|
|
1505
|
+
`invariant violation: last history entry is not completed@'${task.currentNode}' \u2014 task ${taskId}`
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
toStatus = "active";
|
|
1509
|
+
restoredPausedAt = null;
|
|
1510
|
+
const existingState = task.dagInstance.nodeStates[task.currentNode];
|
|
1511
|
+
patch = {
|
|
1512
|
+
status: "active",
|
|
1513
|
+
history: [...task.history, mkHistory(task.currentNode, "reopened", { ...reasonDetails, toStatus, restoredPausedAt })],
|
|
1514
|
+
dagInstance: {
|
|
1515
|
+
...task.dagInstance,
|
|
1516
|
+
nodeStates: {
|
|
1517
|
+
...task.dagInstance.nodeStates,
|
|
1518
|
+
[task.currentNode]: {
|
|
1519
|
+
status: "active",
|
|
1520
|
+
enteredAt: existingState?.enteredAt ?? /* @__PURE__ */ new Date(),
|
|
1521
|
+
completedAt: null
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
};
|
|
1526
|
+
} else {
|
|
1527
|
+
const pre = derivePreTerminalState(task.history);
|
|
1528
|
+
toStatus = pre.status;
|
|
1529
|
+
restoredPausedAt = pre.pausedAt;
|
|
1530
|
+
patch = {
|
|
1531
|
+
status: pre.status,
|
|
1532
|
+
pausedAt: pre.pausedAt,
|
|
1533
|
+
history: [...task.history, mkHistory(task.currentNode, "reopened", { ...reasonDetails, toStatus, restoredPausedAt })]
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
const updated = await deps.updateTask(taskId, patch, {
|
|
1537
|
+
expectedStatus: task.status,
|
|
1538
|
+
expectedCurrentNode: task.currentNode
|
|
1539
|
+
});
|
|
1540
|
+
return { task: updated, restored: { fromStatus: task.status, toStatus, pausedAt: restoredPausedAt } };
|
|
1541
|
+
}
|
|
1542
|
+
function derivePreTerminalState(history) {
|
|
1543
|
+
let cancelIdx = -1;
|
|
1544
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
1545
|
+
if (history[i]?.action === "cancelled") {
|
|
1546
|
+
cancelIdx = i;
|
|
1547
|
+
break;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
if (cancelIdx === -1) {
|
|
1551
|
+
throw new Error("invariant violation: derivePreTerminalState requires a cancelled history entry");
|
|
1552
|
+
}
|
|
1553
|
+
for (let i = cancelIdx - 1; i >= 0; i--) {
|
|
1554
|
+
const entry = history[i];
|
|
1555
|
+
if (!entry) break;
|
|
1556
|
+
const details = entry.details;
|
|
1557
|
+
switch (entry.action) {
|
|
1558
|
+
case "paused":
|
|
1559
|
+
return "pausePoint" in details ? { status: "paused", pausedAt: entry.nodeId } : { status: "paused", pausedAt: null };
|
|
1560
|
+
case "rejected":
|
|
1561
|
+
case "cancelled":
|
|
1562
|
+
continue;
|
|
1563
|
+
// rejected 不改状态锚点(继续向前);更早取消周期防御性跳过
|
|
1564
|
+
case "reopened":
|
|
1565
|
+
return {
|
|
1566
|
+
status: details.toStatus === "paused" ? "paused" : "active",
|
|
1567
|
+
pausedAt: details.restoredPausedAt ?? null
|
|
1568
|
+
};
|
|
1569
|
+
case "resumed":
|
|
1570
|
+
case "advanced":
|
|
1571
|
+
case "entered":
|
|
1572
|
+
case "approved":
|
|
1573
|
+
case "completed":
|
|
1574
|
+
return { status: "active", pausedAt: null };
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
throw new Error("invariant violation: no pre-terminal state anchor found before cancelled entry");
|
|
1578
|
+
}
|
|
1461
1579
|
function findNextEdge(edges, nodes, fromNodeId, track) {
|
|
1462
1580
|
const outEdges = edges.filter((e) => e.from === fromNodeId);
|
|
1463
1581
|
const matchSet = trackMatchSet(track);
|
|
@@ -1831,7 +1949,7 @@ function createTaskRepo(db) {
|
|
|
1831
1949
|
}
|
|
1832
1950
|
return toEntity(result);
|
|
1833
1951
|
},
|
|
1834
|
-
async createTask(input, template, resolvedProjectId) {
|
|
1952
|
+
async createTask(input, template, resolvedProjectId, session) {
|
|
1835
1953
|
if (!input.track) {
|
|
1836
1954
|
throw new BadRequestError(`track is required`);
|
|
1837
1955
|
}
|
|
@@ -1849,13 +1967,14 @@ function createTaskRepo(db) {
|
|
|
1849
1967
|
throw new BadRequestError("DagTemplate has no id");
|
|
1850
1968
|
}
|
|
1851
1969
|
let taskId = null;
|
|
1852
|
-
let seq = await base._collection.countDocuments(
|
|
1853
|
-
taskId: { $regex: `^T${getDatePrefix()}` }
|
|
1854
|
-
|
|
1970
|
+
let seq = await base._collection.countDocuments(
|
|
1971
|
+
{ taskId: { $regex: `^T${getDatePrefix()}` } },
|
|
1972
|
+
...session ? [{ session }] : []
|
|
1973
|
+
);
|
|
1855
1974
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
1856
1975
|
seq++;
|
|
1857
1976
|
taskId = generateTaskId(seq);
|
|
1858
|
-
const exists = await base._collection.findOne({ taskId }, { projection: { _id: 1 } });
|
|
1977
|
+
const exists = await base._collection.findOne({ taskId }, { projection: { _id: 1 }, ...session ? { session } : {} });
|
|
1859
1978
|
if (!exists) break;
|
|
1860
1979
|
taskId = null;
|
|
1861
1980
|
}
|
|
@@ -1888,7 +2007,7 @@ function createTaskRepo(db) {
|
|
|
1888
2007
|
if (!result.success) {
|
|
1889
2008
|
throw new ValidationError("Task validation failed", result.error.issues);
|
|
1890
2009
|
}
|
|
1891
|
-
return base.create(result.data);
|
|
2010
|
+
return base.create(result.data, session);
|
|
1892
2011
|
}
|
|
1893
2012
|
};
|
|
1894
2013
|
}
|
|
@@ -1927,6 +2046,386 @@ function deepCopyEdge(edge) {
|
|
|
1927
2046
|
};
|
|
1928
2047
|
}
|
|
1929
2048
|
|
|
2049
|
+
// src/task/entry-id.ts
|
|
2050
|
+
var ENTRY_ID_LENGTH = 6;
|
|
2051
|
+
var BASE36_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
2052
|
+
function generateEntryId(existing) {
|
|
2053
|
+
const taken = new Set(existing);
|
|
2054
|
+
for (let attempt = 0; attempt < 32; attempt++) {
|
|
2055
|
+
let id = "";
|
|
2056
|
+
for (let i = 0; i < ENTRY_ID_LENGTH; i++) {
|
|
2057
|
+
id += BASE36_ALPHABET[Math.floor(Math.random() * BASE36_ALPHABET.length)];
|
|
2058
|
+
}
|
|
2059
|
+
if (!taken.has(id)) return id;
|
|
2060
|
+
}
|
|
2061
|
+
throw new Error(`entry id generation failed after 32 attempts (existing: ${existing.length})`);
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
// src/schemas/issue.ts
|
|
2065
|
+
import { z as z5 } from "zod";
|
|
2066
|
+
var ISSUE_STATUSES = ["pending", "partial", "converted", "cancelled"];
|
|
2067
|
+
var IssueStatusSchema = z5.enum(ISSUE_STATUSES);
|
|
2068
|
+
var ISSUE_ACTIVE_STATUSES = ["pending", "partial"];
|
|
2069
|
+
var ISSUE_SOURCES = ["mcp", "cli", "web"];
|
|
2070
|
+
var IssueSourceSchema = z5.enum(ISSUE_SOURCES);
|
|
2071
|
+
var TaskLinkSchema = z5.object({
|
|
2072
|
+
/** 关联任务业务 id(T 前缀;任务仅可取消不可删除,引用恒有效) */
|
|
2073
|
+
taskId: z5.string().min(1),
|
|
2074
|
+
/** 该次转出声明(历史事实,展示用;请求级声明——同一问题同次转出全组一致) */
|
|
2075
|
+
mode: z5.enum(["all", "partial"]),
|
|
2076
|
+
linkedAt: z5.date()
|
|
2077
|
+
});
|
|
2078
|
+
var ISSUE_CONVERT_MODES = ["all", "partial"];
|
|
2079
|
+
var IssueConvertModeSchema = z5.enum(ISSUE_CONVERT_MODES);
|
|
2080
|
+
var IssueHistoryEntrySchema = z5.object({
|
|
2081
|
+
id: z5.string().regex(ENTRY_ID_REGEX),
|
|
2082
|
+
action: z5.enum(["created", "status-change", "link-added", "link-terminated"]),
|
|
2083
|
+
from: IssueStatusSchema.optional(),
|
|
2084
|
+
to: IssueStatusSchema.optional(),
|
|
2085
|
+
taskId: z5.string().min(1).optional(),
|
|
2086
|
+
reason: z5.string().max(500).optional(),
|
|
2087
|
+
at: z5.date()
|
|
2088
|
+
});
|
|
2089
|
+
var IssueSchema = z5.object({
|
|
2090
|
+
id: z5.string().optional(),
|
|
2091
|
+
/** 业务 id:I + YYYYMMDD + 4 位序号(taskId 同构,可读可排序) */
|
|
2092
|
+
issueId: z5.string(),
|
|
2093
|
+
title: z5.string().min(1).max(200),
|
|
2094
|
+
description: z5.string().max(1e4).optional(),
|
|
2095
|
+
source: IssueSourceSchema,
|
|
2096
|
+
projectId: z5.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex"),
|
|
2097
|
+
status: IssueStatusSchema.default("pending"),
|
|
2098
|
+
taskLinks: z5.array(TaskLinkSchema).default([]),
|
|
2099
|
+
history: z5.array(IssueHistoryEntrySchema).default([]),
|
|
2100
|
+
createdAt: z5.date().optional(),
|
|
2101
|
+
updatedAt: z5.date().optional()
|
|
2102
|
+
});
|
|
2103
|
+
var IssueCreateSchema = z5.object({
|
|
2104
|
+
title: z5.string().min(1).max(200),
|
|
2105
|
+
description: z5.string().max(1e4).optional()
|
|
2106
|
+
});
|
|
2107
|
+
var IssueUpdateSchema = z5.object({
|
|
2108
|
+
title: z5.string().min(1).max(200).optional(),
|
|
2109
|
+
description: z5.string().max(1e4).optional()
|
|
2110
|
+
});
|
|
2111
|
+
var IssueProgressSchema = z5.object({
|
|
2112
|
+
done: z5.number().int().min(0),
|
|
2113
|
+
cancelled: z5.number().int().min(0),
|
|
2114
|
+
total: z5.number().int().min(0)
|
|
2115
|
+
});
|
|
2116
|
+
|
|
2117
|
+
// src/store/repos/issue.repo.ts
|
|
2118
|
+
var CONVERT_MODE_LABELS = { all: "\u5168\u90E8\u8F6C\u51FA", partial: "\u90E8\u5206\u8F6C\u51FA" };
|
|
2119
|
+
var formatReasonDateTime = (d) => {
|
|
2120
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
2121
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
2122
|
+
};
|
|
2123
|
+
function createIssueRepo(db) {
|
|
2124
|
+
const base = createRepo(db.collection("issues"));
|
|
2125
|
+
const tasks = db.collection("tasks");
|
|
2126
|
+
return {
|
|
2127
|
+
...base,
|
|
2128
|
+
async createIssue(data, source, projectId) {
|
|
2129
|
+
const now = /* @__PURE__ */ new Date();
|
|
2130
|
+
let issueId = null;
|
|
2131
|
+
let seq = await base._collection.countDocuments({
|
|
2132
|
+
issueId: { $regex: `^I${getDatePrefix2()}` }
|
|
2133
|
+
});
|
|
2134
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
2135
|
+
seq++;
|
|
2136
|
+
issueId = `I${getDatePrefix2()}${seq.toString().padStart(4, "0")}`;
|
|
2137
|
+
const exists = await base._collection.findOne({ issueId }, { projection: { _id: 1 } });
|
|
2138
|
+
if (!exists) break;
|
|
2139
|
+
issueId = null;
|
|
2140
|
+
}
|
|
2141
|
+
if (!issueId) {
|
|
2142
|
+
throw new ConflictError("issue", "issueId generation failed after 3 retries");
|
|
2143
|
+
}
|
|
2144
|
+
const issue = {
|
|
2145
|
+
issueId,
|
|
2146
|
+
title: data.title,
|
|
2147
|
+
...data.description !== void 0 ? { description: data.description } : {},
|
|
2148
|
+
source,
|
|
2149
|
+
projectId,
|
|
2150
|
+
status: "pending",
|
|
2151
|
+
taskLinks: [],
|
|
2152
|
+
history: [{ id: generateEntryId([]), action: "created", at: now }]
|
|
2153
|
+
};
|
|
2154
|
+
const result = IssueSchema.safeParse(issue);
|
|
2155
|
+
if (!result.success) {
|
|
2156
|
+
throw new BadRequestError(`Issue validation failed: ${result.error.issues[0]?.message ?? ""}`);
|
|
2157
|
+
}
|
|
2158
|
+
return base.create(result.data);
|
|
2159
|
+
},
|
|
2160
|
+
async getByIssueId(issueId) {
|
|
2161
|
+
const doc = await base._collection.findOne({ issueId });
|
|
2162
|
+
if (!doc) return null;
|
|
2163
|
+
return toEntity(doc);
|
|
2164
|
+
},
|
|
2165
|
+
async updateIssue(issueId, patch) {
|
|
2166
|
+
const sets = {};
|
|
2167
|
+
if (patch.title !== void 0) sets.title = patch.title;
|
|
2168
|
+
if (patch.description !== void 0) sets.description = patch.description;
|
|
2169
|
+
const result = await base._collection.findOneAndUpdate(
|
|
2170
|
+
{ issueId },
|
|
2171
|
+
{ $set: { ...sets, updatedAt: /* @__PURE__ */ new Date() } },
|
|
2172
|
+
{ returnDocument: "after" }
|
|
2173
|
+
);
|
|
2174
|
+
if (!result) throw new NotFoundError("issue", issueId, { bizCode: "ISSUE_NOT_FOUND" });
|
|
2175
|
+
return toEntity(result);
|
|
2176
|
+
},
|
|
2177
|
+
async cancelIssue(issueId, reason) {
|
|
2178
|
+
const current = await base._collection.findOne({ issueId });
|
|
2179
|
+
if (!current) {
|
|
2180
|
+
throw new NotFoundError("issue", issueId, { bizCode: "ISSUE_NOT_FOUND" });
|
|
2181
|
+
}
|
|
2182
|
+
if (current.status === "converted" || current.status === "cancelled") {
|
|
2183
|
+
throw new ConflictError("issue", issueId, {
|
|
2184
|
+
bizCode: "ISSUE_INVALID_TRANSITION",
|
|
2185
|
+
message: `\u95EE\u9898\u5DF2\u662F\u7EC8\u6001\uFF08${String(current.status)}\uFF09\uFF0C\u7981\u6B62\u53D6\u6D88`
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
const now = /* @__PURE__ */ new Date();
|
|
2189
|
+
const links = current.taskLinks ?? [];
|
|
2190
|
+
const terminated = links.map((link) => ({
|
|
2191
|
+
id: generateEntryId([]),
|
|
2192
|
+
action: "link-terminated",
|
|
2193
|
+
taskId: link.taskId,
|
|
2194
|
+
reason: `\u539F\u58F0\u660E ${CONVERT_MODE_LABELS[link.mode]}\uFF08\u5173\u8054\u4E8E ${formatReasonDateTime(link.linkedAt)}\uFF09\uFF0C\u95EE\u9898\u53D6\u6D88\u540E\u7EC8\u6B62`,
|
|
2195
|
+
at: now
|
|
2196
|
+
}));
|
|
2197
|
+
const result = await base._collection.findOneAndUpdate(
|
|
2198
|
+
// 并发安全带:读后窗口内外部转出/取消 → 命中 0 行报终态冲突(终态以先到者为准)
|
|
2199
|
+
{ issueId, status: { $in: ISSUE_ACTIVE_STATUSES } },
|
|
2200
|
+
{
|
|
2201
|
+
$set: { status: "cancelled", taskLinks: [], updatedAt: now },
|
|
2202
|
+
$push: {
|
|
2203
|
+
history: {
|
|
2204
|
+
$each: [
|
|
2205
|
+
...terminated,
|
|
2206
|
+
{
|
|
2207
|
+
id: generateEntryId([]),
|
|
2208
|
+
action: "status-change",
|
|
2209
|
+
from: current.status,
|
|
2210
|
+
to: "cancelled",
|
|
2211
|
+
...reason !== void 0 ? { reason } : {},
|
|
2212
|
+
at: now
|
|
2213
|
+
}
|
|
2214
|
+
]
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
},
|
|
2218
|
+
{ returnDocument: "after" }
|
|
2219
|
+
);
|
|
2220
|
+
if (!result) {
|
|
2221
|
+
throw new ConflictError("issue", issueId, {
|
|
2222
|
+
bizCode: "ISSUE_INVALID_TRANSITION",
|
|
2223
|
+
message: "\u95EE\u9898\u5DF2\u88AB\u5E76\u53D1\u5904\u7406\uFF08\u8F6C\u51FA/\u53D6\u6D88\uFF09\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5"
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
return toEntity(result);
|
|
2227
|
+
},
|
|
2228
|
+
async listIssues(filter) {
|
|
2229
|
+
const match = {};
|
|
2230
|
+
if (filter?.projectId) match.projectId = filter.projectId;
|
|
2231
|
+
if (filter?.status?.length) match.status = { $in: filter.status };
|
|
2232
|
+
if (filter?.source) match.source = filter.source;
|
|
2233
|
+
if (filter?.taskId) match["taskLinks.taskId"] = filter.taskId;
|
|
2234
|
+
if (filter?.q) {
|
|
2235
|
+
match.$or = [
|
|
2236
|
+
{ title: { $regex: escapeRegExpLiteral(filter.q), $options: "i" } },
|
|
2237
|
+
{ description: { $regex: escapeRegExpLiteral(filter.q), $options: "i" } }
|
|
2238
|
+
];
|
|
2239
|
+
}
|
|
2240
|
+
const page = filter?.page ?? 1;
|
|
2241
|
+
const limit = filter?.limit ?? 20;
|
|
2242
|
+
if (filter?.view === "open" && !filter?.status?.length) {
|
|
2243
|
+
const activeMatch = { ...match, status: { $in: ISSUE_ACTIVE_STATUSES } };
|
|
2244
|
+
const convertedMatch = { ...match, status: "converted", taskLinks: { $ne: [] } };
|
|
2245
|
+
const [activeDocs, convertedDocs] = await Promise.all([
|
|
2246
|
+
base._collection.find(activeMatch).toArray(),
|
|
2247
|
+
base._collection.find(convertedMatch).toArray()
|
|
2248
|
+
]);
|
|
2249
|
+
const convertedTaskIds = new Set(convertedDocs.flatMap((doc) => (doc.taskLinks ?? []).map((l) => l.taskId)));
|
|
2250
|
+
const statusMap = /* @__PURE__ */ new Map();
|
|
2251
|
+
if (convertedTaskIds.size > 0) {
|
|
2252
|
+
const statusDocs = await tasks.find({ taskId: { $in: [...convertedTaskIds] } }, { projection: { taskId: 1, status: 1 } }).toArray();
|
|
2253
|
+
for (const doc of statusDocs) statusMap.set(String(doc.taskId), String(doc.status));
|
|
2254
|
+
}
|
|
2255
|
+
const openConverted = convertedDocs.filter(
|
|
2256
|
+
(doc) => doc.taskLinks.some((l) => {
|
|
2257
|
+
const st = statusMap.get(l.taskId);
|
|
2258
|
+
return st === "active" || st === "paused";
|
|
2259
|
+
})
|
|
2260
|
+
);
|
|
2261
|
+
const merged = [...activeDocs, ...openConverted].sort((a, b) => {
|
|
2262
|
+
const at = a.createdAt?.getTime() ?? 0;
|
|
2263
|
+
const bt = b.createdAt?.getTime() ?? 0;
|
|
2264
|
+
return bt - at;
|
|
2265
|
+
});
|
|
2266
|
+
const total2 = merged.length;
|
|
2267
|
+
const slice = merged.slice((page - 1) * limit, page * limit);
|
|
2268
|
+
return { items: await withProgressBatch(db, slice), total: total2 };
|
|
2269
|
+
}
|
|
2270
|
+
const sort = { createdAt: -1 };
|
|
2271
|
+
const [docs, total] = await Promise.all([
|
|
2272
|
+
base._collection.find(match).sort(sort).skip((page - 1) * limit).limit(limit).toArray(),
|
|
2273
|
+
base._collection.countDocuments(match)
|
|
2274
|
+
]);
|
|
2275
|
+
return { items: await withProgressBatch(db, docs), total };
|
|
2276
|
+
},
|
|
2277
|
+
async getIssueDetail(issueId) {
|
|
2278
|
+
const issue = await this.getByIssueId(issueId);
|
|
2279
|
+
if (!issue) return null;
|
|
2280
|
+
const progress = await progressFor(db, issue.taskLinks);
|
|
2281
|
+
const taskDocs = issue.taskLinks.length > 0 ? await tasks.find(
|
|
2282
|
+
{ taskId: { $in: issue.taskLinks.map((l) => l.taskId) } },
|
|
2283
|
+
{ projection: { taskId: 1, title: 1, currentNode: 1, status: 1, updatedAt: 1 } }
|
|
2284
|
+
).toArray() : [];
|
|
2285
|
+
const byTaskId = new Map(taskDocs.map((doc) => [String(doc.taskId), doc]));
|
|
2286
|
+
const taskViews = issue.taskLinks.map((link) => {
|
|
2287
|
+
const doc = byTaskId.get(link.taskId);
|
|
2288
|
+
return {
|
|
2289
|
+
taskId: link.taskId,
|
|
2290
|
+
title: String(doc?.title ?? `\uFF08\u4EFB\u52A1 ${link.taskId}\uFF09`),
|
|
2291
|
+
currentNode: String(doc?.currentNode ?? "\u2014"),
|
|
2292
|
+
status: String(doc?.status ?? "unknown"),
|
|
2293
|
+
mode: link.mode,
|
|
2294
|
+
linkedAt: link.linkedAt,
|
|
2295
|
+
updatedAt: doc?.updatedAt ?? link.linkedAt
|
|
2296
|
+
};
|
|
2297
|
+
});
|
|
2298
|
+
return { ...issue, progress, tasks: taskViews };
|
|
2299
|
+
},
|
|
2300
|
+
async listByTaskId(taskId) {
|
|
2301
|
+
const docs = await base._collection.find({
|
|
2302
|
+
$or: [{ "taskLinks.taskId": taskId }, { "history.taskId": taskId, "history.action": "link-terminated" }]
|
|
2303
|
+
}).toArray();
|
|
2304
|
+
const issues = docs.map((doc) => toEntity(doc));
|
|
2305
|
+
const progressed = await withProgressBatch(db, docs);
|
|
2306
|
+
const progressById = new Map(progressed.map((item) => [item.issueId, item.progress]));
|
|
2307
|
+
return issues.map((issue) => ({
|
|
2308
|
+
issueId: issue.issueId,
|
|
2309
|
+
title: issue.title,
|
|
2310
|
+
status: issue.status,
|
|
2311
|
+
source: issue.source,
|
|
2312
|
+
progress: progressById.get(issue.issueId) ?? { done: 0, cancelled: 0, total: 0 },
|
|
2313
|
+
// 终止判定:当前 taskLinks 不含该 taskId(已取消的关联——历史终止条目命中)
|
|
2314
|
+
terminated: !issue.taskLinks.some((l) => l.taskId === taskId),
|
|
2315
|
+
updatedAt: issue.updatedAt ?? /* @__PURE__ */ new Date(0)
|
|
2316
|
+
}));
|
|
2317
|
+
},
|
|
2318
|
+
async linkTaskForConvert(session, issueId, taskId, mode) {
|
|
2319
|
+
const now = /* @__PURE__ */ new Date();
|
|
2320
|
+
const result = await base._collection.findOneAndUpdate(
|
|
2321
|
+
// 条件更新双保险:外部并发转出/取消(终态)→ 命中 0 行,事务中止整组回滚
|
|
2322
|
+
{ issueId, status: { $in: ISSUE_ACTIVE_STATUSES } },
|
|
2323
|
+
{
|
|
2324
|
+
$push: {
|
|
2325
|
+
taskLinks: { taskId, mode, linkedAt: now },
|
|
2326
|
+
history: {
|
|
2327
|
+
id: generateEntryId([]),
|
|
2328
|
+
action: "link-added",
|
|
2329
|
+
taskId,
|
|
2330
|
+
reason: `\u8F6C\u51FA\u58F0\u660E ${CONVERT_MODE_LABELS[mode]}`,
|
|
2331
|
+
at: now
|
|
2332
|
+
}
|
|
2333
|
+
},
|
|
2334
|
+
$set: { updatedAt: now }
|
|
2335
|
+
},
|
|
2336
|
+
{ returnDocument: "after", session }
|
|
2337
|
+
);
|
|
2338
|
+
if (!result) {
|
|
2339
|
+
const exists = await base._collection.findOne({ issueId }, { projection: { status: 1 }, session });
|
|
2340
|
+
if (!exists) {
|
|
2341
|
+
throw new NotFoundError("issue", issueId, { bizCode: "ISSUE_NOT_FOUND" });
|
|
2342
|
+
}
|
|
2343
|
+
throw new ConflictError("issue", issueId, {
|
|
2344
|
+
bizCode: "ISSUE_INVALID_TRANSITION",
|
|
2345
|
+
message: `\u95EE\u9898\u5DF2\u88AB\u5E76\u53D1\u5904\u7406\uFF08status: ${String(exists.status)}\uFF09\uFF0C\u672C\u7EC4\u8F6C\u51FA\u56DE\u6EDA`
|
|
2346
|
+
});
|
|
2347
|
+
}
|
|
2348
|
+
},
|
|
2349
|
+
async finalizeConvertStatuses(issues, outcomes, declarations) {
|
|
2350
|
+
const changes = [];
|
|
2351
|
+
for (const issue of issues) {
|
|
2352
|
+
const touching = outcomes.filter((o) => o.issueIds.includes(issue.issueId));
|
|
2353
|
+
const successGroups = touching.filter((o) => o.ok);
|
|
2354
|
+
if (successGroups.length === 0) continue;
|
|
2355
|
+
const anyFailed = touching.some((o) => !o.ok);
|
|
2356
|
+
const declaration = declarations.get(issue.issueId) ?? "partial";
|
|
2357
|
+
const to = anyFailed || declaration !== "all" ? "partial" : "converted";
|
|
2358
|
+
if (issue.status === to && !anyFailed) continue;
|
|
2359
|
+
const now = /* @__PURE__ */ new Date();
|
|
2360
|
+
const successTaskIds = successGroups.map((o) => o.taskId).filter((t) => t !== void 0);
|
|
2361
|
+
const result = await base._collection.findOneAndUpdate(
|
|
2362
|
+
// 并发安全带:推导前被外部取消/转出 → 命中 0 行跳过(终态以先到者为准;ISSUE_ACTIVE_STATUSES 单一真相源)
|
|
2363
|
+
{ issueId: issue.issueId, status: { $in: ISSUE_ACTIVE_STATUSES } },
|
|
2364
|
+
{
|
|
2365
|
+
$set: { status: to, updatedAt: now },
|
|
2366
|
+
$push: {
|
|
2367
|
+
history: {
|
|
2368
|
+
id: generateEntryId(issue.history.map((h) => h.id)),
|
|
2369
|
+
action: "status-change",
|
|
2370
|
+
from: issue.status,
|
|
2371
|
+
to,
|
|
2372
|
+
reason: to === "converted" ? `\u8F6C\u51FA\u5B8C\u6210\uFF08\u5173\u8054\u4EFB\u52A1 ${successTaskIds.join("\u3001") || "\u2014"}\uFF09` : anyFailed ? `\u90E8\u5206\u8F6C\u51FA\uFF08\u5B58\u5728\u5931\u8D25\u7EC4\u9057\u7559\uFF0C\u6210\u529F\u4EFB\u52A1 ${successTaskIds.join("\u3001") || "\u2014"}\uFF09` : `\u90E8\u5206\u8F6C\u51FA\uFF08\u58F0\u660E partial\uFF0C\u5173\u8054\u4EFB\u52A1 ${successTaskIds.join("\u3001") || "\u2014"}\uFF09`,
|
|
2373
|
+
at: now
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
},
|
|
2377
|
+
{ returnDocument: "after" }
|
|
2378
|
+
);
|
|
2379
|
+
if (result) {
|
|
2380
|
+
changes.push({ issueId: issue.issueId, from: issue.status, to });
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
return changes;
|
|
2384
|
+
}
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
async function withProgressBatch(db, docs) {
|
|
2388
|
+
const taskIds = /* @__PURE__ */ new Set();
|
|
2389
|
+
for (const doc of docs) {
|
|
2390
|
+
for (const link of doc.taskLinks ?? []) taskIds.add(link.taskId);
|
|
2391
|
+
}
|
|
2392
|
+
const statusMap = /* @__PURE__ */ new Map();
|
|
2393
|
+
if (taskIds.size > 0) {
|
|
2394
|
+
const statusDocs = await db.collection("tasks").find({ taskId: { $in: [...taskIds] } }, { projection: { taskId: 1, status: 1 } }).toArray();
|
|
2395
|
+
for (const doc of statusDocs) statusMap.set(String(doc.taskId), String(doc.status));
|
|
2396
|
+
}
|
|
2397
|
+
return docs.map((doc) => {
|
|
2398
|
+
const issue = toEntity(doc);
|
|
2399
|
+
let done = 0;
|
|
2400
|
+
let cancelled = 0;
|
|
2401
|
+
for (const link of issue.taskLinks) {
|
|
2402
|
+
const st = statusMap.get(link.taskId);
|
|
2403
|
+
if (st === "completed") done++;
|
|
2404
|
+
else if (st === "cancelled") cancelled++;
|
|
2405
|
+
}
|
|
2406
|
+
return { ...issue, progress: { done, cancelled, total: issue.taskLinks.length } };
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
async function progressFor(db, links) {
|
|
2410
|
+
const statusMap = /* @__PURE__ */ new Map();
|
|
2411
|
+
if (links.length > 0) {
|
|
2412
|
+
const statusDocs = await db.collection("tasks").find({ taskId: { $in: links.map((l) => l.taskId) } }, { projection: { taskId: 1, status: 1 } }).toArray();
|
|
2413
|
+
for (const doc of statusDocs) statusMap.set(String(doc.taskId), String(doc.status));
|
|
2414
|
+
}
|
|
2415
|
+
let done = 0;
|
|
2416
|
+
let cancelled = 0;
|
|
2417
|
+
for (const link of links) {
|
|
2418
|
+
const st = statusMap.get(link.taskId);
|
|
2419
|
+
if (st === "completed") done++;
|
|
2420
|
+
else if (st === "cancelled") cancelled++;
|
|
2421
|
+
}
|
|
2422
|
+
return { done, cancelled, total: links.length };
|
|
2423
|
+
}
|
|
2424
|
+
function getDatePrefix2() {
|
|
2425
|
+
const d = /* @__PURE__ */ new Date();
|
|
2426
|
+
return d.getFullYear().toString() + (d.getMonth() + 1).toString().padStart(2, "0") + d.getDate().toString().padStart(2, "0");
|
|
2427
|
+
}
|
|
2428
|
+
|
|
1930
2429
|
// src/store/repos/project.repo.ts
|
|
1931
2430
|
import { ObjectId as ObjectId2 } from "mongodb";
|
|
1932
2431
|
var DEFAULT_PROJECT_KEY = "default";
|
|
@@ -2054,6 +2553,8 @@ var REFERENCE_CHECKS = {
|
|
|
2054
2553
|
task_status: [{ collection: "tasks", query: (v) => ({ status: v }) }],
|
|
2055
2554
|
node_status: [{ collection: "tasks", query: (v) => ({ "dagInstance.nodeStates.status": v }) }],
|
|
2056
2555
|
skill_category: [{ collection: "skills", query: (v) => ({ category: v }) }],
|
|
2556
|
+
// T202609150002:问题状态被 issues.status 引用(四值全 builtin 禁删,检测为未来扩值留防线)
|
|
2557
|
+
issue_status: [{ collection: "issues", query: (v) => ({ status: v }) }],
|
|
2057
2558
|
scope: void 0,
|
|
2058
2559
|
// T202608260002:agent 功能类型被 agents.function 引用(reviewer/executor 为 builtin 禁删;
|
|
2059
2560
|
// 检测映射为未来非 builtin 扩值留防线)
|
|
@@ -2276,7 +2777,7 @@ function createNodeLibraryRepo(db) {
|
|
|
2276
2777
|
|
|
2277
2778
|
// src/store/repos/auth.repo.ts
|
|
2278
2779
|
import { ObjectId as ObjectId3 } from "mongodb";
|
|
2279
|
-
import { z as
|
|
2780
|
+
import { z as z6 } from "zod";
|
|
2280
2781
|
var AUTH_COLLECTIONS = {
|
|
2281
2782
|
accounts: "auth_accounts",
|
|
2282
2783
|
tokens: "auth_tokens",
|
|
@@ -2370,14 +2871,14 @@ function createAuthTokenRepo(db) {
|
|
|
2370
2871
|
}
|
|
2371
2872
|
};
|
|
2372
2873
|
}
|
|
2373
|
-
var AuthSessionSchema =
|
|
2374
|
-
id:
|
|
2375
|
-
sessionId:
|
|
2874
|
+
var AuthSessionSchema = z6.object({
|
|
2875
|
+
id: z6.string().optional(),
|
|
2876
|
+
sessionId: z6.string().min(1),
|
|
2376
2877
|
/** 管理员账号 id(会话 = 管理员身份) */
|
|
2377
|
-
accountId:
|
|
2378
|
-
expiresAt:
|
|
2379
|
-
createdAt:
|
|
2380
|
-
updatedAt:
|
|
2878
|
+
accountId: z6.string().min(1),
|
|
2879
|
+
expiresAt: z6.date(),
|
|
2880
|
+
createdAt: z6.date().optional(),
|
|
2881
|
+
updatedAt: z6.date().optional()
|
|
2381
2882
|
});
|
|
2382
2883
|
function createAuthSessionRepo(db) {
|
|
2383
2884
|
const base = createRepo(db.collection(AUTH_COLLECTIONS.sessions));
|
|
@@ -2456,21 +2957,21 @@ function generateSessionId() {
|
|
|
2456
2957
|
}
|
|
2457
2958
|
|
|
2458
2959
|
// src/schemas/agent.ts
|
|
2459
|
-
import { z as
|
|
2960
|
+
import { z as z8 } from "zod";
|
|
2460
2961
|
|
|
2461
2962
|
// src/schemas/model-alias.ts
|
|
2462
|
-
import { z as
|
|
2963
|
+
import { z as z7 } from "zod";
|
|
2463
2964
|
var SIMING_CODE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
2464
|
-
var ModelAliasShapeSchema =
|
|
2465
|
-
id:
|
|
2965
|
+
var ModelAliasShapeSchema = z7.object({
|
|
2966
|
+
id: z7.string().optional(),
|
|
2466
2967
|
/** siming code:创建后不可变(PUT 显式拒绝 MODEL_CODE_IMMUTABLE,非静默剥离) */
|
|
2467
|
-
code:
|
|
2968
|
+
code: z7.string().regex(SIMING_CODE_REGEX, "code \u5FC5\u987B\u4E3A kebab-case\uFF08\u5982 primary\u3001fast-model\uFF09"),
|
|
2468
2969
|
/** 展示名(如「主力模型」) */
|
|
2469
|
-
name:
|
|
2970
|
+
name: z7.string().min(1, "\u5C55\u793A\u540D\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
2470
2971
|
/** 真实模型标识(如 zhipuai/glm-5.3;改此处 = 引用方全局替换生效) */
|
|
2471
|
-
realModel:
|
|
2472
|
-
createdAt:
|
|
2473
|
-
updatedAt:
|
|
2972
|
+
realModel: z7.string().min(1, "\u771F\u5B9E\u6A21\u578B\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
2973
|
+
createdAt: z7.date().optional(),
|
|
2974
|
+
updatedAt: z7.date().optional()
|
|
2474
2975
|
});
|
|
2475
2976
|
var ModelAliasSchema = ModelAliasShapeSchema;
|
|
2476
2977
|
var ModelAliasCreateSchema = ModelAliasShapeSchema.omit({
|
|
@@ -2478,18 +2979,18 @@ var ModelAliasCreateSchema = ModelAliasShapeSchema.omit({
|
|
|
2478
2979
|
createdAt: true,
|
|
2479
2980
|
updatedAt: true
|
|
2480
2981
|
});
|
|
2481
|
-
var ModelAliasUpdateSchema =
|
|
2482
|
-
code:
|
|
2483
|
-
name:
|
|
2484
|
-
realModel:
|
|
2982
|
+
var ModelAliasUpdateSchema = z7.object({
|
|
2983
|
+
code: z7.string().regex(SIMING_CODE_REGEX).optional(),
|
|
2984
|
+
name: z7.string().min(1).optional(),
|
|
2985
|
+
realModel: z7.string().min(1).optional()
|
|
2485
2986
|
});
|
|
2486
2987
|
var ModelAliasWithRefCountSchema = ModelAliasShapeSchema.extend({
|
|
2487
|
-
refCount:
|
|
2988
|
+
refCount: z7.number().int().min(0)
|
|
2488
2989
|
});
|
|
2489
2990
|
|
|
2490
2991
|
// src/schemas/agent.ts
|
|
2491
|
-
var AgentScopeSchema =
|
|
2492
|
-
var AgentFunctionSchema =
|
|
2992
|
+
var AgentScopeSchema = z8.enum(["global", "project"]);
|
|
2993
|
+
var AgentFunctionSchema = z8.enum(["reviewer", "executor"]);
|
|
2493
2994
|
var AgentScopeRefine = (val, ctx) => {
|
|
2494
2995
|
if (val.scope === "project" && !val.projectId) {
|
|
2495
2996
|
ctx.addIssue({
|
|
@@ -2499,17 +3000,17 @@ var AgentScopeRefine = (val, ctx) => {
|
|
|
2499
3000
|
});
|
|
2500
3001
|
}
|
|
2501
3002
|
};
|
|
2502
|
-
var AgentShapeSchema =
|
|
2503
|
-
id:
|
|
2504
|
-
name:
|
|
2505
|
-
description:
|
|
2506
|
-
systemPrompt:
|
|
2507
|
-
boundSkills:
|
|
2508
|
-
model:
|
|
3003
|
+
var AgentShapeSchema = z8.object({
|
|
3004
|
+
id: z8.string().optional(),
|
|
3005
|
+
name: z8.string(),
|
|
3006
|
+
description: z8.string(),
|
|
3007
|
+
systemPrompt: z8.string(),
|
|
3008
|
+
boundSkills: z8.array(z8.string()).default([]),
|
|
3009
|
+
model: z8.string(),
|
|
2509
3010
|
/** 资产版本(N015 F13):install/export 版本对比依据;default 仅读侧兜底(createRepo 不做读侧解析,存量回填走 M6 迁移) */
|
|
2510
|
-
version:
|
|
2511
|
-
tools:
|
|
2512
|
-
permissions:
|
|
3011
|
+
version: z8.string().default("1.0.0"),
|
|
3012
|
+
tools: z8.array(z8.string()).default([]),
|
|
3013
|
+
permissions: z8.array(z8.string()).default([]),
|
|
2513
3014
|
/** 引用文档集合(可选——存量单文件资产无此字段,行为与升级前一致) */
|
|
2514
3015
|
references: createReferencesSchema(AGENT_MAIN_DOC).optional(),
|
|
2515
3016
|
/** 作用域:global=跨项目复用(默认,仅作存量迁移读侧兜底)/ project=项目专用(N012 D3) */
|
|
@@ -2517,15 +3018,15 @@ var AgentShapeSchema = z7.object({
|
|
|
2517
3018
|
/** 功能类型(T202608260002):default 仅创建侧归一——toEntity 直转不经 Zod parse,读侧归一在 repo 层 + 回填走 M12 */
|
|
2518
3019
|
"function": AgentFunctionSchema.default("executor"),
|
|
2519
3020
|
/** 仅 scope=project 时必填且为合法 ObjectId hex(superRefine 保证) */
|
|
2520
|
-
projectId:
|
|
3021
|
+
projectId: z8.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional(),
|
|
2521
3022
|
/**
|
|
2522
3023
|
* T202608290001 资产启停(可选——存量无此字段 = 启用,零迁移)。
|
|
2523
3024
|
* 全局判断规则:enabled === false 即停用,true/缺失均启用。
|
|
2524
3025
|
* 唯一写入口是专用启停端点(POST /:name/enabled)——Create/Update/Copy 均不含此字段。
|
|
2525
3026
|
*/
|
|
2526
|
-
enabled:
|
|
2527
|
-
createdAt:
|
|
2528
|
-
updatedAt:
|
|
3027
|
+
enabled: z8.boolean().optional(),
|
|
3028
|
+
createdAt: z8.date().optional(),
|
|
3029
|
+
updatedAt: z8.date().optional()
|
|
2529
3030
|
});
|
|
2530
3031
|
var agentAggregateLimitRefine = (val, ctx) => {
|
|
2531
3032
|
const totalChars = (val.systemPrompt?.length ?? 0) + sumReferenceContentChars(val.references);
|
|
@@ -2543,28 +3044,28 @@ var AgentCreateSchema = AgentShapeSchema.omit({
|
|
|
2543
3044
|
createdAt: true,
|
|
2544
3045
|
updatedAt: true,
|
|
2545
3046
|
enabled: true
|
|
2546
|
-
}).extend({ scope: AgentScopeSchema }).extend({ model:
|
|
3047
|
+
}).extend({ scope: AgentScopeSchema }).extend({ model: z8.string().regex(SIMING_CODE_REGEX, "model \u5FC5\u987B\u662F siming code\uFF08kebab-case\uFF09") }).extend({ "function": AgentFunctionSchema.default("executor") }).superRefine(AgentScopeRefine).superRefine(agentAggregateLimitRefine);
|
|
2547
3048
|
var AgentUpdateSchema = AgentShapeSchema.omit({
|
|
2548
3049
|
id: true,
|
|
2549
3050
|
createdAt: true,
|
|
2550
3051
|
updatedAt: true,
|
|
2551
3052
|
enabled: true
|
|
2552
3053
|
}).extend({
|
|
2553
|
-
boundSkills:
|
|
3054
|
+
boundSkills: z8.array(z8.string()).optional(),
|
|
2554
3055
|
// N015:version 放行(export apply 版本递增随 PUT 携带);optional 剥离实体层 default 避免 partial 空 body 注入
|
|
2555
|
-
version:
|
|
2556
|
-
tools:
|
|
2557
|
-
permissions:
|
|
3056
|
+
version: z8.string().optional(),
|
|
3057
|
+
tools: z8.array(z8.string()).optional(),
|
|
3058
|
+
permissions: z8.array(z8.string()).optional(),
|
|
2558
3059
|
scope: AgentScopeSchema.optional(),
|
|
2559
3060
|
// N013:model 收紧为 siming code 格式(存在性校验在 handler 层;undefined = 不更新该字段)
|
|
2560
|
-
model:
|
|
3061
|
+
model: z8.string().regex(SIMING_CODE_REGEX, "model \u5FC5\u987B\u662F siming code\uFF08kebab-case\uFF09").optional(),
|
|
2561
3062
|
// T202608260002:optional 剥离实体层 default——否则 PUT 空 body 会注入 executor 覆盖 reviewer
|
|
2562
3063
|
"function": AgentFunctionSchema.optional()
|
|
2563
3064
|
}).partial().superRefine(AgentScopeRefine).superRefine(agentAggregateLimitRefine);
|
|
2564
|
-
var AgentCopySchema =
|
|
2565
|
-
newName:
|
|
3065
|
+
var AgentCopySchema = z8.object({
|
|
3066
|
+
newName: z8.string(),
|
|
2566
3067
|
newScope: AgentScopeSchema,
|
|
2567
|
-
targetProjectId:
|
|
3068
|
+
targetProjectId: z8.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional()
|
|
2568
3069
|
}).superRefine((val, ctx) => {
|
|
2569
3070
|
if (val.newScope === "project" && !val.targetProjectId) {
|
|
2570
3071
|
ctx.addIssue({
|
|
@@ -2576,7 +3077,7 @@ var AgentCopySchema = z7.object({
|
|
|
2576
3077
|
});
|
|
2577
3078
|
|
|
2578
3079
|
// src/schemas/export-bundle.ts
|
|
2579
|
-
import { z as
|
|
3080
|
+
import { z as z9 } from "zod";
|
|
2580
3081
|
var EXPORT_FORMAT_VERSION = "1.0";
|
|
2581
3082
|
var TemplatePayloadSchema = DagTemplateSchema.omit({
|
|
2582
3083
|
id: true,
|
|
@@ -2586,8 +3087,8 @@ var TemplatePayloadSchema = DagTemplateSchema.omit({
|
|
|
2586
3087
|
updatedAt: true,
|
|
2587
3088
|
code: true
|
|
2588
3089
|
}).extend({
|
|
2589
|
-
version:
|
|
2590
|
-
isDefault:
|
|
3090
|
+
version: z9.string(),
|
|
3091
|
+
isDefault: z9.boolean()
|
|
2591
3092
|
});
|
|
2592
3093
|
var SkillPayloadSchema = SkillShapeSchema.omit({
|
|
2593
3094
|
id: true,
|
|
@@ -2596,7 +3097,7 @@ var SkillPayloadSchema = SkillShapeSchema.omit({
|
|
|
2596
3097
|
createdAt: true,
|
|
2597
3098
|
updatedAt: true
|
|
2598
3099
|
}).extend({
|
|
2599
|
-
version:
|
|
3100
|
+
version: z9.string(),
|
|
2600
3101
|
scope: SkillScopeSchema,
|
|
2601
3102
|
references: createReferencesSchema(SKILL_MAIN_DOC)
|
|
2602
3103
|
});
|
|
@@ -2607,12 +3108,12 @@ var AgentPayloadSchema = AgentShapeSchema.omit({
|
|
|
2607
3108
|
createdAt: true,
|
|
2608
3109
|
updatedAt: true
|
|
2609
3110
|
}).extend({
|
|
2610
|
-
version:
|
|
3111
|
+
version: z9.string(),
|
|
2611
3112
|
scope: AgentScopeSchema,
|
|
2612
3113
|
references: createReferencesSchema(AGENT_MAIN_DOC),
|
|
2613
|
-
boundSkills:
|
|
2614
|
-
tools:
|
|
2615
|
-
permissions:
|
|
3114
|
+
boundSkills: z9.array(z9.string()),
|
|
3115
|
+
tools: z9.array(z9.string()),
|
|
3116
|
+
permissions: z9.array(z9.string()),
|
|
2616
3117
|
"function": AgentFunctionSchema
|
|
2617
3118
|
});
|
|
2618
3119
|
var ModelAliasPayloadSchema = ModelAliasSchema.omit({
|
|
@@ -2620,307 +3121,316 @@ var ModelAliasPayloadSchema = ModelAliasSchema.omit({
|
|
|
2620
3121
|
createdAt: true,
|
|
2621
3122
|
updatedAt: true
|
|
2622
3123
|
});
|
|
2623
|
-
var ExportBundleSchema =
|
|
2624
|
-
exportFormatVersion:
|
|
3124
|
+
var ExportBundleSchema = z9.object({
|
|
3125
|
+
exportFormatVersion: z9.literal(EXPORT_FORMAT_VERSION, {
|
|
2625
3126
|
error: `\u5BFC\u51FA\u683C\u5F0F\u7248\u672C\u4E0D\u652F\u6301\uFF0C\u5F53\u524D\u652F\u6301 ${EXPORT_FORMAT_VERSION}`
|
|
2626
3127
|
}),
|
|
2627
|
-
exportedAt:
|
|
3128
|
+
exportedAt: z9.string(),
|
|
2628
3129
|
/** 源环境悬空提示(§2.2:悬空 skill/agent.model 不阻断导出)。导出响应恒携带;导入入参可缺省——导入侧提示由 plan 生成,不消费本字段 */
|
|
2629
|
-
warnings:
|
|
3130
|
+
warnings: z9.array(z9.string()).optional(),
|
|
2630
3131
|
template: TemplatePayloadSchema,
|
|
2631
|
-
dependencies:
|
|
2632
|
-
skills:
|
|
2633
|
-
agents:
|
|
2634
|
-
modelAliases:
|
|
3132
|
+
dependencies: z9.object({
|
|
3133
|
+
skills: z9.array(SkillPayloadSchema),
|
|
3134
|
+
agents: z9.array(AgentPayloadSchema),
|
|
3135
|
+
modelAliases: z9.array(ModelAliasPayloadSchema)
|
|
2635
3136
|
})
|
|
2636
3137
|
});
|
|
2637
|
-
var ImportPlanRequestSchema =
|
|
2638
|
-
targetProjectId:
|
|
3138
|
+
var ImportPlanRequestSchema = z9.object({
|
|
3139
|
+
targetProjectId: z9.string().regex(OBJECT_ID_HEX, "targetProjectId must be a valid ObjectId hex"),
|
|
2639
3140
|
bundle: ExportBundleSchema
|
|
2640
3141
|
});
|
|
2641
|
-
var ImportDecisionSchema =
|
|
2642
|
-
|
|
2643
|
-
kind:
|
|
2644
|
-
name:
|
|
3142
|
+
var ImportDecisionSchema = z9.discriminatedUnion("kind", [
|
|
3143
|
+
z9.object({
|
|
3144
|
+
kind: z9.literal("skill"),
|
|
3145
|
+
name: z9.string(),
|
|
2645
3146
|
scope: SkillScopeSchema,
|
|
2646
|
-
action:
|
|
3147
|
+
action: z9.enum(["overwrite", "skip"])
|
|
2647
3148
|
}),
|
|
2648
|
-
|
|
2649
|
-
kind:
|
|
2650
|
-
name:
|
|
3149
|
+
z9.object({
|
|
3150
|
+
kind: z9.literal("agent"),
|
|
3151
|
+
name: z9.string(),
|
|
2651
3152
|
scope: AgentScopeSchema,
|
|
2652
|
-
action:
|
|
3153
|
+
action: z9.enum(["overwrite", "skip"])
|
|
2653
3154
|
}),
|
|
2654
|
-
|
|
2655
|
-
kind:
|
|
2656
|
-
name:
|
|
2657
|
-
action:
|
|
3155
|
+
z9.object({
|
|
3156
|
+
kind: z9.literal("modelAlias"),
|
|
3157
|
+
name: z9.string(),
|
|
3158
|
+
action: z9.enum(["overwrite", "skip"])
|
|
2658
3159
|
})
|
|
2659
3160
|
]);
|
|
2660
3161
|
var ImportApplyRequestSchema = ImportPlanRequestSchema.extend({
|
|
2661
3162
|
/** 未列出的冲突项缺省 skip(保守默认:未决策不覆盖) */
|
|
2662
|
-
decisions:
|
|
3163
|
+
decisions: z9.array(ImportDecisionSchema).default([])
|
|
2663
3164
|
});
|
|
2664
|
-
var DependencyStatusSchema =
|
|
2665
|
-
var DependencyCheckSchema =
|
|
2666
|
-
kind:
|
|
2667
|
-
name:
|
|
3165
|
+
var DependencyStatusSchema = z9.enum(["create", "identical", "conflict"]);
|
|
3166
|
+
var DependencyCheckSchema = z9.object({
|
|
3167
|
+
kind: z9.enum(["skill", "agent", "modelAlias"]),
|
|
3168
|
+
name: z9.string(),
|
|
2668
3169
|
/** skill/agent 携带;modelAlias 无 */
|
|
2669
|
-
scope:
|
|
3170
|
+
scope: z9.enum(["global", "project"]).optional(),
|
|
2670
3171
|
status: DependencyStatusSchema,
|
|
2671
3172
|
/** status ≠ create 时目标环境现值版本(modelAlias 无 version 概念不填) */
|
|
2672
|
-
currentVersion:
|
|
2673
|
-
importVersion:
|
|
3173
|
+
currentVersion: z9.string().optional(),
|
|
3174
|
+
importVersion: z9.string().optional(),
|
|
2674
3175
|
/** status = conflict 时差异字段名清单(如 "content, references") */
|
|
2675
|
-
changeSummary:
|
|
3176
|
+
changeSummary: z9.string().optional(),
|
|
2676
3177
|
/** 影响范围(PRD F13):global 资产影响所有项目 / project 资产仅影响所属项目 */
|
|
2677
|
-
impact:
|
|
3178
|
+
impact: z9.enum(["global", "project"])
|
|
2678
3179
|
});
|
|
2679
|
-
var ImportPlanResponseSchema =
|
|
2680
|
-
template:
|
|
2681
|
-
name:
|
|
2682
|
-
willOverwrite:
|
|
2683
|
-
currentVersion:
|
|
2684
|
-
importVersion:
|
|
2685
|
-
isDefaultRequested:
|
|
3180
|
+
var ImportPlanResponseSchema = z9.object({
|
|
3181
|
+
template: z9.object({
|
|
3182
|
+
name: z9.string(),
|
|
3183
|
+
willOverwrite: z9.boolean(),
|
|
3184
|
+
currentVersion: z9.string().optional(),
|
|
3185
|
+
importVersion: z9.string(),
|
|
3186
|
+
isDefaultRequested: z9.boolean(),
|
|
2686
3187
|
/** isDefault 降级后的最终生效值(F17:项目已有默认 → false) */
|
|
2687
|
-
isDefaultEffect:
|
|
2688
|
-
downgradeReason:
|
|
3188
|
+
isDefaultEffect: z9.boolean(),
|
|
3189
|
+
downgradeReason: z9.string().optional()
|
|
2689
3190
|
}),
|
|
2690
|
-
dependencies:
|
|
3191
|
+
dependencies: z9.array(DependencyCheckSchema),
|
|
2691
3192
|
/**
|
|
2692
3193
|
* K10①:模板节点直接技能引用完整性逐项核对(node × skill 粒度)——
|
|
2693
3194
|
* ok = 在 bundle 依赖 ∪ 目标环境可见集;missing = 双侧皆无(绑定悬空,non-blocking warning)
|
|
2694
3195
|
*/
|
|
2695
|
-
directSkillChecks:
|
|
2696
|
-
|
|
2697
|
-
node:
|
|
2698
|
-
skill:
|
|
2699
|
-
status:
|
|
3196
|
+
directSkillChecks: z9.array(
|
|
3197
|
+
z9.object({
|
|
3198
|
+
node: z9.string(),
|
|
3199
|
+
skill: z9.string(),
|
|
3200
|
+
status: z9.enum(["ok", "missing"])
|
|
2700
3201
|
})
|
|
2701
3202
|
),
|
|
2702
3203
|
/** 非阻断提示(源环境悬空绑定、agent.model 引用缺失、sourcePreset 来源缺失等) */
|
|
2703
|
-
warnings:
|
|
3204
|
+
warnings: z9.array(z9.string())
|
|
2704
3205
|
});
|
|
2705
|
-
var DependencyActionSchema =
|
|
2706
|
-
var ImportApplyResponseSchema =
|
|
2707
|
-
template:
|
|
2708
|
-
id:
|
|
2709
|
-
name:
|
|
2710
|
-
action:
|
|
2711
|
-
isDefaultEffect:
|
|
3206
|
+
var DependencyActionSchema = z9.enum(["created", "updated", "skipped", "identical", "failed"]);
|
|
3207
|
+
var ImportApplyResponseSchema = z9.object({
|
|
3208
|
+
template: z9.object({
|
|
3209
|
+
id: z9.string(),
|
|
3210
|
+
name: z9.string(),
|
|
3211
|
+
action: z9.enum(["created", "updated"]),
|
|
3212
|
+
isDefaultEffect: z9.boolean()
|
|
2712
3213
|
}),
|
|
2713
|
-
dependencies:
|
|
2714
|
-
|
|
2715
|
-
kind:
|
|
2716
|
-
name:
|
|
2717
|
-
scope:
|
|
3214
|
+
dependencies: z9.array(
|
|
3215
|
+
z9.object({
|
|
3216
|
+
kind: z9.enum(["skill", "agent", "modelAlias"]),
|
|
3217
|
+
name: z9.string(),
|
|
3218
|
+
scope: z9.enum(["global", "project"]).optional(),
|
|
2718
3219
|
action: DependencyActionSchema,
|
|
2719
3220
|
/** action = failed 时的错误说明 */
|
|
2720
|
-
message:
|
|
3221
|
+
message: z9.string().optional()
|
|
2721
3222
|
})
|
|
2722
3223
|
),
|
|
2723
3224
|
/** K10②:apply 时刻目标环境缺失来源而被剥除 sourcePreset 的节点 id 清单(降级自建导入) */
|
|
2724
|
-
sourceStripped:
|
|
3225
|
+
sourceStripped: z9.array(z9.string())
|
|
2725
3226
|
});
|
|
2726
3227
|
function decisionKey(kind, scope, name) {
|
|
2727
3228
|
return `${kind}:${scope ?? ""}:${name}`;
|
|
2728
3229
|
}
|
|
2729
3230
|
|
|
2730
3231
|
// src/schemas/advance.ts
|
|
2731
|
-
import { z as
|
|
2732
|
-
var AdvanceRequestSchema =
|
|
2733
|
-
note:
|
|
3232
|
+
import { z as z10 } from "zod";
|
|
3233
|
+
var AdvanceRequestSchema = z10.object({
|
|
3234
|
+
note: z10.string().optional(),
|
|
2734
3235
|
/** min(1).max(2000) 与 record summary 端点对齐(同一 $set 目标,两入口校验强度一致) */
|
|
2735
|
-
summary:
|
|
3236
|
+
summary: z10.string().min(1).max(2e3).optional(),
|
|
3237
|
+
/**
|
|
3238
|
+
* T202609130009 收尾确认(可选):终节点推进默认被拒
|
|
3239
|
+
* (TASK_FINALIZE_CONFIRMATION_REQUIRED),携带 finalize=true 才完成收尾终态化;
|
|
3240
|
+
* 中间节点传递无副作用(守卫不在其路径,宽容语义)。
|
|
3241
|
+
*/
|
|
3242
|
+
finalize: z10.boolean().optional()
|
|
2736
3243
|
});
|
|
2737
|
-
var ApproveRequestSchema =
|
|
2738
|
-
decision:
|
|
2739
|
-
comment:
|
|
3244
|
+
var ApproveRequestSchema = z10.object({
|
|
3245
|
+
decision: z10.enum(["approved", "rejected"]),
|
|
3246
|
+
comment: z10.string().optional()
|
|
2740
3247
|
});
|
|
2741
|
-
var TaskPublicSchema =
|
|
2742
|
-
taskId:
|
|
2743
|
-
title:
|
|
3248
|
+
var TaskPublicSchema = z10.object({
|
|
3249
|
+
taskId: z10.string(),
|
|
3250
|
+
title: z10.string(),
|
|
2744
3251
|
// T202608240003:任务类型标签(缺省 = 裸任务/旧任务;模板 PRD 调研变体判定消费)
|
|
2745
|
-
type:
|
|
2746
|
-
currentNode:
|
|
2747
|
-
currentPhase:
|
|
2748
|
-
status:
|
|
2749
|
-
pausedAt:
|
|
2750
|
-
track:
|
|
3252
|
+
type: z10.enum(TASK_TYPES).optional(),
|
|
3253
|
+
currentNode: z10.string(),
|
|
3254
|
+
currentPhase: z10.string(),
|
|
3255
|
+
status: z10.string(),
|
|
3256
|
+
pausedAt: z10.string().nullable(),
|
|
3257
|
+
track: z10.string()
|
|
2751
3258
|
});
|
|
2752
|
-
var NodeInfoSchema =
|
|
2753
|
-
nodeId:
|
|
2754
|
-
label:
|
|
2755
|
-
track:
|
|
2756
|
-
prompt:
|
|
2757
|
-
skills:
|
|
2758
|
-
agents:
|
|
2759
|
-
upcomingPause:
|
|
3259
|
+
var NodeInfoSchema = z10.object({
|
|
3260
|
+
nodeId: z10.string(),
|
|
3261
|
+
label: z10.string(),
|
|
3262
|
+
track: z10.string(),
|
|
3263
|
+
prompt: z10.string(),
|
|
3264
|
+
skills: z10.array(z10.string()),
|
|
3265
|
+
agents: z10.array(z10.string()),
|
|
3266
|
+
upcomingPause: z10.string().nullable()
|
|
2760
3267
|
});
|
|
2761
|
-
var AdvanceResponseSchema =
|
|
2762
|
-
|
|
2763
|
-
status:
|
|
3268
|
+
var AdvanceResponseSchema = z10.discriminatedUnion("status", [
|
|
3269
|
+
z10.object({
|
|
3270
|
+
status: z10.literal("advanced"),
|
|
2764
3271
|
task: TaskPublicSchema,
|
|
2765
3272
|
nextNode: NodeInfoSchema
|
|
2766
3273
|
}),
|
|
2767
|
-
|
|
2768
|
-
status:
|
|
3274
|
+
z10.object({
|
|
3275
|
+
status: z10.literal("paused"),
|
|
2769
3276
|
task: TaskPublicSchema,
|
|
2770
3277
|
pausePoint: EdgePausePointSchema,
|
|
2771
|
-
guidance:
|
|
3278
|
+
guidance: z10.string()
|
|
2772
3279
|
}),
|
|
2773
|
-
|
|
2774
|
-
status:
|
|
3280
|
+
z10.object({
|
|
3281
|
+
status: z10.literal("completed"),
|
|
2775
3282
|
task: TaskPublicSchema
|
|
2776
3283
|
})
|
|
2777
3284
|
]);
|
|
2778
|
-
var ApproveResponseSchema =
|
|
2779
|
-
|
|
2780
|
-
status:
|
|
3285
|
+
var ApproveResponseSchema = z10.discriminatedUnion("status", [
|
|
3286
|
+
z10.object({
|
|
3287
|
+
status: z10.literal("advanced"),
|
|
2781
3288
|
task: TaskPublicSchema,
|
|
2782
3289
|
nextNode: NodeInfoSchema
|
|
2783
3290
|
}),
|
|
2784
|
-
|
|
2785
|
-
status:
|
|
3291
|
+
z10.object({
|
|
3292
|
+
status: z10.literal("rejected"),
|
|
2786
3293
|
task: TaskPublicSchema,
|
|
2787
|
-
guidance:
|
|
3294
|
+
guidance: z10.string()
|
|
2788
3295
|
}),
|
|
2789
3296
|
// 「completed」分支当前引擎不可达(approve 从 paused 流转必有下一节点,技术方案 §2.2
|
|
2790
3297
|
// 已删 paused→completed 直达路径)——按方案 §2.1 契约保留作前向兼容预留
|
|
2791
|
-
|
|
2792
|
-
status:
|
|
3298
|
+
z10.object({
|
|
3299
|
+
status: z10.literal("completed"),
|
|
2793
3300
|
task: TaskPublicSchema
|
|
2794
3301
|
})
|
|
2795
3302
|
]);
|
|
2796
|
-
var PauseRequestSchema =
|
|
2797
|
-
reason:
|
|
3303
|
+
var PauseRequestSchema = z10.object({
|
|
3304
|
+
reason: z10.string().optional()
|
|
3305
|
+
});
|
|
3306
|
+
var ResumeRequestSchema = z10.object({
|
|
3307
|
+
decision: z10.string().optional()
|
|
2798
3308
|
});
|
|
2799
|
-
var
|
|
2800
|
-
|
|
3309
|
+
var CancelRequestSchema = z10.object({
|
|
3310
|
+
reason: z10.string().min(1).max(500).optional()
|
|
2801
3311
|
});
|
|
2802
|
-
var
|
|
2803
|
-
reason:
|
|
3312
|
+
var ReopenRequestSchema = z10.object({
|
|
3313
|
+
reason: z10.string().min(1).max(500)
|
|
2804
3314
|
});
|
|
2805
3315
|
|
|
2806
3316
|
// src/schemas/task-doc.ts
|
|
2807
|
-
import { z as
|
|
2808
|
-
var TaskContextSchema =
|
|
2809
|
-
task:
|
|
2810
|
-
taskId:
|
|
2811
|
-
title:
|
|
3317
|
+
import { z as z11 } from "zod";
|
|
3318
|
+
var TaskContextSchema = z11.object({
|
|
3319
|
+
task: z11.object({
|
|
3320
|
+
taskId: z11.string(),
|
|
3321
|
+
title: z11.string(),
|
|
2812
3322
|
// T202608240003:与 TaskPublicSchema 同步(toTaskPublic 运行时已产出,schema 声明漂移会导致 typed 消费方 strip 掉 type)
|
|
2813
|
-
type:
|
|
2814
|
-
currentNode:
|
|
2815
|
-
currentPhase:
|
|
2816
|
-
status:
|
|
2817
|
-
pausedAt:
|
|
2818
|
-
track:
|
|
3323
|
+
type: z11.enum(TASK_TYPES).optional(),
|
|
3324
|
+
currentNode: z11.string(),
|
|
3325
|
+
currentPhase: z11.string(),
|
|
3326
|
+
status: z11.string(),
|
|
3327
|
+
pausedAt: z11.string().nullable(),
|
|
3328
|
+
track: z11.string()
|
|
2819
3329
|
}),
|
|
2820
|
-
currentNode:
|
|
2821
|
-
nodeId:
|
|
2822
|
-
label:
|
|
2823
|
-
phase:
|
|
2824
|
-
track:
|
|
3330
|
+
currentNode: z11.object({
|
|
3331
|
+
nodeId: z11.string(),
|
|
3332
|
+
label: z11.string(),
|
|
3333
|
+
phase: z11.string(),
|
|
3334
|
+
track: z11.string(),
|
|
2825
3335
|
/** renderPrompt 渲染后(AI 推进任务的直接输入) */
|
|
2826
|
-
prompt:
|
|
2827
|
-
skills:
|
|
2828
|
-
agents:
|
|
3336
|
+
prompt: z11.string(),
|
|
3337
|
+
skills: z11.array(z11.string()),
|
|
3338
|
+
agents: z11.array(z11.string()),
|
|
2829
3339
|
/** 完成当前节点后出边上的暂停点描述(经 findNextEdge 按轨选边) */
|
|
2830
|
-
upcomingPause:
|
|
3340
|
+
upcomingPause: z11.string().nullable()
|
|
2831
3341
|
}).nullable(),
|
|
2832
|
-
pausedAtEdge:
|
|
2833
|
-
from:
|
|
2834
|
-
to:
|
|
3342
|
+
pausedAtEdge: z11.object({
|
|
3343
|
+
from: z11.string(),
|
|
3344
|
+
to: z11.string(),
|
|
2835
3345
|
pausePoint: EdgePausePointBaseSchema
|
|
2836
3346
|
}).nullable(),
|
|
2837
3347
|
/** 全节点实时状态清单 */
|
|
2838
|
-
nodes:
|
|
2839
|
-
nodeId:
|
|
2840
|
-
label:
|
|
2841
|
-
status:
|
|
2842
|
-
enteredAt:
|
|
2843
|
-
completedAt:
|
|
3348
|
+
nodes: z11.array(z11.object({
|
|
3349
|
+
nodeId: z11.string(),
|
|
3350
|
+
label: z11.string(),
|
|
3351
|
+
status: z11.string(),
|
|
3352
|
+
enteredAt: z11.date().nullable(),
|
|
3353
|
+
completedAt: z11.date().nullable()
|
|
2844
3354
|
})),
|
|
2845
3355
|
/** N020 D1:任务级结构化文档(未写时 null) */
|
|
2846
3356
|
taskDoc: TaskDocContentSchema.nullable(),
|
|
2847
3357
|
/** N020 D1:节点执行记录(仅含已写记录的 nodeId) */
|
|
2848
|
-
nodeRecords:
|
|
3358
|
+
nodeRecords: z11.record(z11.string(), NodeRecordSchema),
|
|
2849
3359
|
/** N020 D1:跨节点累积素材(架构信息收集条目) */
|
|
2850
|
-
archNotes:
|
|
3360
|
+
archNotes: z11.array(ArchNoteSchema)
|
|
2851
3361
|
});
|
|
2852
|
-
var TaskSummarySchema =
|
|
2853
|
-
taskId:
|
|
2854
|
-
title:
|
|
3362
|
+
var TaskSummarySchema = z11.object({
|
|
3363
|
+
taskId: z11.string(),
|
|
3364
|
+
title: z11.string(),
|
|
2855
3365
|
// T202608240003:任务类型标签(缺省 = 裸任务/旧任务)
|
|
2856
|
-
type:
|
|
2857
|
-
projectId:
|
|
2858
|
-
dagTemplateId:
|
|
2859
|
-
currentNode:
|
|
2860
|
-
currentPhase:
|
|
2861
|
-
status:
|
|
2862
|
-
pausedAt:
|
|
2863
|
-
track:
|
|
2864
|
-
progress:
|
|
2865
|
-
completed:
|
|
2866
|
-
total:
|
|
3366
|
+
type: z11.enum(TASK_TYPES).optional(),
|
|
3367
|
+
projectId: z11.string(),
|
|
3368
|
+
dagTemplateId: z11.string(),
|
|
3369
|
+
currentNode: z11.string(),
|
|
3370
|
+
currentPhase: z11.string(),
|
|
3371
|
+
status: z11.string(),
|
|
3372
|
+
pausedAt: z11.string().nullable(),
|
|
3373
|
+
track: z11.string(),
|
|
3374
|
+
progress: z11.object({
|
|
3375
|
+
completed: z11.number(),
|
|
3376
|
+
total: z11.number()
|
|
2867
3377
|
}),
|
|
2868
|
-
createdAt:
|
|
2869
|
-
updatedAt:
|
|
3378
|
+
createdAt: z11.date().optional(),
|
|
3379
|
+
updatedAt: z11.date().optional()
|
|
2870
3380
|
});
|
|
2871
3381
|
|
|
2872
3382
|
// src/schemas/write-ack.ts
|
|
2873
|
-
import { z as
|
|
3383
|
+
import { z as z12 } from "zod";
|
|
2874
3384
|
var WRITE_ACK_ENTRY_KINDS = ["check", "artifact", "decision", "confirmation", "archnote"];
|
|
2875
|
-
var WriteAckEntryKindSchema =
|
|
2876
|
-
var EchoItemSchema =
|
|
2877
|
-
path:
|
|
2878
|
-
excerpt:
|
|
3385
|
+
var WriteAckEntryKindSchema = z12.enum(WRITE_ACK_ENTRY_KINDS);
|
|
3386
|
+
var EchoItemSchema = z12.object({
|
|
3387
|
+
path: z12.string(),
|
|
3388
|
+
excerpt: z12.string()
|
|
2879
3389
|
});
|
|
2880
|
-
var TaskProgressSchema =
|
|
2881
|
-
completed:
|
|
2882
|
-
total:
|
|
3390
|
+
var TaskProgressSchema = z12.object({
|
|
3391
|
+
completed: z12.number().int(),
|
|
3392
|
+
total: z12.number().int()
|
|
2883
3393
|
});
|
|
2884
3394
|
var TaskProgressPublicSchema = TaskPublicSchema.extend({
|
|
2885
|
-
projectId:
|
|
3395
|
+
projectId: z12.string(),
|
|
2886
3396
|
progress: TaskProgressSchema
|
|
2887
3397
|
});
|
|
2888
|
-
var WriteAckSchema =
|
|
2889
|
-
taskId:
|
|
3398
|
+
var WriteAckSchema = z12.object({
|
|
3399
|
+
taskId: z12.string(),
|
|
2890
3400
|
/** 本次写入触及的字段点路径(如 doc.what / nodeRecords.PRD.checks) */
|
|
2891
|
-
updated:
|
|
3401
|
+
updated: z12.array(z12.string()),
|
|
2892
3402
|
/** 新建条目标识($push 五类对象条目;无新条目的端点缺省) */
|
|
2893
|
-
entry:
|
|
2894
|
-
id:
|
|
3403
|
+
entry: z12.object({
|
|
3404
|
+
id: z12.string(),
|
|
2895
3405
|
kind: WriteAckEntryKindSchema
|
|
2896
3406
|
}).optional(),
|
|
2897
3407
|
/** 写入内容回显(触及字段逐条;无值可回显的端点可缺省) */
|
|
2898
|
-
echo:
|
|
2899
|
-
updatedAt:
|
|
3408
|
+
echo: z12.array(EchoItemSchema).optional(),
|
|
3409
|
+
updatedAt: z12.date(),
|
|
2900
3410
|
task: TaskProgressPublicSchema
|
|
2901
3411
|
});
|
|
2902
|
-
var TaskBatchEntrySchema =
|
|
2903
|
-
index:
|
|
2904
|
-
id:
|
|
3412
|
+
var TaskBatchEntrySchema = z12.object({
|
|
3413
|
+
index: z12.number().int().min(0),
|
|
3414
|
+
id: z12.string().optional(),
|
|
2905
3415
|
kind: WriteAckEntryKindSchema.optional()
|
|
2906
3416
|
});
|
|
2907
|
-
var TaskBatchFailureSchema =
|
|
2908
|
-
index:
|
|
2909
|
-
message:
|
|
2910
|
-
hint:
|
|
3417
|
+
var TaskBatchFailureSchema = z12.object({
|
|
3418
|
+
index: z12.number().int().min(0),
|
|
3419
|
+
message: z12.string(),
|
|
3420
|
+
hint: z12.string().optional()
|
|
2911
3421
|
});
|
|
2912
|
-
var TaskBatchAckSchema =
|
|
2913
|
-
taskId:
|
|
3422
|
+
var TaskBatchAckSchema = z12.object({
|
|
3423
|
+
taskId: z12.string(),
|
|
2914
3424
|
/** 成功落库条目数(部分失败语义:成功条目保留不回滚) */
|
|
2915
|
-
applied:
|
|
3425
|
+
applied: z12.number().int().min(0),
|
|
2916
3426
|
/** 本次写入触及的字段点路径 */
|
|
2917
|
-
updated:
|
|
2918
|
-
entries:
|
|
2919
|
-
failures:
|
|
2920
|
-
updatedAt:
|
|
3427
|
+
updated: z12.array(z12.string()),
|
|
3428
|
+
entries: z12.array(TaskBatchEntrySchema),
|
|
3429
|
+
failures: z12.array(TaskBatchFailureSchema),
|
|
3430
|
+
updatedAt: z12.date(),
|
|
2921
3431
|
task: TaskProgressPublicSchema
|
|
2922
3432
|
});
|
|
2923
|
-
var CreateTaskResponseSchema =
|
|
3433
|
+
var CreateTaskResponseSchema = z12.object({
|
|
2924
3434
|
task: TaskProgressPublicSchema,
|
|
2925
3435
|
firstNode: NodeInfoSchema
|
|
2926
3436
|
});
|
|
@@ -2936,34 +3446,34 @@ function excerpt(value, max = 120) {
|
|
|
2936
3446
|
return `${chars.slice(0, max - 1).join("")}\u2026`;
|
|
2937
3447
|
}
|
|
2938
3448
|
var CONTEXT_VIEWS = ["basic", "full"];
|
|
2939
|
-
var ContextViewSchema =
|
|
3449
|
+
var ContextViewSchema = z12.enum(CONTEXT_VIEWS);
|
|
2940
3450
|
|
|
2941
3451
|
// src/schemas/project.ts
|
|
2942
|
-
import { z as
|
|
2943
|
-
var ProjectStatusSchema =
|
|
2944
|
-
var ProjectSchema =
|
|
2945
|
-
id:
|
|
2946
|
-
key:
|
|
2947
|
-
name:
|
|
2948
|
-
description:
|
|
3452
|
+
import { z as z13 } from "zod";
|
|
3453
|
+
var ProjectStatusSchema = z13.enum(["active", "archived"]);
|
|
3454
|
+
var ProjectSchema = z13.object({
|
|
3455
|
+
id: z13.string().optional(),
|
|
3456
|
+
key: z13.string().regex(/^[a-z0-9][a-z0-9-]{1,30}$/, "key \u5FC5\u987B\u4E3A kebab-case\uFF082-31 \u5B57\u7B26\uFF09"),
|
|
3457
|
+
name: z13.string().min(1).max(50),
|
|
3458
|
+
description: z13.string().max(500).optional(),
|
|
2949
3459
|
status: ProjectStatusSchema.default("active"),
|
|
2950
|
-
createdAt:
|
|
2951
|
-
updatedAt:
|
|
3460
|
+
createdAt: z13.date().optional(),
|
|
3461
|
+
updatedAt: z13.date().optional()
|
|
2952
3462
|
});
|
|
2953
|
-
var ProjectCreateSchema =
|
|
2954
|
-
key:
|
|
2955
|
-
name:
|
|
2956
|
-
description:
|
|
3463
|
+
var ProjectCreateSchema = z13.object({
|
|
3464
|
+
key: z13.string().regex(/^[a-z0-9][a-z0-9-]{1,30}$/, "key \u5FC5\u987B\u4E3A kebab-case\uFF082-31 \u5B57\u7B26\uFF09").optional(),
|
|
3465
|
+
name: z13.string().min(1).max(50),
|
|
3466
|
+
description: z13.string().max(500).optional()
|
|
2957
3467
|
});
|
|
2958
|
-
var ProjectUpdateSchema =
|
|
2959
|
-
name:
|
|
2960
|
-
description:
|
|
3468
|
+
var ProjectUpdateSchema = z13.object({
|
|
3469
|
+
name: z13.string().min(1).max(50).optional(),
|
|
3470
|
+
description: z13.string().max(500).optional(),
|
|
2961
3471
|
status: ProjectStatusSchema.optional()
|
|
2962
3472
|
});
|
|
2963
3473
|
|
|
2964
3474
|
// src/schemas/enum-registry.ts
|
|
2965
|
-
import { z as
|
|
2966
|
-
var EnumRegistryCategorySchema =
|
|
3475
|
+
import { z as z14 } from "zod";
|
|
3476
|
+
var EnumRegistryCategorySchema = z14.enum([
|
|
2967
3477
|
"dag_phase",
|
|
2968
3478
|
"dag_track",
|
|
2969
3479
|
"pause_type",
|
|
@@ -2971,106 +3481,107 @@ var EnumRegistryCategorySchema = z13.enum([
|
|
|
2971
3481
|
"node_status",
|
|
2972
3482
|
"skill_category",
|
|
2973
3483
|
"scope",
|
|
2974
|
-
"agent_function"
|
|
3484
|
+
"agent_function",
|
|
3485
|
+
"issue_status"
|
|
2975
3486
|
]);
|
|
2976
|
-
var EnumEntrySchema =
|
|
3487
|
+
var EnumEntrySchema = z14.object({
|
|
2977
3488
|
/** 领域层存库的原始枚举值(不可臆造;builtin 值 engine/DB 强依赖;kebab 约束与 skill name 对齐,保证 DELETE /entries/:value 可寻址) */
|
|
2978
|
-
value:
|
|
3489
|
+
value: z14.string().regex(/^[a-z0-9][a-z0-9_-]*$/, "value \u4EC5\u652F\u6301\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF/\u8FDE\u5B57\u7B26\uFF08kebab-case\uFF09"),
|
|
2979
3490
|
/** 展示文案(消费端下拉直接取用) */
|
|
2980
|
-
label:
|
|
3491
|
+
label: z14.string().min(1, "label \u4E0D\u80FD\u4E3A\u7A7A"),
|
|
2981
3492
|
/** 可选语义色 token(如 --success / --warning),消费端映射到 UI */
|
|
2982
|
-
color:
|
|
3493
|
+
color: z14.string().optional(),
|
|
2983
3494
|
/** 下拉排序(升序) */
|
|
2984
|
-
order:
|
|
3495
|
+
order: z14.number().int().default(0),
|
|
2985
3496
|
/** 内置值:禁删 + label/color 可改但 value 不可改(D8);seed 时标记 */
|
|
2986
|
-
builtin:
|
|
3497
|
+
builtin: z14.boolean().default(false),
|
|
2987
3498
|
/** 启停:false = 下拉禁用展示(历史数据仍可读,新选择不可用) */
|
|
2988
|
-
active:
|
|
3499
|
+
active: z14.boolean().default(true)
|
|
2989
3500
|
});
|
|
2990
|
-
var EnumRegistrySchema =
|
|
2991
|
-
id:
|
|
3501
|
+
var EnumRegistrySchema = z14.object({
|
|
3502
|
+
id: z14.string().optional(),
|
|
2992
3503
|
category: EnumRegistryCategorySchema,
|
|
2993
|
-
entries:
|
|
2994
|
-
updatedAt:
|
|
3504
|
+
entries: z14.array(EnumEntrySchema).default([]),
|
|
3505
|
+
updatedAt: z14.date().optional()
|
|
2995
3506
|
});
|
|
2996
|
-
var EnumRegistryUpdateSchema =
|
|
2997
|
-
entries:
|
|
3507
|
+
var EnumRegistryUpdateSchema = z14.object({
|
|
3508
|
+
entries: z14.array(EnumEntrySchema)
|
|
2998
3509
|
});
|
|
2999
3510
|
|
|
3000
3511
|
// src/schemas/asset-enabled.ts
|
|
3001
|
-
import { z as
|
|
3002
|
-
var AssetSetEnabledSchema =
|
|
3003
|
-
enabled:
|
|
3512
|
+
import { z as z15 } from "zod";
|
|
3513
|
+
var AssetSetEnabledSchema = z15.object({
|
|
3514
|
+
enabled: z15.boolean()
|
|
3004
3515
|
});
|
|
3005
3516
|
|
|
3006
3517
|
// src/schemas/auth.ts
|
|
3007
|
-
import { z as
|
|
3008
|
-
var AuthTokenTypeSchema =
|
|
3009
|
-
var AuthAccountSchema =
|
|
3010
|
-
id:
|
|
3011
|
-
username:
|
|
3518
|
+
import { z as z16 } from "zod";
|
|
3519
|
+
var AuthTokenTypeSchema = z16.enum(["admin", "project"]);
|
|
3520
|
+
var AuthAccountSchema = z16.object({
|
|
3521
|
+
id: z16.string().optional(),
|
|
3522
|
+
username: z16.string().min(3, "\u8D26\u53F7\u81F3\u5C11 3 \u4E2A\u5B57\u7B26").max(50).regex(/^[a-zA-Z0-9_-]+$/, "\u8D26\u53F7\u4EC5\u5141\u8BB8\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u4E0E\u8FDE\u5B57\u7B26"),
|
|
3012
3523
|
/** 存储形态:scrypt$N$r$p$salt$hash(base64 段),明文仅存在于请求体 */
|
|
3013
|
-
passwordHash:
|
|
3014
|
-
createdAt:
|
|
3015
|
-
updatedAt:
|
|
3524
|
+
passwordHash: z16.string().min(1),
|
|
3525
|
+
createdAt: z16.date().optional(),
|
|
3526
|
+
updatedAt: z16.date().optional()
|
|
3016
3527
|
});
|
|
3017
|
-
var AuthAccountCreateSchema =
|
|
3528
|
+
var AuthAccountCreateSchema = z16.object({
|
|
3018
3529
|
username: AuthAccountSchema.shape.username,
|
|
3019
|
-
password:
|
|
3530
|
+
password: z16.string().min(8, "\u5BC6\u7801\u81F3\u5C11 8 \u4E2A\u5B57\u7B26").max(128)
|
|
3020
3531
|
});
|
|
3021
|
-
var PasswordChangeSchema =
|
|
3022
|
-
currentPassword:
|
|
3023
|
-
newPassword:
|
|
3532
|
+
var PasswordChangeSchema = z16.object({
|
|
3533
|
+
currentPassword: z16.string().min(1),
|
|
3534
|
+
newPassword: z16.string().min(8, "\u5BC6\u7801\u81F3\u5C11 8 \u4E2A\u5B57\u7B26").max(128)
|
|
3024
3535
|
});
|
|
3025
|
-
var LoginSchema =
|
|
3026
|
-
username:
|
|
3027
|
-
password:
|
|
3536
|
+
var LoginSchema = z16.object({
|
|
3537
|
+
username: z16.string().min(1),
|
|
3538
|
+
password: z16.string().min(1)
|
|
3028
3539
|
});
|
|
3029
|
-
var AuthTokenSchema =
|
|
3030
|
-
id:
|
|
3540
|
+
var AuthTokenSchema = z16.object({
|
|
3541
|
+
id: z16.string().optional(),
|
|
3031
3542
|
/** sha256(token 全串含前缀) hex——明文 Token 不入库 */
|
|
3032
|
-
tokenHash:
|
|
3543
|
+
tokenHash: z16.string().regex(/^[a-f0-9]{64}$/),
|
|
3033
3544
|
type: AuthTokenTypeSchema,
|
|
3034
3545
|
/** type=project 时必填且不可缺失(superRefine 保证);指向 projects.id(24-hex) */
|
|
3035
|
-
projectId:
|
|
3036
|
-
createdAt:
|
|
3037
|
-
updatedAt:
|
|
3546
|
+
projectId: z16.string().regex(/^[a-f0-9]{24}$/, "projectId \u5FC5\u987B\u4E3A 24-hex ObjectId").optional(),
|
|
3547
|
+
createdAt: z16.date().optional(),
|
|
3548
|
+
updatedAt: z16.date().optional()
|
|
3038
3549
|
}).superRefine((data, ctx) => {
|
|
3039
3550
|
if (data.type === "project" && data.projectId === void 0) {
|
|
3040
3551
|
ctx.addIssue({ code: "custom", path: ["projectId"], message: "\u9879\u76EE Token \u5FC5\u987B\u7ED1\u5B9A projectId" });
|
|
3041
3552
|
}
|
|
3042
3553
|
});
|
|
3043
|
-
var AuthTokenGenResponseSchema =
|
|
3044
|
-
token:
|
|
3554
|
+
var AuthTokenGenResponseSchema = z16.object({
|
|
3555
|
+
token: z16.string().min(1),
|
|
3045
3556
|
type: AuthTokenTypeSchema,
|
|
3046
|
-
projectId:
|
|
3557
|
+
projectId: z16.string().optional()
|
|
3047
3558
|
});
|
|
3048
|
-
var AuthTokenStatusSchema =
|
|
3559
|
+
var AuthTokenStatusSchema = z16.object({
|
|
3049
3560
|
type: AuthTokenTypeSchema,
|
|
3050
|
-
projectId:
|
|
3051
|
-
hasToken:
|
|
3052
|
-
createdAt:
|
|
3561
|
+
projectId: z16.string().optional(),
|
|
3562
|
+
hasToken: z16.boolean(),
|
|
3563
|
+
createdAt: z16.date().nullable().optional()
|
|
3053
3564
|
});
|
|
3054
|
-
var AuthWhoamiSchema =
|
|
3055
|
-
identity:
|
|
3056
|
-
project:
|
|
3057
|
-
id:
|
|
3058
|
-
key:
|
|
3059
|
-
name:
|
|
3565
|
+
var AuthWhoamiSchema = z16.object({
|
|
3566
|
+
identity: z16.enum(["admin", "project", "none"]),
|
|
3567
|
+
project: z16.object({
|
|
3568
|
+
id: z16.string(),
|
|
3569
|
+
key: z16.string(),
|
|
3570
|
+
name: z16.string()
|
|
3060
3571
|
}).nullable().optional(),
|
|
3061
|
-
authEnabled:
|
|
3062
|
-
server:
|
|
3063
|
-
url:
|
|
3572
|
+
authEnabled: z16.boolean(),
|
|
3573
|
+
server: z16.object({
|
|
3574
|
+
url: z16.string()
|
|
3064
3575
|
})
|
|
3065
3576
|
});
|
|
3066
|
-
var AuthStatusSchema =
|
|
3067
|
-
authEnabled:
|
|
3577
|
+
var AuthStatusSchema = z16.object({
|
|
3578
|
+
authEnabled: z16.boolean(),
|
|
3068
3579
|
/** 鉴权开启且无管理员账号 = 初始化引导窗口(PRD §3.2) */
|
|
3069
|
-
needsSetup:
|
|
3580
|
+
needsSetup: z16.boolean()
|
|
3070
3581
|
});
|
|
3071
3582
|
|
|
3072
3583
|
// src/schemas/node-preset.ts
|
|
3073
|
-
import { z as
|
|
3584
|
+
import { z as z17 } from "zod";
|
|
3074
3585
|
var NODE_PRESET_CODE_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
3075
3586
|
var NodePresetScopeRefine = (val, ctx) => {
|
|
3076
3587
|
if (val.scope === "project" && !val.projectId) {
|
|
@@ -3081,7 +3592,7 @@ var NodePresetScopeRefine = (val, ctx) => {
|
|
|
3081
3592
|
});
|
|
3082
3593
|
}
|
|
3083
3594
|
};
|
|
3084
|
-
var uniqueNamesSchema =
|
|
3595
|
+
var uniqueNamesSchema = z17.array(z17.string().min(1)).superRefine((names, ctx) => {
|
|
3085
3596
|
const seen = /* @__PURE__ */ new Set();
|
|
3086
3597
|
names.forEach((name, index) => {
|
|
3087
3598
|
if (seen.has(name)) {
|
|
@@ -3090,30 +3601,30 @@ var uniqueNamesSchema = z16.array(z16.string().min(1)).superRefine((names, ctx)
|
|
|
3090
3601
|
seen.add(name);
|
|
3091
3602
|
});
|
|
3092
3603
|
});
|
|
3093
|
-
var NodePresetShapeSchema =
|
|
3094
|
-
id:
|
|
3095
|
-
code:
|
|
3096
|
-
label:
|
|
3604
|
+
var NodePresetShapeSchema = z17.object({
|
|
3605
|
+
id: z17.string().optional(),
|
|
3606
|
+
code: z17.string().regex(NODE_PRESET_CODE_PATTERN, "kebab-case only"),
|
|
3607
|
+
label: z17.string().min(1),
|
|
3097
3608
|
/** 组装默认节点标识(模板图结构域;字符集同 NODE_ID_PATTERN——节点记录点路径拼接安全前提) */
|
|
3098
|
-
nodeId:
|
|
3609
|
+
nodeId: z17.string().regex(/^[A-Za-z0-9_-]+$/, "nodeId \u53EA\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF/\u8FDE\u5B57\u7B26"),
|
|
3099
3610
|
/** 运行时注册表判定(对齐 dag_phase/dag_track 放宽策略——Zod 只做类型级) */
|
|
3100
|
-
phase:
|
|
3101
|
-
track:
|
|
3102
|
-
prompt:
|
|
3611
|
+
phase: z17.string(),
|
|
3612
|
+
track: z17.string(),
|
|
3613
|
+
prompt: z17.string().min(1),
|
|
3103
3614
|
/** 绑定技能名单(by-name 引用;版本要求只存在于 npm 分发层 manifest,不侵入运行链路) */
|
|
3104
3615
|
skills: uniqueNamesSchema,
|
|
3105
3616
|
/** 节点执行时可调用的 Agent 名单(by-name 引用;正文仍由独立 Agent 资产承载) */
|
|
3106
3617
|
agents: uniqueNamesSchema,
|
|
3107
|
-
scope:
|
|
3108
|
-
projectId:
|
|
3109
|
-
description:
|
|
3110
|
-
version:
|
|
3618
|
+
scope: z17.enum(["global", "project"]),
|
|
3619
|
+
projectId: z17.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional(),
|
|
3620
|
+
description: z17.string().optional(),
|
|
3621
|
+
version: z17.string(),
|
|
3111
3622
|
/** 分发来源标注(flow install 落库时填充包名;手工创建无此字段——「来源可见可核查」信任模型) */
|
|
3112
|
-
source:
|
|
3623
|
+
source: z17.object({ package: z17.string().min(1) }).optional(),
|
|
3113
3624
|
/** 资产启停(可选——存量无此字段 = 启用;唯一写入口 POST /:code/enabled,不入 Create/Update/Copy) */
|
|
3114
|
-
enabled:
|
|
3115
|
-
createdAt:
|
|
3116
|
-
updatedAt:
|
|
3625
|
+
enabled: z17.boolean().optional(),
|
|
3626
|
+
createdAt: z17.date().optional(),
|
|
3627
|
+
updatedAt: z17.date().optional()
|
|
3117
3628
|
});
|
|
3118
3629
|
var NodePresetSchema = NodePresetShapeSchema.superRefine(NodePresetScopeRefine);
|
|
3119
3630
|
var NodePresetCreateSchema = NodePresetShapeSchema.omit({
|
|
@@ -3124,7 +3635,7 @@ var NodePresetCreateSchema = NodePresetShapeSchema.omit({
|
|
|
3124
3635
|
}).extend({
|
|
3125
3636
|
skills: uniqueNamesSchema.default([]),
|
|
3126
3637
|
agents: uniqueNamesSchema.default([]),
|
|
3127
|
-
version:
|
|
3638
|
+
version: z17.string().default("1.0.0")
|
|
3128
3639
|
}).superRefine(NodePresetScopeRefine);
|
|
3129
3640
|
var NodePresetUpdateSchema = NodePresetShapeSchema.omit({
|
|
3130
3641
|
id: true,
|
|
@@ -3132,12 +3643,12 @@ var NodePresetUpdateSchema = NodePresetShapeSchema.omit({
|
|
|
3132
3643
|
updatedAt: true,
|
|
3133
3644
|
enabled: true
|
|
3134
3645
|
}).extend({
|
|
3135
|
-
version:
|
|
3646
|
+
version: z17.string().optional()
|
|
3136
3647
|
}).partial().superRefine(NodePresetScopeRefine);
|
|
3137
|
-
var NodePresetCopySchema =
|
|
3138
|
-
newCode:
|
|
3139
|
-
newScope:
|
|
3140
|
-
targetProjectId:
|
|
3648
|
+
var NodePresetCopySchema = z17.object({
|
|
3649
|
+
newCode: z17.string().regex(NODE_PRESET_CODE_PATTERN, "kebab-case only"),
|
|
3650
|
+
newScope: z17.enum(["global", "project"]),
|
|
3651
|
+
targetProjectId: z17.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional()
|
|
3141
3652
|
}).superRefine((val, ctx) => {
|
|
3142
3653
|
if (val.newScope === "project" && !val.targetProjectId) {
|
|
3143
3654
|
ctx.addIssue({
|
|
@@ -3149,38 +3660,38 @@ var NodePresetCopySchema = z16.object({
|
|
|
3149
3660
|
});
|
|
3150
3661
|
|
|
3151
3662
|
// src/schemas/node-library.ts
|
|
3152
|
-
import { z as
|
|
3153
|
-
var CompositionEdgeSchema =
|
|
3154
|
-
from:
|
|
3155
|
-
to:
|
|
3156
|
-
condition:
|
|
3663
|
+
import { z as z18 } from "zod";
|
|
3664
|
+
var CompositionEdgeSchema = z18.object({
|
|
3665
|
+
from: z18.string().min(1),
|
|
3666
|
+
to: z18.string().min(1),
|
|
3667
|
+
condition: z18.string().optional(),
|
|
3157
3668
|
pausePoint: EdgePausePointSchema.optional()
|
|
3158
3669
|
});
|
|
3159
|
-
var CompositionSchema =
|
|
3160
|
-
name:
|
|
3161
|
-
description:
|
|
3162
|
-
nodes:
|
|
3163
|
-
edges:
|
|
3670
|
+
var CompositionSchema = z18.object({
|
|
3671
|
+
name: z18.string().min(1),
|
|
3672
|
+
description: z18.string().optional(),
|
|
3673
|
+
nodes: z18.array(z18.string().min(1)).min(1),
|
|
3674
|
+
edges: z18.array(CompositionEdgeSchema)
|
|
3164
3675
|
});
|
|
3165
|
-
var NodeLibrarySchema =
|
|
3166
|
-
id:
|
|
3676
|
+
var NodeLibrarySchema = z18.object({
|
|
3677
|
+
id: z18.string().optional(),
|
|
3167
3678
|
/** 库名 = npm 包名(同库重装按名 upsert 覆盖登记) */
|
|
3168
|
-
name:
|
|
3169
|
-
version:
|
|
3170
|
-
scope:
|
|
3171
|
-
projectId:
|
|
3679
|
+
name: z18.string().min(1),
|
|
3680
|
+
version: z18.string(),
|
|
3681
|
+
scope: z18.enum(["global", "project"]),
|
|
3682
|
+
projectId: z18.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional(),
|
|
3172
3683
|
/** 已装节点 code 清单(flow compose 逐 code 解析 node_presets) */
|
|
3173
|
-
nodes:
|
|
3174
|
-
compositions:
|
|
3175
|
-
installedAt:
|
|
3684
|
+
nodes: z18.array(z18.string()),
|
|
3685
|
+
compositions: z18.array(CompositionSchema),
|
|
3686
|
+
installedAt: z18.date().optional()
|
|
3176
3687
|
});
|
|
3177
|
-
var NodeLibraryUpsertSchema =
|
|
3178
|
-
name:
|
|
3179
|
-
version:
|
|
3180
|
-
scope:
|
|
3181
|
-
projectId:
|
|
3182
|
-
nodes:
|
|
3183
|
-
compositions:
|
|
3688
|
+
var NodeLibraryUpsertSchema = z18.object({
|
|
3689
|
+
name: z18.string().min(1),
|
|
3690
|
+
version: z18.string(),
|
|
3691
|
+
scope: z18.enum(["global", "project"]),
|
|
3692
|
+
projectId: z18.string().regex(OBJECT_ID_HEX, "projectId must be a valid ObjectId hex").optional(),
|
|
3693
|
+
nodes: z18.array(z18.string()),
|
|
3694
|
+
compositions: z18.array(CompositionSchema)
|
|
3184
3695
|
}).superRefine((val, ctx) => {
|
|
3185
3696
|
if (val.scope === "project" && !val.projectId) {
|
|
3186
3697
|
ctx.addIssue({
|
|
@@ -3192,28 +3703,28 @@ var NodeLibraryUpsertSchema = z17.object({
|
|
|
3192
3703
|
});
|
|
3193
3704
|
|
|
3194
3705
|
// src/schemas/template-upgrade.ts
|
|
3195
|
-
import { z as
|
|
3196
|
-
var UpgradeNodeStatusSchema =
|
|
3706
|
+
import { z as z19 } from "zod";
|
|
3707
|
+
var UpgradeNodeStatusSchema = z19.enum([
|
|
3197
3708
|
"updatable",
|
|
3198
3709
|
"local-modified",
|
|
3199
3710
|
"up-to-date",
|
|
3200
3711
|
"source-missing",
|
|
3201
3712
|
"source-disabled"
|
|
3202
3713
|
]);
|
|
3203
|
-
var UpgradeActionSchema =
|
|
3204
|
-
var UpgradeDecisionSchema =
|
|
3205
|
-
nodeId:
|
|
3714
|
+
var UpgradeActionSchema = z19.enum(["upgrade", "keep", "skip"]);
|
|
3715
|
+
var UpgradeDecisionSchema = z19.object({
|
|
3716
|
+
nodeId: z19.string().min(1),
|
|
3206
3717
|
action: UpgradeActionSchema,
|
|
3207
|
-
expected:
|
|
3718
|
+
expected: z19.object({ status: UpgradeNodeStatusSchema }).optional()
|
|
3208
3719
|
});
|
|
3209
|
-
var UpgradeApplyRequestSchema =
|
|
3210
|
-
decisions:
|
|
3720
|
+
var UpgradeApplyRequestSchema = z19.object({
|
|
3721
|
+
decisions: z19.array(UpgradeDecisionSchema).min(1)
|
|
3211
3722
|
});
|
|
3212
3723
|
|
|
3213
3724
|
// src/config/server-config.ts
|
|
3214
|
-
import { z as
|
|
3215
|
-
var SimingLogLevelSchema =
|
|
3216
|
-
var HttpOriginSchema =
|
|
3725
|
+
import { z as z20 } from "zod";
|
|
3726
|
+
var SimingLogLevelSchema = z20.enum(["debug", "info", "warn", "error"]);
|
|
3727
|
+
var HttpOriginSchema = z20.string().transform((value, ctx) => {
|
|
3217
3728
|
let origin = null;
|
|
3218
3729
|
try {
|
|
3219
3730
|
const url = new URL(value);
|
|
@@ -3222,25 +3733,25 @@ var HttpOriginSchema = z19.string().transform((value, ctx) => {
|
|
|
3222
3733
|
}
|
|
3223
3734
|
if (origin === null) {
|
|
3224
3735
|
ctx.addIssue({ code: "custom", message: "must be an http(s):// URL" });
|
|
3225
|
-
return
|
|
3736
|
+
return z20.NEVER;
|
|
3226
3737
|
}
|
|
3227
3738
|
return origin;
|
|
3228
3739
|
});
|
|
3229
|
-
var SimingConfigSchema =
|
|
3230
|
-
mongoUri:
|
|
3231
|
-
port:
|
|
3740
|
+
var SimingConfigSchema = z20.object({
|
|
3741
|
+
mongoUri: z20.string().min(1).default("mongodb://localhost:27017"),
|
|
3742
|
+
port: z20.coerce.number().int().min(1).max(65535).default(7777),
|
|
3232
3743
|
/**
|
|
3233
3744
|
* N018 D8:默认仅绑定本机回环(安全默认);远程/局域接入(F7)显式配置 host。
|
|
3234
3745
|
* 超出 PRD V1 配置清单的新增项,依据见技术方案 §3.4「超范围扩展标注」。
|
|
3235
3746
|
*/
|
|
3236
|
-
host:
|
|
3747
|
+
host: z20.string().min(1).default("127.0.0.1"),
|
|
3237
3748
|
logLevel: SimingLogLevelSchema.default("info"),
|
|
3238
3749
|
/**
|
|
3239
3750
|
* T202608310001:鉴权开关(F1)——从 F6 预留宽松形态收紧为类型化 schema。
|
|
3240
3751
|
* 默认关闭 = 本地开发/存量行为零破坏;云主机部署显式开启(SIMING_AUTH_ENABLED=true)。
|
|
3241
3752
|
*/
|
|
3242
|
-
auth:
|
|
3243
|
-
enabled:
|
|
3753
|
+
auth: z20.object({
|
|
3754
|
+
enabled: z20.boolean().default(false)
|
|
3244
3755
|
}).prefault({}),
|
|
3245
3756
|
/**
|
|
3246
3757
|
* T202609070001:服务对外可达基础地址(whoami 自报 server.url 用)——反代终止 TLS 后
|
|
@@ -3249,7 +3760,7 @@ var SimingConfigSchema = z19.object({
|
|
|
3249
3760
|
* 消费侧来源/摘要逻辑对 undefined 的 optional 键不补「内置默认值」来源。
|
|
3250
3761
|
*/
|
|
3251
3762
|
publicUrl: HttpOriginSchema.optional(),
|
|
3252
|
-
cors:
|
|
3763
|
+
cors: z20.unknown().optional()
|
|
3253
3764
|
});
|
|
3254
3765
|
var SIMING_CONFIG_KEYS = ["mongoUri", "port", "host", "logLevel", "auth", "publicUrl"];
|
|
3255
3766
|
var SIMING_CONFIG_ENV_KEYS = {
|
|
@@ -3539,21 +4050,6 @@ function applyUpgradeDecisions(template, presetsByCode, decisions) {
|
|
|
3539
4050
|
return { nodes, nextVersion: changed ? bumpPatch(template.version) : null, results };
|
|
3540
4051
|
}
|
|
3541
4052
|
|
|
3542
|
-
// src/task/entry-id.ts
|
|
3543
|
-
var ENTRY_ID_LENGTH = 6;
|
|
3544
|
-
var BASE36_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
3545
|
-
function generateEntryId(existing) {
|
|
3546
|
-
const taken = new Set(existing);
|
|
3547
|
-
for (let attempt = 0; attempt < 32; attempt++) {
|
|
3548
|
-
let id = "";
|
|
3549
|
-
for (let i = 0; i < ENTRY_ID_LENGTH; i++) {
|
|
3550
|
-
id += BASE36_ALPHABET[Math.floor(Math.random() * BASE36_ALPHABET.length)];
|
|
3551
|
-
}
|
|
3552
|
-
if (!taken.has(id)) return id;
|
|
3553
|
-
}
|
|
3554
|
-
throw new Error(`entry id generation failed after 32 attempts (existing: ${existing.length})`);
|
|
3555
|
-
}
|
|
3556
|
-
|
|
3557
4053
|
// src/template-transfer/payload.ts
|
|
3558
4054
|
function toTemplatePayload(tpl) {
|
|
3559
4055
|
const { id: _id, projectId: _projectId, enabled: _enabled, createdAt: _ca, updatedAt: _ua, code: _code, ...rest } = tpl;
|
|
@@ -3977,7 +4473,7 @@ function errorMessage(err) {
|
|
|
3977
4473
|
}
|
|
3978
4474
|
|
|
3979
4475
|
// src/index.ts
|
|
3980
|
-
var PackageJsonSchema =
|
|
4476
|
+
var PackageJsonSchema = z21.object({ version: z21.string().min(1) });
|
|
3981
4477
|
var packageJsonParsed = PackageJsonSchema.safeParse(
|
|
3982
4478
|
JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"))
|
|
3983
4479
|
);
|
|
@@ -4057,11 +4553,23 @@ export {
|
|
|
4057
4553
|
ForbiddenError,
|
|
4058
4554
|
HistoryActionSchema,
|
|
4059
4555
|
HistoryEntrySchema,
|
|
4556
|
+
ISSUE_ACTIVE_STATUSES,
|
|
4557
|
+
ISSUE_CONVERT_MODES,
|
|
4558
|
+
ISSUE_SOURCES,
|
|
4559
|
+
ISSUE_STATUSES,
|
|
4060
4560
|
ImportApplyRequestSchema,
|
|
4061
4561
|
ImportApplyResponseSchema,
|
|
4062
4562
|
ImportDecisionSchema,
|
|
4063
4563
|
ImportPlanRequestSchema,
|
|
4064
4564
|
ImportPlanResponseSchema,
|
|
4565
|
+
IssueConvertModeSchema,
|
|
4566
|
+
IssueCreateSchema,
|
|
4567
|
+
IssueHistoryEntrySchema,
|
|
4568
|
+
IssueProgressSchema,
|
|
4569
|
+
IssueSchema,
|
|
4570
|
+
IssueSourceSchema,
|
|
4571
|
+
IssueStatusSchema,
|
|
4572
|
+
IssueUpdateSchema,
|
|
4065
4573
|
LoginSchema,
|
|
4066
4574
|
ModelAliasCreateSchema,
|
|
4067
4575
|
ModelAliasPayloadSchema,
|
|
@@ -4094,6 +4602,7 @@ export {
|
|
|
4094
4602
|
ProjectStatusSchema,
|
|
4095
4603
|
ProjectUpdateSchema,
|
|
4096
4604
|
REFERENCE_LIMITS,
|
|
4605
|
+
ReopenRequestSchema,
|
|
4097
4606
|
ResumeRequestSchema,
|
|
4098
4607
|
ReviewSummarySchema,
|
|
4099
4608
|
SIMING_CODE_REGEX,
|
|
@@ -4121,6 +4630,7 @@ export {
|
|
|
4121
4630
|
TaskContextSchema,
|
|
4122
4631
|
TaskCreateInputSchema,
|
|
4123
4632
|
TaskDocContentSchema,
|
|
4633
|
+
TaskLinkSchema,
|
|
4124
4634
|
TaskPhaseSchema,
|
|
4125
4635
|
TaskProgressPublicSchema,
|
|
4126
4636
|
TaskProgressSchema,
|
|
@@ -4167,6 +4677,7 @@ export {
|
|
|
4167
4677
|
createAuthTokenRepo,
|
|
4168
4678
|
createDagTemplateRepo,
|
|
4169
4679
|
createEnumRegistryRepo,
|
|
4680
|
+
createIssueRepo,
|
|
4170
4681
|
createModelAliasRepo,
|
|
4171
4682
|
createMongoClient,
|
|
4172
4683
|
createNodeLibraryRepo,
|
|
@@ -4177,6 +4688,7 @@ export {
|
|
|
4177
4688
|
createSkillRepo,
|
|
4178
4689
|
createTaskRepo,
|
|
4179
4690
|
decisionKey,
|
|
4691
|
+
derivePreTerminalState,
|
|
4180
4692
|
diffTemplateContent,
|
|
4181
4693
|
enabledNeFalse,
|
|
4182
4694
|
escapeRegExpLiteral,
|
|
@@ -4199,6 +4711,7 @@ export {
|
|
|
4199
4711
|
ping,
|
|
4200
4712
|
pruneInstance,
|
|
4201
4713
|
renderPrompt,
|
|
4714
|
+
reopenTask,
|
|
4202
4715
|
resumeTask,
|
|
4203
4716
|
sumReferenceContentChars,
|
|
4204
4717
|
taskProgress,
|