@xgjktech/xg_cwork_im 1.17.1 → 1.17.2
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/README.md +433 -433
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -25
- package/dist/index.js.map +1 -1
- package/dist/src/connection.d.ts +1 -1
- package/dist/src/connection.d.ts.map +1 -1
- package/dist/src/connection.js +2 -2
- package/dist/src/connection.js.map +1 -1
- package/dist/src/deliver-text.d.ts.map +1 -1
- package/dist/src/deliver-text.js +16 -4
- package/dist/src/deliver-text.js.map +1 -1
- package/dist/src/deliver-text.test.js +22 -22
- package/dist/src/dispatch-mentioned-reply.d.ts.map +1 -1
- package/dist/src/dispatch-mentioned-reply.js +0 -2
- package/dist/src/dispatch-mentioned-reply.js.map +1 -1
- package/dist/src/send-service.d.ts.map +1 -1
- package/dist/src/send-service.js +4 -1
- package/dist/src/send-service.js.map +1 -1
- package/dist/src/subagent-monitor.js +17 -11
- package/dist/src/subagent-monitor.js.map +1 -1
- package/dist/src/turn-deliver-buffer.test.js +25 -25
- package/openclaw.plugin.json +26 -27
- package/package.json +72 -76
- package/dist/src/plan-blocked-notice.d.ts +0 -14
- package/dist/src/plan-blocked-notice.d.ts.map +0 -1
- package/dist/src/plan-blocked-notice.js +0 -41
- package/dist/src/plan-blocked-notice.js.map +0 -1
- package/dist/src/plan-blocked-notice.test.d.ts +0 -2
- package/dist/src/plan-blocked-notice.test.d.ts.map +0 -1
- package/dist/src/plan-blocked-notice.test.js +0 -96
- package/dist/src/plan-blocked-notice.test.js.map +0 -1
- package/dist/src/plan-event-subscription.d.ts +0 -36
- package/dist/src/plan-event-subscription.d.ts.map +0 -1
- package/dist/src/plan-event-subscription.js +0 -57
- package/dist/src/plan-event-subscription.js.map +0 -1
- package/dist/src/plan-event-subscription.test.d.ts +0 -2
- package/dist/src/plan-event-subscription.test.d.ts.map +0 -1
- package/dist/src/plan-event-subscription.test.js +0 -167
- package/dist/src/plan-event-subscription.test.js.map +0 -1
- package/dist/src/plan-session-registry.d.ts +0 -24
- package/dist/src/plan-session-registry.d.ts.map +0 -1
- package/dist/src/plan-session-registry.js +0 -84
- package/dist/src/plan-session-registry.js.map +0 -1
- package/dist/src/plan-session-registry.test.d.ts +0 -2
- package/dist/src/plan-session-registry.test.d.ts.map +0 -1
- package/dist/src/plan-session-registry.test.js +0 -109
- package/dist/src/plan-session-registry.test.js.map +0 -1
- package/dist/src/plan-stat-event.d.ts +0 -28
- package/dist/src/plan-stat-event.d.ts.map +0 -1
- package/dist/src/plan-stat-event.js +0 -68
- package/dist/src/plan-stat-event.js.map +0 -1
- package/dist/src/plan-stat-event.test.d.ts +0 -2
- package/dist/src/plan-stat-event.test.d.ts.map +0 -1
- package/dist/src/plan-stat-event.test.js +0 -167
- package/dist/src/plan-stat-event.test.js.map +0 -1
- package/dist/src/plan-store-access.d.ts +0 -23
- package/dist/src/plan-store-access.d.ts.map +0 -1
- package/dist/src/plan-store-access.js +0 -96
- package/dist/src/plan-store-access.js.map +0 -1
- package/dist/src/plan-store-access.test.d.ts +0 -2
- package/dist/src/plan-store-access.test.d.ts.map +0 -1
- package/dist/src/plan-store-access.test.js +0 -207
- package/dist/src/plan-store-access.test.js.map +0 -1
- package/dist/src/plan-tool-middleware.d.ts +0 -22
- package/dist/src/plan-tool-middleware.d.ts.map +0 -1
- package/dist/src/plan-tool-middleware.js +0 -85
- package/dist/src/plan-tool-middleware.js.map +0 -1
- package/dist/src/plan-tool-middleware.test.d.ts +0 -2
- package/dist/src/plan-tool-middleware.test.d.ts.map +0 -1
- package/dist/src/plan-tool-middleware.test.js +0 -488
- package/dist/src/plan-tool-middleware.test.js.map +0 -1
- package/dist/src/plan-tool-result.d.ts +0 -20
- package/dist/src/plan-tool-result.d.ts.map +0 -1
- package/dist/src/plan-tool-result.js +0 -78
- package/dist/src/plan-tool-result.js.map +0 -1
- package/dist/src/plan-tool-result.test.d.ts +0 -2
- package/dist/src/plan-tool-result.test.d.ts.map +0 -1
- package/dist/src/plan-tool-result.test.js +0 -107
- package/dist/src/plan-tool-result.test.js.map +0 -1
- package/dist/src/plan-ws-registry.d.ts +0 -11
- package/dist/src/plan-ws-registry.d.ts.map +0 -1
- package/dist/src/plan-ws-registry.js +0 -27
- package/dist/src/plan-ws-registry.js.map +0 -1
- package/dist/src/plan-ws-registry.test.d.ts +0 -2
- package/dist/src/plan-ws-registry.test.d.ts.map +0 -1
- package/dist/src/plan-ws-registry.test.js +0 -43
- package/dist/src/plan-ws-registry.test.js.map +0 -1
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { createPlanEventHandler } from "./plan-event-subscription.js";
|
|
4
|
-
const FAKE_CTX = {
|
|
5
|
-
getRunContext: () => undefined,
|
|
6
|
-
setRunContext: () => { },
|
|
7
|
-
clearRunContext: () => { },
|
|
8
|
-
};
|
|
9
|
-
function makePlan(overrides = {}) {
|
|
10
|
-
return {
|
|
11
|
-
planId: "plan-1",
|
|
12
|
-
goal: "迁移配置到新版本",
|
|
13
|
-
createdAt: "2026-07-27T00:00:00.000Z",
|
|
14
|
-
updatedAt: "2026-07-27T00:00:00.000Z",
|
|
15
|
-
tasks: [],
|
|
16
|
-
...overrides,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
function makeBlockedPayload(overrides = {}) {
|
|
20
|
-
return {
|
|
21
|
-
kind: "plan_update",
|
|
22
|
-
planId: "plan-1",
|
|
23
|
-
goal: "迁移配置到新版本",
|
|
24
|
-
action: "advance",
|
|
25
|
-
taskIndex: 0,
|
|
26
|
-
taskTitle: "备份旧配置",
|
|
27
|
-
taskStatus: "blocked",
|
|
28
|
-
blockedNote: "缺少权限",
|
|
29
|
-
summary: { total: 3, completed: 1, blocked: 1, inProgress: 0 },
|
|
30
|
-
runId: "run-1",
|
|
31
|
-
...overrides,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
class RecordingDeps {
|
|
35
|
-
planById = new Map();
|
|
36
|
-
planStatCalls = [];
|
|
37
|
-
getPlanById = (planId) => this.planById.get(planId);
|
|
38
|
-
sendPlanStat = (params) => {
|
|
39
|
-
this.planStatCalls.push(params);
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
describe("createPlanEventHandler: isPlanEventPayload 守卫", () => {
|
|
43
|
-
it("rejects malformed data without pushing or throwing", async () => {
|
|
44
|
-
const deps = new RecordingDeps();
|
|
45
|
-
const handle = createPlanEventHandler(deps);
|
|
46
|
-
const event = {
|
|
47
|
-
runId: "run-1",
|
|
48
|
-
seq: 1,
|
|
49
|
-
stream: "xg-harness-tools.plan",
|
|
50
|
-
ts: Date.now(),
|
|
51
|
-
data: { kind: "not_plan_update" },
|
|
52
|
-
};
|
|
53
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
54
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
55
|
-
});
|
|
56
|
-
it("rejects when data is not an object at all", async () => {
|
|
57
|
-
const deps = new RecordingDeps();
|
|
58
|
-
const handle = createPlanEventHandler(deps);
|
|
59
|
-
const event = {
|
|
60
|
-
runId: "run-1",
|
|
61
|
-
seq: 1,
|
|
62
|
-
stream: "xg-harness-tools.plan",
|
|
63
|
-
ts: Date.now(),
|
|
64
|
-
data: null,
|
|
65
|
-
};
|
|
66
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
67
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
68
|
-
});
|
|
69
|
-
it("rejects a payload that violates kind only — everything else is valid (pins the guard)", async () => {
|
|
70
|
-
const deps = new RecordingDeps();
|
|
71
|
-
const handle = createPlanEventHandler(deps);
|
|
72
|
-
const event = {
|
|
73
|
-
runId: "run-1",
|
|
74
|
-
seq: 1,
|
|
75
|
-
stream: "xg-harness-tools.plan",
|
|
76
|
-
ts: Date.now(),
|
|
77
|
-
data: makeBlockedPayload({ kind: "some_other_plugin_event" }),
|
|
78
|
-
};
|
|
79
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
80
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
81
|
-
});
|
|
82
|
-
it("rejects a payload with a malformed summary — everything else is valid", async () => {
|
|
83
|
-
const deps = new RecordingDeps();
|
|
84
|
-
const handle = createPlanEventHandler(deps);
|
|
85
|
-
const event = {
|
|
86
|
-
runId: "run-1",
|
|
87
|
-
seq: 1,
|
|
88
|
-
stream: "xg-harness-tools.plan",
|
|
89
|
-
ts: Date.now(),
|
|
90
|
-
data: makeBlockedPayload({ summary: {} }),
|
|
91
|
-
};
|
|
92
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
93
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
describe("createPlanEventHandler: 反查到 plan → 发 PLAN_STAT", () => {
|
|
97
|
-
it("反查到全量 plan → 调用 sendPlanStat,source === \"tool\"", async () => {
|
|
98
|
-
const deps = new RecordingDeps();
|
|
99
|
-
const plan = makePlan({
|
|
100
|
-
tasks: [{ title: "备份旧配置", status: "blocked", note: "缺少权限" }],
|
|
101
|
-
});
|
|
102
|
-
deps.planById.set("plan-1", plan);
|
|
103
|
-
const handle = createPlanEventHandler(deps);
|
|
104
|
-
const event = {
|
|
105
|
-
runId: "run-1",
|
|
106
|
-
seq: 1,
|
|
107
|
-
stream: "xg-harness-tools.plan",
|
|
108
|
-
ts: Date.now(),
|
|
109
|
-
data: makeBlockedPayload(),
|
|
110
|
-
};
|
|
111
|
-
await handle(event, FAKE_CTX);
|
|
112
|
-
assert.equal(deps.planStatCalls.length, 1);
|
|
113
|
-
assert.equal(deps.planStatCalls[0].source, "tool");
|
|
114
|
-
assert.equal(deps.planStatCalls[0].plan.planId, "plan-1");
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe("createPlanEventHandler: 反查不到 → 不发不抛", () => {
|
|
118
|
-
it("getPlanById 返回 undefined → 不调用 sendPlanStat,不抛", async () => {
|
|
119
|
-
const deps = new RecordingDeps();
|
|
120
|
-
const handle = createPlanEventHandler(deps);
|
|
121
|
-
const event = {
|
|
122
|
-
runId: "run-1",
|
|
123
|
-
seq: 1,
|
|
124
|
-
stream: "xg-harness-tools.plan",
|
|
125
|
-
ts: Date.now(),
|
|
126
|
-
data: makeBlockedPayload({ planId: "plan-does-not-exist" }),
|
|
127
|
-
};
|
|
128
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
129
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe("createPlanEventHandler: handle 内部出错不外抛", () => {
|
|
133
|
-
it("resolves normally even when getPlanById throws", async () => {
|
|
134
|
-
const deps = new RecordingDeps();
|
|
135
|
-
deps.getPlanById = () => {
|
|
136
|
-
throw new Error("boom");
|
|
137
|
-
};
|
|
138
|
-
const handle = createPlanEventHandler(deps);
|
|
139
|
-
const event = {
|
|
140
|
-
runId: "run-1",
|
|
141
|
-
seq: 1,
|
|
142
|
-
stream: "xg-harness-tools.plan",
|
|
143
|
-
ts: Date.now(),
|
|
144
|
-
data: makeBlockedPayload(),
|
|
145
|
-
};
|
|
146
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
147
|
-
assert.equal(deps.planStatCalls.length, 0);
|
|
148
|
-
});
|
|
149
|
-
it("resolves normally even when sendPlanStat throws", async () => {
|
|
150
|
-
const deps = new RecordingDeps();
|
|
151
|
-
const plan = makePlan({ tasks: [{ title: "t1", status: "blocked", note: "n" }] });
|
|
152
|
-
deps.planById.set("plan-1", plan);
|
|
153
|
-
deps.sendPlanStat = () => {
|
|
154
|
-
throw new Error("boom");
|
|
155
|
-
};
|
|
156
|
-
const handle = createPlanEventHandler(deps);
|
|
157
|
-
const event = {
|
|
158
|
-
runId: "run-1",
|
|
159
|
-
seq: 1,
|
|
160
|
-
stream: "xg-harness-tools.plan",
|
|
161
|
-
ts: Date.now(),
|
|
162
|
-
data: makeBlockedPayload(),
|
|
163
|
-
};
|
|
164
|
-
await assert.doesNotReject(() => Promise.resolve(handle(event, FAKE_CTX)));
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
//# sourceMappingURL=plan-event-subscription.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-event-subscription.test.js","sourceRoot":"","sources":["../../src/plan-event-subscription.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { BlockedTaskNotice } from "./plan-blocked-notice.js";
|
|
2
|
-
export interface ToolCallTarget {
|
|
3
|
-
groupId: string;
|
|
4
|
-
token: string;
|
|
5
|
-
sessionKey?: string;
|
|
6
|
-
}
|
|
7
|
-
/** 测试用:替换时间源,避免测 TTL 时 sleep。 */
|
|
8
|
-
export declare function setNowFnForTest(fn: () => number): void;
|
|
9
|
-
export declare function registerToolCallTarget(toolCallId: string, target: ToolCallTarget): void;
|
|
10
|
-
/** 取出并删除(一次性消费)。未命中返回 undefined。 */
|
|
11
|
-
export declare function takeToolCallTarget(toolCallId: string): ToolCallTarget | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* 传入本次扫描出的全部 notice,返回其中「需要推送的新增项」,并同步更新集合。
|
|
14
|
-
*
|
|
15
|
-
* 语义(按 DESIGN.md D2):
|
|
16
|
-
* - 新增 = 本次 keys − 已推送 keys → 返回它们
|
|
17
|
-
* - 清理 = 已推送集中「本次已不在」的 key → 移除(让 blocked→修复→再 blocked 能重新推)
|
|
18
|
-
* - 已推送集 = 已推送 ∪ 新增
|
|
19
|
-
* - 按 planId 分桶
|
|
20
|
-
*/
|
|
21
|
-
export declare function diffAndMarkBlockedNotices(planId: string, notices: readonly BlockedTaskNotice[]): BlockedTaskNotice[];
|
|
22
|
-
/** 测试用:重置模块级缓存与 stateDir */
|
|
23
|
-
export declare function resetPlanSessionRegistryForTest(): void;
|
|
24
|
-
//# sourceMappingURL=plan-session-registry.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-session-registry.d.ts","sourceRoot":"","sources":["../../src/plan-session-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAeD,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI,CAEtD;AA0BD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAMvF;AAED,oCAAoC;AACpC,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAUjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,iBAAiB,EAAE,GACtC,iBAAiB,EAAE,CAsBrB;AAED,4BAA4B;AAC5B,wBAAgB,+BAA+B,IAAI,IAAI,CAItD"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/** toolCallId → 投递目标表的 TTL:超过这个时长未被消费的登记视为过期。 */
|
|
2
|
-
const TOOL_CALL_TARGET_TTL_MS = 10 * 60 * 1000;
|
|
3
|
-
/** toolCallId → 投递目标表的容量上限:超出时逐出最旧的条目(插入序)。 */
|
|
4
|
-
const TOOL_CALL_TARGET_CAPACITY = 500;
|
|
5
|
-
let nowFn = () => Date.now();
|
|
6
|
-
/** 测试用:替换时间源,避免测 TTL 时 sleep。 */
|
|
7
|
-
export function setNowFnForTest(fn) {
|
|
8
|
-
nowFn = fn;
|
|
9
|
-
}
|
|
10
|
-
const toolCallTargets = new Map();
|
|
11
|
-
/** planId → 已推送 blocked notice key 集合 */
|
|
12
|
-
const blockedNotifiedKeys = new Map();
|
|
13
|
-
function evictExpiredToolCallTargets() {
|
|
14
|
-
const now = nowFn();
|
|
15
|
-
for (const [toolCallId, entry] of toolCallTargets) {
|
|
16
|
-
if (now - entry.registeredAt > TOOL_CALL_TARGET_TTL_MS) {
|
|
17
|
-
toolCallTargets.delete(toolCallId);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function evictOldestToolCallTargetsOverCapacity() {
|
|
22
|
-
while (toolCallTargets.size > TOOL_CALL_TARGET_CAPACITY) {
|
|
23
|
-
const oldestKey = toolCallTargets.keys().next().value;
|
|
24
|
-
if (oldestKey === undefined) {
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
toolCallTargets.delete(oldestKey);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export function registerToolCallTarget(toolCallId, target) {
|
|
31
|
-
evictExpiredToolCallTargets();
|
|
32
|
-
// 重新登记同一 id 应刷新插入序(视为新条目),先删再插
|
|
33
|
-
toolCallTargets.delete(toolCallId);
|
|
34
|
-
toolCallTargets.set(toolCallId, { target, registeredAt: nowFn() });
|
|
35
|
-
evictOldestToolCallTargetsOverCapacity();
|
|
36
|
-
}
|
|
37
|
-
/** 取出并删除(一次性消费)。未命中返回 undefined。 */
|
|
38
|
-
export function takeToolCallTarget(toolCallId) {
|
|
39
|
-
const entry = toolCallTargets.get(toolCallId);
|
|
40
|
-
if (!entry) {
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
toolCallTargets.delete(toolCallId);
|
|
44
|
-
if (nowFn() - entry.registeredAt > TOOL_CALL_TARGET_TTL_MS) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
return entry.target;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* 传入本次扫描出的全部 notice,返回其中「需要推送的新增项」,并同步更新集合。
|
|
51
|
-
*
|
|
52
|
-
* 语义(按 DESIGN.md D2):
|
|
53
|
-
* - 新增 = 本次 keys − 已推送 keys → 返回它们
|
|
54
|
-
* - 清理 = 已推送集中「本次已不在」的 key → 移除(让 blocked→修复→再 blocked 能重新推)
|
|
55
|
-
* - 已推送集 = 已推送 ∪ 新增
|
|
56
|
-
* - 按 planId 分桶
|
|
57
|
-
*/
|
|
58
|
-
export function diffAndMarkBlockedNotices(planId, notices) {
|
|
59
|
-
const notified = blockedNotifiedKeys.get(planId) ?? new Set();
|
|
60
|
-
const currentKeys = new Set(notices.map((n) => n.key));
|
|
61
|
-
const fresh = notices.filter((n) => !notified.has(n.key));
|
|
62
|
-
for (const key of notified) {
|
|
63
|
-
if (!currentKeys.has(key)) {
|
|
64
|
-
notified.delete(key);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
for (const notice of fresh) {
|
|
68
|
-
notified.add(notice.key);
|
|
69
|
-
}
|
|
70
|
-
if (notified.size > 0) {
|
|
71
|
-
blockedNotifiedKeys.set(planId, notified);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
blockedNotifiedKeys.delete(planId);
|
|
75
|
-
}
|
|
76
|
-
return fresh;
|
|
77
|
-
}
|
|
78
|
-
/** 测试用:重置模块级缓存与 stateDir */
|
|
79
|
-
export function resetPlanSessionRegistryForTest() {
|
|
80
|
-
toolCallTargets.clear();
|
|
81
|
-
blockedNotifiedKeys.clear();
|
|
82
|
-
nowFn = () => Date.now();
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=plan-session-registry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-session-registry.js","sourceRoot":"","sources":["../../src/plan-session-registry.ts"],"names":[],"mappings":"AAQA,iDAAiD;AACjD,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE/C,+CAA+C;AAC/C,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAOtC,IAAI,KAAK,GAAiB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAE3C,iCAAiC;AACjC,MAAM,UAAU,eAAe,CAAC,EAAgB;IAC5C,KAAK,GAAG,EAAE,CAAC;AACf,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,EAA+B,CAAC;AAE/D,yCAAyC;AACzC,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAC;AAE3D,SAAS,2BAA2B;IAChC,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IACpB,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,eAAe,EAAE,CAAC;QAChD,IAAI,GAAG,GAAG,KAAK,CAAC,YAAY,GAAG,uBAAuB,EAAE,CAAC;YACrD,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,sCAAsC;IAC3C,OAAO,eAAe,CAAC,IAAI,GAAG,yBAAyB,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QACtD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM;QACV,CAAC;QACD,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,MAAsB;IAC7E,2BAA2B,EAAE,CAAC;IAC9B,+BAA+B;IAC/B,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACnE,sCAAsC,EAAE,CAAC;AAC7C,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACjD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,KAAK,EAAE,GAAG,KAAK,CAAC,YAAY,GAAG,uBAAuB,EAAE,CAAC;QACzD,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC;AACxB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACrC,MAAc,EACd,OAAqC;IAErC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;IACtE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE1D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACpB,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACJ,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,+BAA+B;IAC3C,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAC5B,KAAK,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-session-registry.test.d.ts","sourceRoot":"","sources":["../../src/plan-session-registry.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { beforeEach, describe, it } from "node:test";
|
|
3
|
-
import { diffAndMarkBlockedNotices, registerToolCallTarget, resetPlanSessionRegistryForTest, setNowFnForTest, takeToolCallTarget, } from "./plan-session-registry.js";
|
|
4
|
-
function makeTarget(overrides = {}) {
|
|
5
|
-
return {
|
|
6
|
-
groupId: "group-1",
|
|
7
|
-
token: "token-1",
|
|
8
|
-
...overrides,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
function makeNotice(overrides = {}) {
|
|
12
|
-
return {
|
|
13
|
-
key: "plan-1::0::缺少权限",
|
|
14
|
-
taskIndex: 0,
|
|
15
|
-
taskTitle: "备份旧配置",
|
|
16
|
-
note: "缺少权限",
|
|
17
|
-
content: "计划「X」卡在任务「备份旧配置」:缺少权限\n需要人工介入才能继续。",
|
|
18
|
-
...overrides,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
resetPlanSessionRegistryForTest();
|
|
23
|
-
});
|
|
24
|
-
describe("registerToolCallTarget / takeToolCallTarget", () => {
|
|
25
|
-
it("hits with the registered target and deletes it on consume (take twice → second undefined)", () => {
|
|
26
|
-
registerToolCallTarget("call-1", makeTarget());
|
|
27
|
-
const first = takeToolCallTarget("call-1");
|
|
28
|
-
assert.deepEqual(first, makeTarget());
|
|
29
|
-
const second = takeToolCallTarget("call-1");
|
|
30
|
-
assert.equal(second, undefined);
|
|
31
|
-
});
|
|
32
|
-
it("misses for an unregistered id", () => {
|
|
33
|
-
assert.equal(takeToolCallTarget("does-not-exist"), undefined);
|
|
34
|
-
});
|
|
35
|
-
it("expires entries past TTL (injected now, no sleep)", () => {
|
|
36
|
-
let t = 0;
|
|
37
|
-
setNowFnForTest(() => t);
|
|
38
|
-
registerToolCallTarget("call-ttl", makeTarget());
|
|
39
|
-
t = 10 * 60 * 1000 + 1; // TTL + 1ms
|
|
40
|
-
assert.equal(takeToolCallTarget("call-ttl"), undefined);
|
|
41
|
-
});
|
|
42
|
-
it("does not expire an entry read exactly at TTL boundary", () => {
|
|
43
|
-
let t = 0;
|
|
44
|
-
setNowFnForTest(() => t);
|
|
45
|
-
registerToolCallTarget("call-boundary", makeTarget());
|
|
46
|
-
t = 10 * 60 * 1000; // exactly TTL, not yet exceeded
|
|
47
|
-
assert.ok(takeToolCallTarget("call-boundary"));
|
|
48
|
-
});
|
|
49
|
-
it("evicts the oldest entry when capacity is exceeded", () => {
|
|
50
|
-
let t = 0;
|
|
51
|
-
setNowFnForTest(() => t);
|
|
52
|
-
for (let i = 0; i < 500; i++) {
|
|
53
|
-
t += 1;
|
|
54
|
-
registerToolCallTarget(`call-${i}`, makeTarget({ groupId: `g${i}` }));
|
|
55
|
-
}
|
|
56
|
-
// 表已满 500 条,call-0 是最旧的
|
|
57
|
-
t += 1;
|
|
58
|
-
registerToolCallTarget("call-500", makeTarget({ groupId: "g500" }));
|
|
59
|
-
assert.equal(takeToolCallTarget("call-0"), undefined, "oldest entry should have been evicted");
|
|
60
|
-
const kept = takeToolCallTarget("call-500");
|
|
61
|
-
assert.ok(kept);
|
|
62
|
-
assert.equal(kept.groupId, "g500");
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe("diffAndMarkBlockedNotices", () => {
|
|
66
|
-
it("returns all notices on first call", () => {
|
|
67
|
-
const notices = [makeNotice()];
|
|
68
|
-
const fresh = diffAndMarkBlockedNotices("plan-1", notices);
|
|
69
|
-
assert.deepEqual(fresh, notices);
|
|
70
|
-
});
|
|
71
|
-
it("returns empty on repeated identical call", () => {
|
|
72
|
-
const notices = [makeNotice()];
|
|
73
|
-
diffAndMarkBlockedNotices("plan-1", notices);
|
|
74
|
-
const second = diffAndMarkBlockedNotices("plan-1", notices);
|
|
75
|
-
assert.deepEqual(second, []);
|
|
76
|
-
});
|
|
77
|
-
it("treats a note change as a new notification (different key)", () => {
|
|
78
|
-
const first = [makeNotice({ key: "plan-1::0::缺少权限" })];
|
|
79
|
-
diffAndMarkBlockedNotices("plan-1", first);
|
|
80
|
-
const changed = [makeNotice({ key: "plan-1::0::权限问题已升级", note: "权限问题已升级" })];
|
|
81
|
-
const fresh = diffAndMarkBlockedNotices("plan-1", changed);
|
|
82
|
-
assert.deepEqual(fresh, changed);
|
|
83
|
-
});
|
|
84
|
-
it("clears a key once the task is no longer blocked, allowing re-notification later", () => {
|
|
85
|
-
const notice = makeNotice({ key: "plan-1::0::缺少权限" });
|
|
86
|
-
diffAndMarkBlockedNotices("plan-1", [notice]);
|
|
87
|
-
// task 修复:本次扫描不再含该 key
|
|
88
|
-
const clearedFresh = diffAndMarkBlockedNotices("plan-1", []);
|
|
89
|
-
assert.deepEqual(clearedFresh, []);
|
|
90
|
-
// 再次 blocked,同 key 应视为新增重新推送
|
|
91
|
-
const reblocked = diffAndMarkBlockedNotices("plan-1", [notice]);
|
|
92
|
-
assert.deepEqual(reblocked, [notice]);
|
|
93
|
-
});
|
|
94
|
-
it("keeps separate planIds independent", () => {
|
|
95
|
-
const noticeA = makeNotice({ key: "plan-a::0::原因A" });
|
|
96
|
-
const noticeB = makeNotice({ key: "plan-b::0::原因B" });
|
|
97
|
-
const freshA = diffAndMarkBlockedNotices("plan-a", [noticeA]);
|
|
98
|
-
const freshB = diffAndMarkBlockedNotices("plan-b", [noticeB]);
|
|
99
|
-
assert.deepEqual(freshA, [noticeA]);
|
|
100
|
-
assert.deepEqual(freshB, [noticeB]);
|
|
101
|
-
// plan-a 重复调用不应受 plan-b 影响,反之亦然
|
|
102
|
-
assert.deepEqual(diffAndMarkBlockedNotices("plan-a", [noticeA]), []);
|
|
103
|
-
assert.deepEqual(diffAndMarkBlockedNotices("plan-b", [noticeB]), []);
|
|
104
|
-
});
|
|
105
|
-
it("returns an empty array and does not throw when there are no notices", () => {
|
|
106
|
-
assert.deepEqual(diffAndMarkBlockedNotices("plan-empty", []), []);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
//# sourceMappingURL=plan-session-registry.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-session-registry.test.js","sourceRoot":"","sources":["../../src/plan-session-registry.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Plan } from "@xgjktech/xg-openclaw-shared";
|
|
2
|
-
import type { ImStreamClient } from "./connection.js";
|
|
3
|
-
/**
|
|
4
|
-
* 组装发往前端的 plan:剥离 origin(内部路由信息,含 sessionKey,前端不需要也不该看到)。
|
|
5
|
-
* 返回浅拷贝,不 mutate 入参(middleware 拿到的 plan 引用可能别处还要用)。
|
|
6
|
-
*/
|
|
7
|
-
export declare function toWirePlan(plan: Plan): Plan;
|
|
8
|
-
/**
|
|
9
|
-
* 发送一条 PLAN_STAT。绝不抛、绝不 await 调用方(内部自己 catch)。
|
|
10
|
-
*/
|
|
11
|
-
export declare function sendPlanStat(params: {
|
|
12
|
-
plan: Plan;
|
|
13
|
-
source: "tool" | "snapshot";
|
|
14
|
-
}): void;
|
|
15
|
-
/**
|
|
16
|
-
* 登记 WS client(供后续 PLAN_STAT 增量路由),登记完立刻 fire-and-forget 触发一次快照:
|
|
17
|
-
* 反查该群未完成的计划,逐个发 PLAN_STAT(source: "snapshot")。
|
|
18
|
-
*
|
|
19
|
-
* dispatch 是热路径:整个快照过程包 try/catch、绝不 await、绝不抛——快照失败不能连累
|
|
20
|
-
* WS 绑定本身(登记必须先于快照执行、且不受快照结果影响)。
|
|
21
|
-
*
|
|
22
|
-
* `deps.listPlansByOrigin` 默认注入 plan-store-access 的实现;测试可传入假实现
|
|
23
|
-
* 模拟反查异常(红线防御性场景——即便被注入的反查实现意外抛出,本函数也绝不外抛)。
|
|
24
|
-
*/
|
|
25
|
-
export declare function registerPlanWsClientAndSnapshot(groupId: string, client: ImStreamClient, replyToMsgId: string, deps?: {
|
|
26
|
-
listPlansByOrigin: (channel: string, to: string) => Plan[];
|
|
27
|
-
}): void;
|
|
28
|
-
//# sourceMappingURL=plan-stat-event.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-stat-event.d.ts","sourceRoot":"","sources":["../../src/plan-stat-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMtD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAG3C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,GAAG,IAAI,CA4BtF;AAOD;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE;IAAE,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EAAE,CAAA;CAA0B,GAC7F,IAAI,CAcN"}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { getPlanWsClient, setPlanWsClient } from "./plan-ws-registry.js";
|
|
2
|
-
import { listPlansByOrigin } from "./plan-store-access.js";
|
|
3
|
-
const LOG_PREFIX = "[xg_cwork_im] [plan-stat-event]";
|
|
4
|
-
/**
|
|
5
|
-
* 组装发往前端的 plan:剥离 origin(内部路由信息,含 sessionKey,前端不需要也不该看到)。
|
|
6
|
-
* 返回浅拷贝,不 mutate 入参(middleware 拿到的 plan 引用可能别处还要用)。
|
|
7
|
-
*/
|
|
8
|
-
export function toWirePlan(plan) {
|
|
9
|
-
const { origin: _origin, ...wirePlan } = plan;
|
|
10
|
-
return wirePlan;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* 发送一条 PLAN_STAT。绝不抛、绝不 await 调用方(内部自己 catch)。
|
|
14
|
-
*/
|
|
15
|
-
export function sendPlanStat(params) {
|
|
16
|
-
const { plan, source } = params;
|
|
17
|
-
const channel = plan.origin?.channel;
|
|
18
|
-
const to = plan.origin?.to;
|
|
19
|
-
if (channel !== "xg_cwork_im" || !to) {
|
|
20
|
-
console.warn(`${LOG_PREFIX} plan.origin 缺失或非本通道,跳过 PLAN_STAT planId=${plan.planId} channel=${channel ?? "(none)"}`);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const target = getPlanWsClient(to);
|
|
24
|
-
if (!target) {
|
|
25
|
-
console.warn(`${LOG_PREFIX} 未登记 WS client,跳过 PLAN_STAT planId=${plan.planId} groupId=${to}`);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
void target.client
|
|
29
|
-
.sendEvent({
|
|
30
|
-
groupId: to,
|
|
31
|
-
replyToMsgId: target.replyToMsgId,
|
|
32
|
-
event: "PLAN_STAT",
|
|
33
|
-
data: { source, plan: toWirePlan(plan) },
|
|
34
|
-
})
|
|
35
|
-
.catch((err) => {
|
|
36
|
-
console.warn(`${LOG_PREFIX} 发送失败 planId=${plan.planId} groupId=${to}: ${String(err)}`);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
/** 「未完成」判定:plan 中存在 status !== "completed" 的 task。 */
|
|
40
|
-
function isUnfinished(plan) {
|
|
41
|
-
return plan.tasks.some((task) => task.status !== "completed");
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* 登记 WS client(供后续 PLAN_STAT 增量路由),登记完立刻 fire-and-forget 触发一次快照:
|
|
45
|
-
* 反查该群未完成的计划,逐个发 PLAN_STAT(source: "snapshot")。
|
|
46
|
-
*
|
|
47
|
-
* dispatch 是热路径:整个快照过程包 try/catch、绝不 await、绝不抛——快照失败不能连累
|
|
48
|
-
* WS 绑定本身(登记必须先于快照执行、且不受快照结果影响)。
|
|
49
|
-
*
|
|
50
|
-
* `deps.listPlansByOrigin` 默认注入 plan-store-access 的实现;测试可传入假实现
|
|
51
|
-
* 模拟反查异常(红线防御性场景——即便被注入的反查实现意外抛出,本函数也绝不外抛)。
|
|
52
|
-
*/
|
|
53
|
-
export function registerPlanWsClientAndSnapshot(groupId, client, replyToMsgId, deps = { listPlansByOrigin }) {
|
|
54
|
-
setPlanWsClient(groupId, client, replyToMsgId);
|
|
55
|
-
try {
|
|
56
|
-
const plans = deps.listPlansByOrigin("xg_cwork_im", groupId);
|
|
57
|
-
for (const plan of plans) {
|
|
58
|
-
if (!isUnfinished(plan)) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
sendPlanStat({ plan, source: "snapshot" });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
console.warn(`${LOG_PREFIX} 会话快照失败,已吞 groupId=${groupId}: ${String(err)}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=plan-stat-event.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-stat-event.js","sourceRoot":"","sources":["../../src/plan-stat-event.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,UAAU,GAAG,iCAAiC,CAAC;AAErD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACjC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC9C,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAmD;IAC5E,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IAC3B,IAAI,OAAO,KAAK,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CACR,GAAG,UAAU,4CAA4C,IAAI,CAAC,MAAM,YAAY,OAAO,IAAI,QAAQ,EAAE,CACxG,CAAC;QACF,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,sCAAsC,IAAI,CAAC,MAAM,YAAY,EAAE,EAAE,CAAC,CAAC;QAC7F,OAAO;IACX,CAAC;IAED,KAAK,MAAM,CAAC,MAAM;SACb,SAAS,CAAC;QACP,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE;KAC3C,CAAC;SACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACpB,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,gBAAgB,IAAI,CAAC,MAAM,YAAY,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACX,CAAC;AAED,sDAAsD;AACtD,SAAS,YAAY,CAAC,IAAU;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,+BAA+B,CAC3C,OAAe,EACf,MAAsB,EACtB,YAAoB,EACpB,OAAuE,EAAE,iBAAiB,EAAE;IAE5F,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAE/C,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,SAAS;YACb,CAAC;YACD,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/C,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,sBAAsB,OAAO,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-stat-event.test.d.ts","sourceRoot":"","sources":["../../src/plan-stat-event.test.ts"],"names":[],"mappings":""}
|