@xgjktech/xg-openclaw-harness-tools 0.4.8 → 0.4.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA+BA,QAAA,MAAM,WAAW,kEA6Df,CAAC;AAaH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiDA,QAAA,MAAM,WAAW,kEAkEf,CAAC;AAeH,eAAe,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { Type } from "typebox";
1
2
  import { defineToolPlugin } from "openclaw/plugin-sdk/tool-plugin";
2
3
  import { isSubagentSessionKey } from "openclaw/plugin-sdk/routing";
3
4
  import { resolvePlanDbPath, SqlitePlanStore, SqliteActionStore } from "@xgjktech/xg-openclaw-shared";
@@ -7,6 +8,18 @@ import { ACTION_DISPATCH_DESCRIPTION, ActionDispatchParams, buildActionDispatchT
7
8
  import { toPlanOrigin } from "./plan-origin.js";
8
9
  import { buildPlanPromptInjection } from "./plan-prompt.js";
9
10
  const PLUGIN_ID = "xg-harness-tools";
11
+ // 计划功能总开关:默认 false(关闭 xg_plan_write / xg_plan_view 及主动建计划 prompt 注入)。
12
+ // 代码与测试保留,部署时在插件配置里设 { "enablePlan": true } 即可重新启用。
13
+ const PluginConfigSchema = Type.Object({
14
+ enablePlan: Type.Optional(Type.Boolean({
15
+ default: false,
16
+ description: "启用 xg 计划工具(xg_plan_write / xg_plan_view)与主动建计划 prompt 注入。默认 false。",
17
+ })),
18
+ });
19
+ /** 计划功能是否启用:仅显式 true 才开启,缺省/其他值一律视为关闭。 */
20
+ function isPlanEnabled(pluginConfig) {
21
+ return pluginConfig?.enablePlan === true;
22
+ }
10
23
  // 临时诊断日志:确认 subagent 会话的 sessionKey 是否到达 hook/tool factory 且判定正确。确认后删除。
11
24
  function logPlanGate(api, tag, sessionKey) {
12
25
  api.runtime?.logging
@@ -20,6 +33,7 @@ const pluginEntry = defineToolPlugin({
20
33
  id: PLUGIN_ID,
21
34
  name: "XG Harness Tools",
22
35
  description: "企业工具插件:计划管理与通用动作分发(plan_write / plan_view / action_dispatch)",
36
+ configSchema: PluginConfigSchema,
23
37
  tools: (tool) => {
24
38
  let planStore;
25
39
  let actionStore;
@@ -44,9 +58,12 @@ const pluginEntry = defineToolPlugin({
44
58
  description: PLAN_WRITE_DESCRIPTION,
45
59
  parameters: PlanWriteParams,
46
60
  optional: true,
47
- factory: ({ api, toolContext }) => {
48
- // 计划只允许主 agent 维护;subagent 会话不注册计划工具,杜绝其建计划。
61
+ factory: ({ api, config, toolContext }) => {
62
+ // 计划功能默认关闭;仅显式 enablePlan:true 时注册。
49
63
  logPlanGate(api, "plan_write_factory", toolContext.sessionKey);
64
+ if (!config.enablePlan)
65
+ return null;
66
+ // 计划只允许主 agent 维护;subagent 会话不注册计划工具,杜绝其建计划。
50
67
  if (isSubagentSessionKey(toolContext.sessionKey))
51
68
  return null;
52
69
  return buildPlanWriteTool(getPlanStore(api), toPlanOrigin(toolContext));
@@ -58,8 +75,11 @@ const pluginEntry = defineToolPlugin({
58
75
  description: PLAN_VIEW_DESCRIPTION,
59
76
  parameters: PlanViewParams,
60
77
  optional: true,
61
- factory: ({ api, toolContext }) => {
78
+ factory: ({ api, config, toolContext }) => {
79
+ // 计划功能默认关闭;仅显式 enablePlan:true 时注册。
62
80
  logPlanGate(api, "plan_view_factory", toolContext.sessionKey);
81
+ if (!config.enablePlan)
82
+ return null;
63
83
  if (isSubagentSessionKey(toolContext.sessionKey))
64
84
  return null;
65
85
  return buildPlanViewTool({ store: getPlanStore(api), origin: toPlanOrigin(toolContext) });
@@ -81,6 +101,9 @@ const pluginEntry = defineToolPlugin({
81
101
  const baseRegister = pluginEntry.register;
82
102
  pluginEntry.register = (api) => {
83
103
  baseRegister(api);
104
+ // 计划功能默认关闭时,不注入主动建计划纪律。
105
+ if (!isPlanEnabled(api.pluginConfig))
106
+ return;
84
107
  api.on("before_prompt_build", (event, ctx) => {
85
108
  logPlanGate(api, "hook", ctx.sessionKey);
86
109
  return buildPlanPromptInjection(event, ctx);
@@ -1 +1 @@
1
- {"version":3,"file":"plan-write-tool.d.ts","sourceRoot":"","sources":["../src/plan-write-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,EAGf,MAAM,8BAA8B,CAAC;AAkCtC,eAAO,MAAM,eAAe;;;;;;;;;EAwB3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB,QA4BvB,CAAC;AA0Eb,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,CA2HtF"}
1
+ {"version":3,"file":"plan-write-tool.d.ts","sourceRoot":"","sources":["../src/plan-write-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,EAGf,MAAM,8BAA8B,CAAC;AAkCtC,eAAO,MAAM,eAAe;;;;;;;;;EAwB3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB,QA6BvB,CAAC;AA+Gb,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,CA4ItF"}
@@ -62,6 +62,7 @@ export const PLAN_WRITE_DESCRIPTION = [
62
62
  "- 更新计划内容时必须重新提交 goal 和所有要保留的 tasks,包括未变化任务及其当前 status/note。只提交变化项会删除其他任务;记不清时先用 xg_plan_view 查看。",
63
63
  "- goal 用一句话;tasks 通常 3-7 项,每项是能判断是否完成的具体动作,不写 TODO、待定或内部思考。",
64
64
  "- status 为 pending、in_progress、completed 或 blocked。通常只有一项 in_progress,确实并行时可以有多项;blocked 时必须用 note 写明原因和继续所需条件。",
65
+ "- 已完成任务不可回退:一旦某项标记 completed,后续回写必须保持 completed,禁止改回 pending/in_progress/blocked。若执行中发现此前完成结论不成立或需返工,保留该 completed 项(可在 note 中说明返工原因),新增一条后续任务承接返工/补做,并相应调整其后的步骤。",
65
66
  "- 同一件工作只维护一份计划;任务方向变化时,先取消不再推进的旧计划({planId, cancel:true})再新建。",
66
67
  ].join("\n");
67
68
  function toTask(input) {
@@ -74,6 +75,32 @@ function toTask(input) {
74
75
  }
75
76
  return task;
76
77
  }
78
+ function normalizeTaskTitle(title) {
79
+ return title.trim();
80
+ }
81
+ /**
82
+ * 检测"已完成任务被回退":以规范化标题对齐旧任务与新提交任务,
83
+ * 凡旧任务为 completed 而新提交同名任务状态不再是 completed,即为回退。
84
+ * 同名任务整体删除属于整张覆盖语义(未提交即删除),不算回退。
85
+ */
86
+ function findTaskStatusRegressions(existing, nextTasks) {
87
+ const completedTitles = new Set();
88
+ for (const task of existing.tasks) {
89
+ if (task.status === "completed") {
90
+ completedTitles.add(normalizeTaskTitle(task.title));
91
+ }
92
+ }
93
+ const regressions = [];
94
+ for (const task of nextTasks) {
95
+ const nextStatus = (task.status ?? "pending");
96
+ if (nextStatus === "completed")
97
+ continue;
98
+ if (completedTitles.has(normalizeTaskTitle(task.title))) {
99
+ regressions.push({ title: task.title, from: "completed", to: nextStatus });
100
+ }
101
+ }
102
+ return regressions;
103
+ }
77
104
  function buildPlan(goal, tasks, existing, planId, origin, now) {
78
105
  const plan = {
79
106
  planId,
@@ -191,6 +218,21 @@ export function buildPlanWriteTool(store, origin) {
191
218
  return toolJsonResult(result);
192
219
  }
193
220
  }
221
+ if (existing !== undefined) {
222
+ const regressions = findTaskStatusRegressions(existing, params.tasks);
223
+ if (regressions.length > 0) {
224
+ const detail = `${regressions
225
+ .map((regression) => `「${compactText(regression.title)}」${regression.from} → ${regression.to}`)
226
+ .join(";")}。` +
227
+ "已完成任务禁止回退:若执行中发现此前完成结论不成立或需返工,请保留该 completed 项," +
228
+ "新增一条后续任务说明补救/返工动作并相应调整后续步骤,而不是把已完成项改回未完成。";
229
+ const result = {
230
+ ok: false,
231
+ error: { code: "TASK_STATUS_REGRESSION", detail },
232
+ };
233
+ return toolJsonResult(result);
234
+ }
235
+ }
194
236
  let warnings;
195
237
  if (planIdParam === undefined && scope !== undefined) {
196
238
  const warning = unfinishedPlanWarning(store.listPlansByOrigin(scope), Date.now());
@@ -6,7 +6,13 @@
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": true,
9
- "properties": {}
9
+ "properties": {
10
+ "enablePlan": {
11
+ "type": "boolean",
12
+ "default": false,
13
+ "description": "启用 xg 计划工具(xg_plan_write / xg_plan_view)与主动建计划 prompt 注入。默认 false。"
14
+ }
15
+ }
10
16
  },
11
17
  "contracts": {
12
18
  "tools": ["xg_plan_write", "xg_plan_view", "xg_action_dispatch"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xgjktech/xg-openclaw-harness-tools",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "description": "企业工具插件:plan_write / plan_view / action_dispatch(OpenClaw 第三方工具插件)",
5
5
  "license": "MIT",
6
6
  "type": "module",